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.

217 righe
7.7 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 HAVE_CONFIG_H
  17. # include "config.h"
  18. #endif
  19. #include "core.h"
  20. namespace lol
  21. {
  22. //-----------------------------------------------------------------------------
  23. //helpers func to retrieve a vertex.
  24. int VertexDictionnary::FindVertexMaster(const int search_idx)
  25. {
  26. //Resolve current vertex idx in the dictionnary (if exist)
  27. for (int j = 0; j < vertex_list.Count(); j++)
  28. if (vertex_list[j].m1 == search_idx)
  29. return vertex_list[j].m3;
  30. return VDictType::DoesNotExist;
  31. }
  32. //-----------------------------------------------------------------------------
  33. //retrieve a list of matching vertices, doesn't include search_idx.
  34. bool VertexDictionnary::FindMatchingVertices(const int search_idx, array<int> &matching_ids)
  35. {
  36. int cur_mast = FindVertexMaster(search_idx);
  37. if (cur_mast == VDictType::DoesNotExist || cur_mast == VDictType::Alone)
  38. return false;
  39. if (cur_mast == VDictType::Master)
  40. cur_mast = search_idx;
  41. else
  42. matching_ids << vertex_list[cur_mast].m1;
  43. for (int j = 0; j < vertex_list.Count(); j++)
  44. if (vertex_list[j].m3 == cur_mast && vertex_list[j].m1 != search_idx)
  45. matching_ids << vertex_list[j].m1;
  46. return (matching_ids.Count() > 0);
  47. }
  48. //-----------------------------------------------------------------------------
  49. //Will return connected vertices (through triangles), if returned vertex has matching ones, it only returns the master.
  50. bool VertexDictionnary::FindConnectedVertices(const int search_idx, const array<uint16_t> &tri_list, const int tri0, array<int> &connected_vert, array<int> const *ignored_tri)
  51. {
  52. array<int> connected_tri;
  53. FindConnectedTriangles(search_idx, tri_list, tri0, connected_tri, ignored_tri);
  54. for (int i = 0; i < connected_tri.Count(); i++)
  55. {
  56. for (int j = 0; j < 3; j++)
  57. {
  58. int v_indice = tri_list[connected_tri[i] + j];
  59. if (v_indice != search_idx)
  60. {
  61. int found_master = FindVertexMaster(tri_list[connected_tri[i] + j]);
  62. if (found_master == VDictType::Alone || found_master == VDictType::Master)
  63. found_master = v_indice;
  64. if (found_master != search_idx)
  65. {
  66. bool already_exist = false;
  67. for (int k = 0; !already_exist && k < connected_vert.Count(); k++)
  68. if (connected_vert[k] == found_master)
  69. already_exist = true;
  70. if (!already_exist)
  71. connected_vert << found_master;
  72. }
  73. }
  74. }
  75. }
  76. return (connected_vert.Count() > 0);
  77. }
  78. //-----------------------------------------------------------------------------
  79. bool VertexDictionnary::FindConnectedTriangles(const int search_idx, const array<uint16_t> &tri_list, const int tri0, array<int> &connected_tri, array<int> const *ignored_tri)
  80. {
  81. return FindConnectedTriangles(ivec3(search_idx, search_idx, search_idx), tri_list, tri0, connected_tri, ignored_tri);
  82. }
  83. //-----------------------------------------------------------------------------
  84. bool VertexDictionnary::FindConnectedTriangles(const ivec2 &search_idx, const array<uint16_t> &tri_list, const int tri0, array<int> &connected_tri, array<int> const *ignored_tri)
  85. {
  86. return FindConnectedTriangles(ivec3(search_idx, search_idx.x), tri_list, tri0, connected_tri, ignored_tri);
  87. }
  88. //-----------------------------------------------------------------------------
  89. bool VertexDictionnary::FindConnectedTriangles(const ivec3 &search_idx, const array<uint16_t> &tri_list, const int tri0, array<int> &connected_tri, array<int> const *ignored_tri)
  90. {
  91. int needed_validation = 0;
  92. array<int> vert_list[3];
  93. for (int i = 0; i < 3; i++)
  94. {
  95. //Small optim since above func will use this one
  96. if ((i == 1 && search_idx[0] == search_idx[1]) ||
  97. (i == 2 && (search_idx[0] == search_idx[2] || search_idx[1] == search_idx[2])))
  98. continue;
  99. else
  100. {
  101. //increment the validation info, hence empty list aren't taken into account.
  102. needed_validation++;
  103. vert_list[i] << search_idx[i];
  104. FindMatchingVertices(search_idx[i], vert_list[i]);
  105. }
  106. }
  107. for (int i = tri0; i < tri_list.Count(); i += 3)
  108. {
  109. if (ignored_tri)
  110. {
  111. bool should_pass = false;
  112. for (int j = 0; !should_pass && j < ignored_tri->Count(); j++)
  113. if ((*ignored_tri)[j] == i)
  114. should_pass = true;
  115. if (should_pass)
  116. continue;
  117. }
  118. int found_validation = 0;
  119. for (int j = 0; j < 3; j++)
  120. {
  121. bool validated = false;
  122. for (int k = 0; !validated && k < vert_list[j].Count(); k++)
  123. for (int l = 0; !validated && l < 3; l++)
  124. if (vert_list[j][k] == tri_list[i + l])
  125. validated = true;
  126. found_validation += (validated)?(1):(0);
  127. }
  128. //triangle is validated store it
  129. if (found_validation == needed_validation)
  130. connected_tri << i;
  131. }
  132. return (connected_tri.Count() > 0);
  133. }
  134. //-----------------------------------------------------------------------------
  135. //Will update the given list with all the vertices on the same spot.
  136. void VertexDictionnary::AddVertex(const int vert_id, const vec3 vert_coord)
  137. {
  138. for (int j = 0; j < vertex_list.Count(); j++)
  139. if (vertex_list[j].m1 == vert_id)
  140. return;
  141. //First, build the vertex Dictionnary
  142. int i = 0;
  143. for (; i < master_list.Count(); i++)
  144. {
  145. int cur_mast = master_list[i];
  146. int cur_id = vertex_list[cur_mast].m1;
  147. vec3 cur_loc = vertex_list[cur_mast].m2;
  148. int &cur_type = vertex_list[cur_mast].m3;
  149. if (cur_id == vert_id)
  150. return;
  151. if (sqlength(cur_loc - vert_coord) < TestEpsilon::Get())
  152. {
  153. if (cur_type == VDictType::Alone)
  154. cur_type = VDictType::Master;
  155. vertex_list.Push(vert_id, vert_coord, cur_mast);
  156. return;
  157. }
  158. }
  159. //We're here because we couldn't find any matching vertex
  160. master_list.Push(vertex_list.Count());
  161. vertex_list.Push(vert_id, vert_coord, VDictType::Alone);
  162. }
  163. //-----------------------------------------------------------------------------
  164. //Will update the given list with all the vertices on the same spot.
  165. void VertexDictionnary::RemoveVertex(const int vert_id)
  166. {
  167. int j = 0;
  168. for (; j < vertex_list.Count(); j++)
  169. if (vertex_list[j].m1 == vert_id)
  170. break;
  171. if (vertex_list[j].m3 == VDictType::Master)
  172. {
  173. int jf = -1;
  174. //change all the master ref in the list
  175. for (int i = 0; i < vertex_list.Count(); i++)
  176. {
  177. if (vertex_list[i].m3 == j)
  178. {
  179. if (jf < 0)
  180. {
  181. jf = i;
  182. vertex_list[i].m3 = VDictType::Master;
  183. }
  184. else
  185. vertex_list[i].m3 = jf;
  186. }
  187. }
  188. }
  189. vertex_list.Remove(j);
  190. for (int i = 0; i < master_list.Count(); i++)
  191. if (master_list[j] == j)
  192. break;
  193. }
  194. } /* namespace lol */