diff options
Diffstat (limited to 'scene/3d/collision_shape_3d.cpp')
-rw-r--r-- | scene/3d/collision_shape_3d.cpp | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp index a66e84ac3c..e1c691b89a 100644 --- a/scene/3d/collision_shape_3d.cpp +++ b/scene/3d/collision_shape_3d.cpp @@ -44,39 +44,48 @@ //TODO: Implement CylinderShape and HeightMapShape? -void CollisionShape3D::make_convex_from_brothers() { - +void CollisionShape3D::make_convex_from_siblings() { Node *p = get_parent(); - if (!p) + if (!p) { return; + } - for (int i = 0; i < p->get_child_count(); i++) { + Vector<Vector3> vertices; + for (int i = 0; i < p->get_child_count(); i++) { Node *n = p->get_child(i); MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n); if (mi) { - Ref<Mesh> m = mi->get_mesh(); if (m.is_valid()) { - - Ref<Shape3D> s = m->create_convex_shape(); - set_shape(s); + for (int j = 0; j < m->get_surface_count(); j++) { + Array a = m->surface_get_arrays(j); + if (!a.empty()) { + Vector<Vector3> v = a[RenderingServer::ARRAY_VERTEX]; + for (int k = 0; k < v.size(); k++) { + vertices.append(mi->get_transform().xform(v[k])); + } + } + } } } } + + Ref<ConvexPolygonShape3D> shape = memnew(ConvexPolygonShape3D); + shape->set_points(vertices); + set_shape(shape); } void CollisionShape3D::_update_in_shape_owner(bool p_xform_only) { parent->shape_owner_set_transform(owner_id, get_transform()); - if (p_xform_only) + if (p_xform_only) { return; + } parent->shape_owner_set_disabled(owner_id, disabled); } void CollisionShape3D::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_PARENTED: { parent = Object::cast_to<CollisionObject3D>(get_parent()); if (parent) { @@ -111,41 +120,48 @@ void CollisionShape3D::_notification(int p_what) { } void CollisionShape3D::resource_changed(RES res) { - update_gizmo(); } String CollisionShape3D::get_configuration_warning() const { + String warning = Node3D::get_configuration_warning(); if (!Object::cast_to<CollisionObject3D>(get_parent())) { - return TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape."); } if (!shape.is_valid()) { - return TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it."); + if (!warning.empty()) { + warning += "\n\n"; + } + warning += TTR("A shape must be provided for CollisionShape3D to function. Please create a shape resource for it."); } - if (Object::cast_to<RigidBody3D>(get_parent())) { - if (Object::cast_to<ConcavePolygonShape3D>(*shape)) { - if (Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) { - return TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static."); - } + if (shape.is_valid() && + Object::cast_to<RigidBody3D>(get_parent()) && + Object::cast_to<ConcavePolygonShape3D>(*shape) && + Object::cast_to<RigidBody3D>(get_parent())->get_mode() != RigidBody3D::MODE_STATIC) { + if (!warning.empty()) { + warning += "\n\n"; } + warning += TTR("ConcavePolygonShape3D doesn't support RigidBody3D in another mode than static."); } - return String(); + return warning; } void CollisionShape3D::_bind_methods() { - //not sure if this should do anything ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &CollisionShape3D::resource_changed); ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape3D::set_shape); ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape3D::get_shape); ClassDB::bind_method(D_METHOD("set_disabled", "enable"), &CollisionShape3D::set_disabled); ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionShape3D::is_disabled); - ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape3D::make_convex_from_brothers); - ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); + ClassDB::bind_method(D_METHOD("make_convex_from_siblings"), &CollisionShape3D::make_convex_from_siblings); + ClassDB::set_method_flags("CollisionShape3D", "make_convex_from_siblings", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR); ClassDB::bind_method(D_METHOD("_update_debug_shape"), &CollisionShape3D::_update_debug_shape); @@ -154,7 +170,6 @@ void CollisionShape3D::_bind_methods() { } void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) { - if (!shape.is_null()) { shape->unregister_owner(this); shape->disconnect("changed", callable_mp(this, &CollisionShape3D::_shape_changed)); @@ -172,18 +187,17 @@ void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) { } } - if (is_inside_tree()) + if (is_inside_tree()) { _shape_changed(); + } update_configuration_warning(); } Ref<Shape3D> CollisionShape3D::get_shape() const { - return shape; } void CollisionShape3D::set_disabled(bool p_disabled) { - disabled = p_disabled; update_gizmo(); if (parent) { @@ -192,12 +206,10 @@ void CollisionShape3D::set_disabled(bool p_disabled) { } bool CollisionShape3D::is_disabled() const { - return disabled; } CollisionShape3D::CollisionShape3D() { - //indicator = RenderingServer::get_singleton()->mesh_create(); disabled = false; debug_shape = nullptr; @@ -207,8 +219,9 @@ CollisionShape3D::CollisionShape3D() { } CollisionShape3D::~CollisionShape3D() { - if (!shape.is_null()) + if (!shape.is_null()) { shape->unregister_owner(this); + } //RenderingServer::get_singleton()->free(indicator); } @@ -221,8 +234,9 @@ void CollisionShape3D::_update_debug_shape() { } Ref<Shape3D> s = get_shape(); - if (s.is_null()) + if (s.is_null()) { return; + } Ref<Mesh> mesh = s->get_debug_mesh(); MeshInstance3D *mi = memnew(MeshInstance3D); |