diff options
Diffstat (limited to 'modules/csg/csg_shape.cpp')
-rw-r--r-- | modules/csg/csg_shape.cpp | 64 |
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) { |