You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

855 line
29 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. #if !defined __EASYMESH_EASYMESH_H__
  17. #define __EASYMESH_EASYMESH_H__
  18. namespace lol
  19. {
  20. //Utility enum for renderers
  21. struct MeshRender
  22. {
  23. enum Value
  24. {
  25. NeedInit,
  26. CanRender,
  27. IgnoreRender
  28. }
  29. m_value;
  30. inline MeshRender(Value v) : m_value(v) {}
  31. inline MeshRender() : m_value(NeedInit) {}
  32. inline operator Value() { return m_value; }
  33. };
  34. //Vertex datas for easymesh vertex list.
  35. //TODO : <COORD, NORM, COLOR, UV>
  36. struct VertexData
  37. {
  38. vec3 m_coord;
  39. vec3 m_normal;
  40. vec4 m_color;
  41. vec4 m_texcoord;
  42. ivec4 m_bone_id;
  43. vec4 m_bone_weight;
  44. VertexData(vec3 new_coord = vec3(0.f),
  45. vec3 new_normal = vec3(0.f, 1.f, 0.f),
  46. vec4 new_color = vec4(0.f),
  47. vec4 new_texcoord = vec4(0.f),
  48. ivec4 new_bone_id = ivec4(0),
  49. vec4 new_bone_weight= vec4(0.f))
  50. {
  51. m_coord = new_coord;
  52. m_normal = new_normal;
  53. m_color = new_color;
  54. m_texcoord = new_texcoord;
  55. m_bone_id = new_bone_id;
  56. m_bone_weight = new_bone_weight;
  57. }
  58. };
  59. //Base class to declare shader datas
  60. class GpuShaderData
  61. {
  62. friend class GpuEasyMeshData;
  63. protected:
  64. GpuShaderData();
  65. public:
  66. //--
  67. GpuShaderData(uint16_t vert_decl_flags, Shader* shader, DebugRenderMode render_mode);
  68. ~GpuShaderData();
  69. //--
  70. void AddUniform(const lol::String &new_uniform);
  71. void AddAttribute(const lol::String &new_attribute, VertexUsage usage, int index);
  72. ShaderUniform const *GetUniform(const lol::String &uniform);
  73. ShaderAttrib const *GetAttribute(const lol::String &attribute);
  74. //--
  75. virtual void SetupShaderDatas(mat4 const &model) { UNUSED(model); }
  76. protected:
  77. uint16_t m_vert_decl_flags;
  78. Shader* m_shader;
  79. DebugRenderMode m_render_mode;
  80. Array<lol::String, ShaderUniform> m_shader_uniform;
  81. Array<lol::String, ShaderAttrib> m_shader_attrib;
  82. };
  83. class DefaultShaderData : public GpuShaderData
  84. {
  85. public:
  86. //---
  87. DefaultShaderData(DebugRenderMode render_mode);
  88. DefaultShaderData(uint16_t vert_decl_flags, Shader* shader, bool with_UV);
  89. //---
  90. void SetupDefaultData(bool with_UV);
  91. virtual void SetupShaderDatas(mat4 const &model);
  92. };
  93. class GpuEasyMeshData
  94. {
  95. public:
  96. //---
  97. GpuEasyMeshData();
  98. ~GpuEasyMeshData();
  99. //---
  100. void AddGpuData(GpuShaderData* gpudata, class EasyMesh* src_mesh);
  101. void RenderMeshData(mat4 const &model);
  102. private:
  103. void SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh);
  104. Array<GpuShaderData*> m_gpudatas;
  105. //uint16_t are the vdecl/vbo flags to avoid copy same vdecl several times.
  106. Array<uint16_t, VertexDeclaration*,
  107. VertexBuffer*> m_vdatas;
  108. int m_vertexcount;
  109. //We only need only one ibo for the whole mesh
  110. IndexBuffer * m_ibo;
  111. int m_indexcount;
  112. };
  113. struct MeshBuildOperation
  114. {
  115. enum Value
  116. {
  117. //When this flag is up, negative scaling will not invert faces.
  118. Scale_Winding = 1 << 0,
  119. All = 0xffffffff
  120. }
  121. m_value;
  122. inline MeshBuildOperation(Value v) : m_value(v) {}
  123. inline MeshBuildOperation(uint64_t i) : m_value((Value)i) {}
  124. inline operator Value() { return m_value; }
  125. };
  126. struct MeshType
  127. {
  128. enum Value
  129. {
  130. Triangle = 0,
  131. Quad,
  132. Box,
  133. Sphere,
  134. Capsule,
  135. Torus,
  136. Cylinder,
  137. Disc,
  138. Star,
  139. ExpandedStar,
  140. Cog,
  141. Max
  142. }
  143. m_value;
  144. inline MeshType(Value v) : m_value(v) {}
  145. inline operator Value() { return m_value; }
  146. };
  147. //TODO : Add other Build type
  148. struct TexCoordBuildType
  149. {
  150. enum Value
  151. {
  152. TriangleDefault = 0,
  153. QuadDefault = 0,
  154. BoxDefault = 0,
  155. SphereDefault = 0,
  156. CapsuleDefault = 0,
  157. TorusDefault = 0,
  158. CylinderDefault = 0,
  159. DiscDefault = 0,
  160. StarDefault = 0,
  161. ExpandedStarDefault = 0,
  162. CogDefault = 0,
  163. //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
  164. Max = 1
  165. }
  166. m_value;
  167. inline TexCoordBuildType() : m_value(TriangleDefault) {}
  168. inline TexCoordBuildType(Value v) : m_value(v) {}
  169. inline TexCoordBuildType(int v) : m_value((Value)v) {}
  170. inline operator Value() { return m_value; }
  171. };
  172. struct MeshFaceType
  173. {
  174. enum Value
  175. {
  176. BoxFront = 0,
  177. BoxLeft = 1,
  178. BoxBack = 2,
  179. BoxRight = 3,
  180. BoxTop = 4,
  181. BoxBottom = 5,
  182. QuadDefault = 0,
  183. //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
  184. Max = 6
  185. }
  186. m_value;
  187. inline MeshFaceType(Value v) : m_value(v) {}
  188. inline operator Value() { return m_value; }
  189. };
  190. struct TexCoordPos
  191. {
  192. enum Value
  193. {
  194. BL, //BottomLeft
  195. BR, //BottomRight
  196. TL, //TopLeft
  197. TR //TopRight
  198. }
  199. m_value;
  200. inline TexCoordPos(Value v) : m_value(v) {}
  201. inline operator Value() { return m_value; }
  202. };
  203. class EasyMeshBuildData
  204. {
  205. public:
  206. EasyMeshBuildData()
  207. {
  208. m_color = vec4(0.f, 0.f, 0.f, 1.f);
  209. m_color2 = vec4(0.f, 0.f, 0.f, 1.f);
  210. m_texcoord_offset = vec2(0.f);
  211. m_texcoord_offset2 = vec2(0.f);
  212. m_texcoord_scale = vec2(1.f);
  213. m_texcoord_scale2 = vec2(1.f);
  214. m_build_flags = 0;
  215. for (int i = 0; i < MeshType::Max; ++i)
  216. {
  217. m_texcoord_build_type[i] = TexCoordBuildType::TriangleDefault;
  218. m_texcoord_build_type2[i] = TexCoordBuildType::TriangleDefault;
  219. }
  220. }
  221. inline vec4 &Color() { return m_color; }
  222. inline vec4 &Color2() { return m_color2; }
  223. inline vec2 &TexCoordOffset() { return m_texcoord_offset; }
  224. inline vec2 &TexCoordScale() { return m_texcoord_scale; }
  225. inline vec2 &TexCoordOffset2() { return m_texcoord_offset2; }
  226. inline vec2 &TexCoordScale2() { return m_texcoord_scale2; }
  227. //UV1
  228. void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type[mt] & 1); }
  229. TexCoordBuildType GetTexCoordBuildType(MeshType mt)
  230. {
  231. uint32_t flag = (uint32_t)((m_texcoord_build_type[mt] & ~(1)) >> 1);
  232. int i = 0;
  233. while (flag >>= 1)
  234. i++;
  235. return TexCoordBuildType(i);
  236. }
  237. void SetTexCoordCustomBuild(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
  238. {
  239. if (face >= m_texcoord_custom_build[mt].Count())
  240. m_texcoord_custom_build[mt].Resize(face + 1);
  241. m_texcoord_custom_build[mt][face].m1 = BL;
  242. m_texcoord_custom_build[mt][face].m2 = TR;
  243. m_texcoord_build_type[mt] |= 1;
  244. }
  245. void ClearTexCoordCustomBuild(MeshType mt) { m_texcoord_build_type[mt] &= ~1; }
  246. /* FIXME : Do something better ? */
  247. vec2 TexCoord(MeshType mt, TexCoordPos tcp, MeshFaceType face)
  248. {
  249. vec2 BL = vec2(0.f);
  250. vec2 TR = vec2(0.f);
  251. if (m_texcoord_build_type[mt] & 1 && face < m_texcoord_custom_build[mt].Count())
  252. {
  253. BL = m_texcoord_custom_build[mt][face].m1;
  254. TR = m_texcoord_custom_build[mt][face].m2;
  255. }
  256. else
  257. {
  258. /* unused for now, but will be if new BuildType are added. */
  259. TexCoordBuildType tcbt = GetTexCoordBuildType(mt);
  260. UNUSED(tcbt);
  261. if (mt == MeshType::Triangle)
  262. mt = mt;
  263. else if (mt == MeshType::Quad)
  264. {
  265. //There's nothin' else than QuadDefault
  266. BL = vec2(0.f);
  267. TR = vec2(1.f);
  268. }
  269. else if (mt == MeshType::Box)
  270. {
  271. vec2 data[][2] =
  272. { //TexCoordBuildType::BoxDefault
  273. { vec2(0.f), vec2(.5f) },
  274. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  275. { vec2(0.f), vec2(.5f) },
  276. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  277. { vec2(0.f, .5f), vec2(.5f, 1.f) },
  278. { vec2(.5f, .5f), vec2(1.f, 1.f) }
  279. };
  280. BL = data[face][0]; //[tcbt]
  281. TR = data[face][1]; //[tcbt]
  282. }
  283. else if (mt == MeshType::Sphere)
  284. mt = mt;
  285. else if (mt == MeshType::Capsule)
  286. mt = mt;
  287. else if (mt == MeshType::Torus)
  288. mt = mt;
  289. else if (mt == MeshType::Cylinder)
  290. mt = mt;
  291. else if (mt == MeshType::Disc)
  292. mt = mt;
  293. else if (mt == MeshType::Star)
  294. mt = mt;
  295. else if (mt == MeshType::ExpandedStar)
  296. mt = mt;
  297. else if (mt == MeshType::Cog)
  298. mt = mt;
  299. }
  300. vec2 res = vec2(.0f);
  301. if (tcp == TexCoordPos::BL)
  302. res = BL;
  303. else if (tcp == TexCoordPos::BR)
  304. res = vec2(TR.x, BL.y);
  305. else if (tcp == TexCoordPos::TL)
  306. res = vec2(BL.x, TR.y);
  307. else if (tcp == TexCoordPos::TR)
  308. res = TR;
  309. return res * m_texcoord_scale + m_texcoord_offset2;
  310. }
  311. //UV2
  312. void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt] & 1); }
  313. TexCoordBuildType GetTexCoordBuildType2(MeshType mt)
  314. {
  315. uint32_t flag = ((m_texcoord_build_type2[mt] & ~(1)) >> 1);
  316. int i = 0;
  317. while (flag >>= 1)
  318. i++;
  319. return TexCoordBuildType(i);
  320. }
  321. void SetTexCoordCustomBuild2(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
  322. {
  323. if (face >= m_texcoord_custom_build2[mt].Count())
  324. m_texcoord_custom_build2[mt].Resize(face + 1);
  325. m_texcoord_custom_build2[mt][face].m1 = BL;
  326. m_texcoord_custom_build2[mt][face].m2 = TR;
  327. m_texcoord_build_type2[mt] |= 1;
  328. }
  329. void ClearTexCoordCustomBuild2(MeshType mt) { m_texcoord_build_type2[mt] &= ~1; }
  330. vec2 TexCoord2(MeshType mt, TexCoordPos tcp, MeshFaceType face)
  331. {
  332. vec2 BL = vec2(0.f);
  333. vec2 TR = vec2(0.f);
  334. if (m_texcoord_build_type2[mt] & 1 && face < m_texcoord_custom_build2[mt].Count())
  335. {
  336. BL = m_texcoord_custom_build2[mt][face].m1;
  337. TR = m_texcoord_custom_build2[mt][face].m2;
  338. }
  339. else
  340. {
  341. TexCoordBuildType tcbt = GetTexCoordBuildType2(mt);
  342. UNUSED(tcbt);
  343. if (mt == MeshType::Triangle)
  344. mt = mt;
  345. else if (mt == MeshType::Quad)
  346. {
  347. //There's nothin' else than QuadDefault
  348. BL = vec2(0.f);
  349. TR = vec2(1.f);
  350. }
  351. else if (mt == MeshType::Box)
  352. {
  353. vec2 data[][2] =
  354. { //TexCoordBuildType::BoxDefault
  355. { vec2(0.f), vec2(.5f) },
  356. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  357. { vec2(0.f), vec2(.5f) },
  358. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  359. { vec2(0.f, .5f), vec2(.5f, 1.f) },
  360. { vec2(.5f, .5f), vec2(1.f, 1.f) }
  361. };
  362. BL = data[face][0]; //[tcbt]
  363. TR = data[face][1]; //[tcbt]
  364. }
  365. else if (mt == MeshType::Sphere)
  366. mt = mt;
  367. else if (mt == MeshType::Capsule)
  368. mt = mt;
  369. else if (mt == MeshType::Torus)
  370. mt = mt;
  371. else if (mt == MeshType::Cylinder)
  372. mt = mt;
  373. else if (mt == MeshType::Disc)
  374. mt = mt;
  375. else if (mt == MeshType::Star)
  376. mt = mt;
  377. else if (mt == MeshType::ExpandedStar)
  378. mt = mt;
  379. else if (mt == MeshType::Cog)
  380. mt = mt;
  381. }
  382. vec2 res = vec2(.0f);
  383. if (tcp == TexCoordPos::BL)
  384. res = BL;
  385. else if (tcp == TexCoordPos::BR)
  386. res = vec2(TR.x, BL.y);
  387. else if (tcp == TexCoordPos::TL)
  388. res = vec2(BL.x, TR.y);
  389. else if (tcp == TexCoordPos::TR)
  390. res = TR;
  391. return res * m_texcoord_scale + m_texcoord_offset2;
  392. }
  393. inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo) != 0; }
  394. inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo; }
  395. inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo; }
  396. inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo; }
  397. inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); }
  398. public:
  399. vec4 m_color;
  400. vec4 m_color2;
  401. vec2 m_texcoord_offset;
  402. vec2 m_texcoord_offset2;
  403. vec2 m_texcoord_scale;
  404. vec2 m_texcoord_scale2;
  405. Array<vec2, vec2> m_texcoord_custom_build[MeshType::Max];
  406. Array<vec2, vec2> m_texcoord_custom_build2[MeshType::Max];
  407. uint32_t m_texcoord_build_type[MeshType::Max];
  408. uint32_t m_texcoord_build_type2[MeshType::Max];
  409. uint32_t m_build_flags;
  410. };
  411. /* A safe enum for MeshCSG operations. */
  412. struct CSGUsage
  413. {
  414. enum Value
  415. {
  416. Union,
  417. Substract,
  418. SubstractLoss, //will remove B from A, but not add inverted B
  419. And,
  420. Xor,
  421. }
  422. m_value;
  423. inline CSGUsage(Value v) : m_value(v) {}
  424. inline operator Value() { return m_value; }
  425. };
  426. /* A safe enum for VertexDictionnary operations. */
  427. struct VDictType
  428. {
  429. enum Value
  430. {
  431. DoesNotExist=-3,
  432. Alone=-2,
  433. Master=-1
  434. }
  435. m_value;
  436. inline VDictType(Value v) : m_value(v) {}
  437. inline operator Value() { return m_value; }
  438. };
  439. /* TODO : replace VDict by a proper Half-edge system */
  440. //a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
  441. class VertexDictionnary
  442. {
  443. public:
  444. int FindVertexMaster(const int search_idx);
  445. bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
  446. 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);
  447. 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);
  448. 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);
  449. 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);
  450. void AddVertex(int vert_id, vec3 vert_coord);
  451. bool GetMasterList(Array<int> &ret_master_list) { ret_master_list = master_list; return ret_master_list.Count() > 0; }
  452. void Clear() { vertex_list.Empty(); }
  453. private:
  454. //<VertexId, VertexLocation, VertexMasterId>
  455. Array<int, vec3, int> vertex_list;
  456. //List of the master_ vertices
  457. Array<int> master_list;
  458. };
  459. struct Axis
  460. {
  461. enum Value
  462. {
  463. X,
  464. Y,
  465. Z
  466. }
  467. m_value;
  468. inline Axis(Value v) : m_value(v) {}
  469. inline operator Value() { return m_value; }
  470. };
  471. class EasyMesh
  472. {
  473. friend class EasyMeshParser;
  474. public:
  475. EasyMesh();
  476. bool Compile(char const *command);
  477. void MeshConvert(GpuShaderData* new_gpu_sdata);
  478. void MeshConvert(Shader* ProvidedShader = NULL);
  479. void Render(mat4 const &model, float damage = 0.f);
  480. private:
  481. void UpdateVertexDict(Array< int, int > &vertex_dict);
  482. //-------------------------------------------------------------------------
  483. //Mesh CSG operations
  484. //-------------------------------------------------------------------------
  485. private:
  486. void MeshCsg(CSGUsage csg_operation);
  487. public:
  488. /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */
  489. void CsgUnion() { MeshCsg(CSGUsage::Union); }
  490. /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */
  491. void CsgSubstract() { MeshCsg(CSGUsage::Substract); }
  492. /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */
  493. void CsgSubstractLoss() { MeshCsg(CSGUsage::SubstractLoss); }
  494. /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */
  495. void CsgAnd() { MeshCsg(CSGUsage::And); }
  496. /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */
  497. void CsgXor() { MeshCsg(CSGUsage::Xor); }
  498. public:
  499. /* [cmd:[] from this point onward, any operation will not be performed on previous vertices */
  500. void OpenBrace();
  501. /* [cmd:]] Merge current vertices with previous context */
  502. void CloseBrace();
  503. /* [cmd:tsw] When activation, on negative-scaling, normal fixing will not occur */
  504. void ToggleScaleWinding();
  505. /* [cmd:sc] Set vertices color */
  506. void SetCurColor(vec4 const &color);
  507. /* [cmd:scb] Set vertices color 2 */
  508. void SetCurColor2(vec4 const &color);
  509. private:
  510. //-------------------------------------------------------------------------
  511. //Internal : Basic triangle/vertex operations
  512. //-------------------------------------------------------------------------
  513. void AddVertex(vec3 const &coord);
  514. void AddDuplicateVertex(int i);
  515. void AddLerpVertex(int i, int j, float alpha);
  516. void AppendQuad(int i1, int i2, int i3, int i4, int base);
  517. void AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base);
  518. void AppendTriangle(int i1, int i2, int i3, int base);
  519. void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
  520. void ComputeNormals(int start, int vcount);
  521. public: //DEBUG
  522. void ComputeTexCoord(float uv_scale, int uv_offset);
  523. //-------------------------------------------------------------------------
  524. //Vertices operations
  525. //-------------------------------------------------------------------------
  526. void SetVertColor(vec4 const &color);
  527. void SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale);
  528. void SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale);
  529. void SetCurVertNormal(vec3 const &normal);
  530. void SetCurVertColor(vec4 const &color);
  531. void SetCurVertTexCoord(vec2 const &texcoord);
  532. void SetCurVertTexCoord2(vec2 const &texcoord);
  533. public:
  534. //-------------------------------------------------------------------------
  535. //Mesh transform operations
  536. //-------------------------------------------------------------------------
  537. /* [cmd:t/tx/ty/tz] Translate vertices
  538. - v : Translation quantity.
  539. */
  540. void Translate(vec3 const &v);
  541. /* See Rotate */
  542. void RotateX(float angle);
  543. /* See Rotate */
  544. void RotateY(float angle);
  545. /* See Rotate */
  546. void RotateZ(float angle);
  547. /* [cmd:r/rx/ry/rz] Rotate vertices
  548. - angle : rotation quantity.
  549. - axis : rotation axis.
  550. */
  551. void Rotate(float angle, vec3 const &axis);
  552. /* [cmd:rj] Randomly move vertices along Origin-to-vertex as o2v *= (1.0 + rand(r))
  553. - r : jitter maximum value.
  554. */
  555. void RadialJitter(float r);
  556. /* [cmd:tax] multiply axis y&z by x as y *= (1.0 + (ny * x + xoff))
  557. - ny : value of n for y.
  558. - nz : value of n for z.
  559. - xoff : value of xoff.
  560. - absolute (def:1) : if (1) Multiply will use an absolute x.
  561. */
  562. void TaperX(float ny, float nz, float xoff, int absolute=1);
  563. /* [cmd:tay] Same as TaperX, with Y */
  564. void TaperY(float nx, float nz, float yoff, int absolute=1);
  565. /* [cmd:taz] Same as TaperX, with Z */
  566. void TaperZ(float nx, float ny, float zoff, int absolute=1);
  567. /* [cmd:twx] Twist vertices around x axis with x as rotation value as p = (RotateX(x * t + toff) * p)
  568. - t : Angle multiplier.
  569. - toff : Applied offset.
  570. */
  571. void TwistX(float t, float toff);
  572. /* [cmd:twy] Same as TwistX, with Y */
  573. void TwistY(float t, float toff);
  574. /* [cmd:twz] Same as TwistX, with Z */
  575. void TwistZ(float t, float toff);
  576. /* [cmd:shx] Shear vertices using x value as shear quantity as y += (ny * x + xoff)
  577. - ny : Value of n for y.
  578. - nz : Value of n for z.
  579. - xoff : Value of xoff.
  580. - absolute (def:1) : if (1) Multiply will use an absolute x.
  581. */
  582. void ShearX(float ny, float nz, float xoff, int absolute=1);
  583. /* [cmd:shy] Same as ShearX, with Y */
  584. void ShearY(float nx, float nz, float yoff, int absolute=1);
  585. /* [cmd:shz] Same as ShearX, with Z */
  586. void ShearZ(float nx, float ny, float zoff, int absolute=1);
  587. /* [cmd:stx] Stretch vertices using x value as stretch quantity as y += (pow(x, ny) + xoff)
  588. - ny : Value of n for y.
  589. - nz : Value of n for z.
  590. - xoff : Value of xoff.
  591. */
  592. void StretchX(float ny, float nz, float xoff);
  593. /* [cmd:sty] Same as StretchX, with Y */
  594. void StretchY(float nx, float nz, float yoff);
  595. /* [cmd:stz] Same as StretchX, with Z */
  596. void StretchZ(float nx, float ny, float zoff);
  597. /* [cmd:bdxy] Bend vertices using x as bend quantity along y axis using p = (RotateY(x * t + toff) * p)
  598. - t : Angle multiplier.
  599. - xoff : Applied offset.
  600. */
  601. void BendXY(float t, float toff);
  602. /* [cmd:bdxz] Same as BendXY, with X & Z */
  603. void BendXZ(float t, float toff);
  604. /* [cmd:bdyx] Same as BendXY, with Y & X */
  605. void BendYX(float t, float toff);
  606. /* [cmd:bdyz] Same as BendXY, with Y & Z */
  607. void BendYZ(float t, float toff);
  608. /* [cmd:bdzx] Same as BendXY, with Z & X */
  609. void BendZX(float t, float toff);
  610. /* [cmd:bdzy] Same as BendXY, with Z & Y */
  611. void BendZY(float t, float toff);
  612. private:
  613. struct MeshTransform
  614. {
  615. enum Value
  616. {
  617. Taper,
  618. Twist,
  619. Bend,
  620. Stretch,
  621. Shear
  622. }
  623. m_value;
  624. inline MeshTransform(Value v) : m_value(v) {}
  625. inline operator Value() { return m_value; }
  626. };
  627. void DoMeshTransform(MeshTransform ct, Axis axis0, Axis axis1, float n0, float n1, float noff, int absolute);
  628. public:
  629. /* [cmd:s/sx/sy/sz] Scale vertices
  630. - s : scale quantity.
  631. */
  632. void Scale(vec3 const &s);
  633. /* [cmd:mx] Mirror vertices through X-plane
  634. Acts as an OpenBrace
  635. */
  636. void MirrorX();
  637. /* [cmd:my] Mirror vertices through Y-plane
  638. Acts as an OpenBrace
  639. */
  640. void MirrorY();
  641. /* [cmd:mz] Mirror vertices through Z-plane
  642. Acts as an OpenBrace
  643. */
  644. void MirrorZ();
  645. /* [no-cmd] Duplicates vertices and scale duplicate
  646. Acts as an OpenBrace
  647. */
  648. void DupAndScale(vec3 const &s);
  649. /* [cmd:ch] Performs a chamfer operation //TODO : Make it work.
  650. - f : Chamfer quantity.
  651. */
  652. void Chamfer(float f);
  653. /* [cmd:splt] split triangles in 4 smaller ones.
  654. - pass : Number of pass applied.
  655. */
  656. void SplitTriangles(int pass);
  657. private:
  658. void SplitTriangles(int pass, VertexDictionnary *vert_dict);
  659. public:
  660. /* [cmd:smth] Smooth the mesh by subdivising it.
  661. - main_pass : a main pass is made of (n0 split then n1 smooth) repeat.
  662. - split_per_main_pass : n0 value in above explanation.
  663. - smooth_per_main_pass : n1 value in above explanation.
  664. */
  665. void SmoothMesh(int main_pass, int split_per_main_pass, int smooth_per_main_pass);
  666. //-------------------------------------------------------------------------
  667. //Mesh shape operations
  668. //-------------------------------------------------------------------------
  669. /* [cmd:ac] Cylinder centered on (0,0,0) with BBox [-.5*max(d1, d2), -.5*h, -.5*max(d1, d2)]
  670. - nbsides : Number of sides. [+.5*max(d1, d2), +.5*h, +.5*max(d1, d2)]
  671. - h : Height of the cylinder.
  672. - d1 : Lower diameter.
  673. - d2 : Upper diameter.
  674. - dualside : if (1) will also create inner sides : TOOD:TOREMOVE?? : needed ?
  675. - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
  676. - close : if (1) will add discs to close the cylinder
  677. */
  678. void AppendCylinder(int nsides, float h, float d1, float d2,
  679. int dualside, int smooth, int close);
  680. /* [cmd:asph] Sphere centered on (0,0,0) with BBox [-.5*d][.5*d]
  681. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  682. - d : Diameter.
  683. */
  684. void AppendSphere(int ndivisions, float d);
  685. /* [cmd:acap] Capsule centered on (0,0,0) with BBox [-.5*d, -(.5*d+h), -.5*d][.5*d, (.5*d+h), .5*d]
  686. - ndivisions : number of subdivisions each Sphere triangle will sustain.
  687. - h : Inner height.
  688. - d : Diameter.
  689. */
  690. void AppendCapsule(int ndivisions, float h, float d);
  691. /* [cmd:ato] Torus centered on (0,0,0) with BBox [-.5*d2][.5*d2]
  692. - ndivisions : number of subdivisions of the torus.
  693. - d1 : Inner diameter.
  694. - d2 : Outer diameter.
  695. */
  696. void AppendTorus(int ndivisions, float d1, float d2);
  697. /* [cmd:ab] Box centered on (0,0,0) with BBox [-.5 * size][.5 * size]
  698. - size : size of the box.
  699. - chamf : size of the chamfer.
  700. - smooth : if (1) will smooth normals : TOOD:TOREMOVE : smooth should be handled elsewhere
  701. */
  702. void AppendBox(vec3 const &size, float chamf = 0.f);
  703. //Same as AppendBox
  704. void AppendSmoothChamfBox(vec3 const &size, float chamf);
  705. //Same as AppendBox
  706. void AppendFlatChamfBox(vec3 const &size, float chamf);
  707. //Same as AppendBox
  708. void AppendBox(vec3 const &size, float chamf, bool smooth);
  709. /* [cmd:as]
  710. Append a Star centered on (0,0,0) contained within a disc of "max(d1, d2)" diameter.
  711. - nbranches : Number of branches.
  712. - d1 : double Length of the branches.
  713. - d2 : double Length of the "branch" located between d1-branches.
  714. - fade : if (1) in-between branches use Color2.
  715. - fade2 : if (1) Star branches use Color2.
  716. */
  717. void AppendStar(int nbranches, float d1, float d2,
  718. int fade = 0, int fade2 = 0);
  719. /* [cmd:aes] Star centered on (0,0,0) contained within a disc of "max(max(d1, d2), max(d1 + extrad, d2 + extrad))" diameter.
  720. Expanded star branches use Color2.
  721. - nbranches : Number of branches.
  722. - d1 : Double Length of the branches.
  723. - d2 : Double Length of the "branch" located between r1-branches.
  724. - extrad : Extra length added to expand all branches.
  725. */
  726. void AppendExpandedStar(int nbranches, float d1, float d2, float extrad);
  727. /* [cmd:ad] Disc centered on (0,0,0) with d diameter.
  728. - nbsides : Number of sides.
  729. - d : Diameter.
  730. - fade : if (1) Outer vertices will use Color2
  731. */
  732. void AppendDisc(int nsides, float d, int fade = 0);
  733. /* [cmd:at] Triangle centered on (0,0,0) contained within a disc of "d" diameter.
  734. - d : diameter of the containing disc..
  735. - fade : if (1) 2nd & 3rd Vertices will use Color2
  736. */
  737. void AppendSimpleTriangle(float d, int fade = 0);
  738. /* [cmd:aq] Quad centered on (0,0,0) contained within BBox [-size*.5f, 0, -size*.5f][size*.5f, 0, size*.5f]
  739. - size : Size of quad.
  740. - fade : if (1) 3rd & 4th Vertices will use Color2
  741. */
  742. void AppendSimpleQuad(float size, int fade = 0);
  743. private:
  744. //complex version of above one
  745. void AppendSimpleQuad(vec2 p1, vec2 p2, float z = 0.f, int fade = 0);
  746. public:
  747. /* [cmd:acg] Gear centered on (0,0,0) contained within BBox [-.5*max(d1,d2), -.5*h, -.5*max(d1, d2)]
  748. - h : Height of the Gear. [+.5*max(d1,d2), +.5*h, +.5*max(d1, d2)]
  749. - d10 : Upper Inner diameter.
  750. - d20 : Lower Inner diameter.
  751. - d1 : Upper Outer diameter.
  752. - d2 : Lower Outer diameter.
  753. - d12 : Upper Cog diameter.
  754. - d22 : Lower Cog diameter.
  755. - sidemul : multiplier for the size of the cogs.
  756. - offset : useless
  757. */
  758. void AppendCog(int nbsides, float h, float d10, float d20, float d1,
  759. float d2, float d12, float d22, float sidemul, int offset);
  760. //-------------------------------------------------------------------------
  761. //TODO : Mesh Bone operations
  762. //-------------------------------------------------------------------------
  763. //void AddBone(int parent_id) {}
  764. //Convenience functions
  765. public:
  766. int GetVertexCount() { return m_vert.Count(); }
  767. vec3 const &GetVertexLocation(int i) { return m_vert[i].m_coord; }
  768. private:
  769. Array<uint16_t> m_indices;
  770. Array<VertexData> m_vert;
  771. //<vert count, indices count>
  772. Array<int, int> m_cursors;
  773. friend class GpuEasyMeshData;
  774. GpuEasyMeshData m_gpu_data;
  775. public:
  776. inline EasyMeshBuildData* BD()
  777. {
  778. if (!m_build_data)
  779. m_build_data = new EasyMeshBuildData();
  780. return m_build_data;
  781. };
  782. private:
  783. class EasyMeshBuildData* m_build_data;
  784. };
  785. } /* namespace lol */
  786. #endif /* __EASYMESH_EASYMESH_H__ */