Ver código fonte

Merge pull request #38348 from asheraryam/convex-decompose

[3.x] Create GDScript bindings for creating multiple-convex collision bodies
Rémi Verschelde 4 anos atrás
pai
commit
3edf1adf91

+ 7 - 0
doc/classes/MeshInstance.xml

@@ -27,6 +27,13 @@
 				This helper creates a [MeshInstance] child node with gizmos at every vertex calculated from the mesh geometry. It's mainly used for testing.
 			</description>
 		</method>
+		<method name="create_multiple_convex_collisions">
+			<return type="void">
+			</return>
+			<description>
+				This helper creates a [StaticBody] child node with multiple [ConvexPolygonShape] collision shapes calculated from the mesh geometry via convex decomposition. It's mainly used for testing.
+			</description>
+		</method>
 		<method name="create_trimesh_collision">
 			<return type="void">
 			</return>

+ 38 - 0
scene/3d/mesh_instance.cpp

@@ -573,6 +573,42 @@ void MeshInstance::create_trimesh_collision() {
 	}
 }
 
+Node *MeshInstance::create_multiple_convex_collisions_node() {
+
+	if (mesh.is_null())
+		return NULL;
+
+	Vector<Ref<Shape> > shapes = mesh->convex_decompose();
+	if (!shapes.size()) {
+		return NULL;
+	}
+
+	StaticBody *static_body = memnew(StaticBody);
+	for (int i = 0; i < shapes.size(); i++) {
+		CollisionShape *cshape = memnew(CollisionShape);
+		cshape->set_shape(shapes[i]);
+		static_body->add_child(cshape);
+	}
+	return static_body;
+}
+
+void MeshInstance::create_multiple_convex_collisions() {
+
+	StaticBody *static_body = Object::cast_to<StaticBody>(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++) {
+			CollisionShape *cshape = Object::cast_to<CollisionShape>(static_body->get_child(i));
+			cshape->set_owner(get_owner());
+		}
+	}
+}
+
 Node *MeshInstance::create_convex_collision_node() {
 
 	if (mesh.is_null())
@@ -803,6 +839,8 @@ void MeshInstance::_bind_methods() {
 
 	ClassDB::bind_method(D_METHOD("create_trimesh_collision"), &MeshInstance::create_trimesh_collision);
 	ClassDB::set_method_flags("MeshInstance", "create_trimesh_collision", METHOD_FLAGS_DEFAULT);
+	ClassDB::bind_method(D_METHOD("create_multiple_convex_collisions"), &MeshInstance::create_multiple_convex_collisions);
+	ClassDB::set_method_flags("MeshInstance", "create_multiple_convex_collisions", METHOD_FLAGS_DEFAULT);
 	ClassDB::bind_method(D_METHOD("create_convex_collision"), &MeshInstance::create_convex_collision);
 	ClassDB::set_method_flags("MeshInstance", "create_convex_collision", METHOD_FLAGS_DEFAULT);
 	ClassDB::bind_method(D_METHOD("_mesh_changed"), &MeshInstance::_mesh_changed);

+ 3 - 0
scene/3d/mesh_instance.h

@@ -127,6 +127,9 @@ public:
 	Node *create_trimesh_collision_node();
 	void create_trimesh_collision();
 
+	Node *create_multiple_convex_collisions_node();
+	void create_multiple_convex_collisions();
+
 	Node *create_convex_collision_node();
 	void create_convex_collision();