Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

417 строки
16 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // (c) 2009-2013 Cédric Lecacheur <jordx@free.fr>
  6. // (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the Do What The Fuck You Want To
  9. // Public License, Version 2, as published by Sam Hocevar. See
  10. // http://www.wtfpl.net/ for more details.
  11. //
  12. #pragma once
  13. //
  14. // The EasyMesh class
  15. // ------------------
  16. //
  17. #include "commandstack.h"
  18. #include "easymeshrender.h"
  19. #include "easymeshbuild.h"
  20. namespace lol
  21. {
  22. //CSGUsage --------------------------------------------------------------------
  23. /* A safe enum for MeshCSG operations. */
  24. struct CSGUsageBase : public StructSafeEnum
  25. {
  26. enum Type
  27. {
  28. Union,
  29. Substract,
  30. SubstractLoss, // will remove B from A, but not add inverted B
  31. And,
  32. Xor
  33. };
  34. protected:
  35. virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
  36. {
  37. enum_map[Union] = "Union";
  38. enum_map[Substract] = "Substract";
  39. enum_map[SubstractLoss] = "SubstractLoss";
  40. enum_map[And] = "And";
  41. enum_map[Xor] = "Xor";
  42. return true;
  43. }
  44. };
  45. typedef SafeEnum<CSGUsageBase> CSGUsage;
  46. //MeshTransform ---------------------------------------------------------------
  47. struct MeshTransformBase : public StructSafeEnum
  48. {
  49. enum Type
  50. {
  51. Taper,
  52. Twist,
  53. Bend,
  54. Stretch,
  55. Shear
  56. };
  57. protected:
  58. virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
  59. {
  60. enum_map[Taper] = "Taper";
  61. enum_map[Twist] = "Twist";
  62. enum_map[Bend] = "Bend";
  63. enum_map[Stretch] = "Stretch";
  64. enum_map[Shear] = "Shear";
  65. return true;
  66. }
  67. };
  68. typedef SafeEnum<MeshTransformBase> MeshTransform;
  69. class EasyMesh : public Mesh
  70. {
  71. friend class EasyMeshParser;
  72. friend class GpuEasyMeshData;
  73. public:
  74. EasyMesh();
  75. EasyMesh(const EasyMesh& em);
  76. bool Compile(char const *command, bool Execute = true);
  77. void ExecuteCmdStack(bool ExecAllStack = true);
  78. void MeshConvert();
  79. MeshRender GetMeshState() { return m_state; }
  80. bool SetRender(bool should_render);
  81. private:
  82. void UpdateVertexDict(array< int, int > &vertex_dict);
  83. //-------------------------------------------------------------------------
  84. //Mesh CSG operations
  85. //-------------------------------------------------------------------------
  86. public:
  87. /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
  88. void CsgUnion();
  89. /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
  90. void CsgSub();
  91. /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
  92. void CsgSubL();
  93. /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
  94. void CsgAnd();
  95. /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */
  96. void CsgXor();
  97. private:
  98. void MeshCsg(CSGUsage csg_operation);
  99. //-------------------------------------------------------------------------
  100. //Mesh Cursor operations
  101. //-------------------------------------------------------------------------
  102. public:
  103. /* [cmd:lp[ ]] will perform a loop of loopnb */
  104. void LoopStart(int loopnb);
  105. /* No cmd, implicit ] */
  106. void LoopEnd();
  107. /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
  108. void OpenBrace();
  109. /* [cmd:]] Merge current vertices with previous context */
  110. void CloseBrace();
  111. /* [cmd:tsw] When active, on negative-scaling, normal-vector correction will not occur */
  112. void ToggleScaleWinding();
  113. /* [cmd:tqw] When active, quad will have a fifth center vertex */
  114. void ToggleQuadWeighting();
  115. /* [cmd:tpbn] When active, normal will be computed after the build */
  116. void TogglePostBuildNormal();
  117. /* [cmd:tpbn] When active, prevents vertices cleanup */
  118. void ToggleVerticeNoCleanup();
  119. /* [cmd:sc] Set both color */
  120. void SetCurColor(vec4 const &color);
  121. /* [cmd:sca] Set base color A */
  122. void SetCurColorA(vec4 const &color);
  123. /* [cmd:scb] Set base color B */
  124. void SetCurColorB(vec4 const &color);
  125. /* [cmd:scv] Sets all vertices in this scope color. */
  126. void SetVertColor(vec4 const &color);
  127. //-------------------------------------------------------------------------
  128. //Internal : Basic triangle/vertex operations
  129. //-------------------------------------------------------------------------
  130. private:
  131. void AddVertex(vec3 const &coord);
  132. void AddDupVertex(int i);
  133. void AddLerpVertex(int i, int j, float alpha);
  134. void AddLerpVertex(VertexData const &vi, VertexData const &vj, float alpha);
  135. VertexData GetLerpVertex(int i, int j, float alpha);
  136. VertexData GetLerpVertex(VertexData const &vi, VertexData const &vj, float alpha);
  137. void AddQuad(int i1, int i2, int i3, int i4, int base, bool duplicate = false);
  138. void AddTriangle(int i1, int i2, int i3, int base, bool duplicate = false);
  139. void ComputeNormals(int start, int vcount);
  140. public:
  141. /* Remove all unused */
  142. void VerticesCleanup();
  143. /* Merge vertices AKA: smooth */
  144. void VerticesMerge();
  145. /* Merge vertices AKA: Flat */
  146. void VerticesSeparate();
  147. public: //DEBUG
  148. void ComputeTexCoord(float uv_scale, int uv_offset);
  149. //-------------------------------------------------------------------------
  150. //Internal : Vertices operations
  151. //-------------------------------------------------------------------------
  152. private:
  153. void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
  154. void SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale);
  155. void SetCurVertNormal(vec3 const &normal);
  156. void SetCurVertColor(vec4 const &color);
  157. void SetCurVertTexCoord(vec2 const &texcoord);
  158. void SetCurVertTexCoord2(vec2 const &texcoord);
  159. public:
  160. //-------------------------------------------------------------------------
  161. //Mesh transform operations
  162. //-------------------------------------------------------------------------
  163. /* [cmd:t/tx/ty/tz] Translate vertices
  164. - v : Translation quantity.
  165. */
  166. void Translate(vec3 const &v);
  167. /* See Rotate */
  168. void RotateX(float angle);
  169. /* See Rotate */
  170. void RotateY(float angle);
  171. /* See Rotate */
  172. void RotateZ(float angle);
  173. /* [cmd:r/rx/ry/rz] Rotate vertices
  174. - angle : rotation quantity.
  175. - axis : rotation axis.
  176. */
  177. void Rotate(float angle, vec3 const &axis);
  178. /* [cmd:rj] Randomly move vertices along Origin-to-vertex as f(vtx) = vtx + o2v * (1.0 + rand(r))
  179. - r : jitter maximum value.
  180. */
  181. void RadialJitter(float r);
  182. /* [cmd:tax] multiply axis y&z by x as f(y) = y * (1.0 + (ny * x + xoff))
  183. - ny : value of n for y.
  184. - nz : value of n for z.
  185. - xoff : value of xoff.
  186. - absolute (def:true) : if (true) Multiply will use an absolute x.
  187. */
  188. void TaperX(float ny, float nz, float xoff=0.f, bool absolute=true);
  189. /* [cmd:tay] Same as TaperX, with Y */
  190. void TaperY(float nx, float nz, float yoff=0.f, bool absolute=true);
  191. /* [cmd:taz] Same as TaperX, with Z */
  192. void TaperZ(float nx, float ny, float zoff=0.f, bool absolute=true);
  193. /* [cmd:twx] Twist vertices around x axis with x as rotation value as f(p) = (RotateX(x * t + toff) * p)
  194. - t : Angle multiplier.
  195. - toff : Applied offset.
  196. */
  197. void TwistX(float t, float toff=0.f);
  198. /* [cmd:twy] Same as TwistX, with Y */
  199. void TwistY(float t, float toff=0.f);
  200. /* [cmd:twz] Same as TwistX, with Z */
  201. void TwistZ(float t, float toff=0.f);
  202. /* [cmd:shx] Shear vertices using x value as shear quantity as f(y) = y + (ny * x + xoff)
  203. - ny : Value of n for y.
  204. - nz : Value of n for z.
  205. - xoff : Value of xoff.
  206. - absolute (def:true) : if (true) Multiply will use an absolute x.
  207. */
  208. void ShearX(float ny, float nz, float xoff=0.f, bool absolute=true);
  209. /* [cmd:shy] Same as ShearX, with Y */
  210. void ShearY(float nx, float nz, float yoff=0.f, bool absolute=true);
  211. /* [cmd:shz] Same as ShearX, with Z */
  212. void ShearZ(float nx, float ny, float zoff=0.f, bool absolute=true);
  213. /* [cmd:stx] Stretch vertices using x value as stretch quantity as f(y) = y + (pow(x, ny) + xoff)
  214. - ny : Value of n for y.
  215. - nz : Value of n for z.
  216. - xoff : Value of xoff.
  217. */
  218. void StretchX(float ny, float nz, float xoff=0.f);
  219. /* [cmd:sty] Same as StretchX, with Y */
  220. void StretchY(float nx, float nz, float yoff=0.f);
  221. /* [cmd:stz] Same as StretchX, with Z */
  222. void StretchZ(float nx, float ny, float zoff=0.f);
  223. /* [cmd:bdxy] Bend vertices using x as bend quantity along y axis using f(p) = (RotateY(x * t + toff) * p)
  224. - t : Angle multiplier.
  225. - xoff : Applied offset.
  226. */
  227. void BendXY(float t, float toff=0.f);
  228. /* [cmd:bdxz] Same as BendXY, with X & Z */
  229. void BendXZ(float t, float toff=0.f);
  230. /* [cmd:bdyx] Same as BendXY, with Y & X */
  231. void BendYX(float t, float toff=0.f);
  232. /* [cmd:bdyz] Same as BendXY, with Y & Z */
  233. void BendYZ(float t, float toff=0.f);
  234. /* [cmd:bdzx] Same as BendXY, with Z & X */
  235. void BendZX(float t, float toff=0.f);
  236. /* [cmd:bdzy] Same as BendXY, with Z & Y */
  237. void BendZY(float t, float toff=0.f);
  238. private:
  239. void DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, bool absolute=false);
  240. public:
  241. /* [cmd:s/sx/sy/sz] Scale vertices
  242. - s : scale quantity.
  243. */
  244. void Scale(float s);
  245. void Scale(vec3 const &s);
  246. /* [cmd:m*] Mirror vertices through *-plane
  247. Acts as an OpenBrace
  248. */
  249. void MirrorX();
  250. void MirrorY();
  251. void MirrorZ();
  252. /* [no-cmd] Duplicates vertices and scale duplicate
  253. Acts as an OpenBrace
  254. */
  255. void DupAndScale(vec3 const &s, bool open_brace=false);
  256. /* [cmd:ch] Performs a chamfer operation //TODO : Make it work
  257. - f : Chamfer quantity.
  258. */
  259. void Chamfer(float f);
  260. /* [cmd:splt] split triangles in 4 smaller ones
  261. - pass : Number of pass applied.
  262. */
  263. void SplitTriangles(int pass);
  264. private:
  265. void SplitTriangles(int pass, VertexDictionnary *vert_dict);
  266. public:
  267. /* [cmd:smth] Smooth the mesh by subdivising it.
  268. - pass : a pass is made of (n0 split then n1 smooth) repeat.
  269. - split_per_pass : n0 value in above explanation.
  270. - smooth_per_pass : n1 value in above explanation.
  271. */
  272. void SmoothMesh(int pass, int split_per_pass, int smooth_per_pass);
  273. //-------------------------------------------------------------------------
  274. //Mesh shape primitive operations
  275. //-------------------------------------------------------------------------
  276. /* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-.5*max(d1, d2), -.5*h, -.5*max(d1, d2)]
  277. - nbsides : Number of sides. [+.5*max(d1, d2), +.5*h, +.5*max(d1, d2)]
  278. - h : Height of the cylinder.
  279. - d1 : Lower diameter.
  280. - d2 : Upper diameter.
  281. - dualside : if (true) will also create inner sides : TOOD:TOREMOVE?? : needed ?
  282. - smooth : if (true) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
  283. - close : if (true) will add discs to close the cylinder
  284. */
  285. void AppendCylinder(int nsides, float h, float d1, float d2,
  286. bool dualside=false, bool smooth=false, bool close=false);
  287. /* [cmd:asph] Sphere centered on (0,0,0) with BBox [-.5*d][.5*d]
  288. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  289. - d : Diameter.
  290. */
  291. void AppendSphere(int ndivisions, float d);
  292. /* [cmd:acap] Capsule centered on (0,0,0) with BBox [-.5*d, -(.5*d+h), -.5*d][.5*d, (.5*d+h), .5*d]
  293. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  294. - h : Inner height.
  295. - d : Diameter.
  296. */
  297. void AppendCapsule(int ndivisions, float h, float d);
  298. /* [cmd:ato] Torus centered on (0,0,0) with BBox [-.5*d2][.5*d2]
  299. - ndivisions : number of subdivisions of the torus.
  300. - d1 : Inner diameter.
  301. - d2 : Outer diameter.
  302. */
  303. void AppendTorus(int ndivisions, float d1, float d2);
  304. /* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
  305. - size : size of the box.
  306. - chamf : size of the chamfer.
  307. */
  308. void AppendBox(vec3 const &size, float chamf=0.f);
  309. //Same as AppendBox
  310. void AppendSmoothChamfBox(vec3 const &size, float chamf);
  311. //Same as AppendBox
  312. void AppendFlatChamfBox(vec3 const &size, float chamf);
  313. //Same as AppendBox
  314. void AppendBox(vec3 const &size, float chamf, bool smooth);
  315. /* [cmd:as]
  316. Append a Star centered on (0,0,0) contained within a disc of "max(d1, d2)" diameter.
  317. - nbranches : Number of branches.
  318. - d1 : double Length of the branches.
  319. - d2 : double Length of the "branch" located between d1-branches.
  320. - fade : if (true) in-between branches use ColorB.
  321. - fade2 : if (true) Star branches use ColorB.
  322. */
  323. void AppendStar(int nbranches, float d1, float d2,
  324. bool fade=false, bool fade2=false);
  325. /* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(d1, d2), max(d1 + extrad, d2 + extrad))" diameter.
  326. Expanded star branches use ColorB.
  327. - nbranches : Number of branches.
  328. - d1 : Double Length of the branches.
  329. - d2 : Double Length of the "branch" located between r1-branches.
  330. - extrad : Extra length added to expand all branches.
  331. */
  332. void AppendExpandedStar(int nbranches, float d1, float d2, float extrad=0.f);
  333. /* [cmd:ad] Disc centered on (0,0,0) with d diameter.
  334. - nbsides : Number of sides.
  335. - d : Diameter.
  336. - fade : if (true) Outer vertices will use ColorB
  337. */
  338. void AppendDisc(int nsides, float d, bool fade=false);
  339. /* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "d" diameter.
  340. - d : diameter of the containing disc..
  341. - fade : if (true) 2nd & 3rd Vertices will use ColorB
  342. */
  343. void AppendSimpleTriangle(float d, bool fade=false);
  344. /* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size*.5f, 0, -size*.5f][size*.5f, 0, size*.5f]
  345. - size : Size of quad.
  346. - fade : if (true) 3rd & 4th Vertices will use ColorB
  347. */
  348. void AppendSimpleQuad(float size, bool fade=false);
  349. private:
  350. //complex version of above one
  351. void AppendSimpleQuad(vec2 p1, vec2 p2, float z=0.f, bool fade=false);
  352. public:
  353. /* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-.5*max(d1,d2), -.5*h, -.5*max(d1, d2)]
  354. - h : Height of the Gear. [+.5*max(d1,d2), +.5*h, +.5*max(d1, d2)]
  355. - d10 : Upper Inner diameter.
  356. - d20 : Lower Inner diameter.
  357. - d1 : Upper Outer diameter.
  358. - d2 : Lower Outer diameter.
  359. - d12 : Upper Cog diameter.
  360. - d22 : Lower Cog diameter.
  361. - sidemul : multiplier for the size of the cogs.
  362. - offset : useless
  363. */
  364. void AppendCog(int nbsides, float h, float d10, float d20, float d11,
  365. float d21, float d12, float d22, float sidemul=0.f, bool offset=false);
  366. //-------------------------------------------------------------------------
  367. //TODO : Mesh Bone operations
  368. //-------------------------------------------------------------------------
  369. //void AddBone(int parent_id) {}
  370. //Convenience functions
  371. public:
  372. ptrdiff_t GetVertexCount() { return m_vert.Count(); }
  373. vec3 const &GetVertexLocation(int i) { return m_vert[i].m_coord; }
  374. //private:
  375. array<uint16_t> m_indices;
  376. array<VertexData> m_vert;
  377. //<vert count, indices count>
  378. array<int, int> m_cursors;
  379. MeshRender m_state;
  380. public:
  381. inline EasyMeshBuildData* BD()
  382. {
  383. if (!m_build_data)
  384. m_build_data = new EasyMeshBuildData();
  385. return m_build_data;
  386. };
  387. private:
  388. class EasyMeshBuildData* m_build_data;
  389. };
  390. } /* namespace lol */