summaryrefslogtreecommitdiffstats
path: root/editor/plugins/spatial_editor_plugin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins/spatial_editor_plugin.cpp')
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp734
1 files changed, 475 insertions, 259 deletions
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 7a43c41b0e..f96cbabde7 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -49,19 +49,22 @@
#define DISTANCE_DEFAULT 4
-#define GIZMO_ARROW_SIZE 0.3
+#define GIZMO_ARROW_SIZE 0.35
#define GIZMO_RING_HALF_WIDTH 0.1
//#define GIZMO_SCALE_DEFAULT 0.28
#define GIZMO_SCALE_DEFAULT 0.15
#define GIZMO_PLANE_SIZE 0.2
#define GIZMO_PLANE_DST 0.3
-#define GIZMO_CIRCLE_SIZE 0.9
+#define GIZMO_CIRCLE_SIZE 1.1
+#define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
+#define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
#define ZOOM_MIN_DISTANCE 0.001
#define ZOOM_MULTIPLIER 1.08
#define ZOOM_INDICATOR_DELAY_S 1.5
-#define FREELOOK_MIN_SPEED 0.1
+#define FREELOOK_MIN_SPEED 0.01
+#define FREELOOK_SPEED_MULTIPLIER 1.08
#define MIN_Z 0.01
#define MAX_Z 10000
@@ -70,53 +73,93 @@
#define MAX_FOV 179
void SpatialEditorViewport::_update_camera(float p_interp_delta) {
- if (orthogonal) {
- //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar());
- camera->set_orthogonal(2 * cursor.distance, 0.1, 8192);
- } else
- camera->set_perspective(get_fov(), get_znear(), get_zfar());
- //when not being manipulated, move softly
- float free_orbit_inertia = EDITOR_DEF("editors/3d/free_orbit_inertia", 0.15);
- float free_translation_inertia = EDITOR_DEF("editors/3d/free_translation_inertia", 0.15);
- //when being manipulated, move more quickly
- float manip_orbit_inertia = EDITOR_DEF("editors/3d/manipulation_orbit_inertia", 0.075);
- float manip_translation_inertia = EDITOR_DEF("editors/3d/manipulation_translation_inertia", 0.075);
-
- //determine if being manipulated
- bool manipulated = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
-
- float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
- float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
+ bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;
Cursor old_camera_cursor = camera_cursor;
camera_cursor = cursor;
- camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
- camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ if (p_interp_delta > 0) {
+
+ //-------
+ // Perform smoothing
+
+ if (is_freelook_active()) {
- camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
- camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
+ // Higher inertia should increase "lag" (lerp with factor between 0 and 1)
+ // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
+ real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia");
+ inertia = MAX(0.001, inertia);
+ real_t factor = (1.0 / inertia) * p_interp_delta;
- if (p_interp_delta == 0 || is_freelook_active()) {
- camera_cursor = cursor;
+ // We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
+ camera_cursor.eye_pos = old_camera_cursor.eye_pos.linear_interpolate(cursor.eye_pos, CLAMP(factor, 0, 1));
+ //camera_cursor.pos = camera_cursor.eye_pos + (cursor.pos - cursor.eye_pos);
+
+ float orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ orbit_inertia = MAX(0.0001, orbit_inertia);
+ camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+
+ Vector3 forward = to_camera_transform(camera_cursor).basis.xform(Vector3(0, 0, -1));
+ camera_cursor.pos = camera_cursor.eye_pos + forward * camera_cursor.distance;
+
+ } else {
+
+ //when not being manipulated, move softly
+ float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
+ //when being manipulated, move more quickly
+ float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
+ float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
+
+ float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
+
+ //determine if being manipulated
+ bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+
+ float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
+ float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
+ zoom_inertia = MAX(0.0001, zoom_inertia);
+
+ camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+
+ camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
+ camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia)));
+ }
}
- float tolerance = 0.0001;
+ //-------
+ // Apply camera transform
+
+ float tolerance = 0.001;
bool equal = true;
- if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance)
+ if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) {
equal = false;
+ }
- if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance)
+ if (equal && old_camera_cursor.pos.distance_squared_to(camera_cursor.pos) > tolerance * tolerance) {
equal = false;
+ }
- if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance)
+ if (equal && Math::abs(old_camera_cursor.distance - camera_cursor.distance) > tolerance) {
equal = false;
+ }
- if (!equal || p_interp_delta == 0 || is_freelook_active()) {
+ if (!equal || p_interp_delta == 0 || is_freelook_active() || is_orthogonal != orthogonal) {
camera->set_global_transform(to_camera_transform(camera_cursor));
update_transform_gizmo_view();
+
+ if (orthogonal) {
+ //camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar());
+ camera->set_orthogonal(2 * cursor.distance, 0.1, 8192);
+ } else
+ camera->set_perspective(get_fov(), get_znear(), get_zfar());
}
}
@@ -217,7 +260,7 @@ Transform SpatialEditorViewport::_get_camera_transform() const {
return camera->get_global_transform();
}
-Vector3 SpatialEditorViewport::_get_camera_pos() const {
+Vector3 SpatialEditorViewport::_get_camera_position() const {
return _get_camera_transform().origin;
}
@@ -464,8 +507,7 @@ void SpatialEditorViewport::_select_region() {
Vector<Plane> frustum;
- Vector3 cam_pos = _get_camera_pos();
- Set<Ref<SpatialEditorGizmo> > found_gizmos;
+ Vector3 cam_pos = _get_camera_position();
for (int i = 0; i < 4; i++) {
@@ -485,6 +527,9 @@ void SpatialEditorViewport::_select_region() {
frustum.push_back(far);
Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario());
+ Vector<Spatial *> selected;
+
+ Node *edited_scene = get_tree()->get_edited_scene_root();
for (int i = 0; i < instances.size(); i++) {
@@ -497,11 +542,14 @@ void SpatialEditorViewport::_select_region() {
if (!seg.is_valid())
continue;
- if (found_gizmos.has(seg))
- continue;
+ Spatial *root_sp = sp;
+ while (root_sp && root_sp != edited_scene && root_sp->get_owner() != edited_scene && !edited_scene->is_editable_instance(root_sp->get_owner())) {
+ root_sp = Object::cast_to<Spatial>(root_sp->get_owner());
+ }
- if (seg->intersect_frustum(camera, frustum))
- _select(sp, true, false);
+ if (selected.find(root_sp) == -1)
+ if (seg->intersect_frustum(camera, frustum))
+ _select(root_sp, true, false);
}
}
@@ -525,8 +573,6 @@ void SpatialEditorViewport::_compute_edit(const Point2 &p_point) {
List<Node *> &selection = editor_selection->get_selected_node_list();
- //Vector3 center;
- //int nc=0;
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Spatial *sp = Object::cast_to<Spatial>(E->get());
@@ -538,14 +584,8 @@ void SpatialEditorViewport::_compute_edit(const Point2 &p_point) {
continue;
se->original = se->sp->get_global_transform();
- //center+=se->original.origin;
- //nc++;
+ se->original_local = se->sp->get_transform();
}
-
- /*
- if (nc)
- _edit.center=center/float(nc);
- */
}
static int _get_key_modifier_setting(const String &p_property) {
@@ -596,7 +636,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
for (int i = 0; i < 3; i++) {
- Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs;
+ Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
float grabber_radius = gs * GIZMO_ARROW_SIZE;
Vector3 r;
@@ -611,7 +651,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
}
bool is_plane_translate = false;
- // second try
+ // plane select
if (col_axis == -1) {
col_d = 1e20;
@@ -697,6 +737,43 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hig
}
}
+ if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE) {
+
+ int col_axis = -1;
+ float col_d = 1e20;
+
+ for (int i = 0; i < 3; i++) {
+
+ Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * GIZMO_SCALE_OFFSET;
+ float grabber_radius = gs * GIZMO_ARROW_SIZE;
+
+ Vector3 r;
+
+ if (Geometry::segment_intersects_sphere(ray_pos, ray_pos + ray * 10000.0, grabber_pos, grabber_radius, &r)) {
+ float d = r.distance_to(ray_pos);
+ if (d < col_d) {
+ col_d = d;
+ col_axis = i;
+ }
+ }
+ }
+
+ if (col_axis != -1) {
+
+ if (p_highlight_only) {
+
+ spatial_editor->select_gizmo_highlight_axis(col_axis + 9);
+
+ } else {
+ //handle scale
+ _edit.mode = TRANSFORM_SCALE;
+ _compute_edit(Point2(p_screenpos.x, p_screenpos.y));
+ _edit.plane = TransformPlane(TRANSFORM_X_AXIS + col_axis);
+ }
+ return true;
+ }
+ }
+
if (p_highlight_only)
spatial_editor->select_gizmo_highlight_axis(-1);
@@ -797,20 +874,26 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
-
+ float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
case BUTTON_WHEEL_UP: {
- scale_cursor_distance(is_freelook_active() ? ZOOM_MULTIPLIER : 1.0 / ZOOM_MULTIPLIER);
+ if (is_freelook_active())
+ scale_freelook_speed(zoom_factor);
+ else
+ scale_cursor_distance(1.0 / zoom_factor);
} break;
case BUTTON_WHEEL_DOWN: {
- scale_cursor_distance(is_freelook_active() ? 1.0 / ZOOM_MULTIPLIER : ZOOM_MULTIPLIER);
+ if (is_freelook_active())
+ scale_freelook_speed(1.0 / zoom_factor);
+ else
+ scale_cursor_distance(zoom_factor);
} break;
case BUTTON_RIGHT: {
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
if (b->is_pressed() && _edit.gizmo.is_valid()) {
//restore
@@ -856,11 +939,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed()) {
int mod = _get_key_modifier(b);
- if (mod == _get_key_modifier_setting("editors/3d/freelook_activation_modifier")) {
- freelook_active = true;
+ if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
+ set_freelook_active(true);
}
} else {
- freelook_active = false;
+ set_freelook_active(false);
}
if (freelook_active && !surface->has_focus()) {
@@ -908,7 +991,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed()) {
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) {
break;
}
@@ -1117,7 +1200,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_gizmo_select(_edit.mouse_pos, true);
}
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
NavigationMode nav_mode = NAVIGATION_NONE;
if (_edit.gizmo.is_valid()) {
@@ -1169,7 +1252,28 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
case TRANSFORM_SCALE: {
- Plane plane = Plane(_edit.center, _get_camera_normal());
+ Vector3 motion_mask;
+ Plane plane;
+ bool plane_mv;
+
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ motion_mask = Vector3(0, 0, 0);
+ plane = Plane(_edit.center, _get_camera_normal());
+ break;
+ case TRANSFORM_X_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ case TRANSFORM_Y_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ case TRANSFORM_Z_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ }
Vector3 intersection;
if (!plane.intersects_ray(ray_pos, ray, &intersection))
@@ -1179,42 +1283,78 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
break;
- float center_click_dist = click.distance_to(_edit.center);
- float center_inters_dist = intersection.distance_to(_edit.center);
- if (center_click_dist == 0)
- break;
+ Vector3 motion = intersection - click;
+ print_line(String(intersection) + " --- " + String(click));
+ if (motion_mask != Vector3()) {
- float scale = (center_inters_dist / center_click_dist) * 100.0;
+ motion = motion_mask.dot(motion) * motion_mask;
+ } else {
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ float center_click_dist = click.distance_to(_edit.center);
+ float center_inters_dist = intersection.distance_to(_edit.center);
+ if (center_click_dist == 0)
+ break;
- scale = Math::stepify(scale, spatial_editor->get_scale_snap());
+ float scale = center_inters_dist - center_click_dist;
+ motion = Vector3(scale, scale, scale);
}
- set_message(vformat(TTR("Scaling to %s%%."), String::num(scale, 1)));
- scale /= 100.0;
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- Transform r;
- r.basis.scale(Vector3(scale, scale, scale));
+ bool local_coords = (spatial_editor->are_local_coords_enabled() && motion_mask != Vector3()); // Disable local transformation for TRANSFORM_VIEW
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ float snap = 0;
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+
+ snap = spatial_editor->get_scale_snap() / 100;
+ }
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Spatial *sp = Object::cast_to<Spatial>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
Transform original = se->original;
-
+ Transform original_local = se->original_local;
Transform base = Transform(Basis(), _edit.center);
- Transform t = base * (r * (base.inverse() * original));
+ Transform t;
+ Vector3 local_scale;
- sp->set_global_transform(t);
+ if (local_coords) {
+
+ Basis g = original.basis.orthonormalized();
+ Vector3 local_motion = g.inverse().xform(motion);
+
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ local_motion.snap(Vector3(snap, snap, snap));
+ }
+
+ local_scale = original_local.basis.get_scale() * (local_motion + Vector3(1, 1, 1));
+
+ } else {
+
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ motion.snap(Vector3(snap, snap, snap));
+ }
+
+ Transform r;
+ r.basis.scale(motion + Vector3(1, 1, 1));
+ t = base * (r * (base.inverse() * original));
+ }
+
+ // Apply scale
+ if (local_coords) {
+ sp->set_scale(local_scale);
+ } else {
+ sp->set_global_transform(t);
+ }
}
surface->update();
@@ -1341,6 +1481,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
case TRANSFORM_ROTATE: {
Plane plane;
+ Vector3 axis;
switch (_edit.plane) {
case TRANSFORM_VIEW:
@@ -1348,12 +1489,15 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
break;
case TRANSFORM_X_AXIS:
plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(0));
+ axis = Vector3(1, 0, 0);
break;
case TRANSFORM_Y_AXIS:
plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(1));
+ axis = Vector3(0, 1, 0);
break;
case TRANSFORM_Z_AXIS:
plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2));
+ axis = Vector3(0, 0, 1);
break;
}
@@ -1369,6 +1513,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 x_axis = plane.normal.cross(y_axis).normalized();
float angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
+
if (_edit.snap || spatial_editor->is_snap_enabled()) {
float snap = spatial_editor->get_rotate_snap();
@@ -1385,11 +1530,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
}
- Transform r;
- r.basis.rotate(plane.normal, angle);
-
List<Node *> &selection = editor_selection->get_selected_node_list();
+ bool local_coords = spatial_editor->are_local_coords_enabled();
+
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Spatial *sp = Object::cast_to<Spatial>(E->get());
@@ -1400,27 +1544,33 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!se)
continue;
- Transform original = se->original;
+ Transform t;
- Transform base = Transform(Basis(), _edit.center);
- Transform t = base * r * base.inverse() * original;
+ if (local_coords) {
- sp->set_global_transform(t);
+ Transform original_local = se->original_local;
+ Basis rot = Basis(axis, angle);
+
+ t.basis = original_local.get_basis() * rot;
+ t.origin = original_local.origin;
+
+ sp->set_transform(t);
+
+ } else {
+
+ Transform original = se->original;
+ Transform r;
+ Transform base = Transform(Basis(), _edit.center);
+
+ r.basis.rotate(plane.normal, angle);
+ t = base * r * base.inverse() * original;
+
+ sp->set_global_transform(t);
+ }
}
surface->update();
- /*
- VisualServer::get_singleton()->poly_clear(indicators);
-
- Vector<Vector3> points;
- Vector<Vector3> empty;
- Vector<Color> colors;
- points.push_back(intersection);
- points.push_back(_edit.original.origin);
- colors.push_back( Color(255,155,100) );
- colors.push_back( Color(255,155,100) );
- VisualServer::get_singleton()->poly_add_primitive(indicators,points,empty,colors,empty);
- */
+
} break;
default: {}
}
@@ -1440,11 +1590,11 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
int mod = _get_key_modifier(m);
- if (mod == _get_key_modifier_setting("editors/3d/pan_modifier"))
+ if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier"))
nav_mode = NAVIGATION_PAN;
- else if (mod == _get_key_modifier_setting("editors/3d/zoom_modifier"))
+ else if (mod == _get_key_modifier_setting("editors/3d/navigation/zoom_modifier"))
nav_mode = NAVIGATION_ZOOM;
- else if (mod == _get_key_modifier_setting("editors/3d/orbit_modifier"))
+ else if (mod == _get_key_modifier_setting("editors/3d/navigation/orbit_modifier"))
nav_mode = NAVIGATION_ORBIT;
} else if (nav_scheme == NAVIGATION_MAYA) {
@@ -1452,16 +1602,16 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_PAN;
}
- } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) {
+ } else if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_3_button_mouse")) {
// Handle trackpad (no external mouse) use case
int mod = _get_key_modifier(m);
if (mod) {
- if (mod == _get_key_modifier_setting("editors/3d/pan_modifier"))
+ if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier"))
nav_mode = NAVIGATION_PAN;
- else if (mod == _get_key_modifier_setting("editors/3d/zoom_modifier"))
+ else if (mod == _get_key_modifier_setting("editors/3d/navigation/zoom_modifier"))
nav_mode = NAVIGATION_ZOOM;
- else if (mod == _get_key_modifier_setting("editors/3d/orbit_modifier"))
+ else if (mod == _get_key_modifier_setting("editors/3d/navigation/orbit_modifier"))
nav_mode = NAVIGATION_ORBIT;
}
}
@@ -1494,7 +1644,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (nav_scheme == NAVIGATION_MAYA && m->get_shift())
zoom_speed *= zoom_speed_modifier;
- NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int();
+ NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/navigation/zoom_style").operator int();
if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
if (m->get_relative().x > 0)
scale_cursor_distance(1 - m->get_relative().x * zoom_speed);
@@ -1512,7 +1662,7 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
case NAVIGATION_ORBIT: {
Point2i relative = _get_warped_mouse_motion(m);
- real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/orbit_sensitivity");
+ real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
cursor.x_rot += relative.y * radians_per_pixel;
@@ -1531,9 +1681,12 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (!orthogonal) {
Point2i relative = _get_warped_mouse_motion(m);
- real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/orbit_sensitivity");
+ real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
+ Transform prev_camera_transform = to_camera_transform(cursor);
+
cursor.x_rot += relative.y * radians_per_pixel;
cursor.y_rot += relative.x * radians_per_pixel;
if (cursor.x_rot > Math_PI / 2.0)
@@ -1541,12 +1694,12 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (cursor.x_rot < -Math_PI / 2.0)
cursor.x_rot = -Math_PI / 2.0;
- // Look is like Orbit, except the cursor translates, not the camera
+ // Look is like the opposite of Orbit: the focus point rotates around the camera
Transform camera_transform = to_camera_transform(cursor);
Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
- Vector3 diff = camera->get_translation() - pos;
+ Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = prev_pos - pos;
cursor.pos += diff;
- freelook_target_position += diff;
name = "";
_update_name();
@@ -1644,23 +1797,57 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
+void SpatialEditorViewport::set_freelook_active(bool active_now) {
+
+ if (!freelook_active && active_now) {
+ // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
+ cursor = camera_cursor;
+
+ // Make sure eye_pos is synced, because freelook referential is eye pos rather than orbit pos
+ Vector3 forward = to_camera_transform(cursor).basis.xform(Vector3(0, 0, -1));
+ cursor.eye_pos = cursor.pos - cursor.distance * forward;
+ // Also sync the camera cursor, otherwise switching to freelook will be trippy if inertia is active
+ camera_cursor.eye_pos = cursor.eye_pos;
+
+ if (EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_speed_zoom_link")) {
+ // Re-adjust freelook speed from the current zoom level
+ real_t base_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed");
+ freelook_speed = base_speed * cursor.distance;
+ }
+
+ } else if (freelook_active && !active_now) {
+ // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
+ cursor = camera_cursor;
+ }
+
+ freelook_active = active_now;
+}
+
void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
// Prevents zero distance which would short-circuit any scaling
if (cursor.distance < ZOOM_MIN_DISTANCE)
cursor.distance = ZOOM_MIN_DISTANCE;
- real_t prev_distance = cursor.distance;
cursor.distance *= scale;
if (cursor.distance < ZOOM_MIN_DISTANCE)
cursor.distance = ZOOM_MIN_DISTANCE;
- if (is_freelook_active()) {
- // In freelook mode, cursor reference is reversed so it needs to be adjusted
- Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
- cursor.pos += (cursor.distance - prev_distance) * forward;
- }
+ zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
+ surface->update();
+}
+
+void SpatialEditorViewport::scale_freelook_speed(real_t scale) {
+
+ // Prevents zero distance which would short-circuit any scaling
+ if (freelook_speed < FREELOOK_MIN_SPEED)
+ freelook_speed = FREELOOK_MIN_SPEED;
+
+ freelook_speed *= scale;
+
+ if (freelook_speed < FREELOOK_MIN_SPEED)
+ freelook_speed = FREELOOK_MIN_SPEED;
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
surface->update();
@@ -1668,7 +1855,7 @@ void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
Point2i relative;
- if (bool(EDITOR_DEF("editors/3d/warped_mouse_panning", false))) {
+ if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) {
relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
} else {
relative = p_ev_mouse_motion->get_relative();
@@ -1679,7 +1866,6 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous
void SpatialEditorViewport::_update_freelook(real_t delta) {
if (!is_freelook_active()) {
- freelook_target_position = cursor.pos;
return;
}
@@ -1722,21 +1908,15 @@ void SpatialEditorViewport::_update_freelook(real_t delta) {
speed_modifier = true;
}
- real_t inertia = EDITOR_DEF("editors/3d/freelook_inertia", 0.2);
- inertia = MAX(0, inertia);
- const real_t base_speed = EDITOR_DEF("editors/3d/freelook_base_speed", 0.5);
- const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook_modifier_speed_factor", 5);
-
- real_t speed = base_speed * cursor.distance;
- if (speed_modifier)
+ real_t speed = freelook_speed;
+ if (speed_modifier) {
+ real_t modifier_speed_factor = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_modifier_speed_factor");
speed *= modifier_speed_factor;
+ }
- // Higher inertia should increase "lag" (lerp with factor between 0 and 1)
- // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
-
- freelook_target_position += direction * speed;
- real_t factor = (1.0 / (inertia + 0.001)) * delta;
- cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1));
+ Vector3 motion = direction * speed * delta;
+ cursor.pos += motion;
+ cursor.eye_pos += motion;
}
void SpatialEditorViewport::set_message(String p_message, float p_time) {
@@ -1775,7 +1955,7 @@ void SpatialEditorViewport::_notification(int p_what) {
}
*/
- real_t delta = get_tree()->get_idle_process_time();
+ real_t delta = get_process_delta_time();
if (zoom_indicator_delay > 0) {
zoom_indicator_delay -= delta;
@@ -1786,7 +1966,7 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
- _update_camera(get_process_delta_time());
+ _update_camera(delta);
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -1837,7 +2017,7 @@ void SpatialEditorViewport::_notification(int p_what) {
last_message = message;
}
- message_time -= get_fixed_process_delta_time();
+ message_time -= get_physics_process_delta_time();
if (message_time < 0)
surface->update();
}
@@ -1915,7 +2095,7 @@ void SpatialEditorViewport::_notification(int p_what) {
}
// TODO That should be part of the drawing API...
-static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = 1.0) {
+static void stroke_rect(CanvasItem &ci, Rect2 rect, Color color, real_t width = 1.0) {
// a---b
// | |
@@ -1925,10 +2105,31 @@ static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width =
Vector2 c(rect.position.x, rect.position.y + rect.size.y);
Vector2 d(rect.position + rect.size);
- ci->draw_line(a, b, color, width);
- ci->draw_line(b, d, color, width);
- ci->draw_line(d, c, color, width);
- ci->draw_line(c, a, color, width);
+ ci.draw_line(a, b, color, width);
+ ci.draw_line(b, d, color, width);
+ ci.draw_line(d, c, color, width);
+ ci.draw_line(c, a, color, width);
+}
+
+static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon) {
+
+ // Adjust bar size from control height
+ Vector2 surface_size = surface.get_size();
+ real_t h = surface_size.y / 2.0;
+ real_t y = (surface_size.y - h) / 2.0;
+
+ Rect2 r(10, y, 6, h);
+ real_t sy = r.size.y * fill;
+
+ // Note: because this bar appears over the viewport, it has to stay readable for any background color
+ // Draw both neutral dark and bright colors to account this
+ surface.draw_rect(r, Color(1, 1, 1, 0.2));
+ surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
+ stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+
+ Vector2 icon_size = icon->get_size();
+ Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2);
+ surface.draw_texture(icon, icon_pos);
}
void SpatialEditorViewport::_draw() {
@@ -1987,35 +2188,47 @@ void SpatialEditorViewport::_draw() {
draw_rect = Rect2(Vector2(), s).clip(draw_rect);
- stroke_rect(surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
+ stroke_rect(*surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
} else {
if (zoom_indicator_delay > 0.0) {
- // Show indicative zoom factor
- real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
- real_t max_distance = camera->get_zfar();
- real_t scale_length = (max_distance - min_distance);
+ if (is_freelook_active()) {
+ // Show speed
+
+ real_t min_speed = FREELOOK_MIN_SPEED;
+ real_t max_speed = camera->get_zfar();
+ real_t scale_length = (max_speed - min_speed);
+
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length);
+
+ // There is no real maximum speed so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+
+ draw_indicator_bar(*surface, 1.0 - logscale_t, get_icon("ViewportSpeed", "EditorIcons"));
+ }
- if (Math::abs(scale_length) > CMP_EPSILON) {
- real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
+ } else {
+ // Show zoom
- // There is no real maximum distance so that factor can become negative,
- // Let's make it look asymptotic instead (will decrease slower and slower).
- if (logscale_t < 0.25)
- logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+ real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
+ real_t max_distance = camera->get_zfar();
+ real_t scale_length = (max_distance - min_distance);
- Vector2 surface_size = surface->get_size();
- real_t h = surface_size.y / 2.0;
- real_t y = (surface_size.y - h) / 2.0;
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
- Rect2 r(10, y, 6, h);
- real_t sy = r.size.y * logscale_t;
+ // There is no real maximum distance so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
- surface->draw_rect(r, Color(1, 1, 1, 0.2));
- surface->draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
- stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+ draw_indicator_bar(*surface, logscale_t, get_icon("ViewportZoom", "EditorIcons"));
+ }
}
}
}
@@ -2258,6 +2471,14 @@ void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
//VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
VS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i], layer);
+
+ scale_gizmo_instance[i] = VS::get_singleton()->instance_create();
+ VS::get_singleton()->instance_set_base(scale_gizmo_instance[i], spatial_editor->get_scale_gizmo(i)->get_rid());
+ VS::get_singleton()->instance_set_scenario(scale_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ VS::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
+ //VS::get_singleton()->instance_geometry_set_flag(scale_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
+ VS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_gizmo_instance[i], VS::SHADOW_CASTING_SETTING_OFF);
+ VS::get_singleton()->instance_set_layer_mask(scale_gizmo_instance[i], layer);
}
}
@@ -2267,6 +2488,7 @@ void SpatialEditorViewport::_finish_gizmo_instances() {
VS::get_singleton()->free(move_gizmo_instance[i]);
VS::get_singleton()->free(move_plane_gizmo_instance[i]);
VS::get_singleton()->free(rotate_gizmo_instance[i]);
+ VS::get_singleton()->free(scale_gizmo_instance[i]);
}
}
void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
@@ -2361,14 +2583,16 @@ void SpatialEditorViewport::update_transform_gizmo_view() {
VisualServer::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE));
VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform);
VisualServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE));
+ VisualServer::get_singleton()->instance_set_transform(scale_gizmo_instance[i], xform);
+ VisualServer::get_singleton()->instance_set_visible(scale_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE));
}
}
void SpatialEditorViewport::set_state(const Dictionary &p_state) {
- cursor.pos = p_state["pos"];
- cursor.x_rot = p_state["x_rot"];
- cursor.y_rot = p_state["y_rot"];
+ cursor.pos = p_state["position"];
+ cursor.x_rot = p_state["x_rotation"];
+ cursor.y_rot = p_state["y_rotation"];
cursor.distance = p_state["distance"];
bool env = p_state["use_environment"];
bool orth = p_state["use_orthogonal"];
@@ -2410,9 +2634,9 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
Dictionary SpatialEditorViewport::get_state() const {
Dictionary d;
- d["pos"] = cursor.pos;
- d["x_rot"] = cursor.x_rot;
- d["y_rot"] = cursor.y_rot;
+ d["position"] = cursor.pos;
+ d["x_rotation"] = cursor.x_rot;
+ d["y_rotation"] = cursor.y_rot;
d["distance"] = cursor.distance;
d["use_environment"] = camera->get_environment().is_valid();
d["use_orthogonal"] = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;
@@ -2454,6 +2678,7 @@ void SpatialEditorViewport::reset() {
cursor.y_rot = 0.5;
cursor.distance = 4;
cursor.region_select = false;
+ cursor.pos = Vector3();
_update_name();
}
@@ -2540,8 +2765,14 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
normal = hit_normal;
}
}
- Vector3 center = preview_bounds->get_size() * 0.5;
- return point + (center * normal);
+ Vector3 offset = Vector3();
+ for (int i = 0; i < 3; i++) {
+ if (normal[i] > 0.0)
+ offset[i] = (preview_bounds->get_size()[i] - (preview_bounds->get_size()[i] + preview_bounds->get_position()[i]));
+ else if (normal[i] < 0.0)
+ offset[i] = -(preview_bounds->get_size()[i] + preview_bounds->get_position()[i]);
+ }
+ return point + offset;
}
Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) {
@@ -2829,7 +3060,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
ViewportContainer *c = memnew(ViewportContainer);
c->set_stretch(true);
add_child(c);
- c->set_area_as_parent_rect();
+ c->set_anchors_and_margins_preset(Control::PRESET_WIDE);
viewport = memnew(Viewport);
viewport->set_disable_input(true);
@@ -2837,7 +3068,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface = memnew(Control);
surface->set_drag_forwarding(this);
add_child(surface);
- surface->set_area_as_parent_rect();
+ surface->set_anchors_and_margins_preset(Control::PRESET_WIDE);
surface->set_clip_contents(true);
camera = memnew(Camera);
camera->set_disable_gizmo(true);
@@ -2914,6 +3145,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
accept = NULL;
freelook_active = false;
+ freelook_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed");
selection_menu = memnew(PopupMenu);
add_child(selection_menu);
@@ -3246,6 +3478,7 @@ void SpatialEditor::select_gizmo_highlight_axis(int p_axis) {
move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_hl : gizmo_color[i]);
move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? gizmo_hl : plane_gizmo_color[i]);
rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_hl : gizmo_color[i]);
+ scale_gizmo[i]->surface_set_material(0, (i + 9) == p_axis ? gizmo_hl : gizmo_color[i]);
}
}
@@ -3256,7 +3489,7 @@ void SpatialEditor::update_transform_gizmo() {
bool first = true;
Basis gizmo_basis;
- bool local_gizmo_coords = transform_menu->get_popup()->is_item_checked(transform_menu->get_popup()->get_item_index(MENU_TRANSFORM_LOCAL_COORDS));
+ bool local_gizmo_coords = are_local_coords_enabled();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
@@ -3707,20 +3940,13 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
void SpatialEditor::_init_indicators() {
- //RID mat = VisualServer::get_singleton()->fixed_material_create();
- ///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
- //VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
-
{
indicator_mat.instance();
indicator_mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- //indicator_mat->set_flag(SpatialMaterial::FLAG_ONTOP,true);
indicator_mat->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
indicator_mat->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- indicator_mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
-
PoolVector<Color> grid_colors[3];
PoolVector<Vector3> grid_points[3];
Vector<Color> origin_colors;
@@ -3740,50 +3966,31 @@ void SpatialEditor::_init_indicators() {
origin_colors.push_back(Color(axis.x, axis.y, axis.z));
origin_points.push_back(axis * 4096);
origin_points.push_back(axis * -4096);
-#define ORIGIN_GRID_SIZE 100
+#define ORIGIN_GRID_SIZE 50
for (int j = -ORIGIN_GRID_SIZE; j <= ORIGIN_GRID_SIZE; j++) {
- for (int k = -ORIGIN_GRID_SIZE; k <= ORIGIN_GRID_SIZE; k++) {
-
- Vector3 p = axis_n1 * j + axis_n2 * k;
- float trans = Math::pow(MAX(0, 1.0 - (Vector2(j, k).length() / ORIGIN_GRID_SIZE)), 2);
-
- Vector3 pj = axis_n1 * (j + 1) + axis_n2 * k;
- float transj = Math::pow(MAX(0, 1.0 - (Vector2(j + 1, k).length() / ORIGIN_GRID_SIZE)), 2);
-
- Vector3 pk = axis_n1 * j + axis_n2 * (k + 1);
- float transk = Math::pow(MAX(0, 1.0 - (Vector2(j, k + 1).length() / ORIGIN_GRID_SIZE)), 2);
+ Vector3 p1 = axis_n1 * j + axis_n2 * -ORIGIN_GRID_SIZE;
+ Vector3 p1_dest = p1 * (-axis_n2 + axis_n1);
+ Vector3 p2 = axis_n2 * j + axis_n1 * -ORIGIN_GRID_SIZE;
+ Vector3 p2_dest = p2 * (-axis_n1 + axis_n2);
- Color trans_color = grid_color;
- trans_color.a *= trans;
-
- Color transk_color = grid_color;
- transk_color.a *= transk;
-
- Color transj_color = grid_color;
- transj_color.a *= transj;
-
- if (j % 10 == 0 || k % 10 == 0) {
- trans_color.a *= 2;
- }
- if ((k + 1) % 10 == 0) {
- transk_color.a *= 2;
- }
- if ((j + 1) % 10 == 0) {
- transj_color.a *= 2;
- }
+ Color line_color = grid_color;
+ if (j == 0) {
+ continue;
+ } else if (j % 10 == 0) {
+ line_color *= 1.5;
+ }
- grid_points[i].push_back(p);
- grid_points[i].push_back(pk);
- grid_colors[i].push_back(trans_color);
- grid_colors[i].push_back(transk_color);
+ grid_points[i].push_back(p1);
+ grid_points[i].push_back(p1_dest);
+ grid_colors[i].push_back(line_color);
+ grid_colors[i].push_back(line_color);
- grid_points[i].push_back(p);
- grid_points[i].push_back(pj);
- grid_colors[i].push_back(trans_color);
- grid_colors[i].push_back(transj_color);
- }
+ grid_points[i].push_back(p2);
+ grid_points[i].push_back(p2_dest);
+ grid_colors[i].push_back(line_color);
+ grid_colors[i].push_back(line_color);
}
grid[i] = VisualServer::get_singleton()->mesh_create();
@@ -3827,32 +4034,6 @@ void SpatialEditor::_init_indicators() {
}
{
- cursor_mesh = VisualServer::get_singleton()->mesh_create();
- PoolVector<Vector3> cursor_points;
- float cs = 0.25;
- cursor_points.push_back(Vector3(+cs, 0, 0));
- cursor_points.push_back(Vector3(-cs, 0, 0));
- cursor_points.push_back(Vector3(0, +cs, 0));
- cursor_points.push_back(Vector3(0, -cs, 0));
- cursor_points.push_back(Vector3(0, 0, +cs));
- cursor_points.push_back(Vector3(0, 0, -cs));
- cursor_material.instance();
- cursor_material->set_albedo(Color(0, 1, 1));
- cursor_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
-
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[VS::ARRAY_VERTEX] = cursor_points;
- VisualServer::get_singleton()->mesh_add_surface_from_arrays(cursor_mesh, VS::PRIMITIVE_LINES, d);
- VisualServer::get_singleton()->mesh_surface_set_material(cursor_mesh, 0, cursor_material->get_rid());
-
- cursor_instance = VisualServer::get_singleton()->instance_create2(cursor_mesh, get_tree()->get_root()->get_world()->get_scenario());
- VS::get_singleton()->instance_set_layer_mask(cursor_instance, 1 << SpatialEditorViewport::GIZMO_GRID_LAYER);
-
- VisualServer::get_singleton()->instance_geometry_set_cast_shadows_setting(cursor_instance, VS::SHADOW_CASTING_SETTING_OFF);
- }
-
- {
//move gizmo
@@ -3870,6 +4051,7 @@ void SpatialEditor::_init_indicators() {
move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
move_plane_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ scale_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
@@ -3892,25 +4074,25 @@ void SpatialEditor::_init_indicators() {
Vector3 ivec3;
ivec3[(i + 2) % 3] = 1;
+ //translate
{
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
- //translate
-
+ // Arrow profile
const int arrow_points = 5;
Vector3 arrow[5] = {
nivec * 0.0 + ivec * 0.0,
nivec * 0.01 + ivec * 0.0,
- nivec * 0.01 + ivec * 1.0,
- nivec * 0.1 + ivec * 1.0,
- nivec * 0.0 + ivec * (1 + GIZMO_ARROW_SIZE),
+ nivec * 0.01 + ivec * GIZMO_ARROW_OFFSET,
+ nivec * 0.065 + ivec * GIZMO_ARROW_OFFSET,
+ nivec * 0.0 + ivec * (GIZMO_ARROW_OFFSET + GIZMO_ARROW_SIZE),
};
int arrow_sides = 6;
- for (int k = 0; k < 7; k++) {
+ for (int k = 0; k < 6; k++) {
Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
@@ -3937,7 +4119,7 @@ void SpatialEditor::_init_indicators() {
surftool->commit(move_gizmo[i]);
}
- // plane translation
+ // Plane Translation
{
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
@@ -3980,6 +4162,7 @@ void SpatialEditor::_init_indicators() {
surftool->commit(move_plane_gizmo[i]);
}
+ // Rotate
{
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
@@ -3993,7 +4176,7 @@ void SpatialEditor::_init_indicators() {
ivec * 0.02 + ivec2 * 0.02 + ivec2 * GIZMO_CIRCLE_SIZE,
};
- for (int k = 0; k < 33; k++) {
+ for (int k = 0; k < 32; k++) {
Basis ma(ivec, Math_PI * 2 * float(k) / 32);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / 32);
@@ -4019,19 +4202,55 @@ void SpatialEditor::_init_indicators() {
surftool->set_material(mat);
surftool->commit(rotate_gizmo[i]);
}
- }
- }
- /*for(int i=0;i<4;i++) {
+ // Scale
+ {
+ Ref<SurfaceTool> surftool = memnew(SurfaceTool);
+ surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
- viewports[i]->init_gizmo_instance(i);
- }*/
+ // Cube arrow profile
+ const int arrow_points = 6;
+ Vector3 arrow[6] = {
+ nivec * 0.0 + ivec * 0.0,
+ nivec * 0.01 + ivec * 0.0,
+ nivec * 0.01 + ivec * 1.0 * GIZMO_SCALE_OFFSET,
+ nivec * 0.07 + ivec * 1.0 * GIZMO_SCALE_OFFSET,
+ nivec * 0.07 + ivec * 1.11 * GIZMO_SCALE_OFFSET,
+ nivec * 0.0 + ivec * 1.11 * GIZMO_SCALE_OFFSET,
+ };
- _generate_selection_box();
+ int arrow_sides = 4;
+
+ for (int k = 0; k < 4; k++) {
+
+ Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
+ Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
- //Object::cast_to<EditorNode>(get_scene()->get_root_node())->get_scene_root()->add_child(camera);
+ for (int j = 0; j < arrow_points - 1; j++) {
- //current_camera=camera;
+ Vector3 points[4] = {
+ ma.xform(arrow[j]),
+ mb.xform(arrow[j]),
+ mb.xform(arrow[j + 1]),
+ ma.xform(arrow[j + 1]),
+ };
+ surftool->add_vertex(points[0]);
+ surftool->add_vertex(points[1]);
+ surftool->add_vertex(points[2]);
+
+ surftool->add_vertex(points[0]);
+ surftool->add_vertex(points[2]);
+ surftool->add_vertex(points[3]);
+ }
+ }
+
+ surftool->set_material(mat);
+ surftool->commit(scale_gizmo[i]);
+ }
+ }
+ }
+
+ _generate_selection_box();
}
void SpatialEditor::_finish_indicators() {
@@ -4045,9 +4264,6 @@ void SpatialEditor::_finish_indicators() {
//VisualServer::get_singleton()->free(poly);
//VisualServer::get_singleton()->free(indicators_instance);
//VisualServer::get_singleton()->free(indicators);
-
- VisualServer::get_singleton()->free(cursor_instance);
- VisualServer::get_singleton()->free(cursor_mesh);
}
bool SpatialEditor::is_any_freelook_active() const {
@@ -4209,7 +4425,7 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
if (i == (uint32_t)index)
- viewports[i]->set_area_as_parent_rect();
+ viewports[i]->set_anchors_and_margins_preset(Control::PRESET_WIDE);
else
viewports[i]->hide();
}
@@ -4644,7 +4860,7 @@ SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
editor->get_viewport()->add_child(spatial_editor);
- //spatial_editor->set_area_as_parent_rect();
+ //spatial_editor->set_anchors_and_margins_preset(Control::PRESET_WIDE);
spatial_editor->hide();
spatial_editor->connect("transform_key_request", editor, "_transform_keyed");