GXS.MeshBuilder.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. //
  2. // The graphics engine GLXEngine. The unit of GXScene for Delphi
  3. //
  4. unit GXS.MeshBuilder;
  5. (*
  6. Build mesh objects.
  7. How often do you miss a BuildSphereMesh function for testing or editors?
  8. Well this unit is intended to solve that problem. We want fast,
  9. flexible functions with lots of options...
  10. *)
  11. interface
  12. uses
  13. System.SysUtils,
  14. System.Classes,
  15. GXS.Scene,
  16. GXS.VectorFileObjects,
  17. Stage.VectorTypes,
  18. Stage.VectorGeometry,
  19. GXS.VectorLists;
  20. procedure BuildCube(Mesh: TgxMeshObject; Position, Scale: TAffineVector);
  21. procedure BuildCylinder(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
  22. Slices: Integer);
  23. procedure BuildCylinder2(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
  24. TopRadius, BottomRadius, Height: single; Slices: Integer);
  25. // ----------------------------------------------------------------------------
  26. implementation
  27. // ----------------------------------------------------------------------------
  28. function VectorCombineWeighted(Position, Scale: TAffineVector; X, Y, Z: single)
  29. : TAffineVector;
  30. begin
  31. Result.X := Position.X + Scale.X * X;
  32. Result.Y := Position.Y + Scale.Y * Y;
  33. Result.Z := Position.Z + Scale.Z * Z;
  34. end;
  35. procedure BuildCube(Mesh: TgxMeshObject; Position, Scale: TAffineVector);
  36. var
  37. FGR: TFGVertexNormalTexIndexList;
  38. VertexOffset: Integer;
  39. NormalOffset: Integer;
  40. TextureOffset: Integer;
  41. begin
  42. // Vertexes
  43. VertexOffset := Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5,
  44. 0.5, 0.5));
  45. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, 0.5, 0.5));
  46. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, -0.5, 0.5));
  47. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, -0.5, 0.5));
  48. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, 0.5, -0.5));
  49. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, 0.5, -0.5));
  50. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5, -0.5, -0.5));
  51. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, -0.5, -0.5, -0.5));
  52. // Normals
  53. NormalOffset := Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
  54. Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
  55. Mesh.Normals.Add(AffineVectorMake(1, 0, 0));
  56. Mesh.Normals.Add(AffineVectorMake(-1, 0, 0));
  57. Mesh.Normals.Add(AffineVectorMake(0, 1, 0));
  58. Mesh.Normals.Add(AffineVectorMake(0, -1, 0));
  59. // Texture Coordinates
  60. TextureOffset := Mesh.TexCoords.Add(AffineVectorMake(1, 1, 1));
  61. Mesh.TexCoords.Add(AffineVectorMake(0, 1, 1));
  62. Mesh.TexCoords.Add(AffineVectorMake(1, 0, 1));
  63. Mesh.TexCoords.Add(AffineVectorMake(0, 0, 1));
  64. Mesh.TexCoords.Add(AffineVectorMake(1, 1, 0));
  65. Mesh.TexCoords.Add(AffineVectorMake(0, 1, 0));
  66. Mesh.TexCoords.Add(AffineVectorMake(1, 0, 0));
  67. Mesh.TexCoords.Add(AffineVectorMake(0, 0, 0));
  68. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  69. FGR.Mode := fgmmTriangles;
  70. // front
  71. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 1, VertexOffset + 3);
  72. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 3, VertexOffset + 2);
  73. FGR.NormalIndices.Add(NormalOffset + 0, NormalOffset + 0, NormalOffset + 0);
  74. FGR.NormalIndices.Add(NormalOffset + 0, NormalOffset + 0, NormalOffset + 0);
  75. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 1,
  76. TextureOffset + 3);
  77. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 3,
  78. TextureOffset + 2);
  79. // back
  80. FGR.VertexIndices.Add(VertexOffset + 4, VertexOffset + 6, VertexOffset + 7);
  81. FGR.VertexIndices.Add(VertexOffset + 4, VertexOffset + 7, VertexOffset + 5);
  82. FGR.NormalIndices.Add(NormalOffset + 1, NormalOffset + 1, NormalOffset + 1);
  83. FGR.NormalIndices.Add(NormalOffset + 1, NormalOffset + 1, NormalOffset + 1);
  84. FGR.TexCoordIndices.Add(TextureOffset + 4, TextureOffset + 6,
  85. TextureOffset + 7);
  86. FGR.TexCoordIndices.Add(TextureOffset + 4, TextureOffset + 7,
  87. TextureOffset + 5);
  88. // right
  89. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 2, VertexOffset + 6);
  90. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 6, VertexOffset + 4);
  91. FGR.NormalIndices.Add(NormalOffset + 2, NormalOffset + 2, NormalOffset + 2);
  92. FGR.NormalIndices.Add(NormalOffset + 2, NormalOffset + 2, NormalOffset + 2);
  93. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 2,
  94. TextureOffset + 6);
  95. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 6,
  96. TextureOffset + 4);
  97. // left
  98. FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + 5, VertexOffset + 7);
  99. FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + 7, VertexOffset + 3);
  100. FGR.NormalIndices.Add(NormalOffset + 3, NormalOffset + 3, NormalOffset + 3);
  101. FGR.NormalIndices.Add(NormalOffset + 3, NormalOffset + 3, NormalOffset + 3);
  102. FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + 5,
  103. TextureOffset + 7);
  104. FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + 7,
  105. TextureOffset + 3);
  106. // top
  107. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 4, VertexOffset + 5);
  108. FGR.VertexIndices.Add(VertexOffset + 0, VertexOffset + 5, VertexOffset + 1);
  109. FGR.NormalIndices.Add(NormalOffset + 4, NormalOffset + 4, NormalOffset + 4);
  110. FGR.NormalIndices.Add(NormalOffset + 4, NormalOffset + 4, NormalOffset + 4);
  111. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 4,
  112. TextureOffset + 5);
  113. FGR.TexCoordIndices.Add(TextureOffset + 0, TextureOffset + 5,
  114. TextureOffset + 1);
  115. // bottom
  116. FGR.VertexIndices.Add(VertexOffset + 2, VertexOffset + 3, VertexOffset + 7);
  117. FGR.VertexIndices.Add(VertexOffset + 2, VertexOffset + 7, VertexOffset + 6);
  118. FGR.NormalIndices.Add(NormalOffset + 5, NormalOffset + 5, NormalOffset + 5);
  119. FGR.NormalIndices.Add(NormalOffset + 5, NormalOffset + 5, NormalOffset + 5);
  120. FGR.TexCoordIndices.Add(TextureOffset + 2, TextureOffset + 3,
  121. TextureOffset + 7);
  122. FGR.TexCoordIndices.Add(TextureOffset + 2, TextureOffset + 7,
  123. TextureOffset + 6);
  124. end;
  125. procedure BuildCylinder(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
  126. Slices: Integer);
  127. var
  128. FGR: TFGVertexNormalTexIndexList;
  129. VertexOffset: Integer;
  130. NormalOffset: Integer;
  131. TextureOffset: Integer;
  132. Cosine, Sine: Array of single;
  133. xc, yc: Integer;
  134. begin
  135. If Slices < 3 then
  136. Exit;
  137. SetLength(Sine, Slices + 1);
  138. SetLength(Cosine, Slices + 1);
  139. PrepareSinCosCache(Sine, Cosine, 0, 360);
  140. VertexOffset := Mesh.Vertices.Count;
  141. NormalOffset := Mesh.Normals.Count;
  142. TextureOffset := Mesh.TexCoords.Count;
  143. For xc := 0 to Slices - 1 do
  144. begin
  145. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5 * Cosine[xc],
  146. 0.5 * Sine[xc], 0.5));
  147. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale, 0.5 * Cosine[xc],
  148. 0.5 * Sine[xc], -0.5));
  149. // Normals
  150. Mesh.Normals.Add(AffineVectorMake(Cosine[xc], Sine[xc], 0));
  151. // Texture Coordinates
  152. Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
  153. 0.5 * Cosine[xc], 0.5 * Sine[xc], 0.5));
  154. Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
  155. 0.5 * Cosine[xc], 0.5 * Sine[xc], -0.5));
  156. end;
  157. Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
  158. Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
  159. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  160. FGR.Mode := fgmmTriangles;
  161. for xc := 0 to Slices - 1 do
  162. begin
  163. yc := xc + 1;
  164. If yc = Slices then
  165. yc := 0;
  166. FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + xc * 2 + 1,
  167. VertexOffset + yc * 2 + 1);
  168. FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + yc * 2 + 1,
  169. VertexOffset + yc * 2);
  170. FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + xc,
  171. NormalOffset + yc);
  172. FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + yc,
  173. NormalOffset + yc);
  174. FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + xc * 2 + 1,
  175. TextureOffset + yc * 2 + 1);
  176. FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + yc * 2 + 1,
  177. TextureOffset + yc * 2);
  178. end;
  179. for xc := 1 to Slices - 2 do
  180. begin
  181. yc := xc + 1;
  182. FGR.VertexIndices.Add(VertexOffset, VertexOffset + xc * 2,
  183. VertexOffset + yc * 2);
  184. FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + yc * 2 + 1,
  185. VertexOffset + xc * 2 + 1);
  186. FGR.NormalIndices.Add(NormalOffset + Slices, NormalOffset + Slices,
  187. NormalOffset + Slices);
  188. FGR.NormalIndices.Add(NormalOffset + Slices + 1, NormalOffset + Slices + 1,
  189. NormalOffset + Slices + 1);
  190. FGR.TexCoordIndices.Add(TextureOffset, TextureOffset + xc * 2,
  191. TextureOffset + yc * 2);
  192. FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + yc * 2 + 1,
  193. TextureOffset + xc * 2 + 1);
  194. end;
  195. end;
  196. procedure BuildCylinder2(Mesh: TgxMeshObject; Position, Scale: TAffineVector;
  197. TopRadius, BottomRadius, Height: single; Slices: Integer);
  198. var
  199. FGR: TFGVertexNormalTexIndexList;
  200. VertexOffset: Integer;
  201. NormalOffset: Integer;
  202. TextureOffset: Integer;
  203. Cosine, Sine: Array of single;
  204. xc, yc: Integer;
  205. begin
  206. If Slices < 3 then
  207. Exit;
  208. SetLength(Sine, Slices + 1);
  209. SetLength(Cosine, Slices + 1);
  210. PrepareSinCosCache(Sine, Cosine, 0, 360);
  211. VertexOffset := Mesh.Vertices.Count;
  212. NormalOffset := Mesh.Normals.Count;
  213. TextureOffset := Mesh.TexCoords.Count;
  214. for xc := 0 to Slices - 1 do
  215. Begin
  216. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale,
  217. TopRadius * 0.5 * Cosine[xc], TopRadius * 0.5 * Sine[xc], Height / 2));
  218. Mesh.Vertices.Add(VectorCombineWeighted(Position, Scale,
  219. BottomRadius * 0.5 * Cosine[xc], BottomRadius * 0.5 * Sine[xc],
  220. -Height / 2));
  221. // Normals
  222. Mesh.Normals.Add(AffineVectorMake(Cosine[xc], Sine[xc], 0));
  223. // Texture Coordinates
  224. Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
  225. TopRadius * 0.5 * Cosine[xc], TopRadius * 0.5 * Sine[xc], Height / 2));
  226. Mesh.TexCoords.Add(VectorCombineWeighted(Position, XYZVector,
  227. BottomRadius * 0.5 * Cosine[xc], BottomRadius * 0.5 * Sine[xc],
  228. -Height / 2));
  229. end;
  230. Mesh.Normals.Add(AffineVectorMake(0, 0, 1));
  231. Mesh.Normals.Add(AffineVectorMake(0, 0, -1));
  232. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  233. FGR.Mode := fgmmTriangles;
  234. for xc := 0 to Slices - 1 do
  235. begin
  236. yc := xc + 1;
  237. If yc = Slices then
  238. yc := 0;
  239. FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + xc * 2 + 1,
  240. VertexOffset + yc * 2 + 1);
  241. FGR.VertexIndices.Add(VertexOffset + xc * 2, VertexOffset + yc * 2 + 1,
  242. VertexOffset + yc * 2);
  243. FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + xc,
  244. NormalOffset + yc);
  245. FGR.NormalIndices.Add(NormalOffset + xc, NormalOffset + yc,
  246. NormalOffset + yc);
  247. FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + xc * 2 + 1,
  248. TextureOffset + yc * 2 + 1);
  249. FGR.TexCoordIndices.Add(TextureOffset + xc * 2, TextureOffset + yc * 2 + 1,
  250. TextureOffset + yc * 2);
  251. end;
  252. for xc := 1 to Slices - 2 do
  253. begin
  254. yc := xc + 1;
  255. FGR.VertexIndices.Add(VertexOffset, VertexOffset + xc * 2,
  256. VertexOffset + yc * 2);
  257. FGR.VertexIndices.Add(VertexOffset + 1, VertexOffset + yc * 2 + 1,
  258. VertexOffset + xc * 2 + 1);
  259. FGR.NormalIndices.Add(NormalOffset + Slices, NormalOffset + Slices,
  260. NormalOffset + Slices);
  261. FGR.NormalIndices.Add(NormalOffset + Slices + 1, NormalOffset + Slices + 1,
  262. NormalOffset + Slices + 1);
  263. FGR.TexCoordIndices.Add(TextureOffset, TextureOffset + xc * 2,
  264. TextureOffset + yc * 2);
  265. FGR.TexCoordIndices.Add(TextureOffset + 1, TextureOffset + yc * 2 + 1,
  266. TextureOffset + xc * 2 + 1);
  267. end;
  268. end;
  269. end.