GLMeshBuilder.pas 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. //
  2. // This unit is part of the GLScene Engine, http://glscene.org
  3. //
  4. unit GLMeshBuilder;
  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. Original Author: Joen Joensen.
  11. Contributed to the GLScene community.
  12. Features: BuildCube, BuildCylinder.
  13. *)
  14. interface
  15. uses
  16. System.SysUtils,
  17. System.Classes,
  18. GLScene,
  19. GLVectorFileObjects,
  20. GLVectorTypes,
  21. GLVectorGeometry,
  22. GLVectorLists;
  23. procedure BuildCube(Mesh : TMeshObject; const Position, Scale : TAffineVector);
  24. procedure BuildCylinder(Mesh : TMeshObject; const Position, Scale : TAffineVector; Slices : Integer);
  25. procedure BuildCylinder2(Mesh : TMeshObject; const Position, Scale : TAffineVector; TopRadius,BottomRadius,Height: single; Slices : Integer);
  26. //------------------------------------------------------------------
  27. implementation
  28. //------------------------------------------------------------------
  29. function VectorCombineWeighted(const Position, Scale : TAffineVector; X, Y, Z : Single) : 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 : TMeshObject; const Position, Scale : TAffineVector);
  36. var
  37. FGR : TFGVertexNormalTexIndexList;
  38. VertexOffset : Integer;
  39. NormalOffset : Integer;
  40. TextureOffset : Integer;
  41. begin
  42. // Vertexes
  43. VertexOffset :=
  44. Mesh.Vertices.Add(VectorCombineWeighted(Position,Scale,0.5,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 :=
  54. Mesh.Normals.add(AffineVectorMake(0,0,1));
  55. Mesh.Normals.add(AffineVectorMake(0,0,-1));
  56. Mesh.Normals.add(AffineVectorMake(1,0,0));
  57. Mesh.Normals.add(AffineVectorMake(-1,0,0));
  58. Mesh.Normals.add(AffineVectorMake(0,1,0));
  59. Mesh.Normals.add(AffineVectorMake(0,-1,0));
  60. // Texture Coordinates
  61. TextureOffset :=
  62. Mesh.TexCoords.add(AffineVectorMake(1,1,1));
  63. Mesh.TexCoords.add(AffineVectorMake(0,1,1));
  64. Mesh.TexCoords.add(AffineVectorMake(1,0,1));
  65. Mesh.TexCoords.add(AffineVectorMake(0,0,1));
  66. Mesh.TexCoords.add(AffineVectorMake(1,1,0));
  67. Mesh.TexCoords.add(AffineVectorMake(0,1,0));
  68. Mesh.TexCoords.add(AffineVectorMake(1,0,0));
  69. Mesh.TexCoords.add(AffineVectorMake(0,0,0));
  70. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  71. FGR.Mode := fgmmTriangles;
  72. // front
  73. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+1,VertexOffset+3);
  74. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+3,VertexOffset+2);
  75. FGR.NormalIndices.Add(NormalOffset+0,NormalOffset+0,NormalOffset+0);
  76. FGR.NormalIndices.Add(NormalOffset+0,NormalOffset+0,NormalOffset+0);
  77. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+1,TextureOffset+3);
  78. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+3,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,TextureOffset+7);
  85. FGR.TexCoordIndices.Add(TextureOffset+4,TextureOffset+7,TextureOffset+5);
  86. // right
  87. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+2,VertexOffset+6);
  88. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+6,VertexOffset+4);
  89. FGR.NormalIndices.Add(NormalOffset+2,NormalOffset+2,NormalOffset+2);
  90. FGR.NormalIndices.Add(NormalOffset+2,NormalOffset+2,NormalOffset+2);
  91. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+2,TextureOffset+6);
  92. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+6,TextureOffset+4);
  93. // left
  94. FGR.VertexIndices.Add(VertexOffset+1,VertexOffset+5,VertexOffset+7);
  95. FGR.VertexIndices.Add(VertexOffset+1,VertexOffset+7,VertexOffset+3);
  96. FGR.NormalIndices.Add(NormalOffset+3,NormalOffset+3,NormalOffset+3);
  97. FGR.NormalIndices.Add(NormalOffset+3,NormalOffset+3,NormalOffset+3);
  98. FGR.TexCoordIndices.Add(TextureOffset+1,TextureOffset+5,TextureOffset+7);
  99. FGR.TexCoordIndices.Add(TextureOffset+1,TextureOffset+7,TextureOffset+3);
  100. // top
  101. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+4,VertexOffset+5);
  102. FGR.VertexIndices.Add(VertexOffset+0,VertexOffset+5,VertexOffset+1);
  103. FGR.NormalIndices.Add(NormalOffset+4,NormalOffset+4,NormalOffset+4);
  104. FGR.NormalIndices.Add(NormalOffset+4,NormalOffset+4,NormalOffset+4);
  105. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+4,TextureOffset+5);
  106. FGR.TexCoordIndices.Add(TextureOffset+0,TextureOffset+5,TextureOffset+1);
  107. // bottom
  108. FGR.VertexIndices.Add(VertexOffset+2,VertexOffset+3,VertexOffset+7);
  109. FGR.VertexIndices.Add(VertexOffset+2,VertexOffset+7,VertexOffset+6);
  110. FGR.NormalIndices.Add(NormalOffset+5,NormalOffset+5,NormalOffset+5);
  111. FGR.NormalIndices.Add(NormalOffset+5,NormalOffset+5,NormalOffset+5);
  112. FGR.TexCoordIndices.Add(TextureOffset+2,TextureOffset+3,TextureOffset+7);
  113. FGR.TexCoordIndices.Add(TextureOffset+2,TextureOffset+7,TextureOffset+6);
  114. end;
  115. procedure BuildCylinder(Mesh : TMeshObject; const Position, Scale : TAffineVector; Slices : Integer);
  116. var
  117. FGR : TFGVertexNormalTexIndexList;
  118. VertexOffset : Integer;
  119. NormalOffset : Integer;
  120. TextureOffset : Integer;
  121. Cosine,Sine : Array of Single;
  122. xc,yc : Integer;
  123. begin
  124. If Slices < 3 then Exit;
  125. SetLength(Sine,Slices+1);
  126. SetLength(Cosine,Slices+1);
  127. PrepareSinCosCache(Sine,Cosine,0,360);
  128. VertexOffset := Mesh.Vertices.Count;
  129. NormalOffset := Mesh.Normals.Count;
  130. TextureOffset := Mesh.TexCoords.Count;
  131. For xc := 0 to Slices-1 do
  132. begin
  133. Mesh.Vertices.Add(VectorCombineWeighted(Position,Scale,0.5*cosine[xc],0.5*sine[xc],0.5));
  134. Mesh.Vertices.Add(VectorCombineWeighted(Position,Scale,0.5*cosine[xc],0.5*sine[xc],-0.5));
  135. // Normals
  136. Mesh.Normals.add(AffineVectorMake(cosine[xc],sine[xc],0));
  137. // Texture Coordinates
  138. Mesh.TexCoords.add(VectorCombineWeighted(Position,XYZVector,0.5*cosine[xc],0.5*sine[xc],0.5));
  139. Mesh.TexCoords.add(VectorCombineWeighted(Position,XYZVector,0.5*cosine[xc],0.5*sine[xc],-0.5));
  140. end;
  141. Mesh.Normals.add(AffineVectorMake(0,0,1));
  142. Mesh.Normals.add(AffineVectorMake(0,0,-1));
  143. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  144. FGR.Mode := fgmmTriangles;
  145. For xc := 0 to Slices-1 do
  146. begin
  147. yc := xc+1;
  148. If yc = slices then yc := 0;
  149. FGR.VertexIndices.Add(VertexOffset+xc*2,VertexOffset+xc*2+1,VertexOffset+yc*2+1);
  150. FGR.VertexIndices.Add(VertexOffset+xc*2,VertexOffset+yc*2+1,VertexOffset+yc*2);
  151. FGR.NormalIndices.Add(NormalOffset+xc,NormalOffset+xc,NormalOffset+yc);
  152. FGR.NormalIndices.Add(NormalOffset+xc,NormalOffset+yc,NormalOffset+yc);
  153. FGR.TexCoordIndices.Add(TextureOffset+xc*2,TextureOffset+xc*2+1,TextureOffset+yc*2+1);
  154. FGR.TexCoordIndices.Add(TextureOffset+xc*2,TextureOffset+yc*2+1,TextureOffset+yc*2);
  155. End;
  156. For xc := 1 to Slices-2 do
  157. begin
  158. yc := xc+1;
  159. FGR.VertexIndices.Add(VertexOffset,VertexOffset+xc*2,VertexOffset+yc*2);
  160. FGR.VertexIndices.Add(VertexOffset+1,VertexOffset+yc*2+1,VertexOffset+xc*2+1);
  161. FGR.NormalIndices.Add(NormalOffset+Slices,NormalOffset+Slices,NormalOffset+Slices);
  162. FGR.NormalIndices.Add(NormalOffset+Slices+1,NormalOffset+Slices+1,NormalOffset+Slices+1);
  163. FGR.TexCoordIndices.Add(TextureOffset,TextureOffset+xc*2,TextureOffset+yc*2);
  164. FGR.TexCoordIndices.Add(TextureOffset+1,TextureOffset+yc*2+1,TextureOffset+xc*2+1);
  165. end;
  166. end;
  167. procedure BuildCylinder2(Mesh : TMeshObject; const Position, Scale : TAffineVector; TopRadius,BottomRadius,Height: single; Slices : Integer);
  168. var
  169. FGR : TFGVertexNormalTexIndexList;
  170. VertexOffset : Integer;
  171. NormalOffset : Integer;
  172. TextureOffset : Integer;
  173. Cosine,Sine : Array of Single;
  174. xc,yc : Integer;
  175. begin
  176. If Slices < 3 then Exit;
  177. SetLength(Sine,Slices+1);
  178. SetLength(Cosine,Slices+1);
  179. PrepareSinCosCache(Sine,Cosine,0,360);
  180. VertexOffset := Mesh.Vertices.Count;
  181. NormalOffset := Mesh.Normals.Count;
  182. TextureOffset := Mesh.TexCoords.Count;
  183. For xc := 0 to Slices-1 do
  184. begin
  185. Mesh.Vertices.Add(VectorCombineWeighted(Position,Scale,TopRadius*0.5*cosine[xc],TopRadius*0.5*sine[xc],Height/2));
  186. Mesh.Vertices.Add(VectorCombineWeighted(Position,Scale,BottomRadius*0.5*cosine[xc],BottomRadius*0.5*sine[xc],-Height/2));
  187. // Normals
  188. Mesh.Normals.add(AffineVectorMake(cosine[xc],sine[xc],0));
  189. // Texture Coordinates
  190. Mesh.TexCoords.add(VectorCombineWeighted(Position,XYZVector,TopRadius*0.5*cosine[xc],TopRadius*0.5*sine[xc],Height/2));
  191. Mesh.TexCoords.add(VectorCombineWeighted(Position,XYZVector,BottomRadius*0.5*cosine[xc],BottomRadius*0.5*sine[xc],-Height/2));
  192. end;
  193. Mesh.Normals.add(AffineVectorMake(0,0,1));
  194. Mesh.Normals.add(AffineVectorMake(0,0,-1));
  195. FGR := TFGVertexNormalTexIndexList.CreateOwned(Mesh.FaceGroups);
  196. FGR.Mode := fgmmTriangles;
  197. For xc := 0 to Slices-1 do
  198. begin
  199. yc := xc+1;
  200. If yc = slices then yc := 0;
  201. FGR.VertexIndices.Add(VertexOffset+xc*2,VertexOffset+xc*2+1,VertexOffset+yc*2+1);
  202. FGR.VertexIndices.Add(VertexOffset+xc*2,VertexOffset+yc*2+1,VertexOffset+yc*2);
  203. FGR.NormalIndices.Add(NormalOffset+xc,NormalOffset+xc,NormalOffset+yc);
  204. FGR.NormalIndices.Add(NormalOffset+xc,NormalOffset+yc,NormalOffset+yc);
  205. FGR.TexCoordIndices.Add(TextureOffset+xc*2,TextureOffset+xc*2+1,TextureOffset+yc*2+1);
  206. FGR.TexCoordIndices.Add(TextureOffset+xc*2,TextureOffset+yc*2+1,TextureOffset+yc*2);
  207. end;
  208. For xc := 1 to Slices-2 do
  209. begin
  210. yc := xc+1;
  211. FGR.VertexIndices.Add(VertexOffset,VertexOffset+xc*2,VertexOffset+yc*2);
  212. FGR.VertexIndices.Add(VertexOffset+1,VertexOffset+yc*2+1,VertexOffset+xc*2+1);
  213. FGR.NormalIndices.Add(NormalOffset+Slices,NormalOffset+Slices,NormalOffset+Slices);
  214. FGR.NormalIndices.Add(NormalOffset+Slices+1,NormalOffset+Slices+1,NormalOffset+Slices+1);
  215. FGR.TexCoordIndices.Add(TextureOffset,TextureOffset+xc*2,TextureOffset+yc*2);
  216. FGR.TexCoordIndices.Add(TextureOffset+1,TextureOffset+yc*2+1,TextureOffset+xc*2+1);
  217. end;
  218. end;
  219. end.