Pārlūkot izejas kodu

Merge pull request #51010 from lawnjelly/portals_fix_csg_update

Rémi Verschelde 4 gadi atpakaļ
vecāks
revīzija
6ce12088c7
3 mainītis faili ar 18 papildinājumiem un 0 dzēšanām
  1. 11 0
      modules/csg/csg_shape.cpp
  2. 2 0
      modules/csg/csg_shape.h
  3. 5 0
      scene/3d/room_manager.cpp

+ 11 - 0
modules/csg/csg_shape.cpp

@@ -576,6 +576,17 @@ void CSGShape::_validate_property(PropertyInfo &property) const {
 	}
 }
 
+// Calling _make_dirty() normally calls a deferred _update_shape.
+// This is problematic if we need to read the geometry immediately.
+// This function provides a means to make sure the shape is updated
+// immediately. It should only be used where necessary to prevent
+// updating CSGs multiple times per frame. Use _make_dirty in preference.
+void CSGShape::force_update_shape() {
+	if (dirty) {
+		_update_shape();
+	}
+}
+
 Array CSGShape::get_meshes() const {
 	if (root_mesh.is_valid()) {
 		Array arr;

+ 2 - 0
modules/csg/csg_shape.h

@@ -119,6 +119,8 @@ protected:
 public:
 	Array get_meshes() const;
 
+	void force_update_shape();
+
 	void set_operation(Operation p_operation);
 	Operation get_operation() const;
 

+ 5 - 0
scene/3d/room_manager.cpp

@@ -1596,6 +1596,11 @@ bool RoomManager::_bound_findpoints_geom_instance(GeometryInstance *p_gi, Vector
 #ifdef MODULE_CSG_ENABLED
 	CSGShape *shape = Object::cast_to<CSGShape>(p_gi);
 	if (shape) {
+		// Shapes will not be up to date on the first frame due to a quirk
+		// of CSG - it defers updates to the next frame. So we need to explicitly
+		// force an update to make sure the CSG is correct on level load.
+		shape->force_update_shape();
+
 		Array arr = shape->get_meshes();
 		if (!arr.size()) {
 			return false;