csg.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475
  1. #include "csg.h"
  2. #include "face3.h"
  3. #include "geometry.h"
  4. #include "os/os.h"
  5. #include "sort.h"
  6. #include "thirdparty/misc/triangulator.h"
  7. void CSGBrush::clear() {
  8. faces.clear();
  9. }
  10. void CSGBrush::build_from_faces(const PoolVector<Vector3> &p_vertices, const PoolVector<Vector2> &p_uvs, const PoolVector<bool> &p_smooth, const PoolVector<Ref<Material> > &p_materials, const PoolVector<bool> &p_invert_faces) {
  11. clear();
  12. int vc = p_vertices.size();
  13. ERR_FAIL_COND((vc % 3) != 0)
  14. PoolVector<Vector3>::Read rv = p_vertices.read();
  15. int uvc = p_uvs.size();
  16. PoolVector<Vector2>::Read ruv = p_uvs.read();
  17. int sc = p_smooth.size();
  18. PoolVector<bool>::Read rs = p_smooth.read();
  19. int mc = p_materials.size();
  20. PoolVector<Ref<Material> >::Read rm = p_materials.read();
  21. int ic = p_invert_faces.size();
  22. PoolVector<bool>::Read ri = p_invert_faces.read();
  23. Map<Ref<Material>, int> material_map;
  24. faces.resize(p_vertices.size() / 3);
  25. for (int i = 0; i < faces.size(); i++) {
  26. Face &f = faces[i];
  27. f.vertices[0] = rv[i * 3 + 0];
  28. f.vertices[1] = rv[i * 3 + 1];
  29. f.vertices[2] = rv[i * 3 + 2];
  30. if (uvc == vc) {
  31. f.uvs[0] = ruv[i * 3 + 0];
  32. f.uvs[1] = ruv[i * 3 + 1];
  33. f.uvs[2] = ruv[i * 3 + 2];
  34. }
  35. if (sc == vc / 3) {
  36. f.smooth = rs[i];
  37. } else {
  38. f.smooth = false;
  39. }
  40. if (ic == vc / 3) {
  41. f.invert = ri[i];
  42. } else {
  43. f.invert = false;
  44. }
  45. if (mc == vc / 3) {
  46. Ref<Material> mat = rm[i];
  47. if (mat.is_valid()) {
  48. const Map<Ref<Material>, int>::Element *E = material_map.find(mat);
  49. if (E) {
  50. f.material = E->get();
  51. } else {
  52. f.material = material_map.size();
  53. material_map[mat] = f.material;
  54. }
  55. } else {
  56. f.material = -1;
  57. }
  58. }
  59. }
  60. materials.resize(material_map.size());
  61. for (Map<Ref<Material>, int>::Element *E = material_map.front(); E; E = E->next()) {
  62. materials[E->get()] = E->key();
  63. }
  64. _regen_face_aabbs();
  65. }
  66. void CSGBrush::_regen_face_aabbs() {
  67. for (int i = 0; i < faces.size(); i++) {
  68. faces[i].aabb.position = faces[i].vertices[0];
  69. faces[i].aabb.expand_to(faces[i].vertices[1]);
  70. faces[i].aabb.expand_to(faces[i].vertices[2]);
  71. faces[i].aabb.grow_by(faces[i].aabb.get_longest_axis_size() * 0.001); //make it a tad bigger to avoid num precision erros
  72. }
  73. }
  74. void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) {
  75. faces = p_brush.faces;
  76. materials = p_brush.materials;
  77. for (int i = 0; i < faces.size(); i++) {
  78. for (int j = 0; j < 3; j++) {
  79. faces[i].vertices[j] = p_xform.xform(p_brush.faces[i].vertices[j]);
  80. }
  81. }
  82. _regen_face_aabbs();
  83. }
  84. ////////////////////////
  85. void CSGBrushOperation::BuildPoly::create(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B) {
  86. //creates the initial face that will be used for clipping against the other faces
  87. Vector3 va[3] = {
  88. p_brush->faces[p_face].vertices[0],
  89. p_brush->faces[p_face].vertices[1],
  90. p_brush->faces[p_face].vertices[2],
  91. };
  92. plane = Plane(va[0], va[1], va[2]);
  93. to_world.origin = va[0];
  94. to_world.basis.set_axis(2, plane.normal);
  95. to_world.basis.set_axis(0, (va[1] - va[2]).normalized());
  96. to_world.basis.set_axis(1, to_world.basis.get_axis(0).cross(to_world.basis.get_axis(2)).normalized());
  97. to_poly = to_world.affine_inverse();
  98. face_index = p_face;
  99. for (int i = 0; i < 3; i++) {
  100. Point p;
  101. Vector3 localp = to_poly.xform(va[i]);
  102. p.point.x = localp.x;
  103. p.point.y = localp.y;
  104. p.uv = p_brush->faces[p_face].uvs[i];
  105. points.push_back(p);
  106. ///edge
  107. Edge e;
  108. e.points[0] = i;
  109. e.points[1] = (i + 1) % 3;
  110. e.outer = true;
  111. edges.push_back(e);
  112. }
  113. smooth = p_brush->faces[p_face].smooth;
  114. invert = p_brush->faces[p_face].invert;
  115. if (p_brush->faces[p_face].material != -1) {
  116. material = p_brush->materials[p_brush->faces[p_face].material];
  117. }
  118. base_edges = 3;
  119. }
  120. static Vector2 interpolate_uv(const Vector2 &p_vertex_a, const Vector2 &p_vertex_b, const Vector2 &p_vertex_c, const Vector2 &p_uv_a, const Vector2 &p_uv_c) {
  121. float len_a_c = (p_vertex_c - p_vertex_a).length();
  122. if (len_a_c < CMP_EPSILON) {
  123. return p_uv_a;
  124. }
  125. float len_a_b = (p_vertex_b - p_vertex_a).length();
  126. float c = len_a_b / len_a_c;
  127. return p_uv_a.linear_interpolate(p_uv_c, c);
  128. }
  129. static Vector2 interpolate_triangle_uv(const Vector2 &p_pos, const Vector2 *p_vtx, const Vector2 *p_uv) {
  130. if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) {
  131. return p_uv[0];
  132. }
  133. if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2) {
  134. return p_uv[1];
  135. }
  136. if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2) {
  137. return p_uv[2];
  138. }
  139. Vector2 v0 = p_vtx[1] - p_vtx[0];
  140. Vector2 v1 = p_vtx[2] - p_vtx[0];
  141. Vector2 v2 = p_pos - p_vtx[0];
  142. float d00 = v0.dot(v0);
  143. float d01 = v0.dot(v1);
  144. float d11 = v1.dot(v1);
  145. float d20 = v2.dot(v0);
  146. float d21 = v2.dot(v1);
  147. float denom = (d00 * d11 - d01 * d01);
  148. if (denom == 0) {
  149. return p_uv[0];
  150. }
  151. float v = (d11 * d20 - d01 * d21) / denom;
  152. float w = (d00 * d21 - d01 * d20) / denom;
  153. float u = 1.0f - v - w;
  154. return p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
  155. }
  156. void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_face, const Vector2 *segment, MeshMerge &mesh_merge, bool p_for_B) {
  157. //keep track of what was inserted
  158. Vector<int> inserted_points;
  159. //keep track of point indices for what was inserted, allowing reuse of points.
  160. int segment_idx[2] = { -1, -1 };
  161. //check if edge and poly share a vertex, of so, assign it to segment_idx
  162. for (int i = 0; i < points.size(); i++) {
  163. for (int j = 0; j < 2; j++) {
  164. if (segment[j].distance_to(points[i].point) < CMP_EPSILON) {
  165. segment_idx[j] = i;
  166. inserted_points.push_back(i);
  167. break;
  168. }
  169. }
  170. }
  171. //check if both segment points are shared with other vertices
  172. if (segment_idx[0] != -1 && segment_idx[1] != -1) {
  173. if (segment_idx[0] == segment_idx[1]) {
  174. return; //segment was too tiny, both mapped to same point
  175. }
  176. bool found = false;
  177. //check if the segment already exists
  178. for (int i = 0; i < edges.size(); i++) {
  179. if (
  180. (edges[i].points[0] == segment_idx[0] && edges[i].points[1] == segment_idx[1]) ||
  181. (edges[i].points[0] == segment_idx[1] && edges[i].points[1] == segment_idx[0])) {
  182. found = true;
  183. break;
  184. }
  185. }
  186. if (found) {
  187. //it does already exist, do nothing
  188. return;
  189. }
  190. //directly add the new segment
  191. Edge new_edge;
  192. new_edge.points[0] = segment_idx[0];
  193. new_edge.points[1] = segment_idx[1];
  194. edges.push_back(new_edge);
  195. return;
  196. }
  197. //check edge by edge against the segment points to see if intersects
  198. for (int i = 0; i < base_edges; i++) {
  199. //if a point is shared with one of the edge points, then this edge must not be tested, as it will result in a numerical precision error.
  200. bool edge_valid = true;
  201. for (int j = 0; j < 2; j++) {
  202. if (edges[i].points[0] == segment_idx[0] || edges[i].points[1] == segment_idx[1] || edges[i].points[0] == segment_idx[1] || edges[i].points[1] == segment_idx[0]) {
  203. edge_valid = false; //segment has this point, cant check against this
  204. break;
  205. }
  206. }
  207. if (!edge_valid) //already hit a point in this edge, so dont test it
  208. continue;
  209. //see if either points are within the edge isntead of crossing it
  210. Vector2 res;
  211. bool found = false;
  212. int assign_segment_id = -1;
  213. for (int j = 0; j < 2; j++) {
  214. Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point };
  215. Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg);
  216. if (closest.distance_to(segment[j]) < CMP_EPSILON) {
  217. //point rest of this edge
  218. res = closest;
  219. found = true;
  220. assign_segment_id = j;
  221. }
  222. }
  223. //test if the point crosses the edge
  224. if (!found && Geometry::segment_intersects_segment_2d(segment[0], segment[1], points[edges[i].points[0]].point, points[edges[i].points[1]].point, &res)) {
  225. //point does cross the edge
  226. found = true;
  227. }
  228. //check whether an intersection against the segment happened
  229. if (found) {
  230. //It did! so first, must slice the segment
  231. Point new_point;
  232. new_point.point = res;
  233. //make sure to interpolate UV too
  234. new_point.uv = interpolate_uv(points[edges[i].points[0]].point, new_point.point, points[edges[i].points[1]].point, points[edges[i].points[0]].uv, points[edges[i].points[1]].uv);
  235. int point_idx = points.size();
  236. points.push_back(new_point);
  237. //split the edge in 2
  238. Edge new_edge;
  239. new_edge.points[0] = edges[i].points[0];
  240. new_edge.points[1] = point_idx;
  241. new_edge.outer = edges[i].outer;
  242. edges[i].points[0] = point_idx;
  243. edges.insert(i, new_edge);
  244. i++; //skip newly inserted edge
  245. base_edges++; //will need an extra one in the base triangle
  246. if (assign_segment_id >= 0) {
  247. //point did split a segment, so make sure to remember this
  248. segment_idx[assign_segment_id] = point_idx;
  249. }
  250. inserted_points.push_back(point_idx);
  251. }
  252. }
  253. //final step: after cutting the original triangle, try to see if we can still insert
  254. //this segment
  255. //if already inserted two points, just use them for a segment
  256. if (inserted_points.size() >= 2) { //should never be >2 on non-manifold geometry, but cope with error
  257. //two points were inserted, create the new edge
  258. Edge new_edge;
  259. new_edge.points[0] = inserted_points[0];
  260. new_edge.points[1] = inserted_points[1];
  261. edges.push_back(new_edge);
  262. return;
  263. }
  264. // One or no points were inserted (besides splitting), so try to see if extra points can be placed inside the triangle.
  265. // This needs to be done here, after the previous tests were exhausted
  266. for (int i = 0; i < 2; i++) {
  267. if (segment_idx[i] != -1)
  268. continue; //already assigned to something, so skip
  269. //check whether one of the segment endpoints is inside the triangle. If it is, this points needs to be inserted
  270. if (Geometry::is_point_in_triangle(segment[i], points[0].point, points[1].point, points[2].point)) {
  271. Point new_point;
  272. new_point.point = segment[i];
  273. Vector2 point3[3] = { points[0].point, points[1].point, points[2].point };
  274. Vector2 uv3[3] = { points[0].uv, points[1].uv, points[2].uv };
  275. new_point.uv = interpolate_triangle_uv(new_point.point, point3, uv3);
  276. int point_idx = points.size();
  277. points.push_back(new_point);
  278. inserted_points.push_back(point_idx);
  279. }
  280. }
  281. //check again whether two points were inserted, if so then create the new edge
  282. if (inserted_points.size() >= 2) { //should never be >2 on non-manifold geometry, but cope with error
  283. Edge new_edge;
  284. new_edge.points[0] = inserted_points[0];
  285. new_edge.points[1] = inserted_points[1];
  286. edges.push_back(new_edge);
  287. }
  288. }
  289. void CSGBrushOperation::BuildPoly::clip(const CSGBrush *p_brush, int p_face, MeshMerge &mesh_merge, bool p_for_B) {
  290. //Clip function.. find triangle points that will be mapped to the plane and form a segment
  291. Vector2 segment[3]; //2D
  292. int src_points = 0;
  293. for (int i = 0; i < 3; i++) {
  294. Vector3 p = p_brush->faces[p_face].vertices[i];
  295. if (plane.has_point(p)) {
  296. Vector3 pp = plane.project(p);
  297. pp = to_poly.xform(pp);
  298. segment[src_points++] = Vector2(pp.x, pp.y);
  299. } else {
  300. Vector3 q = p_brush->faces[p_face].vertices[(i + 1) % 3];
  301. if (plane.has_point(q))
  302. continue; //next point is in plane, will be added eventually
  303. if (plane.is_point_over(p) == plane.is_point_over(q))
  304. continue; // both on same side of the plane, don't add
  305. Vector3 res;
  306. if (plane.intersects_segment(p, q, &res)) {
  307. res = to_poly.xform(res);
  308. segment[src_points++] = Vector2(res.x, res.y);
  309. }
  310. }
  311. }
  312. //all above or all below, nothing to do. Should not happen though since a precheck was done before.
  313. if (src_points == 0)
  314. return;
  315. //just one point in plane is not worth doing anything
  316. if (src_points == 1)
  317. return;
  318. //transform A points to 2D
  319. if (segment[0].distance_to(segment[1]) < CMP_EPSILON)
  320. return; //too small
  321. _clip_segment(p_brush, p_face, segment, mesh_merge, p_for_B);
  322. }
  323. void CSGBrushOperation::_collision_callback(const CSGBrush *A, int p_face_a, Map<int, BuildPoly> &build_polys_a, const CSGBrush *B, int p_face_b, Map<int, BuildPoly> &build_polys_b, MeshMerge &mesh_merge) {
  324. //construct a frame of reference for both transforms, in order to do intersection test
  325. Vector3 va[3] = {
  326. A->faces[p_face_a].vertices[0],
  327. A->faces[p_face_a].vertices[1],
  328. A->faces[p_face_a].vertices[2],
  329. };
  330. Vector3 vb[3] = {
  331. B->faces[p_face_b].vertices[0],
  332. B->faces[p_face_b].vertices[1],
  333. B->faces[p_face_b].vertices[2],
  334. };
  335. {
  336. //check if either is a degenerate
  337. if (va[0].distance_to(va[1]) < CMP_EPSILON || va[0].distance_to(va[2]) < CMP_EPSILON || va[1].distance_to(va[2]) < CMP_EPSILON)
  338. return;
  339. if (vb[0].distance_to(vb[1]) < CMP_EPSILON || vb[0].distance_to(vb[2]) < CMP_EPSILON || vb[1].distance_to(vb[2]) < CMP_EPSILON)
  340. return;
  341. }
  342. {
  343. //check if points are the same
  344. int equal_count = 0;
  345. for (int i = 0; i < 3; i++) {
  346. for (int j = 0; j < 3; j++) {
  347. if (va[i].distance_to(vb[j]) < mesh_merge.vertex_snap) {
  348. equal_count++;
  349. break;
  350. }
  351. }
  352. }
  353. //if 2 or 3 points are the same, there is no point in doing anything. They can't
  354. //be clipped either, so add both.
  355. if (equal_count == 2 || equal_count == 3) {
  356. return;
  357. }
  358. }
  359. // do a quick pre-check for no-intersection using the SAT theorem
  360. {
  361. //b under or over a plane
  362. int over_count = 0, in_plane_count = 0, under_count = 0;
  363. Plane plane_a(va[0], va[1], va[2]);
  364. if (plane_a.normal == Vector3()) {
  365. return; //degenerate
  366. }
  367. for (int i = 0; i < 3; i++) {
  368. if (plane_a.has_point(vb[i]))
  369. in_plane_count++;
  370. else if (plane_a.is_point_over(vb[i]))
  371. over_count++;
  372. else
  373. under_count++;
  374. }
  375. if (over_count == 0 || under_count == 0)
  376. return; //no intersection, something needs to be under AND over
  377. //a under or over b plane
  378. over_count = 0;
  379. under_count = 0;
  380. in_plane_count = 0;
  381. Plane plane_b(vb[0], vb[1], vb[2]);
  382. if (plane_b.normal == Vector3())
  383. return; //degenerate
  384. for (int i = 0; i < 3; i++) {
  385. if (plane_b.has_point(va[i]))
  386. in_plane_count++;
  387. else if (plane_b.is_point_over(va[i]))
  388. over_count++;
  389. else
  390. under_count++;
  391. }
  392. if (over_count == 0 || under_count == 0)
  393. return; //no intersection, something needs to be under AND over
  394. //edge pairs (cross product combinations), see SAT theorem
  395. for (int i = 0; i < 3; i++) {
  396. Vector3 axis_a = (va[i] - va[(i + 1) % 3]).normalized();
  397. for (int j = 0; j < 3; j++) {
  398. Vector3 axis_b = (vb[j] - vb[(j + 1) % 3]).normalized();
  399. Vector3 sep_axis = axis_a.cross(axis_b);
  400. if (sep_axis == Vector3())
  401. continue; //colineal
  402. sep_axis.normalize();
  403. real_t min_a = 1e20, max_a = -1e20;
  404. real_t min_b = 1e20, max_b = -1e20;
  405. for (int k = 0; k < 3; k++) {
  406. real_t d = sep_axis.dot(va[k]);
  407. min_a = MIN(min_a, d);
  408. max_a = MAX(max_a, d);
  409. d = sep_axis.dot(vb[k]);
  410. min_b = MIN(min_b, d);
  411. max_b = MAX(max_b, d);
  412. }
  413. min_b -= (max_a - min_a) * 0.5;
  414. max_b += (max_a - min_a) * 0.5;
  415. real_t dmin = min_b - (min_a + max_a) * 0.5;
  416. real_t dmax = max_b - (min_a + max_a) * 0.5;
  417. if (dmin > CMP_EPSILON || dmax < -CMP_EPSILON) {
  418. return; //does not contain zero, so they don't overlap
  419. }
  420. }
  421. }
  422. }
  423. //if we are still here, it means they most likely intersect, so create BuildPolys if they dont existy
  424. BuildPoly *poly_a = NULL;
  425. if (!build_polys_a.has(p_face_a)) {
  426. BuildPoly bp;
  427. bp.create(A, p_face_a, mesh_merge, false);
  428. build_polys_a[p_face_a] = bp;
  429. }
  430. poly_a = &build_polys_a[p_face_a];
  431. BuildPoly *poly_b = NULL;
  432. if (!build_polys_b.has(p_face_b)) {
  433. BuildPoly bp;
  434. bp.create(B, p_face_b, mesh_merge, true);
  435. build_polys_b[p_face_b] = bp;
  436. }
  437. poly_b = &build_polys_b[p_face_b];
  438. //clip each other, this could be improved by using vertex unique IDs (more vertices may be shared instead of using snap)
  439. poly_a->clip(B, p_face_b, mesh_merge, false);
  440. poly_b->clip(A, p_face_a, mesh_merge, true);
  441. }
  442. void CSGBrushOperation::_add_poly_points(const BuildPoly &p_poly, int p_edge, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<bool> &edge_process, Vector<PolyPoints> &r_poly) {
  443. //this function follows the polygon points counter clockwise and adds them. It creates lists of unique polygons
  444. //every time an unused edge is found, it's pushed to a stack and continues from there.
  445. List<EdgeSort> edge_stack;
  446. {
  447. EdgeSort es;
  448. es.angle = 0; //wont be checked here
  449. es.edge = p_edge;
  450. es.prev_point = p_from_point;
  451. es.edge_point = p_to_point;
  452. edge_stack.push_back(es);
  453. }
  454. int limit = p_poly.points.size() * 4;
  455. //attempt to empty the stack.
  456. while (edge_stack.size()) {
  457. EdgeSort e = edge_stack.front()->get();
  458. edge_stack.pop_front();
  459. if (edge_process[e.edge]) {
  460. //nothing to do here
  461. continue;
  462. }
  463. Vector<int> points;
  464. points.push_back(e.prev_point);
  465. int prev_point = e.prev_point;
  466. int to_point = e.edge_point;
  467. int current_edge = e.edge;
  468. edge_process[e.edge] = true; //mark as processed
  469. while (to_point != e.prev_point) {
  470. Vector2 segment[2] = { p_poly.points[prev_point].point, p_poly.points[to_point].point };
  471. //construct a basis transform from the segment, which will be used to check the angle
  472. Transform2D t2d;
  473. t2d[0] = (segment[1] - segment[0]).normalized(); //use as Y
  474. t2d[1] = Vector2(-t2d[0].y, t2d[0].x); // use as tangent
  475. t2d[2] = segment[1]; //origin
  476. t2d.affine_invert();
  477. //push all edges found here, they will be sorted by minimum angle later.
  478. Vector<EdgeSort> next_edges;
  479. for (int i = 0; i < vertex_process[to_point].size(); i++) {
  480. int edge = vertex_process[to_point][i];
  481. int opposite_point = p_poly.edges[edge].points[0] == to_point ? p_poly.edges[edge].points[1] : p_poly.edges[edge].points[0];
  482. if (opposite_point == prev_point)
  483. continue; //not going back
  484. EdgeSort e;
  485. Vector2 local_vec = t2d.xform(p_poly.points[opposite_point].point);
  486. e.angle = -local_vec.angle(); //negate so we can sort by minimum angle
  487. e.edge = edge;
  488. e.edge_point = opposite_point;
  489. e.prev_point = to_point;
  490. next_edges.push_back(e);
  491. }
  492. //finally, sort by minimum angle
  493. next_edges.sort();
  494. int next_point = -1;
  495. int next_edge = -1;
  496. for (int i = 0; i < next_edges.size(); i++) {
  497. if (i == 0) {
  498. //minimum angle found is the next point
  499. next_point = next_edges[i].edge_point;
  500. next_edge = next_edges[i].edge;
  501. } else {
  502. //the rest are pushed to the stack IF they were not processed yet.
  503. if (!edge_process[next_edges[i].edge]) {
  504. edge_stack.push_back(next_edges[i]);
  505. }
  506. }
  507. }
  508. if (next_edge == -1) {
  509. //did not find anything, may be a dead-end edge (this should normally not happen)
  510. //just flip the direction and go back
  511. next_point = prev_point;
  512. next_edge = current_edge;
  513. }
  514. points.push_back(to_point);
  515. prev_point = to_point;
  516. to_point = next_point;
  517. edge_process[next_edge] = true; //mark this edge as processed
  518. current_edge = next_edge;
  519. }
  520. //if more than 2 points were added to the polygon, add it to the list of polygons.
  521. if (points.size() > 2) {
  522. PolyPoints pp;
  523. pp.points = points;
  524. r_poly.push_back(pp);
  525. }
  526. }
  527. }
  528. void CSGBrushOperation::_add_poly_outline(const BuildPoly &p_poly, int p_from_point, int p_to_point, const Vector<Vector<int> > &vertex_process, Vector<int> &r_outline) {
  529. //this is the opposite of the function above. It adds polygon outlines instead.
  530. //this is used for triangulating holes.
  531. //no stack is used here because only the bigger outline is interesting.
  532. r_outline.push_back(p_from_point);
  533. int prev_point = p_from_point;
  534. int to_point = p_to_point;
  535. while (to_point != p_from_point) {
  536. Vector2 segment[2] = { p_poly.points[prev_point].point, p_poly.points[to_point].point };
  537. //again create a transform to compute the angle.
  538. Transform2D t2d;
  539. t2d[0] = (segment[1] - segment[0]).normalized(); //use as Y
  540. t2d[1] = Vector2(-t2d[0].y, t2d[0].x); // use as tangent
  541. t2d[2] = segment[1]; //origin
  542. t2d.affine_invert();
  543. float max_angle;
  544. int next_point_angle = -1;
  545. for (int i = 0; i < vertex_process[to_point].size(); i++) {
  546. int edge = vertex_process[to_point][i];
  547. int opposite_point = p_poly.edges[edge].points[0] == to_point ? p_poly.edges[edge].points[1] : p_poly.edges[edge].points[0];
  548. if (opposite_point == prev_point)
  549. continue; //not going back
  550. float angle = -t2d.xform(p_poly.points[opposite_point].point).angle();
  551. if (next_point_angle == -1 || angle > max_angle) { //same as before but use greater to check.
  552. max_angle = angle;
  553. next_point_angle = opposite_point;
  554. }
  555. }
  556. if (next_point_angle == -1) {
  557. //go back because no route found
  558. next_point_angle = prev_point;
  559. }
  560. r_outline.push_back(to_point);
  561. prev_point = to_point;
  562. to_point = next_point_angle;
  563. }
  564. }
  565. void CSGBrushOperation::_merge_poly(MeshMerge &mesh, int p_face_idx, const BuildPoly &p_poly, bool p_from_b) {
  566. //finally, merge the 2D polygon back to 3D
  567. Vector<Vector<int> > vertex_process;
  568. Vector<bool> edge_process;
  569. vertex_process.resize(p_poly.points.size());
  570. edge_process.resize(p_poly.edges.size());
  571. //none processed by default
  572. for (int i = 0; i < edge_process.size(); i++) {
  573. edge_process[i] = false;
  574. }
  575. //put edges in points, so points can go through them
  576. for (int i = 0; i < p_poly.edges.size(); i++) {
  577. vertex_process[p_poly.edges[i].points[0]].push_back(i);
  578. vertex_process[p_poly.edges[i].points[1]].push_back(i);
  579. }
  580. Vector<PolyPoints> polys;
  581. //process points that were not processed
  582. for (int i = 0; i < edge_process.size(); i++) {
  583. if (edge_process[i] == true)
  584. continue; //already processed
  585. int intersect_poly = -1;
  586. if (i > 0) {
  587. //this is disconnected, so it's clearly a hole. lets find where it belongs
  588. Vector2 ref_point = p_poly.points[p_poly.edges[i].points[0]].point;
  589. for (int j = 0; j < polys.size(); j++) {
  590. //find a point outside poly
  591. Vector2 out_point(-1e20, -1e20);
  592. const PolyPoints &pp = polys[j];
  593. for (int k = 0; k < pp.points.size(); k++) {
  594. Vector2 p = p_poly.points[pp.points[k]].point;
  595. out_point.x = MAX(out_point.x, p.x);
  596. out_point.y = MAX(out_point.y, p.y);
  597. }
  598. out_point += Vector2(0.12341234, 0.4123412); // move to a random place to avoid direct edge-point chances
  599. int intersections = 0;
  600. for (int k = 0; k < pp.points.size(); k++) {
  601. Vector2 p1 = p_poly.points[pp.points[k]].point;
  602. Vector2 p2 = p_poly.points[pp.points[(k + 1) % pp.points.size()]].point;
  603. if (Geometry::segment_intersects_segment_2d(ref_point, out_point, p1, p2, NULL)) {
  604. intersections++;
  605. }
  606. }
  607. if (intersections % 2 == 1) {
  608. //hole is inside this poly
  609. intersect_poly = j;
  610. break;
  611. }
  612. }
  613. }
  614. if (intersect_poly != -1) {
  615. //must add this as a hole
  616. Vector<int> outline;
  617. _add_poly_outline(p_poly, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, outline);
  618. if (outline.size() > 1) {
  619. polys[intersect_poly].holes.push_back(outline);
  620. }
  621. }
  622. _add_poly_points(p_poly, i, p_poly.edges[i].points[0], p_poly.edges[i].points[1], vertex_process, edge_process, polys);
  623. }
  624. //get rid of holes, not the most optiomal way, but also not a common case at all to be inoptimal
  625. for (int i = 0; i < polys.size(); i++) {
  626. if (!polys[i].holes.size())
  627. continue;
  628. //repeat until no more holes are left to be merged
  629. while (polys[i].holes.size()) {
  630. //try to merge a hole with the outline
  631. bool added_hole = false;
  632. for (int j = 0; j < polys[i].holes.size(); j++) {
  633. //try hole vertices
  634. int with_outline_vertex = -1;
  635. int from_hole_vertex = -1;
  636. bool found = false;
  637. for (int k = 0; k < polys[i].holes[j].size(); k++) {
  638. int from_idx = polys[i].holes[j][k];
  639. Vector2 from = p_poly.points[from_idx].point;
  640. //try a segment from hole vertex to outline vertices
  641. from_hole_vertex = k;
  642. bool valid = true;
  643. for (int l = 0; l < polys[i].points.size(); l++) {
  644. int to_idx = polys[i].points[l];
  645. Vector2 to = p_poly.points[to_idx].point;
  646. with_outline_vertex = l;
  647. //try agaisnt outline (other points) first
  648. valid = true;
  649. for (int m = 0; m < polys[i].points.size(); m++) {
  650. int m_next = (m + 1) % polys[i].points.size();
  651. if (m == with_outline_vertex || m_next == with_outline_vertex) //do not test with edges that share this point
  652. continue;
  653. if (Geometry::segment_intersects_segment_2d(from, to, p_poly.points[polys[i].points[m]].point, p_poly.points[polys[i].points[m_next]].point, NULL)) {
  654. valid = false;
  655. break;
  656. }
  657. }
  658. if (!valid)
  659. continue;
  660. //try agaisnt all holes including self
  661. for (int m = 0; m < polys[i].holes.size(); m++) {
  662. for (int n = 0; n < polys[i].holes[m].size(); n++) {
  663. int n_next = (n + 1) % polys[i].holes[m].size();
  664. if (m == j && (n == from_hole_vertex || n_next == from_hole_vertex)) //contains vertex being tested from current hole, skip
  665. continue;
  666. if (Geometry::segment_intersects_segment_2d(from, to, p_poly.points[polys[i].holes[m][n]].point, p_poly.points[polys[i].holes[m][n_next]].point, NULL)) {
  667. valid = false;
  668. break;
  669. }
  670. }
  671. if (!valid)
  672. break;
  673. }
  674. if (valid) //all passed! exit loop
  675. break;
  676. else
  677. continue; //something went wrong, go on.
  678. }
  679. if (valid) {
  680. found = true; //if in the end this was valid, use it
  681. break;
  682. }
  683. }
  684. if (found) {
  685. //hook this hole with outline, and remove from list of holes
  686. //duplicate point
  687. int insert_at = with_outline_vertex;
  688. polys[i].points.insert(insert_at, polys[i].points[insert_at]);
  689. insert_at++;
  690. //insert all others, outline should be backwards (must check)
  691. int holesize = polys[i].holes[j].size();
  692. for (int k = 0; k <= holesize; k++) {
  693. int idx = (from_hole_vertex + k) % holesize;
  694. polys[i].points.insert(insert_at, polys[i].holes[j][idx]);
  695. insert_at++;
  696. }
  697. added_hole = true;
  698. polys[i].holes.remove(j);
  699. break; //got rid of hole, break and continue
  700. }
  701. }
  702. ERR_BREAK(!added_hole);
  703. }
  704. }
  705. //triangulate polygons
  706. for (int i = 0; i < polys.size(); i++) {
  707. Vector<Vector2> vertices;
  708. vertices.resize(polys[i].points.size());
  709. for (int j = 0; j < vertices.size(); j++) {
  710. vertices[j] = p_poly.points[polys[i].points[j]].point;
  711. }
  712. Vector<int> indices = Geometry::triangulate_polygon(vertices);
  713. for (int j = 0; j < indices.size(); j += 3) {
  714. //obtain the vertex
  715. Vector3 face[3];
  716. Vector2 uv[3];
  717. float cp = Geometry::vec2_cross(p_poly.points[polys[i].points[indices[j + 0]]].point, p_poly.points[polys[i].points[indices[j + 1]]].point, p_poly.points[polys[i].points[indices[j + 2]]].point);
  718. if (Math::abs(cp) < CMP_EPSILON)
  719. continue;
  720. for (int k = 0; k < 3; k++) {
  721. Vector2 p = p_poly.points[polys[i].points[indices[j + k]]].point;
  722. face[k] = p_poly.to_world.xform(Vector3(p.x, p.y, 0));
  723. uv[k] = p_poly.points[polys[i].points[indices[j + k]]].uv;
  724. }
  725. mesh.add_face(face[0], face[1], face[2], uv[0], uv[1], uv[2], p_poly.smooth, p_poly.invert, p_poly.material, p_from_b);
  726. }
  727. }
  728. }
  729. //use a limit to speed up bvh and limit the depth
  730. #define BVH_LIMIT 8
  731. int CSGBrushOperation::MeshMerge::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
  732. if (p_depth > max_depth) {
  733. max_depth = p_depth;
  734. }
  735. if (p_size <= BVH_LIMIT) {
  736. for (int i = 0; i < p_size - 1; i++) {
  737. p_bb[p_from + i]->next = p_bb[p_from + i + 1] - p_bvh;
  738. }
  739. return p_bb[p_from] - p_bvh;
  740. } else if (p_size == 0) {
  741. return -1;
  742. }
  743. AABB aabb;
  744. aabb = p_bb[p_from]->aabb;
  745. for (int i = 1; i < p_size; i++) {
  746. aabb.merge_with(p_bb[p_from + i]->aabb);
  747. }
  748. int li = aabb.get_longest_axis_index();
  749. switch (li) {
  750. case Vector3::AXIS_X: {
  751. SortArray<BVH *, BVHCmpX> sort_x;
  752. sort_x.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
  753. //sort_x.sort(&p_bb[p_from],p_size);
  754. } break;
  755. case Vector3::AXIS_Y: {
  756. SortArray<BVH *, BVHCmpY> sort_y;
  757. sort_y.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
  758. //sort_y.sort(&p_bb[p_from],p_size);
  759. } break;
  760. case Vector3::AXIS_Z: {
  761. SortArray<BVH *, BVHCmpZ> sort_z;
  762. sort_z.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
  763. //sort_z.sort(&p_bb[p_from],p_size);
  764. } break;
  765. }
  766. int left = _create_bvh(p_bvh, p_bb, p_from, p_size / 2, p_depth + 1, max_depth, max_alloc);
  767. int right = _create_bvh(p_bvh, p_bb, p_from + p_size / 2, p_size - p_size / 2, p_depth + 1, max_depth, max_alloc);
  768. int index = max_alloc++;
  769. BVH *_new = &p_bvh[index];
  770. _new->aabb = aabb;
  771. _new->center = aabb.position + aabb.size * 0.5;
  772. _new->face = -1;
  773. _new->left = left;
  774. _new->right = right;
  775. _new->next = -1;
  776. return index;
  777. }
  778. int CSGBrushOperation::MeshMerge::_bvh_count_intersections(BVH *bvhptr, int p_max_depth, int p_bvh_first, const Vector3 &p_begin, const Vector3 &p_end, int p_exclude) const {
  779. uint32_t *stack = (uint32_t *)alloca(sizeof(int) * p_max_depth);
  780. enum {
  781. TEST_AABB_BIT = 0,
  782. VISIT_LEFT_BIT = 1,
  783. VISIT_RIGHT_BIT = 2,
  784. VISIT_DONE_BIT = 3,
  785. VISITED_BIT_SHIFT = 29,
  786. NODE_IDX_MASK = (1 << VISITED_BIT_SHIFT) - 1,
  787. VISITED_BIT_MASK = ~NODE_IDX_MASK,
  788. };
  789. int intersections = 0;
  790. int level = 0;
  791. const Vector3 *vertexptr = points.ptr();
  792. const Face *facesptr = faces.ptr();
  793. AABB segment_aabb;
  794. segment_aabb.position = p_begin;
  795. segment_aabb.expand_to(p_end);
  796. int pos = p_bvh_first;
  797. stack[0] = pos;
  798. while (true) {
  799. uint32_t node = stack[level] & NODE_IDX_MASK;
  800. const BVH &b = bvhptr[node];
  801. bool done = false;
  802. switch (stack[level] >> VISITED_BIT_SHIFT) {
  803. case TEST_AABB_BIT: {
  804. if (b.face >= 0) {
  805. const BVH *bp = &b;
  806. while (bp) {
  807. bool valid = segment_aabb.intersects(bp->aabb) && bp->aabb.intersects_segment(p_begin, p_end);
  808. if (valid && p_exclude != bp->face) {
  809. const Face &s = facesptr[bp->face];
  810. Face3 f3(vertexptr[s.points[0]], vertexptr[s.points[1]], vertexptr[s.points[2]]);
  811. Vector3 res;
  812. if (f3.intersects_segment(p_begin, p_end, &res)) {
  813. intersections++;
  814. }
  815. }
  816. if (bp->next != -1) {
  817. bp = &bvhptr[bp->next];
  818. } else {
  819. bp = NULL;
  820. }
  821. }
  822. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  823. } else {
  824. bool valid = segment_aabb.intersects(b.aabb) && b.aabb.intersects_segment(p_begin, p_end);
  825. if (!valid) {
  826. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  827. } else {
  828. stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
  829. }
  830. }
  831. continue;
  832. }
  833. case VISIT_LEFT_BIT: {
  834. stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
  835. stack[level + 1] = b.left | TEST_AABB_BIT;
  836. level++;
  837. continue;
  838. }
  839. case VISIT_RIGHT_BIT: {
  840. stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
  841. stack[level + 1] = b.right | TEST_AABB_BIT;
  842. level++;
  843. continue;
  844. }
  845. case VISIT_DONE_BIT: {
  846. if (level == 0) {
  847. done = true;
  848. break;
  849. } else
  850. level--;
  851. continue;
  852. }
  853. }
  854. if (done)
  855. break;
  856. }
  857. return intersections;
  858. }
  859. void CSGBrushOperation::MeshMerge::mark_inside_faces() {
  860. // mark faces that are inside. This helps later do the boolean ops when merging.
  861. // this approach is very brute force (with a bunch of optimizatios, such as BVH and pre AABB intersection test)
  862. AABB aabb;
  863. for (int i = 0; i < points.size(); i++) {
  864. if (i == 0) {
  865. aabb.position = points[i];
  866. } else {
  867. aabb.expand_to(points[i]);
  868. }
  869. }
  870. float max_distance = aabb.size.length() * 1.2;
  871. Vector<BVH> bvhvec;
  872. bvhvec.resize(faces.size() * 3); //will never be larger than this (todo make better)
  873. BVH *bvh = bvhvec.ptrw();
  874. AABB faces_a;
  875. AABB faces_b;
  876. bool first_a = true;
  877. bool first_b = true;
  878. for (int i = 0; i < faces.size(); i++) {
  879. bvh[i].left = -1;
  880. bvh[i].right = -1;
  881. bvh[i].face = i;
  882. bvh[i].aabb.position = points[faces[i].points[0]];
  883. bvh[i].aabb.expand_to(points[faces[i].points[1]]);
  884. bvh[i].aabb.expand_to(points[faces[i].points[2]]);
  885. bvh[i].center = bvh[i].aabb.position + bvh[i].aabb.size * 0.5;
  886. bvh[i].next = -1;
  887. if (faces[i].from_b) {
  888. if (first_b) {
  889. faces_b = bvh[i].aabb;
  890. first_b = false;
  891. } else {
  892. faces_b.merge_with(bvh[i].aabb);
  893. }
  894. } else {
  895. if (first_a) {
  896. faces_a = bvh[i].aabb;
  897. first_a = false;
  898. } else {
  899. faces_a.merge_with(bvh[i].aabb);
  900. }
  901. }
  902. }
  903. AABB intersection_aabb = faces_a.intersection(faces_b);
  904. intersection_aabb.grow_by(intersection_aabb.get_longest_axis_size() * 0.01); //grow a little, avoid numerical error
  905. if (intersection_aabb.size == Vector3()) //AABB do not intersect, so neither do shapes.
  906. return;
  907. Vector<BVH *> bvhtrvec;
  908. bvhtrvec.resize(faces.size());
  909. BVH **bvhptr = bvhtrvec.ptrw();
  910. for (int i = 0; i < faces.size(); i++) {
  911. bvhptr[i] = &bvh[i];
  912. }
  913. int max_depth = 0;
  914. int max_alloc = faces.size();
  915. _create_bvh(bvh, bvhptr, 0, faces.size(), 1, max_depth, max_alloc);
  916. for (int i = 0; i < faces.size(); i++) {
  917. if (!intersection_aabb.intersects(bvh[i].aabb))
  918. continue; //not in AABB intersection, so not in face intersection
  919. Vector3 center = points[faces[i].points[0]];
  920. center += points[faces[i].points[1]];
  921. center += points[faces[i].points[2]];
  922. center /= 3.0;
  923. Plane plane(points[faces[i].points[0]], points[faces[i].points[1]], points[faces[i].points[2]]);
  924. Vector3 target = center + plane.normal * max_distance + Vector3(0.0001234, 0.000512, 0.00013423); //reduce chance of edge hits by doing a small increment
  925. int intersections = _bvh_count_intersections(bvh, max_depth, max_alloc - 1, center, target, i);
  926. if (intersections & 1) {
  927. faces[i].inside = true;
  928. }
  929. }
  930. }
  931. void CSGBrushOperation::MeshMerge::add_face(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector2 &p_uv_a, const Vector2 &p_uv_b, const Vector2 &p_uv_c, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
  932. Vector3 src_points[3] = { p_a, p_b, p_c };
  933. Vector2 src_uvs[3] = { p_uv_a, p_uv_b, p_uv_c };
  934. int indices[3];
  935. for (int i = 0; i < 3; i++) {
  936. VertexKey vk;
  937. vk.x = int((double(src_points[i].x) + double(vertex_snap) * 0.31234) / double(vertex_snap));
  938. vk.y = int((double(src_points[i].y) + double(vertex_snap) * 0.31234) / double(vertex_snap));
  939. vk.z = int((double(src_points[i].z) + double(vertex_snap) * 0.31234) / double(vertex_snap));
  940. int res;
  941. if (snap_cache.lookup(vk, &res)) {
  942. indices[i] = res;
  943. } else {
  944. indices[i] = points.size();
  945. points.push_back(src_points[i]);
  946. snap_cache.set(vk, indices[i]);
  947. }
  948. }
  949. if (indices[0] == indices[2] || indices[0] == indices[1] || indices[1] == indices[2])
  950. return; //not adding degenerate
  951. MeshMerge::Face face;
  952. face.from_b = p_from_b;
  953. face.inside = false;
  954. face.smooth = p_smooth;
  955. face.invert = p_invert;
  956. if (p_material.is_valid()) {
  957. if (!materials.has(p_material)) {
  958. face.material_idx = materials.size();
  959. materials[p_material] = face.material_idx;
  960. } else {
  961. face.material_idx = materials[p_material];
  962. }
  963. } else {
  964. face.material_idx = -1;
  965. }
  966. for (int k = 0; k < 3; k++) {
  967. face.points[k] = indices[k];
  968. face.uvs[k] = src_uvs[k];
  969. ;
  970. }
  971. faces.push_back(face);
  972. }
  973. void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_A, const CSGBrush &p_B, CSGBrush &result, float p_snap) {
  974. CallbackData cd;
  975. cd.self = this;
  976. cd.A = &p_A;
  977. cd.B = &p_B;
  978. MeshMerge mesh_merge;
  979. mesh_merge.vertex_snap = p_snap;
  980. //check intersections between faces. Use AABB to speed up precheck
  981. //this generates list of buildpolys and clips them.
  982. //this was originally BVH optimized, but its not really worth it.
  983. for (int i = 0; i < p_A.faces.size(); i++) {
  984. cd.face_a = i;
  985. for (int j = 0; j < p_B.faces.size(); j++) {
  986. if (p_A.faces[i].aabb.intersects(p_B.faces[j].aabb)) {
  987. _collision_callback(&p_A, i, cd.build_polys_A, &p_B, j, cd.build_polys_B, mesh_merge);
  988. }
  989. }
  990. }
  991. //merge the already cliped polys back to 3D
  992. for (Map<int, BuildPoly>::Element *E = cd.build_polys_A.front(); E; E = E->next()) {
  993. _merge_poly(mesh_merge, E->key(), E->get(), false);
  994. }
  995. for (Map<int, BuildPoly>::Element *E = cd.build_polys_B.front(); E; E = E->next()) {
  996. _merge_poly(mesh_merge, E->key(), E->get(), true);
  997. }
  998. //merge the non clipped faces back
  999. for (int i = 0; i < p_A.faces.size(); i++) {
  1000. if (cd.build_polys_A.has(i))
  1001. continue; //made from buildpoly, skipping
  1002. Vector3 points[3];
  1003. Vector2 uvs[3];
  1004. for (int j = 0; j < 3; j++) {
  1005. points[j] = p_A.faces[i].vertices[j];
  1006. uvs[j] = p_A.faces[i].uvs[j];
  1007. }
  1008. Ref<Material> material;
  1009. if (p_A.faces[i].material != -1) {
  1010. material = p_A.materials[p_A.faces[i].material];
  1011. }
  1012. mesh_merge.add_face(points[0], points[1], points[2], uvs[0], uvs[1], uvs[2], p_A.faces[i].smooth, p_A.faces[i].invert, material, false);
  1013. }
  1014. for (int i = 0; i < p_B.faces.size(); i++) {
  1015. if (cd.build_polys_B.has(i))
  1016. continue; //made from buildpoly, skipping
  1017. Vector3 points[3];
  1018. Vector2 uvs[3];
  1019. for (int j = 0; j < 3; j++) {
  1020. points[j] = p_B.faces[i].vertices[j];
  1021. uvs[j] = p_B.faces[i].uvs[j];
  1022. }
  1023. Ref<Material> material;
  1024. if (p_B.faces[i].material != -1) {
  1025. material = p_B.materials[p_B.faces[i].material];
  1026. }
  1027. mesh_merge.add_face(points[0], points[1], points[2], uvs[0], uvs[1], uvs[2], p_B.faces[i].smooth, p_B.faces[i].invert, material, true);
  1028. }
  1029. //mark faces that ended up inside the intersection
  1030. mesh_merge.mark_inside_faces();
  1031. //regen new brush to start filling it again
  1032. result.clear();
  1033. switch (p_operation) {
  1034. case OPERATION_UNION: {
  1035. int outside_count = 0;
  1036. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1037. if (mesh_merge.faces[i].inside)
  1038. continue;
  1039. outside_count++;
  1040. }
  1041. result.faces.resize(outside_count);
  1042. outside_count = 0;
  1043. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1044. if (mesh_merge.faces[i].inside)
  1045. continue;
  1046. for (int j = 0; j < 3; j++) {
  1047. result.faces[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
  1048. result.faces[outside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
  1049. }
  1050. result.faces[outside_count].smooth = mesh_merge.faces[i].smooth;
  1051. result.faces[outside_count].invert = mesh_merge.faces[i].invert;
  1052. result.faces[outside_count].material = mesh_merge.faces[i].material_idx;
  1053. outside_count++;
  1054. }
  1055. result._regen_face_aabbs();
  1056. } break;
  1057. case OPERATION_INTERSECTION: {
  1058. int inside_count = 0;
  1059. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1060. if (!mesh_merge.faces[i].inside)
  1061. continue;
  1062. inside_count++;
  1063. }
  1064. result.faces.resize(inside_count);
  1065. inside_count = 0;
  1066. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1067. if (!mesh_merge.faces[i].inside)
  1068. continue;
  1069. for (int j = 0; j < 3; j++) {
  1070. result.faces[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
  1071. result.faces[inside_count].uvs[j] = mesh_merge.faces[i].uvs[j];
  1072. }
  1073. result.faces[inside_count].smooth = mesh_merge.faces[i].smooth;
  1074. result.faces[inside_count].invert = mesh_merge.faces[i].invert;
  1075. result.faces[inside_count].material = mesh_merge.faces[i].material_idx;
  1076. inside_count++;
  1077. }
  1078. result._regen_face_aabbs();
  1079. } break;
  1080. case OPERATION_SUBSTRACTION: {
  1081. int face_count = 0;
  1082. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1083. if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
  1084. continue;
  1085. if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
  1086. continue;
  1087. face_count++;
  1088. }
  1089. result.faces.resize(face_count);
  1090. face_count = 0;
  1091. for (int i = 0; i < mesh_merge.faces.size(); i++) {
  1092. if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
  1093. continue;
  1094. if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
  1095. continue;
  1096. for (int j = 0; j < 3; j++) {
  1097. result.faces[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
  1098. result.faces[face_count].uvs[j] = mesh_merge.faces[i].uvs[j];
  1099. }
  1100. if (mesh_merge.faces[i].from_b) {
  1101. //invert facing of insides of B
  1102. SWAP(result.faces[face_count].vertices[1], result.faces[face_count].vertices[2]);
  1103. SWAP(result.faces[face_count].uvs[1], result.faces[face_count].uvs[2]);
  1104. }
  1105. result.faces[face_count].smooth = mesh_merge.faces[i].smooth;
  1106. result.faces[face_count].invert = mesh_merge.faces[i].invert;
  1107. result.faces[face_count].material = mesh_merge.faces[i].material_idx;
  1108. face_count++;
  1109. }
  1110. result._regen_face_aabbs();
  1111. } break;
  1112. }
  1113. //updatelist of materials
  1114. result.materials.resize(mesh_merge.materials.size());
  1115. for (const Map<Ref<Material>, int>::Element *E = mesh_merge.materials.front(); E; E = E->next()) {
  1116. result.materials[E->get()] = E->key();
  1117. }
  1118. }