Limit the zoom and freelook speed based on camera settings
This commit is contained in:
parent
ba51af7904
commit
896a297c1f
1 changed files with 27 additions and 42 deletions
|
@ -63,12 +63,15 @@
|
||||||
#define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
|
#define GIZMO_SCALE_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
|
||||||
#define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
|
#define GIZMO_ARROW_OFFSET (GIZMO_CIRCLE_SIZE + 0.3)
|
||||||
|
|
||||||
#define ZOOM_MIN_DISTANCE 0.001
|
#define ZOOM_FREELOOK_MIN 0.01
|
||||||
#define ZOOM_MULTIPLIER 1.08
|
#define ZOOM_FREELOOK_MULTIPLIER 1.08
|
||||||
#define ZOOM_INDICATOR_DELAY_S 1.5
|
#define ZOOM_FREELOOK_INDICATOR_DELAY_S 1.5
|
||||||
|
|
||||||
#define FREELOOK_MIN_SPEED 0.01
|
#ifdef REAL_T_IS_DOUBLE
|
||||||
#define FREELOOK_SPEED_MULTIPLIER 1.08
|
#define ZOOM_FREELOOK_MAX 1'000'000'000'000
|
||||||
|
#else
|
||||||
|
#define ZOOM_FREELOOK_MAX 10'000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MIN_Z 0.01
|
#define MIN_Z 0.01
|
||||||
#define MAX_Z 1000000.0
|
#define MAX_Z 1000000.0
|
||||||
|
@ -1117,7 +1120,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
|
||||||
if (b.is_valid()) {
|
if (b.is_valid()) {
|
||||||
emit_signal("clicked", this);
|
emit_signal("clicked", this);
|
||||||
|
|
||||||
float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor();
|
float zoom_factor = 1 + (ZOOM_FREELOOK_MULTIPLIER - 1) * b->get_factor();
|
||||||
switch (b->get_button_index()) {
|
switch (b->get_button_index()) {
|
||||||
case BUTTON_WHEEL_UP: {
|
case BUTTON_WHEEL_UP: {
|
||||||
if (is_freelook_active()) {
|
if (is_freelook_active()) {
|
||||||
|
@ -2207,34 +2210,28 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
|
void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
|
||||||
// Prevents zero distance which would short-circuit any scaling
|
real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
|
||||||
if (cursor.distance < ZOOM_MIN_DISTANCE) {
|
real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
|
||||||
cursor.distance = ZOOM_MIN_DISTANCE;
|
if (unlikely(min_distance > max_distance)) {
|
||||||
|
cursor.distance = (min_distance + max_distance) / 2;
|
||||||
|
} else {
|
||||||
|
cursor.distance = CLAMP(cursor.distance * scale, min_distance, max_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.distance *= scale;
|
zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S;
|
||||||
|
|
||||||
if (cursor.distance < ZOOM_MIN_DISTANCE) {
|
|
||||||
cursor.distance = ZOOM_MIN_DISTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
|
|
||||||
surface->update();
|
surface->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
|
void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
|
||||||
// Prevents zero distance which would short-circuit any scaling
|
real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
|
||||||
if (freelook_speed < FREELOOK_MIN_SPEED) {
|
real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
|
||||||
freelook_speed = FREELOOK_MIN_SPEED;
|
if (unlikely(min_speed > max_speed)) {
|
||||||
|
freelook_speed = (min_speed + max_speed) / 2;
|
||||||
|
} else {
|
||||||
|
freelook_speed = CLAMP(freelook_speed * scale, min_speed, max_speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
freelook_speed *= scale;
|
zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S;
|
||||||
|
|
||||||
if (freelook_speed < FREELOOK_MIN_SPEED) {
|
|
||||||
freelook_speed = FREELOOK_MIN_SPEED;
|
|
||||||
}
|
|
||||||
|
|
||||||
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
|
|
||||||
surface->update();
|
surface->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2698,19 +2695,13 @@ void Node3DEditorViewport::_draw() {
|
||||||
if (is_freelook_active()) {
|
if (is_freelook_active()) {
|
||||||
// Show speed
|
// Show speed
|
||||||
|
|
||||||
real_t min_speed = FREELOOK_MIN_SPEED;
|
real_t min_speed = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
|
||||||
real_t max_speed = camera->get_zfar();
|
real_t max_speed = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
|
||||||
real_t scale_length = (max_speed - min_speed);
|
real_t scale_length = (max_speed - min_speed);
|
||||||
|
|
||||||
if (!Math::is_zero_approx(scale_length)) {
|
if (!Math::is_zero_approx(scale_length)) {
|
||||||
real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length);
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the freelook speed to help the user get a better sense of scale.
|
// Display the freelook speed to help the user get a better sense of scale.
|
||||||
const int precision = freelook_speed < 1.0 ? 2 : 1;
|
const int precision = freelook_speed < 1.0 ? 2 : 1;
|
||||||
draw_indicator_bar(
|
draw_indicator_bar(
|
||||||
|
@ -2725,19 +2716,13 @@ void Node3DEditorViewport::_draw() {
|
||||||
} else {
|
} else {
|
||||||
// Show zoom
|
// Show zoom
|
||||||
|
|
||||||
real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
|
real_t min_distance = MAX(camera->get_znear() * 4, ZOOM_FREELOOK_MIN);
|
||||||
real_t max_distance = camera->get_zfar();
|
real_t max_distance = MIN(camera->get_zfar() / 4, ZOOM_FREELOOK_MAX);
|
||||||
real_t scale_length = (max_distance - min_distance);
|
real_t scale_length = (max_distance - min_distance);
|
||||||
|
|
||||||
if (!Math::is_zero_approx(scale_length)) {
|
if (!Math::is_zero_approx(scale_length)) {
|
||||||
real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
|
real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Display the zoom center distance to help the user get a better sense of scale.
|
// Display the zoom center distance to help the user get a better sense of scale.
|
||||||
const int precision = cursor.distance < 1.0 ? 2 : 1;
|
const int precision = cursor.distance < 1.0 ? 2 : 1;
|
||||||
draw_indicator_bar(
|
draw_indicator_bar(
|
||||||
|
|
Loading…
Reference in a new issue