Explorar el Código

Merge pull request #76675 from rburing/csg_debug_collision

Add debug collision shape to CSG with collision
Rémi Verschelde hace 2 años
padre
commit
140c7f4114
Se han modificado 2 ficheros con 46 adiciones y 0 borrados
  1. 40 0
      modules/csg/csg_shape.cpp
  2. 6 0
      modules/csg/csg_shape.h

+ 40 - 0
modules/csg/csg_shape.cpp

@@ -476,6 +476,43 @@ void CSGShape3D::_update_collision_faces() {
 		}
 
 		root_collision_shape->set_faces(physics_faces);
+
+		if (_is_debug_collision_shape_visible()) {
+			_update_debug_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());
+}
+
+void CSGShape3D::_update_debug_collision_shape() {
+	// NOTE: This is called only for the root shape with collision, when root_collision_shape is valid.
+
+	ERR_FAIL_NULL(RenderingServer::get_singleton());
+
+	if (root_collision_debug_instance.is_null()) {
+		root_collision_debug_instance = RS::get_singleton()->instance_create();
+	}
+
+	Ref<Mesh> debug_mesh = root_collision_shape->get_debug_mesh();
+	RS::get_singleton()->instance_set_scenario(root_collision_debug_instance, get_world_3d()->get_scenario());
+	RS::get_singleton()->instance_set_base(root_collision_debug_instance, debug_mesh->get_rid());
+	RS::get_singleton()->instance_set_transform(root_collision_debug_instance, get_global_transform());
+}
+
+void CSGShape3D::_clear_debug_collision_shape() {
+	if (root_collision_debug_instance.is_valid()) {
+		RS::get_singleton()->free(root_collision_debug_instance);
+		root_collision_debug_instance = RID();
+	}
+}
+
+void CSGShape3D::_on_transform_changed() {
+	if (root_collision_debug_instance.is_valid() && !debug_shape_old_transform.is_equal_approx(get_global_transform())) {
+		debug_shape_old_transform = get_global_transform();
+		RS::get_singleton()->instance_set_transform(root_collision_debug_instance, debug_shape_old_transform);
 	}
 }
 
@@ -558,6 +595,7 @@ void CSGShape3D::_notification(int p_what) {
 				set_collision_layer(collision_layer);
 				set_collision_mask(collision_mask);
 				set_collision_priority(collision_priority);
+				debug_shape_old_transform = get_global_transform();
 				_make_dirty();
 			}
 		} break;
@@ -567,6 +605,7 @@ void CSGShape3D::_notification(int p_what) {
 				PhysicsServer3D::get_singleton()->free(root_collision_instance);
 				root_collision_instance = RID();
 				root_collision_shape.unref();
+				_clear_debug_collision_shape();
 			}
 		} break;
 
@@ -574,6 +613,7 @@ void CSGShape3D::_notification(int p_what) {
 			if (use_collision && is_root_shape() && root_collision_instance.is_valid()) {
 				PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
 			}
+			_on_transform_changed();
 		} break;
 	}
 }

+ 6 - 0
modules/csg/csg_shape.h

@@ -68,6 +68,8 @@ private:
 	real_t collision_priority = 1.0;
 	Ref<ConcavePolygonShape3D> root_collision_shape;
 	RID root_collision_instance;
+	RID root_collision_debug_instance;
+	Transform3D debug_shape_old_transform;
 
 	bool calculate_tangents = true;
 
@@ -107,6 +109,10 @@ private:
 
 	void _update_shape();
 	void _update_collision_faces();
+	bool _is_debug_collision_shape_visible();
+	void _update_debug_collision_shape();
+	void _clear_debug_collision_shape();
+	void _on_transform_changed();
 
 protected:
 	void _notification(int p_what);