diff options
Diffstat (limited to 'scene/3d/mesh_instance_3d.cpp')
-rw-r--r-- | scene/3d/mesh_instance_3d.cpp | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index b997c64b29..c495f68890 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -51,13 +51,13 @@ bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) { return true; } - if (p_name.operator String().begins_with("material/")) { + if (p_name.operator String().begins_with("surface_material_override/")) { int idx = p_name.operator String().get_slicec('/', 1).to_int(); - if (idx >= materials.size() || idx < 0) { + if (idx >= surface_override_materials.size() || idx < 0) { return false; } - set_surface_material(idx, p_value); + set_surface_override_material(idx, p_value); return true; } @@ -75,12 +75,12 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const { return true; } - if (p_name.operator String().begins_with("material/")) { + if (p_name.operator String().begins_with("surface_material_override/")) { int idx = p_name.operator String().get_slicec('/', 1).to_int(); - if (idx >= materials.size() || idx < 0) { + if (idx >= surface_override_materials.size() || idx < 0) { return false; } - r_ret = materials[idx]; + r_ret = surface_override_materials[idx]; return true; } return false; @@ -100,7 +100,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const { if (mesh.is_valid()) { for (int i = 0; i < mesh->get_surface_count(); i++) { - p_list->push_back(PropertyInfo(Variant::OBJECT, "material/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE)); + p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_material_override/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE)); } } } @@ -126,7 +126,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) { } mesh->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed)); - materials.resize(mesh->get_surface_count()); + surface_override_materials.resize(mesh->get_surface_count()); set_base(mesh->get_rid()); } else { @@ -271,32 +271,67 @@ void MeshInstance3D::create_convex_collision() { } } +Node *MeshInstance3D::create_multiple_convex_collisions_node() { + if (mesh.is_null()) { + return nullptr; + } + + Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(); + if (!shapes.size()) { + return nullptr; + } + + StaticBody3D *static_body = memnew(StaticBody3D); + for (int i = 0; i < shapes.size(); i++) { + CollisionShape3D *cshape = memnew(CollisionShape3D); + cshape->set_shape(shapes[i]); + static_body->add_child(cshape); + } + return static_body; +} + +void MeshInstance3D::create_multiple_convex_collisions() { + StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_multiple_convex_collisions_node()); + ERR_FAIL_COND(!static_body); + static_body->set_name(String(get_name()) + "_col"); + + add_child(static_body); + if (get_owner()) { + static_body->set_owner(get_owner()); + int count = static_body->get_child_count(); + for (int i = 0; i < count; i++) { + CollisionShape3D *cshape = Object::cast_to<CollisionShape3D>(static_body->get_child(i)); + cshape->set_owner(get_owner()); + } + } +} + void MeshInstance3D::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE) { _resolve_skeleton_path(); } } -int MeshInstance3D::get_surface_material_count() const { - return materials.size(); +int MeshInstance3D::get_surface_override_material_count() const { + return surface_override_materials.size(); } -void MeshInstance3D::set_surface_material(int p_surface, const Ref<Material> &p_material) { - ERR_FAIL_INDEX(p_surface, materials.size()); +void MeshInstance3D::set_surface_override_material(int p_surface, const Ref<Material> &p_material) { + ERR_FAIL_INDEX(p_surface, surface_override_materials.size()); - materials.write[p_surface] = p_material; + surface_override_materials.write[p_surface] = p_material; - if (materials[p_surface].is_valid()) { - RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, materials[p_surface]->get_rid()); + if (surface_override_materials[p_surface].is_valid()) { + RS::get_singleton()->instance_set_surface_override_material(get_instance(), p_surface, surface_override_materials[p_surface]->get_rid()); } else { - RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, RID()); + RS::get_singleton()->instance_set_surface_override_material(get_instance(), p_surface, RID()); } } -Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const { - ERR_FAIL_INDEX_V(p_surface, materials.size(), Ref<Material>()); +Ref<Material> MeshInstance3D::get_surface_override_material(int p_surface) const { + ERR_FAIL_INDEX_V(p_surface, surface_override_materials.size(), Ref<Material>()); - return materials[p_surface]; + return surface_override_materials[p_surface]; } Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { @@ -305,7 +340,7 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { return material_override; } - Ref<Material> surface_material = get_surface_material(p_surface); + Ref<Material> surface_material = get_surface_override_material(p_surface); if (surface_material.is_valid()) { return surface_material; } @@ -320,7 +355,8 @@ Ref<Material> MeshInstance3D::get_active_material(int p_surface) const { void MeshInstance3D::_mesh_changed() { ERR_FAIL_COND(mesh.is_null()); - materials.resize(mesh->get_surface_count()); + surface_override_materials.resize(mesh->get_surface_count()); + update_gizmo(); } void MeshInstance3D::create_debug_tangents() { @@ -391,7 +427,7 @@ void MeshInstance3D::create_debug_tangents() { add_child(mi); #ifdef TOOLS_ENABLED - if (this == get_tree()->get_edited_scene_root()) { + if (is_inside_tree() && this == get_tree()->get_edited_scene_root()) { mi->set_owner(this); } else { mi->set_owner(get_owner()); @@ -408,15 +444,17 @@ void MeshInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_skin", "skin"), &MeshInstance3D::set_skin); ClassDB::bind_method(D_METHOD("get_skin"), &MeshInstance3D::get_skin); - ClassDB::bind_method(D_METHOD("get_surface_material_count"), &MeshInstance3D::get_surface_material_count); - ClassDB::bind_method(D_METHOD("set_surface_material", "surface", "material"), &MeshInstance3D::set_surface_material); - ClassDB::bind_method(D_METHOD("get_surface_material", "surface"), &MeshInstance3D::get_surface_material); + ClassDB::bind_method(D_METHOD("get_surface_override_material_count"), &MeshInstance3D::get_surface_override_material_count); + ClassDB::bind_method(D_METHOD("set_surface_override_material", "surface", "material"), &MeshInstance3D::set_surface_override_material); + ClassDB::bind_method(D_METHOD("get_surface_override_material", "surface"), &MeshInstance3D::get_surface_override_material); ClassDB::bind_method(D_METHOD("get_active_material", "surface"), &MeshInstance3D::get_active_material); ClassDB::bind_method(D_METHOD("create_trimesh_collision"), &MeshInstance3D::create_trimesh_collision); ClassDB::set_method_flags("MeshInstance3D", "create_trimesh_collision", METHOD_FLAGS_DEFAULT); ClassDB::bind_method(D_METHOD("create_convex_collision"), &MeshInstance3D::create_convex_collision); ClassDB::set_method_flags("MeshInstance3D", "create_convex_collision", METHOD_FLAGS_DEFAULT); + ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions"), &MeshInstance3D::create_multiple_convex_collisions); + ClassDB::set_method_flags("MeshInstance3D", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT); ClassDB::bind_method(D_METHOD("create_debug_tangents"), &MeshInstance3D::create_debug_tangents); ClassDB::set_method_flags("MeshInstance3D", "create_debug_tangents", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); |