[Bf-blender-cvs] [b789d2a2f41] lineart-shadow: Walk Navigation: Z axis correction

Dalai Felinto noreply at git.blender.org
Tue Jul 13 10:45:56 CEST 2021


Commit: b789d2a2f41caca5c91b1e25c525e3a98fe6ac3a
Author: Dalai Felinto
Date:   Fri Jul 9 10:59:18 2021 +0200
Branches: lineart-shadow
https://developer.blender.org/rBb789d2a2f41caca5c91b1e25c525e3a98fe6ac3a

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

===================================================================

M	release/scripts/presets/keyconfig/keymap_data/blender_default.py
M	source/blender/editors/space_view3d/view3d_navigate_walk.c

===================================================================

diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 4319e3a962b..0af7493ed47 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -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
diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c
index 5cd11b5d7c0..09936b41a74 100644
--- a/source/blender/editors/space_view3d/view3d_navigate_walk.c
+++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c
@@ -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);



More information about the Bf-blender-cvs mailing list