Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

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