summaryrefslogtreecommitdiffstats
path: root/modules/csg/csg_shape.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/csg/csg_shape.cpp')
-rw-r--r--modules/csg/csg_shape.cpp64
1 files changed, 46 insertions, 18 deletions
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 296cda627a..8777651545 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -460,27 +460,31 @@ void CSGShape3D::_update_shape() {
_update_collision_faces();
}
-void CSGShape3D::_update_collision_faces() {
- if (use_collision && is_root_shape() && root_collision_shape.is_valid()) {
- CSGBrush *n = _get_brush();
- ERR_FAIL_NULL_MSG(n, "Cannot get CSGBrush.");
- Vector<Vector3> physics_faces;
- physics_faces.resize(n->faces.size() * 3);
- Vector3 *physicsw = physics_faces.ptrw();
-
- for (int i = 0; i < n->faces.size(); i++) {
- int order[3] = { 0, 1, 2 };
+Vector<Vector3> CSGShape3D::_get_brush_collision_faces() {
+ Vector<Vector3> collision_faces;
+ CSGBrush *n = _get_brush();
+ ERR_FAIL_NULL_V_MSG(n, collision_faces, "Cannot get CSGBrush.");
+ collision_faces.resize(n->faces.size() * 3);
+ Vector3 *collision_faces_ptrw = collision_faces.ptrw();
- if (n->faces[i].invert) {
- SWAP(order[1], order[2]);
- }
+ for (int i = 0; i < n->faces.size(); i++) {
+ int order[3] = { 0, 1, 2 };
- 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]];
+ if (n->faces[i].invert) {
+ SWAP(order[1], order[2]);
}
- root_collision_shape->set_faces(physics_faces);
+ collision_faces_ptrw[i * 3 + 0] = n->faces[i].vertices[order[0]];
+ collision_faces_ptrw[i * 3 + 1] = n->faces[i].vertices[order[1]];
+ collision_faces_ptrw[i * 3 + 2] = n->faces[i].vertices[order[2]];
+ }
+
+ return collision_faces;
+}
+
+void CSGShape3D::_update_collision_faces() {
+ if (use_collision && is_root_shape() && root_collision_shape.is_valid()) {
+ root_collision_shape->set_faces(_get_brush_collision_faces());
if (_is_debug_collision_shape_visible()) {
_update_debug_collision_shape();
@@ -488,6 +492,26 @@ void CSGShape3D::_update_collision_faces() {
}
}
+Ref<ArrayMesh> CSGShape3D::bake_static_mesh() {
+ Ref<ArrayMesh> baked_mesh;
+ if (is_root_shape() && root_mesh.is_valid()) {
+ baked_mesh = root_mesh;
+ }
+ return baked_mesh;
+}
+
+Ref<ConcavePolygonShape3D> CSGShape3D::bake_collision_shape() {
+ Ref<ConcavePolygonShape3D> baked_collision_shape;
+ if (is_root_shape() && root_collision_shape.is_valid()) {
+ baked_collision_shape.instantiate();
+ baked_collision_shape->set_faces(root_collision_shape->get_faces());
+ } else if (is_root_shape()) {
+ baked_collision_shape.instantiate();
+ baked_collision_shape->set_faces(_get_brush_collision_faces());
+ }
+ return baked_collision_shape;
+}
+
bool CSGShape3D::_is_debug_collision_shape_visible() {
return is_inside_tree() && (get_tree()->is_debugging_collisions_hint() || Engine::get_singleton()->is_editor_hint());
}
@@ -704,6 +728,9 @@ void CSGShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_meshes"), &CSGShape3D::get_meshes);
+ ClassDB::bind_method(D_METHOD("bake_static_mesh"), &CSGShape3D::bake_static_mesh);
+ ClassDB::bind_method(D_METHOD("bake_collision_shape"), &CSGShape3D::bake_collision_shape);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "operation", PROPERTY_HINT_ENUM, "Union,Intersection,Subtraction"), "set_operation", "get_operation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "snap", PROPERTY_HINT_RANGE, "0.000001,1,0.000001,suffix:m"), "set_snap", "get_snap");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "calculate_tangents"), "set_calculate_tangents", "is_calculating_tangents");
@@ -934,7 +961,8 @@ CSGBrush *CSGMesh3D::_build_brush() {
void CSGMesh3D::_mesh_changed() {
_make_dirty();
- update_gizmos();
+
+ callable_mp((Node3D *)this, &Node3D::update_gizmos).call_deferred();
}
void CSGMesh3D::set_material(const Ref<Material> &p_material) {