No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 

456 líneas
14 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
  5. // (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  6. // (c) 2009-2013 Cédric Lecacheur <jordx@free.fr>
  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 __EASYMESHBUILD_EASYMESHBUILD_H__
  17. #define __EASYMESHBUILD_EASYMESHBUILD_H__
  18. namespace lol
  19. {
  20. struct MeshBuildOperation
  21. {
  22. enum Value
  23. {
  24. //When this flag is up, negative scaling will not invert faces.
  25. ScaleWinding = (1 << 0),
  26. CommandRecording = (1 << 1),
  27. CommandExecution = (1 << 2),
  28. QuadWeighting = (1 << 3),
  29. IgnoreQuadWeighting = (1 << 4),
  30. PostBuildComputeNormals = (1 << 5),
  31. PreventVertCleanup = (1 << 6),
  32. All = 0xffffffff
  33. }
  34. m_value;
  35. inline MeshBuildOperation(Value v) : m_value(v) {}
  36. inline MeshBuildOperation(uint64_t i) : m_value((Value)i) {}
  37. inline operator Value() { return m_value; }
  38. };
  39. struct EasyMeshCmdType
  40. {
  41. enum Value
  42. {
  43. MeshCsg = 0,
  44. LoopStart,
  45. LoopEnd,
  46. OpenBrace,
  47. CloseBrace,
  48. ScaleWinding,
  49. QuadWeighting,
  50. PostBuildNormal,
  51. PreventVertCleanup,
  52. SetColorA,
  53. SetColorB,
  54. SetVertColor,
  55. VerticesMerge,
  56. VerticesSeparate,
  57. Translate,
  58. Rotate,
  59. RadialJitter,
  60. MeshTranform,
  61. Scale,
  62. DupAndScale,
  63. Chamfer,
  64. SplitTriangles,
  65. SmoothMesh,
  66. AppendCylinder,
  67. AppendCapsule,
  68. AppendTorus,
  69. AppendBox,
  70. AppendStar,
  71. AppendExpandedStar,
  72. AppendDisc,
  73. AppendSimpleTriangle,
  74. AppendSimpleQuad,
  75. AppendCog,
  76. Max
  77. }
  78. m_value;
  79. inline EasyMeshCmdType(Value v) : m_value(v) {}
  80. inline operator Value() { return m_value; }
  81. inline int Value() { return m_value; }
  82. };
  83. struct MeshType
  84. {
  85. enum Value
  86. {
  87. Triangle = 0,
  88. Quad,
  89. Box,
  90. Sphere,
  91. Capsule,
  92. Torus,
  93. Cylinder,
  94. Disc,
  95. Star,
  96. ExpandedStar,
  97. Cog,
  98. Max
  99. }
  100. m_value;
  101. inline MeshType(Value v) : m_value(v) {}
  102. inline operator Value() { return m_value; }
  103. };
  104. //TODO : Add other Build type
  105. struct TexCoordBuildType
  106. {
  107. enum Value
  108. {
  109. TriangleDefault = 0,
  110. QuadDefault = 0,
  111. BoxDefault = 0,
  112. SphereDefault = 0,
  113. CapsuleDefault = 0,
  114. TorusDefault = 0,
  115. CylinderDefault = 0,
  116. DiscDefault = 0,
  117. StarDefault = 0,
  118. ExpandedStarDefault = 0,
  119. CogDefault = 0,
  120. //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
  121. Max = 1
  122. }
  123. m_value;
  124. inline TexCoordBuildType() : m_value(TriangleDefault) {}
  125. inline TexCoordBuildType(Value v) : m_value(v) {}
  126. inline TexCoordBuildType(int v) : m_value((Value)v) {}
  127. inline operator Value() { return m_value; }
  128. };
  129. struct MeshFaceType
  130. {
  131. enum Value
  132. {
  133. BoxFront = 0,
  134. BoxLeft = 1,
  135. BoxBack = 2,
  136. BoxRight = 3,
  137. BoxTop = 4,
  138. BoxBottom = 5,
  139. QuadDefault = 0,
  140. //NEVER FORGET TO INCREMENT THIS WHEN ADDING A VALUE
  141. Max = 6
  142. }
  143. m_value;
  144. inline MeshFaceType(Value v) : m_value(v) {}
  145. inline operator Value() { return m_value; }
  146. };
  147. struct TexCoordPos
  148. {
  149. enum Value
  150. {
  151. BL, //BottomLeft
  152. BR, //BottomRight
  153. TL, //TopLeft
  154. TR //TopRight
  155. }
  156. m_value;
  157. inline TexCoordPos(Value v) : m_value(v) {}
  158. inline operator Value() { return m_value; }
  159. };
  160. class EasyMeshBuildData
  161. {
  162. public:
  163. EasyMeshBuildData()
  164. {
  165. m_color_a = vec4(0.f, 0.f, 0.f, 1.f);
  166. m_color_b = vec4(0.f, 0.f, 0.f, 1.f);
  167. m_texcoord_offset = vec2(0.f);
  168. m_texcoord_offset2 = vec2(0.f);
  169. m_texcoord_scale = vec2(1.f);
  170. m_texcoord_scale2 = vec2(1.f);
  171. m_build_flags = 0;
  172. m_i_cmd = 0;
  173. m_exec_nb = -1;
  174. for (int i = 0; i < MeshType::Max; ++i)
  175. {
  176. m_texcoord_build_type[i] = TexCoordBuildType::TriangleDefault;
  177. m_texcoord_build_type2[i] = TexCoordBuildType::TriangleDefault;
  178. }
  179. }
  180. inline CommandStack &CmdStack() { return m_stack; }
  181. inline int &Cmdi() { return m_i_cmd; }
  182. inline int &CmdExecNb() { return m_exec_nb; }
  183. inline Array<int, int> &LoopStack(){ return m_loop_stack; }
  184. inline vec4 &ColorA() { return m_color_a; }
  185. inline vec4 &ColorB() { return m_color_b; }
  186. inline vec2 &TexCoordOffset() { return m_texcoord_offset; }
  187. inline vec2 &TexCoordScale() { return m_texcoord_scale; }
  188. inline vec2 &TexCoordOffset2() { return m_texcoord_offset2; }
  189. inline vec2 &TexCoordScale2() { return m_texcoord_scale2; }
  190. //UV1
  191. void SetTexCoordBuildType(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type[mt] & 1); }
  192. TexCoordBuildType GetTexCoordBuildType(MeshType mt)
  193. {
  194. uint32_t flag = (uint32_t)((m_texcoord_build_type[mt] & ~(1)) >> 1);
  195. int i = 0;
  196. while (flag >>= 1)
  197. i++;
  198. return TexCoordBuildType(i);
  199. }
  200. void SetTexCoordCustomBuild(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
  201. {
  202. if (face >= m_texcoord_custom_build[mt].Count())
  203. m_texcoord_custom_build[mt].Resize(face + 1);
  204. m_texcoord_custom_build[mt][face].m1 = BL;
  205. m_texcoord_custom_build[mt][face].m2 = TR;
  206. m_texcoord_build_type[mt] |= 1;
  207. }
  208. void ClearTexCoordCustomBuild(MeshType mt) { m_texcoord_build_type[mt] &= ~1; }
  209. /* FIXME : Do something better ? */
  210. vec2 TexCoord(MeshType mt, TexCoordPos tcp, MeshFaceType face)
  211. {
  212. vec2 BL = vec2(0.f);
  213. vec2 TR = vec2(0.f);
  214. if (m_texcoord_build_type[mt] & 1 && face < m_texcoord_custom_build[mt].Count())
  215. {
  216. BL = m_texcoord_custom_build[mt][face].m1;
  217. TR = m_texcoord_custom_build[mt][face].m2;
  218. }
  219. else
  220. {
  221. /* unused for now, but will be if new BuildType are added. */
  222. TexCoordBuildType tcbt = GetTexCoordBuildType(mt);
  223. UNUSED(tcbt);
  224. if (mt == MeshType::Triangle)
  225. mt = mt;
  226. else if (mt == MeshType::Quad)
  227. {
  228. //There's nothin' else than QuadDefault
  229. BL = vec2(0.f);
  230. TR = vec2(1.f);
  231. }
  232. else if (mt == MeshType::Box)
  233. {
  234. vec2 data[][2] =
  235. { //TexCoordBuildType::BoxDefault
  236. { vec2(0.f), vec2(.5f) },
  237. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  238. { vec2(0.f), vec2(.5f) },
  239. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  240. { vec2(0.f, .5f), vec2(.5f, 1.f) },
  241. { vec2(.5f, .5f), vec2(1.f, 1.f) }
  242. };
  243. BL = data[face][0]; //[tcbt]
  244. TR = data[face][1]; //[tcbt]
  245. }
  246. else if (mt == MeshType::Sphere)
  247. mt = mt;
  248. else if (mt == MeshType::Capsule)
  249. mt = mt;
  250. else if (mt == MeshType::Torus)
  251. mt = mt;
  252. else if (mt == MeshType::Cylinder)
  253. mt = mt;
  254. else if (mt == MeshType::Disc)
  255. mt = mt;
  256. else if (mt == MeshType::Star)
  257. mt = mt;
  258. else if (mt == MeshType::ExpandedStar)
  259. mt = mt;
  260. else if (mt == MeshType::Cog)
  261. mt = mt;
  262. }
  263. vec2 res = vec2(.0f);
  264. if (tcp == TexCoordPos::BL)
  265. res = BL;
  266. else if (tcp == TexCoordPos::BR)
  267. res = vec2(TR.x, BL.y);
  268. else if (tcp == TexCoordPos::TL)
  269. res = vec2(BL.x, TR.y);
  270. else if (tcp == TexCoordPos::TR)
  271. res = TR;
  272. return res * m_texcoord_scale + m_texcoord_offset2;
  273. }
  274. //UV2
  275. void SetTexCoordBuildType2(MeshType mt, TexCoordBuildType tcbt) { m_texcoord_build_type2[mt] = (1 << (tcbt + 1)) | (m_texcoord_build_type2[mt] & 1); }
  276. TexCoordBuildType GetTexCoordBuildType2(MeshType mt)
  277. {
  278. uint32_t flag = ((m_texcoord_build_type2[mt] & ~(1)) >> 1);
  279. int i = 0;
  280. while (flag >>= 1)
  281. i++;
  282. return TexCoordBuildType(i);
  283. }
  284. void SetTexCoordCustomBuild2(MeshType mt, MeshFaceType face, vec2 BL, vec2 TR)
  285. {
  286. if (face >= m_texcoord_custom_build2[mt].Count())
  287. m_texcoord_custom_build2[mt].Resize(face + 1);
  288. m_texcoord_custom_build2[mt][face].m1 = BL;
  289. m_texcoord_custom_build2[mt][face].m2 = TR;
  290. m_texcoord_build_type2[mt] |= 1;
  291. }
  292. void ClearTexCoordCustomBuild2(MeshType mt) { m_texcoord_build_type2[mt] &= ~1; }
  293. vec2 TexCoord2(MeshType mt, TexCoordPos tcp, MeshFaceType face)
  294. {
  295. vec2 BL = vec2(0.f);
  296. vec2 TR = vec2(0.f);
  297. if (m_texcoord_build_type2[mt] & 1 && face < m_texcoord_custom_build2[mt].Count())
  298. {
  299. BL = m_texcoord_custom_build2[mt][face].m1;
  300. TR = m_texcoord_custom_build2[mt][face].m2;
  301. }
  302. else
  303. {
  304. TexCoordBuildType tcbt = GetTexCoordBuildType2(mt);
  305. UNUSED(tcbt);
  306. if (mt == MeshType::Triangle)
  307. mt = mt;
  308. else if (mt == MeshType::Quad)
  309. {
  310. //There's nothin' else than QuadDefault
  311. BL = vec2(0.f);
  312. TR = vec2(1.f);
  313. }
  314. else if (mt == MeshType::Box)
  315. {
  316. vec2 data[][2] =
  317. { //TexCoordBuildType::BoxDefault
  318. { vec2(0.f), vec2(.5f) },
  319. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  320. { vec2(0.f), vec2(.5f) },
  321. { vec2(.5f, 0.f), vec2(1.f, .5f) },
  322. { vec2(0.f, .5f), vec2(.5f, 1.f) },
  323. { vec2(.5f, .5f), vec2(1.f, 1.f) }
  324. };
  325. BL = data[face][0]; //[tcbt]
  326. TR = data[face][1]; //[tcbt]
  327. }
  328. else if (mt == MeshType::Sphere)
  329. mt = mt;
  330. else if (mt == MeshType::Capsule)
  331. mt = mt;
  332. else if (mt == MeshType::Torus)
  333. mt = mt;
  334. else if (mt == MeshType::Cylinder)
  335. mt = mt;
  336. else if (mt == MeshType::Disc)
  337. mt = mt;
  338. else if (mt == MeshType::Star)
  339. mt = mt;
  340. else if (mt == MeshType::ExpandedStar)
  341. mt = mt;
  342. else if (mt == MeshType::Cog)
  343. mt = mt;
  344. }
  345. vec2 res = vec2(.0f);
  346. if (tcp == TexCoordPos::BL)
  347. res = BL;
  348. else if (tcp == TexCoordPos::BR)
  349. res = vec2(TR.x, BL.y);
  350. else if (tcp == TexCoordPos::TL)
  351. res = vec2(BL.x, TR.y);
  352. else if (tcp == TexCoordPos::TR)
  353. res = TR;
  354. return res * m_texcoord_scale + m_texcoord_offset2;
  355. }
  356. inline bool IsEnabled(MeshBuildOperation mbo) { return (m_build_flags & mbo) != 0; }
  357. inline void Enable(MeshBuildOperation mbo) { m_build_flags |= mbo; }
  358. inline void Disable(MeshBuildOperation mbo) { m_build_flags &= ~mbo; }
  359. inline void Toggle(MeshBuildOperation mbo) { m_build_flags ^= mbo; }
  360. inline void Set(MeshBuildOperation mbo, bool value) { if (value) Enable(mbo); else Disable(mbo); }
  361. public:
  362. CommandStack m_stack;
  363. int m_i_cmd;
  364. int m_exec_nb;
  365. Array<int, int> m_loop_stack;
  366. vec4 m_color_a;
  367. vec4 m_color_b;
  368. vec2 m_texcoord_offset;
  369. vec2 m_texcoord_offset2;
  370. vec2 m_texcoord_scale;
  371. vec2 m_texcoord_scale2;
  372. Array<vec2, vec2> m_texcoord_custom_build[MeshType::Max];
  373. Array<vec2, vec2> m_texcoord_custom_build2[MeshType::Max];
  374. uint32_t m_texcoord_build_type[MeshType::Max];
  375. uint32_t m_texcoord_build_type2[MeshType::Max];
  376. uint32_t m_build_flags;
  377. };
  378. /* A safe enum for VertexDictionnary operations. */
  379. struct VDictType
  380. {
  381. enum Value
  382. {
  383. DoesNotExist=-3,
  384. Alone=-2,
  385. Master=-1
  386. }
  387. m_value;
  388. inline VDictType(Value v) : m_value(v) {}
  389. inline operator Value() { return m_value; }
  390. };
  391. /* TODO : replace VDict by a proper Half-edge system */
  392. //a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
  393. class VertexDictionnary
  394. {
  395. public:
  396. int FindVertexMaster(const int search_idx);
  397. bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
  398. bool FindConnectedVertices(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_vert, Array<int> const *ignored_tri = nullptr);
  399. bool FindConnectedTriangles(const int search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
  400. bool FindConnectedTriangles(const ivec2 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
  401. bool FindConnectedTriangles(const ivec3 &search_idx, const Array<uint16_t> &tri_list, const int tri0, Array<int> &connected_tri, Array<int> const *ignored_tri = nullptr);
  402. void AddVertex(int vert_id, vec3 vert_coord);
  403. void RemoveVertex(int vert_id);
  404. bool GetMasterList(Array<int> &ret_master_list) { ret_master_list = master_list; return ret_master_list.Count() > 0; }
  405. void Clear() { vertex_list.Empty(); }
  406. private:
  407. //<VertexId, VertexLocation, VertexMasterId>
  408. Array<int, vec3, int> vertex_list;
  409. //List of the master_ vertices
  410. Array<int> master_list;
  411. };
  412. } /* namespace lol */
  413. #endif /* __EASYMESHBUILD_EASYMESHBUILD_H__ */