Improve the 3D editor manipulation gizmo

- Allow some tolerance when clicking the plane move/scale,
  even if the click is actually slightly outside the plane
  (similar to Blender).
- Make the rotate manipulation circles visually thinner to be
  less distracting.
- Make the hovered color less saturated to be more distinguishable
  from the non-hovered state.
  - Don't set brightness above 1.0 to prevent the gizmo from glowing
    when hovered.

(cherry picked from commit 6cfcbbbb93)
This commit is contained in:
Hugo Locurcio 2021-07-19 00:09:59 +02:00 committed by Rémi Verschelde
parent 48308a5e0a
commit 8fc99ef680
No known key found for this signature in database
GPG key ID: C3336907360768E1

View file

@ -844,14 +844,18 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST);
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
const Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
Vector3 r;
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
float dist = r.distance_to(grabber_pos);
if (dist < (gs * GIZMO_PLANE_SIZE)) {
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
if (dist < (gs * GIZMO_PLANE_SIZE * 1.5)) {
float d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
@ -944,14 +948,18 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST);
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
Vector3 grabber_pos = gt.origin + (ivec2 + ivec3) * gs * (GIZMO_PLANE_SIZE + GIZMO_PLANE_DST * 0.6667);
Vector3 r;
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
float dist = r.distance_to(grabber_pos);
if (dist < (gs * GIZMO_PLANE_SIZE)) {
// Allow some tolerance to make the plane easier to click,
// even if the click is actually slightly outside the plane.
if (dist < (gs * GIZMO_PLANE_SIZE * 1.5)) {
float d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
@ -2631,9 +2639,7 @@ void SpatialEditorViewport::_draw() {
handle_color = get_color("accent_color", "Editor");
break;
}
handle_color.a = 1.0;
const float brightness = 1.3;
handle_color *= Color(brightness, brightness, brightness);
handle_color = handle_color.from_hsv(handle_color.get_h(), 0.25, 1.0, 1);
VisualServer::get_singleton()->canvas_item_add_line(
ci,
@ -5142,8 +5148,7 @@ void SpatialEditor::_init_indicators() {
gizmo_color[i] = mat;
Ref<SpatialMaterial> mat_hl = mat->duplicate();
const float brightness = 1.3;
const Color albedo = Color(col.r * brightness, col.g * brightness, col.b * brightness);
const Color albedo = col.from_hsv(col.get_h(), 0.25, 1.0, 1);
mat_hl->set_albedo(albedo);
gizmo_color_hl[i] = mat_hl;
@ -5249,7 +5254,7 @@ void SpatialEditor::_init_indicators() {
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
int n = 128; // number of circle segments
int m = 6; // number of thickness segments
int m = 3; // number of thickness segments
for (int j = 0; j < n; ++j) {
Basis basis = Basis(ivec, (Math_PI * 2.0f * j) / n);
@ -5448,7 +5453,7 @@ void SpatialEditor::_init_indicators() {
surftool->commit(scale_plane_gizmo[i]);
Ref<SpatialMaterial> plane_mat_hl = plane_mat->duplicate();
plane_mat_hl->set_albedo(Color(col.r * 1.3, col.g * 1.3, col.b * 1.3));
plane_mat_hl->set_albedo(col.from_hsv(col.get_h(), 0.25, 1.0, 1));
plane_gizmo_color_hl[i] = plane_mat_hl; // needed, so we can draw planes from both sides
}
}