diff options
Diffstat (limited to 'editor/plugins')
| -rw-r--r-- | editor/plugins/physical_bone_plugin.cpp | 123 | ||||
| -rw-r--r-- | editor/plugins/physical_bone_plugin.h | 78 | ||||
| -rw-r--r-- | editor/plugins/skeleton_editor_plugin.cpp | 189 | ||||
| -rw-r--r-- | editor/plugins/skeleton_editor_plugin.h | 95 | ||||
| -rw-r--r-- | editor/plugins/spatial_editor_plugin.cpp | 31 |
5 files changed, 505 insertions, 11 deletions
diff --git a/editor/plugins/physical_bone_plugin.cpp b/editor/plugins/physical_bone_plugin.cpp new file mode 100644 index 000000000..42f1adcad --- /dev/null +++ b/editor/plugins/physical_bone_plugin.cpp @@ -0,0 +1,123 @@ +/*************************************************************************/ +/* physical_bone_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "physical_bone_plugin.h" +#include "editor/plugins/spatial_editor_plugin.h" +#include "scene/3d/physics_body.h" + +void PhysicalBoneEditor::_bind_methods() { + ClassDB::bind_method(D_METHOD("_on_toggle_button_transform_joint", "is_pressed"), &PhysicalBoneEditor::_on_toggle_button_transform_joint); +} + +void PhysicalBoneEditor::_on_toggle_button_transform_joint(bool p_is_pressed) { + + _set_move_joint(); +} + +void PhysicalBoneEditor::_set_move_joint() { + if (selected) { + selected->_set_gizmo_move_joint(button_transform_joint->is_pressed()); + } +} + +PhysicalBoneEditor::PhysicalBoneEditor(EditorNode *p_editor) : + editor(p_editor), + selected(NULL) { + + spatial_editor_hb = memnew(HBoxContainer); + spatial_editor_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + spatial_editor_hb->set_alignment(BoxContainer::ALIGN_BEGIN); + SpatialEditor::get_singleton()->add_control_to_menu_panel(spatial_editor_hb); + + spatial_editor_hb->add_child(memnew(VSeparator)); + + button_transform_joint = memnew(ToolButton); + spatial_editor_hb->add_child(button_transform_joint); + + button_transform_joint->set_text(TTR("Move joint")); + button_transform_joint->set_icon(SpatialEditor::get_singleton()->get_icon("PhysicalBone", "EditorIcons")); + button_transform_joint->set_toggle_mode(true); + button_transform_joint->connect("toggled", this, "_on_toggle_button_transform_joint"); + + hide(); +} + +PhysicalBoneEditor::~PhysicalBoneEditor() { + // TODO the spatial_editor_hb should be removed from SpatialEditor, but in this moment it's not possible + for (int i = spatial_editor_hb->get_child_count() - 1; 0 <= i; --i) { + Node *n = spatial_editor_hb->get_child(i); + spatial_editor_hb->remove_child(n); + memdelete(n); + } + memdelete(spatial_editor_hb); +} + +void PhysicalBoneEditor::set_selected(PhysicalBone *p_pb) { + + button_transform_joint->set_pressed(false); + + _set_move_joint(); + selected = p_pb; + _set_move_joint(); +} + +void PhysicalBoneEditor::hide() { + spatial_editor_hb->hide(); +} + +void PhysicalBoneEditor::show() { + spatial_editor_hb->show(); +} + +PhysicalBonePlugin::PhysicalBonePlugin(EditorNode *p_editor) : + editor(p_editor), + selected(NULL) { + + physical_bone_editor = memnew(PhysicalBoneEditor(editor)); +} + +void PhysicalBonePlugin::make_visible(bool p_visible) { + if (p_visible) { + + physical_bone_editor->show(); + } else { + + physical_bone_editor->hide(); + physical_bone_editor->set_selected(NULL); + selected = NULL; + } +} + +void PhysicalBonePlugin::edit(Object *p_node) { + selected = static_cast<PhysicalBone *>(p_node); // Trust it + ERR_FAIL_COND(!selected); + + physical_bone_editor->set_selected(selected); +} diff --git a/editor/plugins/physical_bone_plugin.h b/editor/plugins/physical_bone_plugin.h new file mode 100644 index 000000000..9e7a50307 --- /dev/null +++ b/editor/plugins/physical_bone_plugin.h @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* physical_bone_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef PHYSICAL_BONE_PLUGIN_H +#define PHYSICAL_BONE_PLUGIN_H + +#include "editor/editor_node.h" + +class PhysicalBoneEditor : public Object { + GDCLASS(PhysicalBoneEditor, Object); + + EditorNode *editor; + HBoxContainer *spatial_editor_hb; + ToolButton *button_transform_joint; + + PhysicalBone *selected; + +protected: + static void _bind_methods(); + +private: + void _on_toggle_button_transform_joint(bool p_is_pressed); + void _set_move_joint(); + +public: + PhysicalBoneEditor(EditorNode *p_editor); + ~PhysicalBoneEditor(); + + void set_selected(PhysicalBone *p_pb); + + void hide(); + void show(); +}; + +class PhysicalBonePlugin : public EditorPlugin { + GDCLASS(PhysicalBonePlugin, EditorPlugin); + + EditorNode *editor; + PhysicalBone *selected; + PhysicalBoneEditor *physical_bone_editor; + +public: + virtual String get_name() const { return "PhysicalBone"; } + virtual bool handles(Object *p_object) const { return p_object->is_class("PhysicalBone"); } + virtual void make_visible(bool p_visible); + virtual void edit(Object *p_node); + + PhysicalBonePlugin(EditorNode *p_editor); +}; + +#endif diff --git a/editor/plugins/skeleton_editor_plugin.cpp b/editor/plugins/skeleton_editor_plugin.cpp new file mode 100644 index 000000000..c41e3b546 --- /dev/null +++ b/editor/plugins/skeleton_editor_plugin.cpp @@ -0,0 +1,189 @@ +/*************************************************************************/ +/* skeleton_editor_plugin.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "skeleton_editor_plugin.h" +#include "scene/3d/collision_shape.h" +#include "scene/3d/physics_body.h" +#include "scene/3d/physics_joint.h"; +#include "scene/resources/capsule_shape.h" +#include "scene/resources/sphere_shape.h" +#include "spatial_editor_plugin.h" + +void SkeletonEditor::_on_click_option(int p_option) { + if (!skeleton) { + return; + } + + switch (p_option) { + case MENU_OPTION_CREATE_PHYSICAL_SKELETON: { + create_physical_skeleton(); + } break; + } +} + +void SkeletonEditor::create_physical_skeleton() { + UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); + Node *owner = skeleton == get_tree()->get_edited_scene_root() ? skeleton : skeleton->get_owner(); + + const int bc = skeleton->get_bone_count(); + + if (!bc) { + return; + } + + Vector<BoneInfo> bones_infos; + bones_infos.resize(bc); + + for (int bone_id = 0; bc > bone_id; ++bone_id) { + + const int parent = skeleton->get_bone_parent(bone_id); + const int parent_parent = skeleton->get_bone_parent(parent); + + if (parent < 0) { + + bones_infos[bone_id].relative_rest = skeleton->get_bone_rest(bone_id); + + } else { + + bones_infos[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id); + + /// create physical bone on parent + if (!bones_infos[parent].physical_bone) { + + bones_infos[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos); + + ur->create_action(TTR("Create physical bones")); + ur->add_do_method(skeleton, "add_child", bones_infos[parent].physical_bone); + ur->add_do_reference(bones_infos[parent].physical_bone); + ur->add_undo_method(skeleton, "remove_child", bones_infos[parent].physical_bone); + ur->commit_action(); + + bones_infos[parent].physical_bone->set_bone_name(skeleton->get_bone_name(parent)); + bones_infos[parent].physical_bone->set_owner(owner); + bones_infos[parent].physical_bone->get_child(0)->set_owner(owner); // set shape owner + + /// Create joint between parent of parent + if (-1 != parent_parent) { + + bones_infos[parent].physical_bone->set_joint_type(PhysicalBone::JOINT_TYPE_PIN); + } + } + } + } +} + +PhysicalBone *SkeletonEditor::create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos) { + + real_t half_height(skeleton->get_bone_rest(bone_child_id).origin.length() * 0.5); + real_t radius(half_height * 0.2); + + CapsuleShape *bone_shape_capsule = memnew(CapsuleShape); + bone_shape_capsule->set_height((half_height - radius) * 2); + bone_shape_capsule->set_radius(radius); + + CollisionShape *bone_shape = memnew(CollisionShape); + bone_shape->set_shape(bone_shape_capsule); + + Transform body_transform; + body_transform.origin = Vector3(0, 0, -half_height); + + Transform joint_transform; + joint_transform.origin = Vector3(0, 0, half_height); + + PhysicalBone *physical_bone = memnew(PhysicalBone); + physical_bone->add_child(bone_shape); + physical_bone->set_name("Physical Bone " + skeleton->get_bone_name(bone_id)); + physical_bone->set_body_offset(body_transform); + physical_bone->set_joint_offset(joint_transform); + return physical_bone; +} + +void SkeletonEditor::edit(Skeleton *p_node) { + skeleton = p_node; +} + +void SkeletonEditor::_node_removed(Node *p_node) { + + if (p_node == skeleton) { + skeleton = NULL; + options->hide(); + } +} + +void SkeletonEditor::_bind_methods() { + ClassDB::bind_method("_on_click_option", &SkeletonEditor::_on_click_option); +} + +SkeletonEditor::SkeletonEditor() { + options = memnew(MenuButton); + SpatialEditor::get_singleton()->add_control_to_menu_panel(options); + + options->set_text(TTR("Skeleton")); + options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Skeleton", "EditorIcons")); + + options->get_popup()->add_item(TTR("Create physical skeleton"), MENU_OPTION_CREATE_PHYSICAL_SKELETON); + + options->get_popup()->connect("id_pressed", this, "_on_click_option"); + options->hide(); +} + +SkeletonEditor::~SkeletonEditor() { + SpatialEditor::get_singleton()->remove_child(options); + memdelete(options); +} + +void SkeletonEditorPlugin::edit(Object *p_object) { + skeleton_editor->edit(Object::cast_to<Skeleton>(p_object)); +} + +bool SkeletonEditorPlugin::handles(Object *p_object) const { + return p_object->is_class("Skeleton"); +} + +void SkeletonEditorPlugin::make_visible(bool p_visible) { + if (p_visible) { + skeleton_editor->options->show(); + } else { + + skeleton_editor->options->hide(); + skeleton_editor->edit(NULL); + } +} + +SkeletonEditorPlugin::SkeletonEditorPlugin(EditorNode *p_node) { + editor = p_node; + skeleton_editor = memnew(SkeletonEditor); + editor->get_viewport()->add_child(skeleton_editor); +} + +SkeletonEditorPlugin::~SkeletonEditorPlugin() { + editor->get_viewport()->remove_child(skeleton_editor); + memdelete(skeleton_editor); +} diff --git a/editor/plugins/skeleton_editor_plugin.h b/editor/plugins/skeleton_editor_plugin.h new file mode 100644 index 000000000..b9bdf9190 --- /dev/null +++ b/editor/plugins/skeleton_editor_plugin.h @@ -0,0 +1,95 @@ +/*************************************************************************/ +/* skeleton_editor_plugin.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SKELETON_EDITOR_PLUGIN_H +#define SKELETON_EDITOR_PLUGIN_H + +#include "editor/editor_node.h" +#include "editor/editor_plugin.h" +#include "scene/3d/skeleton.h" + +class PhysicalBone; +class Joint; + +class SkeletonEditor : public Node { + GDCLASS(SkeletonEditor, Node); + + enum Menu { + MENU_OPTION_CREATE_PHYSICAL_SKELETON + }; + + struct BoneInfo { + PhysicalBone *physical_bone; + Transform relative_rest; // Relative to skeleton node + BoneInfo() : + physical_bone(NULL) {} + }; + + Skeleton *skeleton; + + MenuButton *options; + + void _on_click_option(int p_option); + + friend class SkeletonEditorPlugin; + +protected: + void _node_removed(Node *p_node); + static void _bind_methods(); + + void create_physical_skeleton(); + PhysicalBone *create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos); + +public: + void edit(Skeleton *p_mesh); + + SkeletonEditor(); + ~SkeletonEditor(); +}; + +class SkeletonEditorPlugin : public EditorPlugin { + + GDCLASS(SkeletonEditorPlugin, EditorPlugin); + + EditorNode *editor; + SkeletonEditor *skeleton_editor; + +public: + virtual String get_name() const { return "Skeleton"; } + virtual bool has_main_screen() const { return false; } + virtual void edit(Object *p_object); + virtual bool handles(Object *p_object) const; + virtual void make_visible(bool p_visible); + + SkeletonEditorPlugin(EditorNode *p_node); + ~SkeletonEditorPlugin(); +}; + +#endif // SKELETON_EDITOR_PLUGIN_H diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 1e6c73638..5b713ef3c 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -72,6 +72,14 @@ #define MIN_FOV 0.01 #define MAX_FOV 179 +#ifdef TOOLS_ENABLED +#define get_global_gizmo_transform get_global_gizmo_transform +#define get_local_gizmo_transform get_local_gizmo_transform +#else +#define get_global_gizmo_transform get_global_transform +#define get_local_gizmo_transform get_transform +#endif + void SpatialEditorViewport::_update_camera(float p_interp_delta) { bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL; @@ -584,8 +592,8 @@ void SpatialEditorViewport::_compute_edit(const Point2 &p_point) { if (!se) continue; - se->original = se->sp->get_global_transform(); - se->original_local = se->sp->get_transform(); + se->original = se->sp->get_global_gizmo_transform(); + se->original_local = se->sp->get_local_gizmo_transform(); } } @@ -1184,7 +1192,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) { if (!se) continue; - undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_transform()); + 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->commit_action(); @@ -2150,7 +2158,7 @@ void SpatialEditorViewport::_notification(int p_what) { se->aabb = vi ? vi->get_aabb() : AABB(Vector3(-0.2, -0.2, -0.2), Vector3(0.4, 0.4, 0.4)); } - Transform t = sp->get_global_transform(); + Transform t = sp->get_global_gizmo_transform(); t.translate(se->aabb.position); // apply AABB scaling before item's global transform @@ -2503,7 +2511,7 @@ void SpatialEditorViewport::_menu_option(int p_option) { xform.scale_basis(sp->get_scale()); undo_redo->add_do_method(sp, "set_global_transform", xform); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform()); + undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); } undo_redo->commit_action(); } break; @@ -2961,7 +2969,7 @@ void SpatialEditorViewport::focus_selection() { if (!se) continue; - center += sp->get_global_transform().origin; + center += sp->get_global_gizmo_transform().origin; count++; } @@ -3043,7 +3051,7 @@ AABB SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, c MeshInstance *mesh_instance = Object::cast_to<MeshInstance>(child); if (mesh_instance) { AABB mesh_instance_bounds = mesh_instance->get_aabb(); - mesh_instance_bounds.position += mesh_instance->get_global_transform().origin - p_parent->get_global_transform().origin; + mesh_instance_bounds.position += mesh_instance->get_global_gizmo_transform().origin - p_parent->get_global_gizmo_transform().origin; bounds.merge_with(mesh_instance_bounds); } bounds = _calculate_spatial_bounds(child, bounds); @@ -3154,7 +3162,7 @@ bool SpatialEditorViewport::_create_instance(Node *parent, String &path, const P Transform global_transform; Spatial *parent_spatial = Object::cast_to<Spatial>(parent); if (parent_spatial) - global_transform = parent_spatial->get_global_transform(); + global_transform = parent_spatial->get_global_gizmo_transform(); global_transform.origin = spatial_editor->snap_point(_get_instance_position(p_point)); @@ -3787,7 +3795,8 @@ void SpatialEditor::update_transform_gizmo() { if (!se) continue; - Transform xf = se->sp->get_global_transform(); + Transform xf = se->sp->get_global_gizmo_transform(); + if (first) { center.position = xf.origin; first = false; @@ -4054,7 +4063,7 @@ void SpatialEditor::_xform_dialog_action() { bool post = xform_type->get_selected() > 0; - Transform tr = sp->get_global_transform(); + Transform tr = sp->get_global_gizmo_transform(); if (post) tr = tr * t; else { @@ -4064,7 +4073,7 @@ void SpatialEditor::_xform_dialog_action() { } undo_redo->add_do_method(sp, "set_global_transform", tr); - undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_transform()); + undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform()); } undo_redo->commit_action(); } |
