From 97f9dbda8100751729cbda96e4b7ec2f791a0a2c Mon Sep 17 00:00:00 2001 From: Zi Ye Date: Sat, 30 Dec 2023 20:00:41 -0600 Subject: [PATCH] Changed various editor transform operations to be committed in local instead of global space. Fixed a couple of bugs when syncing transforms to debug instance. --- editor/plugins/canvas_item_editor_plugin.cpp | 6 ++- editor/plugins/node_3d_editor_plugin.cpp | 33 ++++++------ scene/debugger/scene_debugger.cpp | 54 ++++++++++++++++++++ 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 7d4502b69de..3d8a48cab42 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -5775,7 +5775,11 @@ void CanvasItemEditorViewport::_create_nodes(Node *parent, Node *child, String & // there's nothing to be used as source position so snapping will work as absolute if enabled target_position = canvas_item_editor->snap_point(target_position); - undo_redo->add_do_method(child, "set_global_position", target_position); + + CanvasItem *parent_ci = Object::cast_to(parent); + Point2 local_target_pos = parent_ci ? parent_ci->get_global_transform().xform_inv(target_position) : target_position; + + undo_redo->add_do_method(child, "set_position", local_target_pos); } bool CanvasItemEditorViewport::_create_instance(Node *parent, String &path, const Point2 &p_point) { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 146fd54b6eb..1e86ee3b187 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -3295,8 +3295,10 @@ void Node3DEditorViewport::_menu_option(int p_option) { xform.basis.rotate_local(Vector3(1, 0, 0), Math_TAU * 0.25); } - undo_redo->add_do_method(sp, "set_global_transform", xform); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); + Node3D *parent = sp->get_parent_node_3d(); + Transform3D local_xform = parent ? parent->get_global_transform().inverse_xform(xform) : xform; + undo_redo->add_do_method(sp, "set_transform", local_xform); + undo_redo->add_undo_method(sp, "set_transform", sp->get_local_gizmo_transform()); } undo_redo->commit_action(); @@ -4362,16 +4364,7 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po Node3D *node3d = Object::cast_to(instantiated_scene); if (node3d) { - Transform3D gl_transform; - Node3D *parent_node3d = Object::cast_to(parent); - if (parent_node3d) { - gl_transform = parent_node3d->get_global_gizmo_transform(); - } - - gl_transform.origin = preview_node_pos; - gl_transform.basis *= node3d->get_transform().basis; - - undo_redo->add_do_method(instantiated_scene, "set_global_transform", gl_transform); + undo_redo->add_do_method(instantiated_scene, "set_transform", node3d->get_transform()); } return true; @@ -4607,8 +4600,8 @@ void Node3DEditorViewport::commit_transform() { continue; } - undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); - undo_redo->add_undo_method(sp, "set_global_transform", se->original); + undo_redo->add_do_method(sp, "set_transform", sp->get_local_gizmo_transform()); + undo_redo->add_undo_method(sp, "set_transform", se->original_local); } undo_redo->commit_action(); @@ -6168,8 +6161,10 @@ void Node3DEditor::_xform_dialog_action() { tr.origin += t.origin; } - undo_redo->add_do_method(sp, "set_global_transform", tr); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); + Node3D *parent = sp->get_parent_node_3d(); + Transform3D local_tr = parent ? parent->get_global_transform().inverse_xform(tr) : tr; + undo_redo->add_do_method(sp, "set_transform", local_tr); + undo_redo->add_undo_method(sp, "set_transform", sp->get_transform()); } undo_redo->commit_action(); } @@ -7518,8 +7513,10 @@ void Node3DEditor::_snap_selected_nodes_to_floor() { new_transform.origin.y = result.position.y; new_transform.origin = new_transform.origin - position_offset; - undo_redo->add_do_method(sp, "set_global_transform", new_transform); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform()); + Node3D *parent = sp->get_parent_node_3d(); + Transform3D new_local_xform = parent ? parent->get_global_transform().inverse_xform(new_transform) : new_transform; + undo_redo->add_do_method(sp, "set_transform", new_local_xform); + undo_redo->add_undo_method(sp, "set_transform", sp->get_transform()); } } diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 5603b2dbe45..3b5644af4a2 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -630,7 +630,34 @@ void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Varian } Node *n2 = n->get_node(np); + // Do not change transform of edited scene root, unless it's the scene being played. + // See GH-86659 for additional context. + bool keep_transform = (n2 == n) && (n2->get_parent() != scene_tree->root); + Variant orig_tf; + + if (keep_transform) { + if (n2->is_class("Node3D")) { + orig_tf = n2->call("get_transform"); + } else if (n2->is_class("CanvasItem")) { + orig_tf = n2->call("_edit_get_state"); + } + } + n2->set(p_prop, p_value); + + if (keep_transform) { + if (n2->is_class("Node3D")) { + Variant new_tf = n2->call("get_transform"); + if (new_tf != orig_tf) { + n2->call("set_transform", orig_tf); + } + } else if (n2->is_class("CanvasItem")) { + Variant new_tf = n2->call("_edit_get_state"); + if (new_tf != orig_tf) { + n2->call("_edit_set_state", orig_tf); + } + } + } } } @@ -674,8 +701,35 @@ void LiveEditor::_node_call_func(int p_id, const StringName &p_method, const Var } Node *n2 = n->get_node(np); + // Do not change transform of edited scene root, unless it's the scene being played. + // See GH-86659 for additional context. + bool keep_transform = (n2 == n) && (n2->get_parent() != scene_tree->root); + Variant orig_tf; + + if (keep_transform) { + if (n2->is_class("Node3D")) { + orig_tf = n2->call("get_transform"); + } else if (n2->is_class("CanvasItem")) { + orig_tf = n2->call("_edit_get_state"); + } + } + Callable::CallError ce; n2->callp(p_method, p_args, p_argcount, ce); + + if (keep_transform) { + if (n2->is_class("Node3D")) { + Variant new_tf = n2->call("get_transform"); + if (new_tf != orig_tf) { + n2->call("set_transform", orig_tf); + } + } else if (n2->is_class("CanvasItem")) { + Variant new_tf = n2->call("_edit_get_state"); + if (new_tf != orig_tf) { + n2->call("_edit_set_state", orig_tf); + } + } + } } }