diff options
Diffstat (limited to 'modules/csg')
-rw-r--r-- | modules/csg/csg.cpp | 45 | ||||
-rw-r--r-- | modules/csg/csg_gizmos.cpp | 45 | ||||
-rw-r--r-- | modules/csg/csg_shape.cpp | 72 |
3 files changed, 106 insertions, 56 deletions
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 6714db76bb..a6951a9320 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -138,10 +138,12 @@ inline bool is_point_in_triangle(const Vector3 &p_point, const Vector3 p_vertice lambda[2] = p_vertices[0].cross(p_vertices[1]).dot(p_point) / det; // Point is in the plane if all lambdas sum to 1. - if (!Math::is_equal_approx(lambda[0] + lambda[1] + lambda[2], 1)) return false; + if (!Math::is_equal_approx(lambda[0] + lambda[1] + lambda[2], 1)) + return false; // Point is inside the triangle if all lambdas are positive. - if (lambda[0] < 0 || lambda[1] < 0 || lambda[2] < 0) return false; + if (lambda[0] < 0 || lambda[1] < 0 || lambda[2] < 0) + return false; return true; } @@ -524,7 +526,8 @@ void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA, // Check if distance exists. for (const List<real_t>::Element *E = intersections.front(); E; E = E->next()) - if (Math::abs(**E - p_distance) < vertex_snap) return; + if (Math::abs(**E - p_distance) < vertex_snap) + return; intersections.push_back(p_distance); } @@ -790,7 +793,8 @@ int CSGBrushOperation::Build2DFaces::_add_vertex(const Vertex2D &p_vertex) { // Check if vertex exists. int vertex_id = _get_point_idx(p_vertex.point); - if (vertex_id != -1) return vertex_id; + if (vertex_id != -1) + return vertex_id; vertices.push_back(p_vertex); return vertices.size() - 1; @@ -816,7 +820,8 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert // Sort along the axis with the greatest difference. int axis = 0; - if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) axis = 1; + if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) + axis = 1; // Add it to the beginning or the end appropriately. if (new_point[axis] < first_point[axis]) @@ -834,7 +839,8 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert // Determine axis being sorted against i.e. the axis with the greatest difference. int axis = 0; - if (Math::abs(last_point.x - first_point.x) < Math::abs(last_point.y - first_point.y)) axis = 1; + if (Math::abs(last_point.x - first_point.x) < Math::abs(last_point.y - first_point.y)) + axis = 1; // Insert the point at the appropriate index. for (int insert_idx = 0; insert_idx < r_vertex_indices.size(); ++insert_idx) { @@ -853,7 +859,8 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_indices) { int segments = p_segment_indices.size() - 1; - if (segments < 2) return; + if (segments < 2) + return; // Faces around an inner vertex are merged by moving the inner vertex to the first vertex. for (int sorted_idx = 1; sorted_idx < segments; ++sorted_idx) { @@ -893,7 +900,8 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ // Skip flattened faces. if (outer_edge_idx[0] == p_segment_indices[closest_idx] || - outer_edge_idx[1] == p_segment_indices[closest_idx]) continue; + outer_edge_idx[1] == p_segment_indices[closest_idx]) + continue; //Don't create degenerate triangles. Vector2 edge1[2] = { @@ -924,7 +932,8 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ for (int i = 0; i < merge_faces_idx.size(); ++i) faces.remove(merge_faces_idx[i]); - if (degenerate_points.size() == 0) continue; + if (degenerate_points.size() == 0) + continue; // Split faces using degenerate points. for (int face_idx = 0; face_idx < faces.size(); ++face_idx) { @@ -954,7 +963,8 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_ break; } } - if (existing) continue; + if (existing) + continue; // Check if point is on an each edge. for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) { @@ -1043,10 +1053,12 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s // Check if intersection point is an edge point. if ((intersection_point - edge_points[0]).length_squared() < vertex_snap2 || - (intersection_point - edge_points[1]).length_squared() < vertex_snap2) continue; + (intersection_point - edge_points[1]).length_squared() < vertex_snap2) + continue; // Check if edge exists, by checking if the intersecting segment is parallel to the edge. - if (are_segements_parallel(p_segment_points, edge_points, vertex_snap2)) continue; + if (are_segements_parallel(p_segment_points, edge_points, vertex_snap2)) + continue; // Add the intersection point as a new vertex. Vertex2D new_vertex; @@ -1384,7 +1396,8 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face p_collection.build2DFacesB[p_face_idx_b] = Build2DFaces(); has_degenerate = true; } - if (has_degenerate) return; + if (has_degenerate) + return; // Ensure B has points either side of or in the plane of A. int in_plane_count = 0, over_count = 0, under_count = 0; @@ -1400,7 +1413,8 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face under_count++; } // If all points under or over the plane, there is no intesection. - if (over_count == 3 || under_count == 3) return; + if (over_count == 3 || under_count == 3) + return; // Ensure A has points either side of or in the plane of B. in_plane_count = 0; @@ -1418,7 +1432,8 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face under_count++; } // If all points under or over the plane, there is no intesection. - if (over_count == 3 || under_count == 3) return; + if (over_count == 3 || under_count == 3) + return; // Check for intersection using the SAT theorem. { diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index fa176cb94e..a859ef80a6 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -90,9 +90,12 @@ Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int CSGBox3D *s = Object::cast_to<CSGBox3D>(cs); switch (p_idx) { - case 0: return s->get_width(); - case 1: return s->get_height(); - case 2: return s->get_depth(); + case 0: + return s->get_width(); + case 1: + return s->get_height(); + case 2: + return s->get_depth(); } } @@ -157,9 +160,15 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca d = 0.001; switch (p_idx) { - case 0: s->set_width(d * 2); break; - case 1: s->set_height(d * 2); break; - case 2: s->set_depth(d * 2); break; + case 0: + s->set_width(d * 2); + break; + case 1: + s->set_height(d * 2); + break; + case 2: + s->set_depth(d * 2); + break; } } @@ -229,9 +238,15 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, CSGBox3D *s = Object::cast_to<CSGBox3D>(cs); if (p_cancel) { switch (p_idx) { - case 0: s->set_width(p_restore); break; - case 1: s->set_height(p_restore); break; - case 2: s->set_depth(p_restore); break; + case 0: + s->set_width(p_restore); + break; + case 1: + s->set_height(p_restore); + break; + case 2: + s->set_depth(p_restore); + break; } return; } @@ -241,9 +256,15 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, static const char *method[3] = { "set_width", "set_height", "set_depth" }; float current = 0; switch (p_idx) { - case 0: current = s->get_width(); break; - case 1: current = s->get_height(); break; - case 2: current = s->get_depth(); break; + case 0: + current = s->get_width(); + break; + case 1: + current = s->get_height(); + break; + case 2: + current = s->get_depth(); + break; } ur->add_do_method(s, method[p_idx], current); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 550a919d0d..a5b664eeab 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -185,9 +185,15 @@ CSGBrush *CSGShape3D::_get_brush() { CSGBrushOperation bop; switch (child->get_operation()) { - case CSGShape3D::OPERATION_UNION: bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap); break; - case CSGShape3D::OPERATION_INTERSECTION: bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); break; - case CSGShape3D::OPERATION_SUBTRACTION: bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); break; + case CSGShape3D::OPERATION_UNION: + bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap); + break; + case CSGShape3D::OPERATION_INTERSECTION: + bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); + break; + case CSGShape3D::OPERATION_SUBTRACTION: + bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); + break; } memdelete(n); memdelete(nn2); @@ -340,21 +346,31 @@ void CSGShape3D::_update_shape() { } } - //fill arrays - Vector<Vector3> physics_faces; - bool fill_physics_faces = false; + // Update collision faces. if (root_collision_shape.is_valid()) { + + Vector<Vector3> physics_faces; physics_faces.resize(n->faces.size() * 3); - fill_physics_faces = true; - } + Vector3 *physicsw = physics_faces.ptrw(); - { - Vector3 *physicsw; + for (int i = 0; i < n->faces.size(); i++) { + + int order[3] = { 0, 1, 2 }; + + if (n->faces[i].invert) { + SWAP(order[1], order[2]); + } - if (fill_physics_faces) { - physicsw = physics_faces.ptrw(); + physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]]; + physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]]; + physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]]; } + root_collision_shape->set_faces(physics_faces); + } + + //fill arrays + { for (int i = 0; i < n->faces.size(); i++) { int order[3] = { 0, 1, 2 }; @@ -363,12 +379,6 @@ void CSGShape3D::_update_shape() { SWAP(order[1], order[2]); } - if (fill_physics_faces) { - physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]]; - physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]]; - physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]]; - } - int mat = n->faces[i].material; ERR_CONTINUE(mat < -1 || mat >= face_count.size()); int idx = mat == -1 ? face_count.size() - 1 : mat; @@ -452,10 +462,6 @@ void CSGShape3D::_update_shape() { root_mesh->surface_set_material(idx, surfaces[i].material); } - if (root_collision_shape.is_valid()) { - root_collision_shape->set_faces(physics_faces); - } - set_base(root_mesh->get_rid()); } AABB CSGShape3D::get_aabb() const { @@ -1783,11 +1789,15 @@ CSGBrush *CSGPolygon3D::_build_brush() { final_polygon_min = p; final_polygon_max = final_polygon_min; } else { - if (p.x < final_polygon_min.x) final_polygon_min.x = p.x; - if (p.y < final_polygon_min.y) final_polygon_min.y = p.y; - - if (p.x > final_polygon_max.x) final_polygon_max.x = p.x; - if (p.y > final_polygon_max.y) final_polygon_max.y = p.y; + if (p.x < final_polygon_min.x) + final_polygon_min.x = p.x; + if (p.y < final_polygon_min.y) + final_polygon_min.y = p.y; + + if (p.x > final_polygon_max.x) + final_polygon_max.x = p.x; + if (p.y > final_polygon_max.y) + final_polygon_max.y = p.y; } } Vector2 final_polygon_size = final_polygon_max - final_polygon_min; @@ -1826,8 +1836,12 @@ CSGBrush *CSGPolygon3D::_build_brush() { int face_count = 0; switch (mode) { - case MODE_DEPTH: face_count = triangles.size() * 2 / 3 + (final_polygon.size()) * 2; break; - case MODE_SPIN: face_count = (spin_degrees < 360 ? triangles.size() * 2 / 3 : 0) + (final_polygon.size()) * 2 * spin_sides; break; + case MODE_DEPTH: + face_count = triangles.size() * 2 / 3 + (final_polygon.size()) * 2; + break; + case MODE_SPIN: + face_count = (spin_degrees < 360 ? triangles.size() * 2 / 3 : 0) + (final_polygon.size()) * 2 * spin_sides; + break; case MODE_PATH: { float bl = curve->get_baked_length(); int splits = MAX(2, Math::ceil(bl / path_interval)); |