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

Improve editing of box collision shapes #71092

Merged
merged 1 commit into from
Aug 3, 2023
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
46 changes: 35 additions & 11 deletions editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ Variant CollisionShape3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p
return Variant();
}

void CollisionShape3DGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
initial_transform = p_gizmo->get_node_3d()->get_global_transform();
initial_value = get_handle_value(p_gizmo, p_id, p_secondary);
}

void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_node_3d());

Expand All @@ -142,7 +147,7 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i
return;
}

Transform3D gt = cs->get_global_transform();
Transform3D gt = initial_transform;
Transform3D gi = gt.affine_inverse();

Vector3 ray_from = p_camera->project_ray_origin(p_point);
Expand Down Expand Up @@ -184,22 +189,37 @@ void CollisionShape3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, i

if (Object::cast_to<BoxShape3D>(*s)) {
Vector3 axis;
axis[p_id] = 1.0;
axis[p_id / 2] = 1.0;
Ref<BoxShape3D> bs = s;
Vector3 ra, rb;
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = ra[p_id] * 2;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
d = Math::snapped(d, Node3DEditor::get_singleton()->get_translate_snap());
}
int sign = p_id % 2 * -2 + 1;
Vector3 initial_size = initial_value;

if (d < 0.001) {
d = 0.001;
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * sign, sg[0], sg[1], ra, rb);
if (ra[p_id / 2] == 0) {
// Point before half of the shape. Needs to be calculated in opposite direction.
Geometry3D::get_closest_points_between_segments(Vector3(), axis * 4096 * -sign, sg[0], sg[1], ra, rb);
}

float d = ra[p_id / 2] * sign;

Vector3 he = bs->get_size();
he[p_id] = d;
bs->set_size(he);
he[p_id / 2] = d * 2;
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
he[p_id / 2] = Math::snapped(he[p_id / 2], Node3DEditor::get_singleton()->get_translate_snap());
}

if (Input::get_singleton()->is_key_pressed(Key::ALT)) {
he[p_id / 2] = MAX(he[p_id / 2], 0.001);
bs->set_size(he);
cs->set_global_position(initial_transform.get_origin());
} else {
he[p_id / 2] = MAX(he[p_id / 2], -initial_size[p_id / 2] + 0.002);
bs->set_size((initial_size + (he - initial_size) * 0.5).abs());
Vector3 pos = initial_transform.affine_inverse().xform(initial_transform.get_origin());
pos += (bs->get_size() - initial_size) * 0.5 * sign;
cs->set_global_position(initial_transform.xform(pos));
}
}

if (Object::cast_to<CapsuleShape3D>(*s)) {
Expand Down Expand Up @@ -273,14 +293,17 @@ void CollisionShape3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo
if (Object::cast_to<BoxShape3D>(*s)) {
Ref<BoxShape3D> ss = s;
if (p_cancel) {
cs->set_global_position(initial_transform.get_origin());
ss->set_size(p_restore);
return;
}

EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton();
ur->create_action(TTR("Change Box Shape Size"));
ur->add_do_method(ss.ptr(), "set_size", ss->get_size());
ur->add_do_method(cs, "set_position", cs->get_global_position());
ur->add_undo_method(ss.ptr(), "set_size", p_restore);
ur->add_undo_method(cs, "set_global_position", initial_transform.get_origin());
ur->commit_action();
}

Expand Down Expand Up @@ -429,6 +452,7 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 ax;
ax[i] = bs->get_size()[i] / 2;
handles.push_back(ax);
handles.push_back(-ax);
}

p_gizmo->add_lines(lines, material);
Expand Down
4 changes: 4 additions & 0 deletions editor/plugins/gizmos/collision_shape_3d_gizmo_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin);

Transform3D initial_transform;
Variant initial_value;

public:
bool has_gizmo(Node3D *p_spatial) override;
String get_gizmo_name() const override;
Expand All @@ -44,6 +47,7 @@ class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {

String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const override;
void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) override;
void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) override;
void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false) override;

Expand Down
13 changes: 13 additions & 0 deletions editor/plugins/node_3d_editor_gizmos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ Variant EditorNode3DGizmo::get_handle_value(int p_id, bool p_secondary) const {
return gizmo_plugin->get_handle_value(this, p_id, p_secondary);
}

void EditorNode3DGizmo::begin_handle_action(int p_id, bool p_secondary) {
if (GDVIRTUAL_CALL(_begin_handle_action, p_id, p_secondary)) {
return;
}

ERR_FAIL_COND(!gizmo_plugin);
gizmo_plugin->begin_handle_action(this, p_id, p_secondary);
}

void EditorNode3DGizmo::set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
if (GDVIRTUAL_CALL(_set_handle, p_id, p_secondary, p_camera, p_point)) {
return;
Expand Down Expand Up @@ -1095,6 +1104,10 @@ Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_giz
return ret;
}

void EditorNode3DGizmoPlugin::begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) {
GDVIRTUAL_CALL(_begin_handle_action, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary);
}

void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point) {
GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_secondary, p_camera, p_point);
}
Expand Down
4 changes: 4 additions & 0 deletions editor/plugins/node_3d_editor_gizmos.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class EditorNode3DGizmo : public Node3DGizmo {
GDVIRTUAL2RC(String, _get_handle_name, int, bool)
GDVIRTUAL2RC(bool, _is_handle_highlighted, int, bool)
GDVIRTUAL2RC(Variant, _get_handle_value, int, bool)
GDVIRTUAL2(_begin_handle_action, int, bool)
GDVIRTUAL4(_set_handle, int, bool, const Camera3D *, Vector2)
GDVIRTUAL4(_commit_handle, int, bool, Variant, bool)

Expand All @@ -104,6 +105,7 @@ class EditorNode3DGizmo : public Node3DGizmo {
virtual bool is_handle_highlighted(int p_id, bool p_secondary) const;
virtual String get_handle_name(int p_id, bool p_secondary) const;
virtual Variant get_handle_value(int p_id, bool p_secondary) const;
virtual void begin_handle_action(int p_id, bool p_secondary);
virtual void set_handle(int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point);
virtual void commit_handle(int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);

Expand Down Expand Up @@ -170,6 +172,7 @@ class EditorNode3DGizmoPlugin : public Resource {
GDVIRTUAL3RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int, bool)
GDVIRTUAL3RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int, bool)

GDVIRTUAL3(_begin_handle_action, Ref<EditorNode3DGizmo>, int, bool)
GDVIRTUAL5(_set_handle, Ref<EditorNode3DGizmo>, int, bool, const Camera3D *, Vector2)
GDVIRTUAL5(_commit_handle, Ref<EditorNode3DGizmo>, int, bool, Variant, bool)

Expand All @@ -196,6 +199,7 @@ class EditorNode3DGizmoPlugin : public Resource {
virtual bool is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
virtual String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
virtual Variant get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary) const;
virtual void begin_handle_action(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary);
virtual void set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, Camera3D *p_camera, const Point2 &p_point);
virtual void commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, bool p_secondary, const Variant &p_restore, bool p_cancel = false);

Expand Down
3 changes: 2 additions & 1 deletion editor/plugins/node_3d_editor_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1775,6 +1775,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
seg->handles_intersect_ray(camera, _edit.mouse_pos, b->is_shift_pressed(), gizmo_handle, gizmo_secondary);
if (gizmo_handle != -1) {
_edit.gizmo = seg;
seg->begin_handle_action(gizmo_handle, gizmo_secondary);
_edit.gizmo_handle = gizmo_handle;
_edit.gizmo_handle_secondary = gizmo_secondary;
_edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle, gizmo_secondary);
Expand Down Expand Up @@ -2152,7 +2153,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}

if (_edit.mode == TRANSFORM_NONE) {
if (_edit.gizmo.is_valid()) {
if (_edit.gizmo.is_valid() && (k->get_keycode() == Key::ESCAPE || k->get_keycode() == Key::BACKSPACE)) {
// Restore.
_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_handle_secondary, _edit.gizmo_initial_value, true);
_edit.gizmo = Ref<EditorNode3DGizmo>();
Expand Down
Loading