浏览代码

Snap To Floor improperly offsets node

fix for issue #44282

AABB for collision geometry was being calculated based on parent nodes transform without consideration for collision geometries translation.
Also hopefully clarified logic for selecting starting point for ray cast
jeffuntildeath 4 年之前
父节点
当前提交
4f171afecc
共有 1 个文件被更改,包括 12 次插入10 次删除
  1. 12 10
      editor/plugins/node_3d_editor_plugin.cpp

+ 12 - 10
editor/plugins/node_3d_editor_plugin.cpp

@@ -5824,17 +5824,20 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 			// Priorities for snapping to floor are CollisionShapes, VisualInstances and then origin
 			Set<VisualInstance3D *> vi = _get_child_nodes<VisualInstance3D>(sp);
 			Set<CollisionShape3D *> cs = _get_child_nodes<CollisionShape3D>(sp);
+			bool found_valid_shape = false;
 
 			if (cs.size()) {
 				AABB aabb;
-				bool found_valid_shape = false;
-				if (cs.front()->get()->get_shape().is_valid()) {
-					aabb = sp->get_global_transform().xform(cs.front()->get()->get_shape()->get_debug_mesh()->get_aabb());
+				Set<CollisionShape3D *>::Element *I = cs.front();
+				if (I->get()->get_shape().is_valid()) {
+					CollisionShape3D *collision_shape = cs.front()->get();
+					aabb = collision_shape->get_global_transform().xform(collision_shape->get_shape()->get_debug_mesh()->get_aabb());
 					found_valid_shape = true;
 				}
-				for (Set<CollisionShape3D *>::Element *I = cs.front(); I; I = I->next()) {
-					if (I->get()->get_shape().is_valid()) {
-						aabb.merge_with(sp->get_global_transform().xform(I->get()->get_shape()->get_debug_mesh()->get_aabb()));
+				for (I = I->next(); I; I = I->next()) {
+					CollisionShape3D *col_shape = I->get();
+					if (col_shape->get_shape().is_valid()) {
+						aabb.merge_with(col_shape->get_global_transform().xform(col_shape->get_shape()->get_debug_mesh()->get_aabb()));
 						found_valid_shape = true;
 					}
 				}
@@ -5842,10 +5845,9 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 					Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
 					from = aabb.position + size;
 					position_offset.y = from.y - sp->get_global_transform().origin.y;
-				} else {
-					from = sp->get_global_transform().origin;
 				}
-			} else if (vi.size()) {
+			}
+			if (!found_valid_shape && vi.size()) {
 				AABB aabb = vi.front()->get()->get_transformed_aabb();
 				for (Set<VisualInstance3D *>::Element *I = vi.front(); I; I = I->next()) {
 					aabb.merge_with(I->get()->get_transformed_aabb());
@@ -5853,7 +5855,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
 				Vector3 size = aabb.size * Vector3(0.5, 0.0, 0.5);
 				from = aabb.position + size;
 				position_offset.y = from.y - sp->get_global_transform().origin.y;
-			} else {
+			} else if (!found_valid_shape) {
 				from = sp->get_global_transform().origin;
 			}