Skip to content

Commit 61accf0

Browse files
committed
Merge pull request godotengine#97535 from HolonProduction/gizmo-cylinder
Editor: Improve cylinder gizmos
2 parents edad871 + 9ea357a commit 61accf0

File tree

4 files changed

+120
-91
lines changed

4 files changed

+120
-91
lines changed

editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp

+10-47
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
9393
}
9494

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

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

221221
if (Object::cast_to<CylinderShape3D>(*s)) {
222-
Vector3 axis;
223-
axis[p_id == 0 ? 0 : 1] = 1.0;
224222
Ref<CylinderShape3D> cs2 = s;
225-
Vector3 ra, rb;
226-
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
227-
float d = axis.dot(ra);
228-
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
229-
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
230-
}
231223

232-
if (d < 0.001) {
233-
d = 0.001;
234-
}
235-
236-
if (p_id == 0) {
237-
cs2->set_radius(d);
238-
} else if (p_id == 1) {
239-
cs2->set_height(d * 2.0);
240-
}
224+
real_t height = cs2->get_height();
225+
real_t radius = cs2->get_radius();
226+
Vector3 position;
227+
helper->cylinder_set_handle(sg, p_id, height, radius, position);
228+
cs2->set_height(height);
229+
cs2->set_radius(radius);
230+
cs->set_global_position(position);
241231
}
242232
}
243233

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

294284
if (Object::cast_to<CylinderShape3D>(*s)) {
295285
Ref<CylinderShape3D> ss = s;
296-
if (p_cancel) {
297-
if (p_id == 0) {
298-
ss->set_radius(p_restore);
299-
} else {
300-
ss->set_height(p_restore);
301-
}
302-
return;
303-
}
304-
305-
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
306-
if (p_id == 0) {
307-
ur->create_action(TTR("Change Cylinder Shape Radius"));
308-
ur->add_do_method(ss.ptr(), "set_radius", ss->get_radius());
309-
ur->add_undo_method(ss.ptr(), "set_radius", p_restore);
310-
} else {
311-
ur->create_action(
312-
///
313-
314-
////////
315-
TTR("Change Cylinder Shape Height"));
316-
ur->add_do_method(ss.ptr(), "set_height", ss->get_height());
317-
ur->add_undo_method(ss.ptr(), "set_height", p_restore);
318-
}
319-
320-
ur->commit_action();
286+
helper->cylinder_commit_handle(p_id, TTR("Change Cylinder Shape Radius"), TTR("Change Cylinder Shape Height"), p_cancel, cs, *ss, *ss);
321287
}
322288

323289
if (Object::cast_to<SeparationRayShape3D>(*s)) {
@@ -534,10 +500,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
534500

535501
p_gizmo->add_collision_segments(collision_segments);
536502

537-
Vector<Vector3> handles = {
538-
Vector3(cs2->get_radius(), 0, 0),
539-
Vector3(0, cs2->get_height() * 0.5, 0)
540-
};
503+
Vector<Vector3> handles = helper->cylinder_get_handles(cs2->get_height(), cs2->get_radius());
541504
p_gizmo->add_handles(handles, handles_material);
542505
}
543506

editor/plugins/gizmos/gizmo_3d_helper.cpp

+95
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,98 @@ void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel
139139
ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin());
140140
ur->commit_action();
141141
}
142+
143+
Vector<Vector3> Gizmo3DHelper::cylinder_get_handles(real_t p_height, real_t p_radius) {
144+
Vector<Vector3> handles;
145+
handles.push_back(Vector3(p_radius, 0, 0));
146+
handles.push_back(Vector3(0, p_height * 0.5, 0));
147+
handles.push_back(Vector3(0, p_height * -0.5, 0));
148+
return handles;
149+
}
150+
151+
String Gizmo3DHelper::cylinder_get_handle_name(int p_id) const {
152+
if (p_id == 0) {
153+
return "Radius";
154+
} else {
155+
return "Height";
156+
}
157+
}
158+
159+
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) {
160+
int sign = p_id == 2 ? -1 : 1;
161+
int axis = p_id == 0 ? 0 : 1;
162+
163+
Vector3 axis_vector;
164+
axis_vector[axis] = sign;
165+
Vector3 ra, rb;
166+
Geometry3D::get_closest_points_between_segments(axis_vector * -4096, axis_vector * 4096, p_segment[0], p_segment[1], ra, rb);
167+
float d = axis_vector.dot(ra);
168+
169+
// Snap to grid.
170+
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
171+
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
172+
}
173+
174+
if (p_id == 0) {
175+
// Adjust radius.
176+
if (d < 0.001) {
177+
d = 0.001;
178+
}
179+
r_radius = d;
180+
r_cylinder_position = initial_transform.get_origin();
181+
} else if (p_id == 1 || p_id == 2) {
182+
real_t initial_height = initial_value;
183+
184+
// Adjust height.
185+
if (Input::get_singleton()->is_key_pressed(Key::ALT)) {
186+
r_height = d * 2.0;
187+
} else {
188+
r_height = (initial_height * 0.5) + d;
189+
}
190+
191+
if (r_height < 0.001) {
192+
r_height = 0.001;
193+
}
194+
195+
// Adjust position.
196+
if (Input::get_singleton()->is_key_pressed(Key::ALT)) {
197+
r_cylinder_position = initial_transform.get_origin();
198+
} else {
199+
Vector3 offset;
200+
offset[axis] = (r_height - initial_height) * 0.5 * sign;
201+
r_cylinder_position = initial_transform.xform(offset);
202+
}
203+
}
204+
}
205+
206+
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) {
207+
if (!p_height_object) {
208+
p_height_object = p_position_object;
209+
}
210+
if (!p_radius_object) {
211+
p_radius_object = p_position_object;
212+
}
213+
214+
if (p_cancel) {
215+
if (p_id == 0) {
216+
p_radius_object->set(p_radius_property, initial_value);
217+
} else {
218+
p_height_object->set(p_height_property, initial_value);
219+
}
220+
p_position_object->set(p_position_property, initial_transform.get_origin());
221+
return;
222+
}
223+
224+
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
225+
ur->create_action(p_id == 0 ? p_radius_action_name : p_height_action_name);
226+
if (p_id == 0) {
227+
ur->add_do_property(p_radius_object, p_radius_property, p_radius_object->get(p_radius_property));
228+
ur->add_undo_property(p_radius_object, p_radius_property, initial_value);
229+
} else {
230+
ur->add_do_property(p_height_object, p_height_property, p_height_object->get(p_height_property));
231+
ur->add_do_property(p_position_object, p_position_property, p_position_object->get(p_position_property));
232+
ur->add_undo_property(p_height_object, p_height_property, initial_value);
233+
ur->add_undo_property(p_position_object, p_position_property, initial_transform.get_origin());
234+
}
235+
ur->commit_action();
236+
}

editor/plugins/gizmos/gizmo_3d_helper.h

+5
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ class Gizmo3DHelper : public RefCounted {
5050
String box_get_handle_name(int p_id) const;
5151
void box_set_handle(const Vector3 p_segment[2], int p_id, Vector3 &r_box_size, Vector3 &r_box_position);
5252
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");
53+
54+
Vector<Vector3> cylinder_get_handles(real_t p_height, real_t p_radius);
55+
String cylinder_get_handle_name(int p_id) const;
56+
void cylinder_set_handle(const Vector3 p_segment[2], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position);
57+
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");
5358
};
5459

5560
#endif // GIZMO_3D_HELPER_H

modules/csg/editor/csg_gizmos.cpp

+10-44
Original file line numberDiff line numberDiff line change
@@ -278,24 +278,13 @@ void CSGShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_i
278278
if (Object::cast_to<CSGCylinder3D>(cs)) {
279279
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
280280

281-
Vector3 axis;
282-
axis[p_id == 0 ? 0 : 1] = 1.0;
283-
Vector3 ra, rb;
284-
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
285-
float d = axis.dot(ra);
286-
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
287-
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
288-
}
289-
290-
if (d < 0.001) {
291-
d = 0.001;
292-
}
293-
294-
if (p_id == 0) {
295-
s->set_radius(d);
296-
} else if (p_id == 1) {
297-
s->set_height(d * 2.0);
298-
}
281+
real_t height = s->get_height();
282+
real_t radius = s->get_radius();
283+
Vector3 position;
284+
helper->cylinder_set_handle(sg, p_id, height, radius, position);
285+
s->set_height(height);
286+
s->set_radius(radius);
287+
s->set_global_position(position);
299288
}
300289

301290
if (Object::cast_to<CSGTorus3D>(cs)) {
@@ -340,32 +329,11 @@ void CSGShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int
340329
}
341330

342331
if (Object::cast_to<CSGBox3D>(cs)) {
343-
helper->box_commit_handle(TTR("Change Box Shape Size"), p_cancel, cs);
332+
helper->box_commit_handle(TTR("Change CSG Box Size"), p_cancel, cs);
344333
}
345334

346335
if (Object::cast_to<CSGCylinder3D>(cs)) {
347-
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
348-
if (p_cancel) {
349-
if (p_id == 0) {
350-
s->set_radius(p_restore);
351-
} else {
352-
s->set_height(p_restore);
353-
}
354-
return;
355-
}
356-
357-
EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
358-
if (p_id == 0) {
359-
ur->create_action(TTR("Change Cylinder Radius"));
360-
ur->add_do_method(s, "set_radius", s->get_radius());
361-
ur->add_undo_method(s, "set_radius", p_restore);
362-
} else {
363-
ur->create_action(TTR("Change Cylinder Height"));
364-
ur->add_do_method(s, "set_height", s->get_height());
365-
ur->add_undo_method(s, "set_height", p_restore);
366-
}
367-
368-
ur->commit_action();
336+
helper->cylinder_commit_handle(p_id, TTR("Change CSG Cylinder Radius"), TTR("Change CSG Cylinder Height"), p_cancel, cs);
369337
}
370338

371339
if (Object::cast_to<CSGTorus3D>(cs)) {
@@ -506,9 +474,7 @@ void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
506474
if (Object::cast_to<CSGCylinder3D>(cs)) {
507475
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
508476

509-
Vector<Vector3> handles;
510-
handles.push_back(Vector3(s->get_radius(), 0, 0));
511-
handles.push_back(Vector3(0, s->get_height() * 0.5, 0));
477+
Vector<Vector3> handles = helper->cylinder_get_handles(s->get_height(), s->get_radius());
512478
p_gizmo->add_handles(handles, handles_material);
513479
}
514480

0 commit comments

Comments
 (0)