Walk Navigation: Z axis correction
Fly navigation has always had this option. They is particularly useful when users use "Trackball" as their orbit method. For walk navigation this works as a one off option. Not as a toggle like for fly navigation. Differential Revision: https://developer.blender.org/D11863
This commit is contained in:
parent
c04cceb40e
commit
c749c24682
|
@ -5551,6 +5551,7 @@ def km_view3d_walk_modal(_params):
|
|||
("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True, "repeat": True}, None),
|
||||
("ACCELERATE", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "any": True}, None),
|
||||
("DECELERATE", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "any": True}, None),
|
||||
("AXIS_LOCK_Z", {"type": 'Z', "value": 'PRESS'}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
|
|
@ -101,6 +101,7 @@ enum {
|
|||
WALK_MODAL_GRAVITY_TOGGLE,
|
||||
WALK_MODAL_ACCELERATE,
|
||||
WALK_MODAL_DECELERATE,
|
||||
WALK_MODAL_AXIS_LOCK_Z,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -129,6 +130,18 @@ typedef enum eWalkGravityState {
|
|||
WALK_GRAVITY_STATE_ON,
|
||||
} eWalkGravityState;
|
||||
|
||||
/* Relative view axis z axis locking. */
|
||||
typedef enum eWalkLockState {
|
||||
/* Disabled. */
|
||||
WALK_AXISLOCK_STATE_OFF = 0,
|
||||
|
||||
/* Moving. */
|
||||
WALK_AXISLOCK_STATE_ACTIVE = 2,
|
||||
|
||||
/* Done moving, it cannot be activated again. */
|
||||
WALK_AXISLOCK_STATE_DONE = 3,
|
||||
} eWalkLockState;
|
||||
|
||||
/* Called in transform_ops.c, on each regeneration of key-maps. */
|
||||
void walk_modal_keymap(wmKeyConfig *keyconf)
|
||||
{
|
||||
|
@ -166,6 +179,8 @@ void walk_modal_keymap(wmKeyConfig *keyconf)
|
|||
|
||||
{WALK_MODAL_GRAVITY_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
|
||||
|
||||
{WALK_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction"},
|
||||
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -292,6 +307,10 @@ typedef struct WalkInfo {
|
|||
/** To use for fast/slow speeds. */
|
||||
float speed_factor;
|
||||
|
||||
eWalkLockState zlock;
|
||||
/** Nicer dynamics. */
|
||||
float zlock_momentum;
|
||||
|
||||
struct SnapObjectContext *snap_context;
|
||||
|
||||
struct View3DCameraControl *v3d_camera_control;
|
||||
|
@ -540,6 +559,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
|
|||
walk->jump_height = U.walk_navigation.jump_height;
|
||||
walk->speed = U.walk_navigation.walk_speed;
|
||||
walk->speed_factor = U.walk_navigation.walk_speed_factor;
|
||||
walk->zlock = WALK_AXISLOCK_STATE_OFF;
|
||||
|
||||
walk->gravity_state = WALK_GRAVITY_STATE_OFF;
|
||||
|
||||
|
@ -947,6 +967,13 @@ static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
|
|||
walk_navigation_mode_set(walk, WALK_MODE_GRAVITY);
|
||||
}
|
||||
break;
|
||||
|
||||
case WALK_MODAL_AXIS_LOCK_Z:
|
||||
if (walk->zlock != WALK_AXISLOCK_STATE_DONE) {
|
||||
walk->zlock = WALK_AXISLOCK_STATE_ACTIVE;
|
||||
walk->zlock_momentum = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -986,6 +1013,8 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
|
|||
#define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f)
|
||||
#define WALK_MOVE_SPEED base_speed
|
||||
#define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
|
||||
#define WALK_ZUP_CORRECT_FAC 0.1f /* Amount to correct per step. */
|
||||
#define WALK_ZUP_CORRECT_ACCEL 0.05f /* Increase upright momentum each step. */
|
||||
|
||||
RegionView3D *rv3d = walk->rv3d;
|
||||
ARegion *region = walk->region;
|
||||
|
@ -1020,20 +1049,25 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
|
|||
|
||||
/* Should we redraw? */
|
||||
if ((walk->active_directions) || moffset[0] || moffset[1] ||
|
||||
walk->teleport.state == WALK_TELEPORT_STATE_ON ||
|
||||
walk->gravity_state != WALK_GRAVITY_STATE_OFF || is_confirm) {
|
||||
walk->zlock == WALK_AXISLOCK_STATE_ACTIVE ||
|
||||
walk->gravity_state != WALK_GRAVITY_STATE_OFF ||
|
||||
walk->teleport.state == WALK_TELEPORT_STATE_ON || is_confirm) {
|
||||
float dvec_tmp[3];
|
||||
|
||||
/* time how fast it takes for us to redraw,
|
||||
* this is so simple scenes don't walk too fast */
|
||||
double time_current;
|
||||
float time_redraw;
|
||||
float time_redraw_clamped;
|
||||
#ifdef NDOF_WALK_DRAW_TOOMUCH
|
||||
walk->redraw = 1;
|
||||
#endif
|
||||
time_current = PIL_check_seconds_timer();
|
||||
time_redraw = (float)(time_current - walk->time_lastdraw);
|
||||
|
||||
/* Clamp redraw time to avoid jitter in roll correction. */
|
||||
time_redraw_clamped = min_ff(0.05f, time_redraw);
|
||||
|
||||
walk->time_lastdraw = time_current;
|
||||
|
||||
/* base speed in m/s */
|
||||
|
@ -1126,6 +1160,32 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
|
|||
axis_angle_to_quat_single(tmp_quat, 'Z', x);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
||||
}
|
||||
|
||||
if (walk->zlock == WALK_AXISLOCK_STATE_ACTIVE) {
|
||||
float upvec[3];
|
||||
copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
|
||||
mul_m3_v3(mat, upvec);
|
||||
|
||||
/* Make sure we have some z rolling. */
|
||||
if (fabsf(upvec[2]) > 0.00001f) {
|
||||
float roll = upvec[2] * 5.0f;
|
||||
/* Rotate the view about this axis. */
|
||||
copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
|
||||
mul_m3_v3(mat, upvec);
|
||||
/* Rotate about the relative up vec. */
|
||||
axis_angle_to_quat(tmp_quat,
|
||||
upvec,
|
||||
roll * time_redraw_clamped * walk->zlock_momentum *
|
||||
WALK_ZUP_CORRECT_FAC);
|
||||
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
|
||||
|
||||
walk->zlock_momentum += WALK_ZUP_CORRECT_ACCEL;
|
||||
}
|
||||
else {
|
||||
/* Lock fixed, don't need to check it ever again. */
|
||||
walk->zlock = WALK_AXISLOCK_STATE_DONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* WASD - 'move' translation code */
|
||||
|
@ -1316,7 +1376,8 @@ static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
|
|||
add_v3_v3(rv3d->ofs, dvec_tmp);
|
||||
|
||||
if (rv3d->persp == RV3D_CAMOB) {
|
||||
walk->need_rotation_keyframe |= (moffset[0] || moffset[1]);
|
||||
walk->need_rotation_keyframe |= (moffset[0] || moffset[1] ||
|
||||
walk->zlock == WALK_AXISLOCK_STATE_ACTIVE);
|
||||
walk->need_translation_keyframe |= (len_squared_v3(dvec_tmp) > FLT_EPSILON);
|
||||
walkMoveCamera(
|
||||
C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
|
||||
|
|
Loading…
Reference in New Issue