summaryrefslogtreecommitdiff
path: root/scene/3d/collision_shape_3d.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/collision_shape_3d.cpp')
-rw-r--r--scene/3d/collision_shape_3d.cpp76
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);