csg.cpp 43 KB

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