@@ -142,26 +142,36 @@ void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel
142142
143143Vector<Vector3> Gizmo3DHelper::cylinder_get_handles (real_t p_height, real_t p_radius) {
144144 Vector<Vector3> handles;
145- handles.push_back (Vector3 (p_radius, 0 , 0 ));
146145 handles.push_back (Vector3 (0 , p_height * 0.5 , 0 ));
147146 handles.push_back (Vector3 (0 , p_height * -0.5 , 0 ));
147+ handles.push_back (Vector3 (p_radius, 0 , 0 ));
148148 return handles;
149149}
150150
151- String Gizmo3DHelper::cylinder_get_handle_name (int p_id) const {
152- if (p_id == 0 ) {
153- return " Radius" ;
154- } else {
151+ String Gizmo3DHelper::_cylinder_or_capsule_or_cone_frustum_get_handle_name (int p_id) const {
152+ if (p_id < 2 ) {
155153 return " Height" ;
154+ } else {
155+ return " Radius" ;
156156 }
157157}
158158
159- void Gizmo3DHelper::_cylinder_or_capsule_set_handle (const Vector3 p_segment[2 ], int p_id, real_t &r_height, real_t &r_radius, Vector3 &r_cylinder_position, bool p_is_capsule) {
160- real_t initial_radius = initial_value.operator Vector2 ().x ;
161- real_t initial_height = initial_value.operator Vector2 ().y ;
159+ void Gizmo3DHelper::_cylinder_or_capsule_or_cone_frustum_set_handle (const Vector3 p_segment[2 ], int p_id, real_t &r_height, real_t &r_radius_top, real_t &r_radius_bottom, Vector3 &r_position, bool p_is_capsule, bool p_is_frustum) {
160+ ERR_FAIL_COND (p_is_capsule && p_is_frustum);
161+
162+ real_t initial_radius_top, initial_radius_bottom, initial_height;
163+ if (p_is_frustum) {
164+ initial_radius_top = initial_value.operator Vector3 ().x ;
165+ initial_radius_bottom = initial_value.operator Vector3 ().y ;
166+ initial_height = initial_value.operator Vector3 ().z ;
167+ } else {
168+ initial_radius_top = initial_value.operator Vector2 ().x ;
169+ initial_radius_bottom = initial_radius_top;
170+ initial_height = initial_value.operator Vector2 ().y ;
171+ }
162172
163- int sign = p_id == 2 ? -1 : 1 ;
164- int axis = p_id == 0 ? 0 : 1 ;
173+ int sign = p_id == 1 ? -1 : 1 ;
174+ int axis = p_id >= 2 ? 0 : 1 ;
165175
166176 Vector3 axis_vector;
167177 axis_vector[axis] = sign;
@@ -174,20 +184,7 @@ void Gizmo3DHelper::_cylinder_or_capsule_set_handle(const Vector3 p_segment[2],
174184 d = Math::snapped (d, Node3DEditor::get_singleton ()->get_translate_snap ());
175185 }
176186
177- if (p_id == 0 ) {
178- // Adjust radius.
179- if (d < 0.001 ) {
180- d = 0.001 ;
181- }
182- r_radius = d;
183- r_cylinder_position = initial_transform.get_origin ();
184-
185- if (p_is_capsule) {
186- r_height = MAX (initial_height, r_radius * 2.0 );
187- } else {
188- r_height = initial_height;
189- }
190- } else if (p_id == 1 || p_id == 2 ) {
187+ if (p_id < 2 ) {
191188 // Adjust height.
192189 if (Input::get_singleton ()->is_key_pressed (Key::ALT )) {
193190 r_height = d * 2.0 ;
@@ -201,17 +198,41 @@ void Gizmo3DHelper::_cylinder_or_capsule_set_handle(const Vector3 p_segment[2],
201198
202199 // Adjust position.
203200 if (Input::get_singleton ()->is_key_pressed (Key::ALT )) {
204- r_cylinder_position = initial_transform.get_origin ();
201+ r_position = initial_transform.get_origin ();
205202 } else {
206203 Vector3 offset;
207204 offset[axis] = (r_height - initial_height) * 0.5 * sign;
208- r_cylinder_position = initial_transform.xform (offset);
205+ r_position = initial_transform.xform (offset);
209206 }
210207
211208 if (p_is_capsule) {
212- r_radius = MIN (initial_radius, r_height / 2.0 );
209+ r_radius_top = MIN (initial_radius_top, r_height / 2.0 );
210+ r_radius_bottom = r_radius_top;
211+ } else {
212+ r_radius_top = initial_radius_top;
213+ r_radius_bottom = initial_radius_bottom;
214+ }
215+ } else {
216+ // Adjust radius.
217+ if (d < 0.001 ) {
218+ d = 0.001 ;
219+ }
220+ if (!p_is_frustum) {
221+ r_radius_top = d;
222+ r_radius_bottom = d;
213223 } else {
214- r_radius = initial_radius;
224+ real_t diff = d - (initial_radius_bottom + initial_radius_top) / 2.0 ;
225+ diff = MAX (MAX (-initial_radius_bottom + 0.001 , -initial_radius_top + 0.001 ), diff);
226+ r_radius_top = initial_radius_top + diff;
227+ r_radius_bottom = initial_radius_bottom + diff;
228+ }
229+
230+ r_position = initial_transform.get_origin ();
231+
232+ if (p_is_capsule) {
233+ r_height = MAX (initial_height, r_radius_top * 2.0 );
234+ } else {
235+ r_height = initial_height;
215236 }
216237 }
217238}
@@ -232,7 +253,7 @@ void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_acti
232253 }
233254
234255 EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
235- ur->create_action (p_id == 0 ? p_radius_action_name : p_height_action_name );
256+ ur->create_action (p_id < 2 ? p_height_action_name : p_radius_action_name );
236257 ur->add_do_property (p_radius_object, p_radius_property, p_radius_object->get (p_radius_property));
237258 ur->add_undo_property (p_radius_object, p_radius_property, initial_value.operator Vector2 ().x );
238259 ur->add_do_property (p_height_object, p_height_property, p_height_object->get (p_height_property));
@@ -241,3 +262,43 @@ void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_acti
241262 ur->add_undo_property (p_position_object, p_position_property, initial_transform.get_origin ());
242263 ur->commit_action ();
243264}
265+
266+ Vector<Vector3> Gizmo3DHelper::cone_frustum_get_handles (real_t p_height, real_t p_radius_top, real_t p_radius_bottom) {
267+ Vector<Vector3> handles;
268+ handles.push_back (Vector3 (0 , p_height * 0.5 , 0 ));
269+ handles.push_back (Vector3 (0 , p_height * -0.5 , 0 ));
270+ handles.push_back (Vector3 ((p_radius_top + p_radius_bottom) / 2.0 , 0 , 0 ));
271+ return handles;
272+ }
273+
274+ void Gizmo3DHelper::cone_frustum_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_top_object, Object *p_radius_bottom_object, const StringName &p_position_property, const StringName &p_height_property, const StringName &p_radius_top_property, const StringName &p_radius_bottom_property) {
275+ if (!p_height_object) {
276+ p_height_object = p_position_object;
277+ }
278+ if (!p_radius_top_object) {
279+ p_radius_top_object = p_position_object;
280+ }
281+ if (!p_radius_bottom_object) {
282+ p_radius_bottom_object = p_position_object;
283+ }
284+
285+ if (p_cancel) {
286+ p_radius_top_object->set (p_radius_top_property, initial_value.operator Vector3 ().x );
287+ p_radius_bottom_object->set (p_radius_bottom_property, initial_value.operator Vector3 ().y );
288+ p_height_object->set (p_height_property, initial_value.operator Vector3 ().z );
289+ p_position_object->set (p_position_property, initial_transform.get_origin ());
290+ return ;
291+ }
292+
293+ EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
294+ ur->create_action (p_id < 2 ? p_height_action_name : p_radius_action_name);
295+ ur->add_do_property (p_radius_top_object, p_radius_top_property, p_radius_top_object->get (p_radius_top_property));
296+ ur->add_do_property (p_radius_bottom_object, p_radius_bottom_property, p_radius_bottom_object->get (p_radius_bottom_property));
297+ ur->add_undo_property (p_radius_top_object, p_radius_top_property, initial_value.operator Vector3 ().x );
298+ ur->add_undo_property (p_radius_bottom_object, p_radius_bottom_property, initial_value.operator Vector3 ().y );
299+ ur->add_do_property (p_height_object, p_height_property, p_height_object->get (p_height_property));
300+ ur->add_undo_property (p_height_object, p_height_property, initial_value.operator Vector3 ().z );
301+ ur->add_do_property (p_position_object, p_position_property, p_position_object->get (p_position_property));
302+ ur->add_undo_property (p_position_object, p_position_property, initial_transform.get_origin ());
303+ ur->commit_action ();
304+ }
0 commit comments