@@ -143,26 +143,36 @@ void Gizmo3DHelper::box_commit_handle(const String &p_action_name, bool p_cancel
143143
144144Vector<Vector3> Gizmo3DHelper::cylinder_get_handles (real_t p_height, real_t p_radius) {
145145 Vector<Vector3> handles;
146- handles.push_back (Vector3 (p_radius, 0 , 0 ));
147146 handles.push_back (Vector3 (0 , p_height * 0.5 , 0 ));
148147 handles.push_back (Vector3 (0 , p_height * -0.5 , 0 ));
148+ handles.push_back (Vector3 (p_radius, 0 , 0 ));
149149 return handles;
150150}
151151
152- String Gizmo3DHelper::cylinder_get_handle_name (int p_id) const {
153- if (p_id == 0 ) {
154- return " Radius" ;
155- } else {
152+ String Gizmo3DHelper::_cylinder_or_capsule_or_cone_frustum_get_handle_name (int p_id) const {
153+ if (p_id < 2 ) {
156154 return " Height" ;
155+ } else {
156+ return " Radius" ;
157157 }
158158}
159159
160- 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) {
161- real_t initial_radius = initial_value.operator Vector2 ().x ;
162- real_t initial_height = initial_value.operator Vector2 ().y ;
160+ 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) {
161+ ERR_FAIL_COND (p_is_capsule && p_is_frustum);
162+
163+ real_t initial_radius_top, initial_radius_bottom, initial_height;
164+ if (p_is_frustum) {
165+ initial_radius_top = initial_value.operator Vector3 ().x ;
166+ initial_radius_bottom = initial_value.operator Vector3 ().y ;
167+ initial_height = initial_value.operator Vector3 ().z ;
168+ } else {
169+ initial_radius_top = initial_value.operator Vector2 ().x ;
170+ initial_radius_bottom = initial_radius_top;
171+ initial_height = initial_value.operator Vector2 ().y ;
172+ }
163173
164- int sign = p_id == 2 ? -1 : 1 ;
165- int axis = p_id == 0 ? 0 : 1 ;
174+ int sign = p_id == 1 ? -1 : 1 ;
175+ int axis = p_id >= 2 ? 0 : 1 ;
166176
167177 Vector3 axis_vector;
168178 axis_vector[axis] = sign;
@@ -175,20 +185,7 @@ void Gizmo3DHelper::_cylinder_or_capsule_set_handle(const Vector3 p_segment[2],
175185 d = Math::snapped (d, Node3DEditor::get_singleton ()->get_translate_snap ());
176186 }
177187
178- if (p_id == 0 ) {
179- // Adjust radius.
180- if (d < 0.001 ) {
181- d = 0.001 ;
182- }
183- r_radius = d;
184- r_cylinder_position = initial_transform.get_origin ();
185-
186- if (p_is_capsule) {
187- r_height = MAX (initial_height, r_radius * 2.0 );
188- } else {
189- r_height = initial_height;
190- }
191- } else if (p_id == 1 || p_id == 2 ) {
188+ if (p_id < 2 ) {
192189 // Adjust height.
193190 if (Input::get_singleton ()->is_key_pressed (Key::ALT )) {
194191 r_height = d * 2.0 ;
@@ -202,17 +199,41 @@ void Gizmo3DHelper::_cylinder_or_capsule_set_handle(const Vector3 p_segment[2],
202199
203200 // Adjust position.
204201 if (Input::get_singleton ()->is_key_pressed (Key::ALT )) {
205- r_cylinder_position = initial_transform.get_origin ();
202+ r_position = initial_transform.get_origin ();
206203 } else {
207204 Vector3 offset;
208205 offset[axis] = (r_height - initial_height) * 0.5 * sign;
209- r_cylinder_position = initial_transform.xform (offset);
206+ r_position = initial_transform.xform (offset);
210207 }
211208
212209 if (p_is_capsule) {
213- r_radius = MIN (initial_radius, r_height / 2.0 );
210+ r_radius_top = MIN (initial_radius_top, r_height / 2.0 );
211+ r_radius_bottom = r_radius_top;
212+ } else {
213+ r_radius_top = initial_radius_top;
214+ r_radius_bottom = initial_radius_bottom;
215+ }
216+ } else {
217+ // Adjust radius.
218+ if (d < 0.001 ) {
219+ d = 0.001 ;
220+ }
221+ if (!p_is_frustum) {
222+ r_radius_top = d;
223+ r_radius_bottom = d;
214224 } else {
215- r_radius = initial_radius;
225+ real_t diff = d - (initial_radius_bottom + initial_radius_top) / 2.0 ;
226+ diff = MAX (MAX (-initial_radius_bottom + 0.001 , -initial_radius_top + 0.001 ), diff);
227+ r_radius_top = initial_radius_top + diff;
228+ r_radius_bottom = initial_radius_bottom + diff;
229+ }
230+
231+ r_position = initial_transform.get_origin ();
232+
233+ if (p_is_capsule) {
234+ r_height = MAX (initial_height, r_radius_top * 2.0 );
235+ } else {
236+ r_height = initial_height;
216237 }
217238 }
218239}
@@ -233,7 +254,7 @@ void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_acti
233254 }
234255
235256 EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
236- ur->create_action (p_id == 0 ? p_radius_action_name : p_height_action_name );
257+ ur->create_action (p_id < 2 ? p_height_action_name : p_radius_action_name );
237258 ur->add_do_property (p_radius_object, p_radius_property, p_radius_object->get (p_radius_property));
238259 ur->add_undo_property (p_radius_object, p_radius_property, initial_value.operator Vector2 ().x );
239260 ur->add_do_property (p_height_object, p_height_property, p_height_object->get (p_height_property));
@@ -242,3 +263,43 @@ void Gizmo3DHelper::cylinder_commit_handle(int p_id, const String &p_radius_acti
242263 ur->add_undo_property (p_position_object, p_position_property, initial_transform.get_origin ());
243264 ur->commit_action ();
244265}
266+
267+ Vector<Vector3> Gizmo3DHelper::cone_frustum_get_handles (real_t p_height, real_t p_radius_top, real_t p_radius_bottom) {
268+ Vector<Vector3> handles;
269+ handles.push_back (Vector3 (0 , p_height * 0.5 , 0 ));
270+ handles.push_back (Vector3 (0 , p_height * -0.5 , 0 ));
271+ handles.push_back (Vector3 ((p_radius_top + p_radius_bottom) / 2.0 , 0 , 0 ));
272+ return handles;
273+ }
274+
275+ 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) {
276+ if (!p_height_object) {
277+ p_height_object = p_position_object;
278+ }
279+ if (!p_radius_top_object) {
280+ p_radius_top_object = p_position_object;
281+ }
282+ if (!p_radius_bottom_object) {
283+ p_radius_bottom_object = p_position_object;
284+ }
285+
286+ if (p_cancel) {
287+ p_radius_top_object->set (p_radius_top_property, initial_value.operator Vector3 ().x );
288+ p_radius_bottom_object->set (p_radius_bottom_property, initial_value.operator Vector3 ().y );
289+ p_height_object->set (p_height_property, initial_value.operator Vector3 ().z );
290+ p_position_object->set (p_position_property, initial_transform.get_origin ());
291+ return ;
292+ }
293+
294+ EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton ();
295+ ur->create_action (p_id < 2 ? p_height_action_name : p_radius_action_name);
296+ ur->add_do_property (p_radius_top_object, p_radius_top_property, p_radius_top_object->get (p_radius_top_property));
297+ ur->add_do_property (p_radius_bottom_object, p_radius_bottom_property, p_radius_bottom_object->get (p_radius_bottom_property));
298+ ur->add_undo_property (p_radius_top_object, p_radius_top_property, initial_value.operator Vector3 ().x );
299+ ur->add_undo_property (p_radius_bottom_object, p_radius_bottom_property, initial_value.operator Vector3 ().y );
300+ ur->add_do_property (p_height_object, p_height_property, p_height_object->get (p_height_property));
301+ ur->add_undo_property (p_height_object, p_height_property, initial_value.operator Vector3 ().z );
302+ ur->add_do_property (p_position_object, p_position_property, p_position_object->get (p_position_property));
303+ ur->add_undo_property (p_position_object, p_position_property, initial_transform.get_origin ());
304+ ur->commit_action ();
305+ }
0 commit comments