476 lines
18 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. //
  13. // The EasyMesh class
  14. // ------------------
  15. //
  16. #define VU_BONES 2
  17. #define VU_TEX_UV 1
  18. #define VU_VANILLA 0
  19. #define VERTEX_USEAGE VU_TEX_UV
  20. #if !defined __EASYMESH_EASYMESH_H__
  21. #define __EASYMESH_EASYMESH_H__
  22. namespace lol
  23. {
  24. /* A safe enum for MeshCSG operations. */
  25. struct CSGUsage
  26. {
  27. enum Value
  28. {
  29. Union,
  30. Substract,
  31. SubstractLoss, //will remove B from A, but not add inverted B
  32. And,
  33. Xor,
  34. }
  35. m_value;
  36. inline CSGUsage(Value v) : m_value(v) {}
  37. inline operator Value() { return m_value; }
  38. };
  39. /* A safe enum for VertexDictionnary operations. */
  40. struct VDictType
  41. {
  42. enum Value
  43. {
  44. DoesNotExist=-3,
  45. Alone=-2,
  46. Master=-1
  47. }
  48. m_value;
  49. inline VDictType(Value v) : m_value(v) {}
  50. inline operator Value() { return m_value; }
  51. };
  52. //a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
  53. class VertexDictionnary
  54. {
  55. public:
  56. int FindVertexMaster(const int search_idx);
  57. bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
  58. bool FindConnectedVertices(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_vert, Array<int> const *ignored_tri = NULL);
  59. bool FindConnectedTriangles(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
  60. bool FindConnectedTriangles(const ivec2 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
  61. bool FindConnectedTriangles(const ivec3 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
  62. void AddVertex(int vert_id, vec3 vert_coord);
  63. bool GetMasterList(Array<int> &ret_master_list) { ret_master_list = master_list; return ret_master_list.Count() > 0; }
  64. void Clear() { vertex_list.Empty(); }
  65. private:
  66. //<VertexId, VertexLocation, VertexMasterId>
  67. Array<int, vec3, int> vertex_list;
  68. //List of the master_ vertices
  69. Array<int> master_list;
  70. };
  71. struct Axis
  72. {
  73. enum Value
  74. {
  75. X,
  76. Y,
  77. Z
  78. }
  79. m_value;
  80. inline Axis(Value v) : m_value(v) {}
  81. inline operator Value() { return m_value; }
  82. };
  83. struct MeshBuildOperation
  84. {
  85. enum Value
  86. {
  87. Scale_Winding = 1 << 0,
  88. All = 0xffffffff
  89. }
  90. m_value;
  91. inline MeshBuildOperation(Value v) : m_value(v) {}
  92. inline MeshBuildOperation(uint64_t i) : m_value((Value)i) {}
  93. inline operator Value() { return m_value; }
  94. };
  95. class EasyMesh
  96. {
  97. friend class EasyMeshParser;
  98. public:
  99. EasyMesh();
  100. bool Compile(char const *command);
  101. void MeshConvert(Shader* ProvidedShader = NULL);
  102. void Render(mat4 const &model, float damage = 0.f);
  103. private:
  104. void UpdateVertexDict(Array< int, int > &vertex_dict);
  105. //-------------------------------------------------------------------------
  106. //Mesh CSG operations
  107. //-------------------------------------------------------------------------
  108. private:
  109. void MeshCsg(CSGUsage csg_operation);
  110. public:
  111. /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
  112. void CsgUnion() { MeshCsg(CSGUsage::Union); }
  113. /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
  114. void CsgSubstract() { MeshCsg(CSGUsage::Substract); }
  115. /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
  116. void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); }
  117. /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
  118. void CsgAnd() { MeshCsg(CSGUsage::And); }
  119. /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */
  120. void CsgXor() { MeshCsg(CSGUsage::Xor); }
  121. public:
  122. /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
  123. void OpenBrace();
  124. /* [cmd:]] Merge current vertices with previous context */
  125. void CloseBrace();
  126. /* [cmd:tsw] When activation, on negative-scaling, normal fixing will not occur */
  127. void ToggleScaleWinding();
  128. /* [cmd:sc] Set vertices color */
  129. void SetCurColor(vec4 const &color);
  130. /* [cmd:scb] Set vertices color 2 */
  131. void SetCurColor2(vec4 const &color);
  132. private:
  133. //-------------------------------------------------------------------------
  134. //Internal : Basic triangle/vertex operations
  135. //-------------------------------------------------------------------------
  136. void AddVertex(vec3 const &coord);
  137. void AddDuplicateVertex(int i);
  138. void AddLerpVertex(int i, int j, float alpha);
  139. void AppendQuad(int i1, int i2, int i3, int i4, int base);
  140. void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base);
  141. void AppendTriangle(int i1, int i2, int i3, int base);
  142. void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
  143. void ComputeNormals(int start, int vcount);
  144. public: //DEBUG
  145. void ComputeTexCoord(float uv_scale, int uv_offset);
  146. //-------------------------------------------------------------------------
  147. //Vertices operations
  148. //-------------------------------------------------------------------------
  149. void SetVertColor(vec4 const &color);
  150. void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
  151. void SetCurVertNormal(vec3 const &normal);
  152. void SetCurVertColor(vec4 const &color);
  153. void SetCurVertTexCoord(vec2 const &texcoord);
  154. public:
  155. //-------------------------------------------------------------------------
  156. //Mesh transform operations
  157. //-------------------------------------------------------------------------
  158. /* [cmd:t/tx/ty/tz] Translate vertices
  159. - v : Translation quantity.
  160. */
  161. void Translate(vec3 const &v);
  162. /* See Rotate */
  163. void RotateX(float angle);
  164. /* See Rotate */
  165. void RotateY(float angle);
  166. /* See Rotate */
  167. void RotateZ(float angle);
  168. /* [cmd:r/rx/ry/rz] Rotate vertices
  169. - angle : rotation quantity.
  170. - axis : rotation axis.
  171. */
  172. void Rotate(float angle, vec3 const &axis);
  173. /* [cmd:rj] Randomly move vertices along Origin-to-vertex as o2v *= (1.0 + rand(r))
  174. - r : jitter maximum value.
  175. */
  176. void RadialJitter(float r);
  177. /* [cmd:tax] multiply axis y&z by x as y *= (1.0 + (ny * x + xoff))
  178. - ny : value of n for y.
  179. - nz : value of n for z.
  180. - xoff : value of xoff.
  181. - absolute (def:1) : if (1) Multiply will use an absolute x.
  182. */
  183. void TaperX(float ny, float nz, float xoff, int absolute=1);
  184. /* [cmd:tay] Same as TaperX, with Y */
  185. void TaperY(float nx, float nz, float yoff, int absolute=1);
  186. /* [cmd:taz] Same as TaperX, with Z */
  187. void TaperZ(float nx, float ny, float zoff, int absolute=1);
  188. /* [cmd:twx] Twist vertices around x axis with x as rotation value as p = (RotateX(x * t + toff) * p)
  189. - t : Angle multiplier.
  190. - toff : Applied offset.
  191. */
  192. void TwistX(float t, float toff);
  193. /* [cmd:twy] Same as TwistX, with Y */
  194. void TwistY(float t, float toff);
  195. /* [cmd:twz] Same as TwistX, with Z */
  196. void TwistZ(float t, float toff);
  197. /* [cmd:shx] Shear vertices using x value as shear quantity as y += (ny * x + xoff)
  198. - ny : Value of n for y.
  199. - nz : Value of n for z.
  200. - xoff : Value of xoff.
  201. - absolute (def:1) : if (1) Multiply will use an absolute x.
  202. */
  203. void ShearX(float ny, float nz, float xoff, int absolute=1);
  204. /* [cmd:shy] Same as ShearX, with Y */
  205. void ShearY(float nx, float nz, float yoff, int absolute=1);
  206. /* [cmd:shz] Same as ShearX, with Z */
  207. void ShearZ(float nx, float ny, float zoff, int absolute=1);
  208. /* [cmd:stx] Stretch vertices using x value as stretch quantity as y += (pow(x, ny) + xoff)
  209. - ny : Value of n for y.
  210. - nz : Value of n for z.
  211. - xoff : Value of xoff.
  212. */
  213. void StretchX(float ny, float nz, float xoff);
  214. /* [cmd:sty] Same as StretchX, with Y */
  215. void StretchY(float nx, float nz, float yoff);
  216. /* [cmd:stz] Same as StretchX, with Z */
  217. void StretchZ(float nx, float ny, float zoff);
  218. /* [cmd:bdxy] Bend vertices using x as bend quantity along y axis using p = (RotateY(x * t + toff) * p)
  219. - t : Angle multiplier.
  220. - xoff : Applied offset.
  221. */
  222. void BendXY(float t, float toff);
  223. /* [cmd:bdxz] Same as BendXY, with X & Z */
  224. void BendXZ(float t, float toff);
  225. /* [cmd:bdyx] Same as BendXY, with Y & X */
  226. void BendYX(float t, float toff);
  227. /* [cmd:bdyz] Same as BendXY, with Y & Z */
  228. void BendYZ(float t, float toff);
  229. /* [cmd:bdzx] Same as BendXY, with Z & X */
  230. void BendZX(float t, float toff);
  231. /* [cmd:bdzy] Same as BendXY, with Z & Y */
  232. void BendZY(float t, float toff);
  233. private:
  234. struct MeshTransform
  235. {
  236. enum Value
  237. {
  238. Taper,
  239. Twist,
  240. Bend,
  241. Stretch,
  242. Shear
  243. }
  244. m_value;
  245. inline MeshTransform(Value v) : m_value(v) {}
  246. inline operator Value() { return m_value; }
  247. };
  248. void DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, int absolute);
  249. public:
  250. /* [cmd:s/sx/sy/sz] Scale vertices
  251. - s : scale quantity.
  252. */
  253. void Scale(vec3 const &s);
  254. /* [cmd:mx] Mirror vertices through X-plane
  255. Acts as an OpenBrace
  256. */
  257. void MirrorX();
  258. /* [cmd:my] Mirror vertices through Y-plane
  259. Acts as an OpenBrace
  260. */
  261. void MirrorY();
  262. /* [cmd:mz] Mirror vertices through Z-plane
  263. Acts as an OpenBrace
  264. */
  265. void MirrorZ();
  266. /* [no-cmd] Duplicates vertices and scale duplicate
  267. Acts as an OpenBrace
  268. */
  269. void DupAndScale(vec3 const &s);
  270. /* [cmd:ch] Performs a chamfer operation //TODO : Make it work.
  271. - f : Chamfer quantity.
  272. */
  273. void Chamfer(float f);
  274. /* [cmd:splt] split triangles in 4 smaller ones.
  275. - pass : Number of pass applied.
  276. */
  277. void SplitTriangles(int pass);
  278. private:
  279. void SplitTriangles(int pass, VertexDictionnary *vert_dict);
  280. public:
  281. /* [cmd:smth] Smooth the mesh by subdivising it.
  282. - main_pass : a main pass is made of (n0 split then n1 smooth) repeat.
  283. - split_per_main_pass : n0 value in above explanation.
  284. - smooth_per_main_pass : n1 value in above explanation.
  285. */
  286. void SmoothMesh(int main_pass, int split_per_main_pass, int smooth_per_main_pass);
  287. //-------------------------------------------------------------------------
  288. //Mesh shape operations
  289. //-------------------------------------------------------------------------
  290. /* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-.5*max(d1, d2), -.5*h, -.5*max(d1, d2)]
  291. - nbsides : Number of sides. [+.5*max(d1, d2), +.5*h, +.5*max(d1, d2)]
  292. - h : Height of the cylinder.
  293. - d1 : Lower diameter.
  294. - d2 : Upper diameter.
  295. - dualside : if (1) will also create inner sides : TOOD:TOREMOVE?? : needed ?
  296. - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
  297. - close : if (1) will add discs to close the cylinder
  298. */
  299. void AppendCylinder(int nsides, float h, float d1, float d2,
  300. int dualside, int smooth, int close);
  301. /* [cmd:asph] Sphere centered on (0,0,0) with BBox [-.5*d][.5*d]
  302. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  303. - d : Diameter.
  304. */
  305. void AppendSphere(int ndivisions, float d);
  306. /* [cmd:acap] Capsule centered on (0,0,0) with BBox [-.5*d, -(.5*d+h), -.5*d][.5*d, (.5*d+h), .5*d]
  307. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  308. - h : Inner height.
  309. - d : Diameter.
  310. */
  311. void AppendCapsule(int ndivisions, float h, float d);
  312. /* [cmd:ato] Torus centered on (0,0,0) with BBox [-.5*d2][.5*d2]
  313. - ndivisions : number of subdivisions of the torus.
  314. - d1 : Inner diameter.
  315. - d2 : Outer diameter.
  316. */
  317. void AppendTorus(int ndivisions, float d1, float d2);
  318. /* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
  319. - size : size of the box.
  320. - chamf : size of the chamfer.
  321. - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
  322. */
  323. void AppendBox(vec3 const &size, float chamf = 0.f);
  324. //Same as AppendBox
  325. void AppendSmoothChamfBox(vec3 const &size, float chamf);
  326. //Same as AppendBox
  327. void AppendFlatChamfBox(vec3 const &size, float chamf);
  328. //Same as AppendBox
  329. void AppendBox(vec3 const &size, float chamf, bool smooth);
  330. /* [cmd:as]
  331. Append a Star centered on (0,0,0) contained within a disc of "max(d1, d2)" diameter.
  332. - nbranches : Number of branches.
  333. - d1 : double Length of the branches.
  334. - d2 : double Length of the "branch" located between d1-branches.
  335. - fade : if (1) in-between branches use Color2.
  336. - fade2 : if (1) Star branches use Color2.
  337. */
  338. void AppendStar(int nbranches, float d1, float d2,
  339. int fade = 0, int fade2 = 0);
  340. /* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(d1, d2), max(d1 + extrad, d2 + extrad))" diameter.
  341. Expanded star branches use Color2.
  342. - nbranches : Number of branches.
  343. - d1 : Double Length of the branches.
  344. - d2 : Double Length of the "branch" located between r1-branches.
  345. - extrad : Extra length added to expand all branches.
  346. */
  347. void AppendExpandedStar(int nbranches, float d1, float d2, float extrad);
  348. /* [cmd:ad] Disc centered on (0,0,0) with d diameter.
  349. - nbsides : Number of sides.
  350. - d : Diameter.
  351. - fade : if (1) Outer vertices will use Color2
  352. */
  353. void AppendDisc(int nsides, float d, int fade = 0);
  354. /* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "d" diameter.
  355. - d : diameter of the containing disc..
  356. - fade : if (1) 2nd & 3rd Vertices will use Color2
  357. */
  358. void AppendSimpleTriangle(float d, int fade = 0);
  359. /* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size*.5f, 0, -size*.5f][size*.5f, 0, size*.5f]
  360. - size : Size of quad.
  361. - fade : if (1) 3rd & 4th Vertices will use Color2
  362. */
  363. void AppendSimpleQuad(float size, int fade = 0);
  364. private:
  365. //complex version of above one
  366. void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0);
  367. public:
  368. /* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-.5*max(d1,d2), -.5*h, -.5*max(d1, d2)]
  369. - h : Height of the Gear. [+.5*max(d1,d2), +.5*h, +.5*max(d1, d2)]
  370. - d10 : Upper Inner diameter.
  371. - d20 : Lower Inner diameter.
  372. - d1 : Upper Outer diameter.
  373. - d2 : Lower Outer diameter.
  374. - d12 : Upper Cog diameter.
  375. - d22 : Lower Cog diameter.
  376. - sidemul : multiplier for the size of the cogs.
  377. - offset : useless
  378. */
  379. void AppendCog(int nbsides, float h, float d10, float d20, float d1,
  380. float d2, float d12, float d22, float sidemul, int offset);
  381. //-------------------------------------------------------------------------
  382. //TODO : Mesh Bone operations
  383. //-------------------------------------------------------------------------
  384. //void AddBone(int parent_id) {}
  385. //Convenience functions
  386. public:
  387. int GetVertexCount() { return m_vert.Count(); }
  388. vec3 const &GetVertexLocation(int i) { return m_vert[i].m1; }
  389. private:
  390. vec4 m_color, m_color2;
  391. Array<uint16_t> m_indices;
  392. #if VERTEX_USEAGE == VU_BONES
  393. //TODO : -- BONE SUPPORT --
  394. //TODO : <COORD, NORM, COLOR, BONE_ID, BONE_WEIGHT>
  395. Array<vec3, vec3, vec4, ivec2, vec2> m_vert;
  396. //TODO : More bone blend support than 2 ?
  397. #elif VERTEX_USEAGE == VU_TEX_UV
  398. //TODO : -- UV SUPPORT --
  399. //TODO : <COORD, NORM, COLOR, UV>
  400. Array<vec3, vec3, vec4, vec2> m_vert;
  401. #else
  402. //-- VANILLA --
  403. //<COORD, NORM, COLOR>
  404. Array<vec3, vec3, vec4> m_vert;
  405. #endif
  406. //<vert count, indices count>
  407. Array<int, int> m_cursors;
  408. //When this flag is up, negative scaling will not invert faces.
  409. bool m_ignore_winding_on_scale;
  410. //Texture coordinate modifiers.
  411. vec2 m_texcoord_offset;
  412. vec2 m_texcoord_scale;
  413. /* FIXME: put this in a separate class so that we can copy meshes. */
  414. struct
  415. {
  416. /* FIXME: very naughty way of handling debug render modes */
  417. Array<Shader *>shader;
  418. #if VERTEX_USEAGE == VU_BONES
  419. //TODO : -- BONE SUPPORT --
  420. Array<ShaderAttrib> coord, norm, color, bone_id, bone_weight;
  421. #elif VERTEX_USEAGE == VU_TEX_UV
  422. //-- UV SUPPORT --
  423. Array<ShaderAttrib> coord, norm, color, tex_coord;
  424. #else
  425. //-- VANILLA --
  426. Array<ShaderAttrib> coord, norm, color;
  427. #endif
  428. Array<ShaderUniform> modelview, invmodelview, view, invview, proj, normalmat, damage, lights;
  429. VertexDeclaration *vdecl;
  430. VertexBuffer *vbo;
  431. IndexBuffer *ibo;
  432. int vertexcount, indexcount;
  433. }
  434. m_gpu;
  435. };
  436. } /* namespace lol */
  437. #endif /* __EASYMESH_EASYMESH_H__ */