您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

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