Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

208 linhas
7.6 KiB

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