Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Improve cylinder gizmos #97535

Merged
merged 1 commit into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 10 additions & 47 deletions editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
}

if (Object::cast_to<CylinderShape3D>(*s)) {
return p_id == 0 ? "Radius" : "Height";
return helper->cylinder_get_handle_name(p_id);
}

if (Object::cast_to<SeparationRayShape3D>(*s)) {
Expand Down Expand Up @@ -219,25 +219,15 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
}

if (Object::cast_to<CylinderShape3D>(*s)) {
Vector3 axis;
axis[p_id == 0 ? 0 : 1] = 1.0;
Ref<CylinderShape3D> 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);
}
}

Expand Down Expand Up @@ -293,31 +283,7 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo

if (Object::cast_to<CylinderShape3D>(*s)) {
Ref<CylinderShape3D> 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<SeparationRayShape3D>(*s)) {
Expand Down Expand Up @@ -534,10 +500,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {

p_gizmo->add_collision_segments(collision_segments);

Vector<Vector3> handles = {
Vector3(cs2->get_radius(), 0, 0),
Vector3(0, cs2->get_height() * 0.5, 0)
};
Vector<Vector3> handles = helper->cylinder_get_handles(cs2->get_height(), cs2->get_radius());
p_gizmo->add_handles(handles, handles_material);
}

Expand Down
95 changes: 95 additions & 0 deletions editor/plugins/gizmos/gizmo_3d_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vector3> Gizmo3DHelper::cylinder_get_handles(real_t p_height, real_t p_radius) {
Vector<Vector3> 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();
}
5 changes: 5 additions & 0 deletions editor/plugins/gizmos/gizmo_3d_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vector3> 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
54 changes: 10 additions & 44 deletions modules/csg/editor/csg_gizmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,24 +278,13 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i
if (Object::cast_to<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(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<CSGTorus3D>(cs)) {
Expand Down Expand Up @@ -340,32 +329,11 @@ void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int
}

if (Object::cast_to<CSGBox3D>(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<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(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<CSGTorus3D>(cs)) {
Expand Down Expand Up @@ -506,9 +474,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (Object::cast_to<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);

Vector<Vector3> handles;
handles.push_back(Vector3(s->get_radius(), 0, 0));
handles.push_back(Vector3(0, s->get_height() * 0.5, 0));
Vector<Vector3> handles = helper->cylinder_get_handles(s->get_height(), s->get_radius());
p_gizmo->add_handles(handles, handles_material);
}

Expand Down
Loading