From 9ea357af20c7e55413f459c70d913b7b42a56228 Mon Sep 17 00:00:00 2001 From: HolonProduction Date: Fri, 27 Sep 2024 12:55:42 +0200 Subject: [PATCH] =?UTF-8?q?Editor:=20Improve=20cylinder=20gizmos=20?= =?UTF-8?q?=F0=9F=8C=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collision_shape_3d_gizmo_plugin.cpp | 57 ++--------- editor/plugins/gizmos/gizmo_3d_helper.cpp | 95 +++++++++++++++++++ editor/plugins/gizmos/gizmo_3d_helper.h | 5 + modules/csg/editor/csg_gizmos.cpp | 54 ++--------- 4 files changed, 120 insertions(+), 91 deletions(-) diff --git a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp index 01492c1dd040..4a784be064f8 100644 --- a/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp +++ b/editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp @@ -93,7 +93,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g } if (Object::cast_to(*s)) { - return p_id == 0 ? "Radius" : "Height"; + return helper->cylinder_get_handle_name(p_id); } if (Object::cast_to(*s)) { @@ -219,25 +219,15 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i } if (Object::cast_to(*s)) { - Vector3 axis; - axis[p_id == 0 ? 0 : 1] = 1.0; Ref cs2 = s; - Vector3 ra, rb; - Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = axis.dot(ra); - if (Node3DEditor::get_singleton()->is_snap_enabled()) { - d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); - } - if (d < 0.001) { - d = 0.001; - } - - if (p_id == 0) { - cs2->set_radius(d); - } else if (p_id == 1) { - cs2->set_height(d * 2.0); - } + real_t height = cs2->get_height(); + real_t radius = cs2->get_radius(); + Vector3 position; + helper->cylinder_set_handle(sg, p_id, height, radius, position); + cs2->set_height(height); + cs2->set_radius(radius); + cs->set_global_position(position); } } @@ -293,31 +283,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo if (Object::cast_to(*s)) { Ref ss = s; - if (p_cancel) { - if (p_id == 0) { - ss->set_radius(p_restore); - } else { - ss->set_height(p_restore); - } - return; - } - - EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); - if (p_id == 0) { - ur->create_action(TTR("Change Cylinder Shape Radius")); - ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius()); - ur->add_undo_method(ss.ptr(), "set_radius", p_restore); - } else { - ur->create_action( - /// - - //////// - TTR("Change Cylinder Shape Height")); - ur->add_do_method(ss.ptr(), "set_height", ss->get_height()); - ur->add_undo_method(ss.ptr(), "set_height", p_restore); - } - - ur->commit_action(); + helper->cylinder_commit_handle(p_id, TTR("Change Cylinder Shape Radius"), TTR("Change Cylinder Shape Height"), p_cancel, cs, *ss, *ss); } if (Object::cast_to(*s)) { @@ -534,10 +500,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { p_gizmo->add_collision_segments(collision_segments); - Vector handles = { - Vector3(cs2->get_radius(), 0, 0), - Vector3(0, cs2->get_height() * 0.5, 0) - }; + Vector handles = helper->cylinder_get_handles(cs2->get_height(), cs2->get_radius()); p_gizmo->add_handles(handles, handles_material); } diff --git a/editor/plugins/gizmos/gizmo_3d_helper.cpp b/editor/plugins/gizmos/gizmo_3d_helper.cpp index 1226be90cb7e..ff1b67aa4a65 100644 --- a/editor/plugins/gizmos/gizmo_3d_helper.cpp +++ b/editor/plugins/gizmos/gizmo_3d_helper.cpp @@ -139,3 +139,98 @@ void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin()); ur->commit_action(); } + +Vector Gizmo3DHelper::cylinder_get_handles(real_t p_height, real_t p_radius) { + Vector handles; + handles.push_back(Vector3(p_radius, 0, 0)); + handles.push_back(Vector3(0, p_height * 0.5, 0)); + handles.push_back(Vector3(0, p_height * -0.5, 0)); + return handles; +} + +String Gizmo3DHelper::cylinder_get_handle_name(int p_id) const { + if (p_id == 0) { + return "Radius"; + } else { + return "Height"; + } +} + +void Gizmo3DHelper::cylinder_set_handle(const Vector3 p_segment[2], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position) { + int sign = p_id == 2 ? -1 : 1; + int axis = p_id == 0 ? 0 : 1; + + Vector3 axis_vector; + axis_vector[axis] = sign; + Vector3 ra, rb; + Geometry3D::get_closest_points_between_segments(axis_vector * -4096, axis_vector * 4096, p_segment[0], p_segment[1], ra, rb); + float d = axis_vector.dot(ra); + + // Snap to grid. + if (Node3DEditor::get_singleton()->is_snap_enabled()) { + d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); + } + + if (p_id == 0) { + // Adjust radius. + if (d < 0.001) { + d = 0.001; + } + r_radius = d; + r_cylinder_position = initial_transform.get_origin(); + } else if (p_id == 1 || p_id == 2) { + real_t initial_height = initial_value; + + // Adjust height. + if (Input::get_singleton()->is_key_pressed(Key::ALT)) { + r_height = d * 2.0; + } else { + r_height = (initial_height * 0.5) + d; + } + + if (r_height < 0.001) { + r_height = 0.001; + } + + // Adjust position. + if (Input::get_singleton()->is_key_pressed(Key::ALT)) { + r_cylinder_position = initial_transform.get_origin(); + } else { + Vector3 offset; + offset[axis] = (r_height - initial_height) * 0.5 * sign; + r_cylinder_position = initial_transform.xform(offset); + } + } +} + +void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_action_name, const String &p_height_action_name, bool p_cancel, Object *p_position_object, Object *p_height_object, Object *p_radius_object, const StringName &p_position_property, const StringName &p_height_property, const StringName &p_radius_property) { + if (!p_height_object) { + p_height_object = p_position_object; + } + if (!p_radius_object) { + p_radius_object = p_position_object; + } + + if (p_cancel) { + if (p_id == 0) { + p_radius_object->set(p_radius_property, initial_value); + } else { + p_height_object->set(p_height_property, initial_value); + } + p_position_object->set(p_position_property, initial_transform.get_origin()); + return; + } + + EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); + ur->create_action(p_id == 0 ? p_radius_action_name : p_height_action_name); + if (p_id == 0) { + ur->add_do_property(p_radius_object, p_radius_property, p_radius_object->get(p_radius_property)); + ur->add_undo_property(p_radius_object, p_radius_property, initial_value); + } else { + ur->add_do_property(p_height_object, p_height_property, p_height_object->get(p_height_property)); + ur->add_do_property(p_position_object, p_position_property, p_position_object->get(p_position_property)); + ur->add_undo_property(p_height_object, p_height_property, initial_value); + ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin()); + } + ur->commit_action(); +} diff --git a/editor/plugins/gizmos/gizmo_3d_helper.h b/editor/plugins/gizmos/gizmo_3d_helper.h index 387ea020b8c9..6d27e547704a 100644 --- a/editor/plugins/gizmos/gizmo_3d_helper.h +++ b/editor/plugins/gizmos/gizmo_3d_helper.h @@ -50,6 +50,11 @@ class Gizmo3DHelper : public RefCounted { String box_get_handle_name(int p_id) const; void box_set_handle(const Vector3 p_segment[2], int p_id, Vector3 &r_box_size, Vector3 &r_box_position); void box_commit_handle(const String &p_action_name, bool p_cancel, Object *p_position_object, Object *p_size_object = nullptr, const StringName &p_position_property = "global_position", const StringName &p_size_property = "size"); + + Vector cylinder_get_handles(real_t p_height, real_t p_radius); + String cylinder_get_handle_name(int p_id) const; + void cylinder_set_handle(const Vector3 p_segment[2], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position); + void cylinder_commit_handle(int p_id, const String &p_radius_action_name, const String &p_height_action_name, bool p_cancel, Object *p_position_object, Object *p_height_object = nullptr, Object *p_radius_object = nullptr, const StringName &p_position_property = "global_position", const StringName &p_height_property = "height", const StringName &p_radius_property = "radius"); }; #endif // GIZMO_3D_HELPER_H diff --git a/modules/csg/editor/csg_gizmos.cpp b/modules/csg/editor/csg_gizmos.cpp index 95ffeed6c315..e5d33dd179aa 100644 --- a/modules/csg/editor/csg_gizmos.cpp +++ b/modules/csg/editor/csg_gizmos.cpp @@ -278,24 +278,13 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i if (Object::cast_to(cs)) { CSGCylinder3D *s = Object::cast_to(cs); - Vector3 axis; - axis[p_id == 0 ? 0 : 1] = 1.0; - Vector3 ra, rb; - Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); - float d = axis.dot(ra); - if (Node3DEditor::get_singleton()->is_snap_enabled()) { - d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap()); - } - - if (d < 0.001) { - d = 0.001; - } - - if (p_id == 0) { - s->set_radius(d); - } else if (p_id == 1) { - s->set_height(d * 2.0); - } + real_t height = s->get_height(); + real_t radius = s->get_radius(); + Vector3 position; + helper->cylinder_set_handle(sg, p_id, height, radius, position); + s->set_height(height); + s->set_radius(radius); + s->set_global_position(position); } if (Object::cast_to(cs)) { @@ -340,32 +329,11 @@ void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int } if (Object::cast_to(cs)) { - helper->box_commit_handle(TTR("Change Box Shape Size"), p_cancel, cs); + helper->box_commit_handle(TTR("Change CSG Box Size"), p_cancel, cs); } if (Object::cast_to(cs)) { - CSGCylinder3D *s = Object::cast_to(cs); - if (p_cancel) { - if (p_id == 0) { - s->set_radius(p_restore); - } else { - s->set_height(p_restore); - } - return; - } - - EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); - if (p_id == 0) { - ur->create_action(TTR("Change Cylinder Radius")); - ur->add_do_method(s, "set_radius", s->get_radius()); - ur->add_undo_method(s, "set_radius", p_restore); - } else { - ur->create_action(TTR("Change Cylinder Height")); - ur->add_do_method(s, "set_height", s->get_height()); - ur->add_undo_method(s, "set_height", p_restore); - } - - ur->commit_action(); + helper->cylinder_commit_handle(p_id, TTR("Change CSG Cylinder Radius"), TTR("Change CSG Cylinder Height"), p_cancel, cs); } if (Object::cast_to(cs)) { @@ -506,9 +474,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { if (Object::cast_to(cs)) { CSGCylinder3D *s = Object::cast_to(cs); - Vector handles; - handles.push_back(Vector3(s->get_radius(), 0, 0)); - handles.push_back(Vector3(0, s->get_height() * 0.5, 0)); + Vector handles = helper->cylinder_get_handles(s->get_height(), s->get_radius()); p_gizmo->add_handles(handles, handles_material); }