Blender  V3.3
view3d_navigate_walk.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
12 /* defines VIEW3D_OT_navigate - walk modal operator */
13 
14 #include "DNA_object_types.h"
15 #include "DNA_scene_types.h"
16 
17 #include "MEM_guardedalloc.h"
18 
19 #include "BLI_blenlib.h"
20 #include "BLI_kdopbvh.h"
21 #include "BLI_math.h"
22 #include "BLI_utildefines.h"
23 
24 #include "BKE_context.h"
25 #include "BKE_lib_id.h"
26 #include "BKE_main.h"
27 #include "BKE_report.h"
28 
29 #include "BLT_translation.h"
30 
31 #include "WM_api.h"
32 #include "WM_types.h"
33 
34 #include "ED_screen.h"
35 #include "ED_space_api.h"
37 
38 #include "PIL_time.h" /* Smooth-view. */
39 
40 #include "UI_interface.h"
41 #include "UI_resources.h"
42 
43 #include "GPU_immediate.h"
44 
45 #include "DEG_depsgraph.h"
46 
47 #include "view3d_intern.h" /* own include */
48 #include "view3d_navigate.h"
49 
50 #ifdef WITH_INPUT_NDOF
51 //# define NDOF_WALK_DEBUG
52 /* is this needed for ndof? - commented so redraw doesn't thrash - campbell */
53 //# define NDOF_WALK_DRAW_TOOMUCH
54 #endif
55 
56 #define USE_TABLET_SUPPORT
57 
58 /* -------------------------------------------------------------------- */
62 /* NOTE: these defines are saved in keymap files,
63  * do not change values but just add new ones */
64 enum {
90 };
91 
92 enum {
93  WALK_BIT_FORWARD = 1 << 0,
95  WALK_BIT_LEFT = 1 << 2,
96  WALK_BIT_RIGHT = 1 << 3,
97  WALK_BIT_UP = 1 << 4,
98  WALK_BIT_DOWN = 1 << 5,
99 };
100 
101 typedef enum eWalkTeleportState {
105 
106 typedef enum eWalkMethod {
110 
111 typedef enum eWalkGravityState {
117 
118 /* Relative view axis z axis locking. */
119 typedef enum eWalkLockState {
120  /* Disabled. */
122 
123  /* Moving. */
125 
126  /* Done moving, it cannot be activated again. */
129 
131 {
132  static const EnumPropertyItem modal_items[] = {
133  {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
134  {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
135 
136  {WALK_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
137  {WALK_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
138  {WALK_MODAL_DIR_LEFT, "LEFT", 0, "Left", ""},
139  {WALK_MODAL_DIR_RIGHT, "RIGHT", 0, "Right", ""},
140  {WALK_MODAL_DIR_UP, "UP", 0, "Up", ""},
141  {WALK_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
142 
143  {WALK_MODAL_DIR_FORWARD_STOP, "FORWARD_STOP", 0, "Stop Move Forward", ""},
144  {WALK_MODAL_DIR_BACKWARD_STOP, "BACKWARD_STOP", 0, "Stop Mode Backward", ""},
145  {WALK_MODAL_DIR_LEFT_STOP, "LEFT_STOP", 0, "Stop Move Left", ""},
146  {WALK_MODAL_DIR_RIGHT_STOP, "RIGHT_STOP", 0, "Stop Mode Right", ""},
147  {WALK_MODAL_DIR_UP_STOP, "UP_STOP", 0, "Stop Move Up", ""},
148  {WALK_MODAL_DIR_DOWN_STOP, "DOWN_STOP", 0, "Stop Mode Down", ""},
149 
150  {WALK_MODAL_TELEPORT, "TELEPORT", 0, "Teleport", "Move forward a few units at once"},
151 
152  {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
153  {WALK_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
154 
155  {WALK_MODAL_FAST_ENABLE, "FAST_ENABLE", 0, "Fast", "Move faster (walk or fly)"},
156  {WALK_MODAL_FAST_DISABLE, "FAST_DISABLE", 0, "Fast (Off)", "Resume regular speed"},
157 
158  {WALK_MODAL_SLOW_ENABLE, "SLOW_ENABLE", 0, "Slow", "Move slower (walk or fly)"},
159  {WALK_MODAL_SLOW_DISABLE, "SLOW_DISABLE", 0, "Slow (Off)", "Resume regular speed"},
160 
161  {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
162  {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"},
163 
164  {WALK_MODAL_GRAVITY_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
165 
166  {WALK_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "Z Axis Correction", "Z axis correction"},
167 
168  {0, NULL, 0, NULL, NULL},
169  };
170 
171  wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Walk Modal");
172 
173  /* this function is called for each spacetype, only needs to add map once */
174  if (keymap && keymap->modal_items) {
175  return;
176  }
177 
178  keymap = WM_modalkeymap_ensure(keyconf, "View3D Walk Modal", modal_items);
179 
180  /* assign map to operators */
181  WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
182 }
183 
186 /* -------------------------------------------------------------------- */
190 typedef struct WalkTeleport {
192  float duration; /* from user preferences */
193  float origin[3];
194  float direction[3];
195  double initial_time;
196  eWalkMethod navigation_mode; /* teleport always set FREE mode on */
197 
199 
200 typedef struct WalkInfo {
201  /* context stuff */
207 
210 
211  short state;
212  bool redraw;
213 
223 
225  int prev_mval[2];
227  int init_mval[2];
228 
229  int moffset[2];
230 
231 #ifdef WITH_INPUT_NDOF
233  wmNDOFMotionData *ndof;
234 #endif
235 
236  /* Walk state. */
238  float base_speed;
240  float speed;
242  float grid;
243 
244  /* compare between last state */
247 
249 
250  /* use for some lag */
252  float dvec_prev[3];
253 
256 
257  /* teleport */
259 
261  float mouse_speed;
262 
264  bool is_fast;
265  bool is_slow;
266 
269 
270 #ifdef USE_TABLET_SUPPORT
273 #endif
274 
277  float gravity;
278 
280  float view_height;
281 
284 
285  float speed_jump;
287  float jump_height;
290 
294 
296 
298 
300 
303 /* -------------------------------------------------------------------- */
307 /* prototypes */
308 #ifdef WITH_INPUT_NDOF
309 static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm);
310 #endif /* WITH_INPUT_NDOF */
311 static int walkApply(bContext *C, struct WalkInfo *walk, bool is_confirm);
312 static float getVelocityZeroTime(const float gravity, const float velocity);
313 
314 static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *region, void *arg)
315 {
316  /* draws an aim/cross in the center */
317  WalkInfo *walk = arg;
318 
319  const int outter_length = 24;
320  const int inner_length = 14;
321  int xoff, yoff;
322  rctf viewborder;
323 
326  walk->scene, walk->depsgraph, region, walk->v3d, walk->rv3d, &viewborder, false);
327  xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f;
328  yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f;
329  }
330  else {
331  xoff = walk->region->winx / 2;
332  yoff = walk->region->winy / 2;
333  }
334 
337 
339 
341 
343 
344  /* North */
345  immVertex2i(pos, xoff, yoff + inner_length);
346  immVertex2i(pos, xoff, yoff + outter_length);
347 
348  /* East */
349  immVertex2i(pos, xoff + inner_length, yoff);
350  immVertex2i(pos, xoff + outter_length, yoff);
351 
352  /* South */
353  immVertex2i(pos, xoff, yoff - inner_length);
354  immVertex2i(pos, xoff, yoff - outter_length);
355 
356  /* West */
357  immVertex2i(pos, xoff - inner_length, yoff);
358  immVertex2i(pos, xoff - outter_length, yoff);
359 
360  immEnd();
362 }
363 
366 /* -------------------------------------------------------------------- */
371 {
372  if (mode == WALK_MODE_FREE) {
375  }
376  else { /* WALK_MODE_GRAVITY */
379  }
380 }
381 
386  WalkInfo *walk,
387  const float dvec[3],
388  float *r_distance)
389 {
390  const float ray_normal[3] = {0, 0, -1}; /* down */
391  float ray_start[3];
392  float r_location[3];
393  float r_normal_dummy[3];
394  float dvec_tmp[3];
395  bool ret;
396 
397  *r_distance = BVH_RAYCAST_DIST_MAX;
398 
399  copy_v3_v3(ray_start, rv3d->viewinv[3]);
400 
401  mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
402  add_v3_v3(ray_start, dvec_tmp);
403 
405  walk->snap_context,
406  walk->depsgraph,
407  walk->v3d,
408  &(const struct SnapObjectParams){
409  .snap_target_select = SCE_SNAP_TARGET_ALL,
410  /* Avoid having to convert the edit-mesh to a regular mesh. */
411  .edit_mode_type = SNAP_GEOM_EDIT,
412  },
413  ray_start,
414  ray_normal,
415  r_distance,
416  r_location,
417  r_normal_dummy);
418 
419  /* artificially scale the distance to the scene size */
420  *r_distance /= walk->grid;
421  return ret;
422 }
423 
429 static bool walk_ray_cast(RegionView3D *rv3d,
430  WalkInfo *walk,
431  float r_location[3],
432  float r_normal[3],
433  float *ray_distance)
434 {
435  float ray_normal[3] = {0, 0, -1}; /* forward */
436  float ray_start[3];
437  bool ret;
438 
439  *ray_distance = BVH_RAYCAST_DIST_MAX;
440 
441  copy_v3_v3(ray_start, rv3d->viewinv[3]);
442 
443  mul_mat3_m4_v3(rv3d->viewinv, ray_normal);
444 
445  normalize_v3(ray_normal);
446 
448  walk->depsgraph,
449  walk->v3d,
450  &(const struct SnapObjectParams){
451  .snap_target_select = SCE_SNAP_TARGET_ALL,
452  },
453  ray_start,
454  ray_normal,
455  NULL,
456  r_location,
457  r_normal);
458 
459  /* dot is positive if both rays are facing the same direction */
460  if (dot_v3v3(ray_normal, r_normal) > 0) {
461  negate_v3(r_normal);
462  }
463 
464  /* artificially scale the distance to the scene size */
465  *ray_distance /= walk->grid;
466 
467  return ret;
468 }
469 
470 /* WalkInfo->state */
471 enum {
475 };
476 
477 /* keep the previous speed until user changes userpreferences */
478 static float base_speed = -1.0f;
479 static float userdef_speed = -1.0f;
480 
481 static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int mval[2])
482 {
484  wmWindow *win = CTX_wm_window(C);
485 
486  walk->rv3d = CTX_wm_region_view3d(C);
487  walk->v3d = CTX_wm_view3d(C);
488  walk->region = CTX_wm_region(C);
490  walk->scene = CTX_data_scene(C);
491 
492 #ifdef NDOF_WALK_DEBUG
493  puts("\n-- walk begin --");
494 #endif
495 
496  /* sanity check: for rare but possible case (if lib-linking the camera fails) */
497  if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) {
498  walk->rv3d->persp = RV3D_PERSP;
499  }
500 
501  if (walk->rv3d->persp == RV3D_CAMOB &&
503  BKE_report(op->reports,
504  RPT_ERROR,
505  "Cannot navigate a camera from an external library or non-editable override");
506  return false;
507  }
508 
509  if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) {
510  BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked");
511  return false;
512  }
513 
514  if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) {
515  BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints");
516  return false;
517  }
518 
519  walk->state = WALK_RUNNING;
520 
521  if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) {
522  base_speed = U.walk_navigation.walk_speed;
523  userdef_speed = U.walk_navigation.walk_speed;
524  }
525 
526  walk->speed = 0.0f;
527  walk->is_fast = false;
528  walk->is_slow = false;
529  walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ?
530  1.0f :
531  1.0f / walk->scene->unit.scale_length;
532 
533  /* user preference settings */
534  walk->teleport.duration = U.walk_navigation.teleport_time;
535  walk->mouse_speed = U.walk_navigation.mouse_speed;
536 
537  if (U.walk_navigation.flag & USER_WALK_GRAVITY) {
539  }
540  else {
542  }
543 
544  walk->view_height = U.walk_navigation.view_height;
545  walk->jump_height = U.walk_navigation.jump_height;
546  walk->speed = U.walk_navigation.walk_speed;
547  walk->speed_factor = U.walk_navigation.walk_speed_factor;
549 
551 
553  walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]);
554  }
555  else {
556  walk->gravity = 9.80668f; /* m/s2 */
557  }
558 
559  walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
560 
561 #ifdef USE_TABLET_SUPPORT
562  walk->is_cursor_absolute = false;
563 #endif
564 
565  walk->active_directions = 0;
566 
567 #ifdef NDOF_WALK_DRAW_TOOMUCH
568  walk->redraw = 1;
569 #endif
570  zero_v3(walk->dvec_prev);
571 
572  walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
573 
574 #ifdef WITH_INPUT_NDOF
575  walk->ndof = NULL;
576 #endif
577 
579  walk->need_rotation_keyframe = false;
580  walk->need_translation_keyframe = false;
581 
583 
586 
587  walk->rv3d->rflag |= RV3D_NAVIGATING;
588 
590 
592  walk->depsgraph, walk->scene, walk->v3d, walk->rv3d);
593 
594  copy_v2_v2_int(walk->init_mval, mval);
595  copy_v2_v2_int(walk->prev_mval, mval);
596 
597  WM_cursor_grab_enable(win, 0, true, NULL);
598 
599  return 1;
600 }
601 
602 static int walkEnd(bContext *C, WalkInfo *walk)
603 {
604  wmWindow *win;
605  RegionView3D *rv3d;
606 
607  if (walk->state == WALK_RUNNING) {
608  return OPERATOR_RUNNING_MODAL;
609  }
610  if (walk->state == WALK_CONFIRM) {
611  /* Needed for auto_keyframe. */
612 #ifdef WITH_INPUT_NDOF
613  if (walk->ndof) {
614  walkApply_ndof(C, walk, true);
615  }
616  else
617 #endif /* WITH_INPUT_NDOF */
618  {
619  walkApply(C, walk, true);
620  }
621  }
622 
623 #ifdef NDOF_WALK_DEBUG
624  puts("\n-- walk end --");
625 #endif
626 
627  win = CTX_wm_window(C);
628  rv3d = walk->rv3d;
629 
631 
633 
635 
637 
638  rv3d->rflag &= ~RV3D_NAVIGATING;
639 
640 #ifdef WITH_INPUT_NDOF
641  if (walk->ndof) {
642  MEM_freeN(walk->ndof);
643  }
644 #endif
645 
646  WM_cursor_grab_enable(win, 0, true, NULL);
647 
648  if (walk->state == WALK_CONFIRM) {
649  MEM_freeN(walk);
650  return OPERATOR_FINISHED;
651  }
652 
653  MEM_freeN(walk);
654  return OPERATOR_CANCELLED;
655 }
656 
657 static void walkEvent(WalkInfo *walk, const wmEvent *event)
658 {
659  if (event->type == TIMER && event->customdata == walk->timer) {
660  walk->redraw = true;
661  }
662  else if (ISMOUSE_MOTION(event->type)) {
663 
664 #ifdef USE_TABLET_SUPPORT
665  if ((walk->is_cursor_absolute == false) && event->tablet.is_motion_absolute) {
666  walk->is_cursor_absolute = true;
667  }
668 #endif /* USE_TABLET_SUPPORT */
669 
670  walk->moffset[0] += event->mval[0] - walk->prev_mval[0];
671  walk->moffset[1] += event->mval[1] - walk->prev_mval[1];
672 
673  copy_v2_v2_int(walk->prev_mval, event->mval);
674 
675  if (walk->moffset[0] || walk->moffset[1]) {
676  walk->redraw = true;
677  }
678  }
679 #ifdef WITH_INPUT_NDOF
680  else if (event->type == NDOF_MOTION) {
681  /* do these automagically get delivered? yes. */
682  // puts("ndof motion detected in walk mode!");
683  // static const char *tag_name = "3D mouse position";
684 
685  const wmNDOFMotionData *incoming_ndof = event->customdata;
686  switch (incoming_ndof->progress) {
687  case P_STARTING:
688  /* start keeping track of 3D mouse position */
689 # ifdef NDOF_WALK_DEBUG
690  puts("start keeping track of 3D mouse position");
691 # endif
692  /* fall-through */
693  case P_IN_PROGRESS:
694  /* update 3D mouse position */
695 # ifdef NDOF_WALK_DEBUG
696  putchar('.');
697  fflush(stdout);
698 # endif
699  if (walk->ndof == NULL) {
700  // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
701  walk->ndof = MEM_dupallocN(incoming_ndof);
702  // walk->ndof = malloc(sizeof(wmNDOFMotionData));
703  }
704  else {
705  memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
706  }
707  break;
708  case P_FINISHING:
709  /* stop keeping track of 3D mouse position */
710 # ifdef NDOF_WALK_DEBUG
711  puts("stop keeping track of 3D mouse position");
712 # endif
713  if (walk->ndof) {
714  MEM_freeN(walk->ndof);
715  // free(walk->ndof);
716  walk->ndof = NULL;
717  }
718 
719  /* update the time else the view will jump when 2D mouse/timer resume */
721 
722  break;
723  default:
724  break; /* should always be one of the above 3 */
725  }
726  }
727 #endif /* WITH_INPUT_NDOF */
728  /* handle modal keymap first */
729  else if (event->type == EVT_MODAL_MAP) {
730  switch (event->val) {
731  case WALK_MODAL_CANCEL:
732  walk->state = WALK_CANCEL;
733  break;
734  case WALK_MODAL_CONFIRM:
735  walk->state = WALK_CONFIRM;
736  break;
737 
739  base_speed *= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
740  break;
742  base_speed /= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
743  break;
744 
745  /* implement WASD keys */
748  break;
751  break;
752  case WALK_MODAL_DIR_LEFT:
754  break;
757  break;
758  case WALK_MODAL_DIR_UP:
760  break;
761  case WALK_MODAL_DIR_DOWN:
763  break;
764 
767  break;
770  break;
773  break;
776  break;
778  walk->active_directions &= ~WALK_BIT_UP;
779  break;
782  break;
783 
785  walk->is_fast = true;
786  break;
788  walk->is_fast = false;
789  break;
791  walk->is_slow = true;
792  break;
794  walk->is_slow = false;
795  break;
796 
797 #define JUMP_SPEED_MIN 1.0f
798 #define JUMP_TIME_MAX 0.2f /* s */
799 #define JUMP_SPEED_MAX sqrtf(2.0f * walk->gravity * walk->jump_height)
800 
802  if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
803  float t;
804 
805  /* delta time */
807 
808  /* Reduce the velocity, if JUMP wasn't hold for long enough. */
809  t = min_ff(t, JUMP_TIME_MAX);
810  walk->speed_jump = JUMP_SPEED_MIN +
812 
813  /* when jumping, duration is how long it takes before we start going down */
815 
816  /* no more increase of jump speed */
818  }
819  break;
820  case WALK_MODAL_JUMP:
821  if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
824  /* no need to check for ground,
825  * walk->gravity wouldn't be off
826  * if we were over a hole */
828  walk->speed_jump = JUMP_SPEED_MAX;
829 
831  copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
832 
833  /* using previous vec because WASD keys are not called when SPACE is */
834  copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
835 
836  /* when jumping, duration is how long it takes before we start going down */
838  }
839 
840  break;
841 
842  case WALK_MODAL_TELEPORT: {
843  float loc[3], nor[3];
844  float distance;
845  bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance);
846 
847  /* in case we are teleporting middle way from a jump */
848  walk->speed_jump = 0.0f;
849 
850  if (ret) {
851  WalkTeleport *teleport = &walk->teleport;
852 
853  /* Store the current navigation mode if we are not already teleporting. */
854  if (teleport->state == WALK_TELEPORT_STATE_OFF) {
855  teleport->navigation_mode = walk->navigation_mode;
856  }
857  teleport->state = WALK_TELEPORT_STATE_ON;
859  teleport->duration = U.walk_navigation.teleport_time;
860 
862 
863  copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
864 
865  /* stop the camera from a distance (camera height) */
867  add_v3_v3(loc, nor);
868 
869  sub_v3_v3v3(teleport->direction, loc, teleport->origin);
870  }
871 
872  break;
873  }
874 
875 #undef JUMP_SPEED_MAX
876 #undef JUMP_TIME_MAX
877 #undef JUMP_SPEED_MIN
878 
880  if (walk->navigation_mode == WALK_MODE_GRAVITY) {
882  }
883  else { /* WALK_MODE_FREE */
885  }
886  break;
887 
889  if (walk->zlock != WALK_AXISLOCK_STATE_DONE) {
891  walk->zlock_momentum = 0.0f;
892  }
893  break;
894  }
895  }
896 }
897 
898 static void walkMoveCamera(bContext *C,
899  WalkInfo *walk,
900  const bool do_rotate,
901  const bool do_translate,
902  const bool is_confirm)
903 {
904  /* we only consider autokeying on playback or if user confirmed walk on the same frame
905  * otherwise we get a keyframe even if the user cancels. */
906  const bool use_autokey = is_confirm || walk->anim_playing;
908  walk->v3d_camera_control, use_autokey, C, do_rotate, do_translate);
909  if (use_autokey) {
910  walk->need_rotation_keyframe = false;
911  walk->need_translation_keyframe = false;
912  }
913 }
914 
915 static float getFreeFallDistance(const float gravity, const float time)
916 {
917  return gravity * (time * time) * 0.5f;
918 }
919 
920 static float getVelocityZeroTime(const float gravity, const float velocity)
921 {
922  return velocity / gravity;
923 }
924 
925 static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
926 {
927 #define WALK_ROTATE_TABLET_FAC 8.8f /* Higher is faster, relative to region size. */
928 #define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* Higher is faster, radians per-pixel. */
929 #define WALK_TOP_LIMIT DEG2RADF(85.0f)
930 #define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f)
931 #define WALK_MOVE_SPEED base_speed
932 #define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
933 #define WALK_ZUP_CORRECT_FAC 0.1f /* Amount to correct per step. */
934 #define WALK_ZUP_CORRECT_ACCEL 0.05f /* Increase upright momentum each step. */
935 
936  RegionView3D *rv3d = walk->rv3d;
937  ARegion *region = walk->region;
938 
939  /* 3x3 copy of the view matrix so we can move along the view axis */
940  float mat[3][3];
941  /* this is the direction that's added to the view offset per redraw */
942  float dvec[3] = {0.0f, 0.0f, 0.0f};
943 
944  int moffset[2]; /* mouse offset from the views center */
945  float tmp_quat[4]; /* used for rotating the view */
946 
947 #ifdef NDOF_WALK_DEBUG
948  {
949  static uint iteration = 1;
950  printf("walk timer %d\n", iteration++);
951  }
952 #endif
953 
954  {
955  /* mouse offset from the center */
956  copy_v2_v2_int(moffset, walk->moffset);
957 
958  /* apply moffset so we can re-accumulate */
959  walk->moffset[0] = 0;
960  walk->moffset[1] = 0;
961 
962  /* revert mouse */
963  if (walk->is_reversed) {
964  moffset[1] = -moffset[1];
965  }
966 
967  /* Should we redraw? */
968  if ((walk->active_directions) || moffset[0] || moffset[1] ||
971  walk->teleport.state == WALK_TELEPORT_STATE_ON || is_confirm) {
972  float dvec_tmp[3];
973 
974  /* time how fast it takes for us to redraw,
975  * this is so simple scenes don't walk too fast */
976  double time_current;
977  float time_redraw;
978  float time_redraw_clamped;
979 #ifdef NDOF_WALK_DRAW_TOOMUCH
980  walk->redraw = 1;
981 #endif
982  time_current = PIL_check_seconds_timer();
983  time_redraw = (float)(time_current - walk->time_lastdraw);
984 
985  /* Clamp redraw time to avoid jitter in roll correction. */
986  time_redraw_clamped = min_ff(0.05f, time_redraw);
987 
988  walk->time_lastdraw = time_current;
989 
990  /* base speed in m/s */
991  walk->speed = WALK_MOVE_SPEED;
992 
993  if (walk->is_fast) {
994  walk->speed *= WALK_BOOST_FACTOR;
995  }
996  else if (walk->is_slow) {
997  walk->speed *= 1.0f / WALK_BOOST_FACTOR;
998  }
999 
1000  copy_m3_m4(mat, rv3d->viewinv);
1001 
1002  {
1003  /* rotate about the X axis- look up/down */
1004  if (moffset[1]) {
1005  float upvec[3];
1006  float angle;
1007  float y;
1008 
1009  /* relative offset */
1010  y = (float)moffset[1];
1011 
1012  /* Speed factor. */
1013 #ifdef USE_TABLET_SUPPORT
1014  if (walk->is_cursor_absolute) {
1015  y /= region->winy;
1017  }
1018  else
1019 #endif
1020  {
1022  }
1023 
1024  /* user adjustment factor */
1025  y *= walk->mouse_speed;
1026 
1027  /* clamp the angle limits */
1028  /* it ranges from 90.0f to -90.0f */
1029  angle = -asinf(rv3d->viewmat[2][2]);
1030 
1031  if (angle > WALK_TOP_LIMIT && y > 0.0f) {
1032  y = 0.0f;
1033  }
1034  else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) {
1035  y = 0.0f;
1036  }
1037 
1038  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
1039  mul_m3_v3(mat, upvec);
1040  /* Rotate about the relative up vec */
1041  axis_angle_to_quat(tmp_quat, upvec, -y);
1042  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
1043  }
1044 
1045  /* rotate about the Y axis- look left/right */
1046  if (moffset[0]) {
1047  float upvec[3];
1048  float x;
1049 
1050  /* if we're upside down invert the moffset */
1051  copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
1052  mul_m3_v3(mat, upvec);
1053 
1054  if (upvec[2] < 0.0f) {
1055  moffset[0] = -moffset[0];
1056  }
1057 
1058  /* relative offset */
1059  x = (float)moffset[0];
1060 
1061  /* Speed factor. */
1062 #ifdef USE_TABLET_SUPPORT
1063  if (walk->is_cursor_absolute) {
1064  x /= region->winx;
1066  }
1067  else
1068 #endif
1069  {
1071  }
1072 
1073  /* user adjustment factor */
1074  x *= walk->mouse_speed;
1075 
1076  /* Rotate about the relative up vec */
1077  axis_angle_to_quat_single(tmp_quat, 'Z', x);
1078  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
1079  }
1080 
1081  if (walk->zlock == WALK_AXISLOCK_STATE_ACTIVE) {
1082  float upvec[3];
1083  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
1084  mul_m3_v3(mat, upvec);
1085 
1086  /* Make sure we have some z rolling. */
1087  if (fabsf(upvec[2]) > 0.00001f) {
1088  float roll = upvec[2] * 5.0f;
1089  /* Rotate the view about this axis. */
1090  copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
1091  mul_m3_v3(mat, upvec);
1092  /* Rotate about the relative up vec. */
1093  axis_angle_to_quat(tmp_quat,
1094  upvec,
1095  roll * time_redraw_clamped * walk->zlock_momentum *
1097  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
1098 
1100  }
1101  else {
1102  /* Lock fixed, don't need to check it ever again. */
1104  }
1105  }
1106  }
1107 
1108  /* WASD - 'move' translation code */
1109  if ((walk->active_directions) && (walk->gravity_state == WALK_GRAVITY_STATE_OFF)) {
1110 
1111  short direction;
1112  zero_v3(dvec);
1113 
1114  if ((walk->active_directions & WALK_BIT_FORWARD) ||
1116 
1117  direction = 0;
1118 
1119  if (walk->active_directions & WALK_BIT_FORWARD) {
1120  direction += 1;
1121  }
1122 
1123  if (walk->active_directions & WALK_BIT_BACKWARD) {
1124  direction -= 1;
1125  }
1126 
1127  copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
1128  mul_m3_v3(mat, dvec_tmp);
1129 
1130  if (walk->navigation_mode == WALK_MODE_GRAVITY) {
1131  dvec_tmp[2] = 0.0f;
1132  }
1133 
1134  add_v3_v3(dvec, dvec_tmp);
1135  }
1136 
1137  if ((walk->active_directions & WALK_BIT_LEFT) ||
1138  (walk->active_directions & WALK_BIT_RIGHT)) {
1139 
1140  direction = 0;
1141 
1142  if (walk->active_directions & WALK_BIT_LEFT) {
1143  direction += 1;
1144  }
1145 
1146  if (walk->active_directions & WALK_BIT_RIGHT) {
1147  direction -= 1;
1148  }
1149 
1150  dvec_tmp[0] = direction * rv3d->viewinv[0][0];
1151  dvec_tmp[1] = direction * rv3d->viewinv[0][1];
1152  dvec_tmp[2] = 0.0f;
1153 
1154  add_v3_v3(dvec, dvec_tmp);
1155  }
1156 
1157  if ((walk->active_directions & WALK_BIT_UP) || (walk->active_directions & WALK_BIT_DOWN)) {
1158 
1159  if (walk->navigation_mode == WALK_MODE_FREE) {
1160 
1161  direction = 0;
1162 
1163  if (walk->active_directions & WALK_BIT_UP) {
1164  direction -= 1;
1165  }
1166 
1167  if (walk->active_directions & WALK_BIT_DOWN) {
1168  direction = 1;
1169  }
1170 
1171  copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
1172  add_v3_v3(dvec, dvec_tmp);
1173  }
1174  }
1175 
1176  normalize_v3(dvec);
1177 
1178  /* apply movement */
1179  mul_v3_fl(dvec, walk->speed * time_redraw);
1180  }
1181 
1182  /* stick to the floor */
1183  if (walk->navigation_mode == WALK_MODE_GRAVITY &&
1185 
1186  bool ret;
1187  float ray_distance;
1188  float difference = -100.0f;
1189  float fall_distance;
1190 
1191  ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
1192 
1193  if (ret) {
1194  difference = walk->view_height - ray_distance;
1195  }
1196 
1197  /* the distance we would fall naturally smoothly enough that we
1198  * can manually drop the object without activating gravity */
1199  fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
1200 
1201  if (fabsf(difference) < fall_distance) {
1202  /* slope/stairs */
1203  dvec[2] -= difference;
1204 
1205  /* in case we switched from FREE to GRAVITY too close to the ground */
1206  if (walk->gravity_state == WALK_GRAVITY_STATE_START) {
1208  }
1209  }
1210  else {
1211  /* hijack the teleport variables */
1214  walk->teleport.duration = 0.0f;
1215 
1216  copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
1217  copy_v2_v2(walk->teleport.direction, dvec);
1218  }
1219  }
1220 
1221  /* Falling or jumping) */
1223  float t;
1224  float z_cur, z_new;
1225  bool ret;
1226  float ray_distance, difference = -100.0f;
1227 
1228  /* delta time */
1230 
1231  /* keep moving if we were moving */
1232  copy_v2_v2(dvec, walk->teleport.direction);
1233 
1234  z_cur = walk->rv3d->viewinv[3][2];
1235  z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
1236 
1237  /* jump */
1238  z_new += t * walk->speed_jump * walk->grid;
1239 
1240  /* duration is the jump duration */
1241  if (t > walk->teleport.duration) {
1242 
1243  /* check to see if we are landing */
1244  ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
1245 
1246  if (ret) {
1247  difference = walk->view_height - ray_distance;
1248  }
1249 
1250  if (difference > 0.0f) {
1251  /* quit falling, lands at "view_height" from the floor */
1252  dvec[2] -= difference;
1254  walk->speed_jump = 0.0f;
1255  }
1256  else {
1257  /* keep falling */
1258  dvec[2] = z_cur - z_new;
1259  }
1260  }
1261  else {
1262  /* keep going up (jump) */
1263  dvec[2] = z_cur - z_new;
1264  }
1265  }
1266 
1267  /* Teleport */
1268  else if (walk->teleport.state == WALK_TELEPORT_STATE_ON) {
1269  float t; /* factor */
1270  float new_loc[3];
1271  float cur_loc[3];
1272 
1273  /* linear interpolation */
1275  t /= walk->teleport.duration;
1276 
1277  /* clamp so we don't go past our limit */
1278  if (t >= 1.0f) {
1279  t = 1.0f;
1282  }
1283 
1284  mul_v3_v3fl(new_loc, walk->teleport.direction, t);
1285  add_v3_v3(new_loc, walk->teleport.origin);
1286 
1287  copy_v3_v3(cur_loc, walk->rv3d->viewinv[3]);
1288  sub_v3_v3v3(dvec, cur_loc, new_loc);
1289  }
1290 
1291  /* scale the movement to the scene size */
1292  mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
1293  add_v3_v3(rv3d->ofs, dvec_tmp);
1294 
1295  if (rv3d->persp == RV3D_CAMOB) {
1296  walk->need_rotation_keyframe |= (moffset[0] || moffset[1] ||
1298  walk->need_translation_keyframe |= (len_squared_v3(dvec_tmp) > FLT_EPSILON);
1300  C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
1301  }
1302  }
1303  else {
1304  /* we're not redrawing but we need to update the time else the view will jump */
1306  }
1307  /* end drawing */
1308  copy_v3_v3(walk->dvec_prev, dvec);
1309  }
1310 
1311  return OPERATOR_FINISHED;
1312 #undef WALK_ROTATE_TABLET_FAC
1313 #undef WALK_TOP_LIMIT
1314 #undef WALK_BOTTOM_LIMIT
1315 #undef WALK_MOVE_SPEED
1316 #undef WALK_BOOST_FACTOR
1317 }
1318 
1319 #ifdef WITH_INPUT_NDOF
1320 static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm)
1321 {
1323  bool has_translate, has_rotate;
1324 
1325  view3d_ndof_fly(walk->ndof,
1326  walk->v3d,
1327  walk->rv3d,
1328  walk->is_slow,
1329  lock_ob ? lock_ob->protectflag : 0,
1330  &has_translate,
1331  &has_rotate);
1332 
1333  if (has_translate || has_rotate) {
1334  walk->redraw = true;
1335 
1336  if (walk->rv3d->persp == RV3D_CAMOB) {
1337  walk->need_rotation_keyframe |= has_rotate;
1338  walk->need_translation_keyframe |= has_translate;
1340  C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
1341  }
1342  }
1343 }
1344 #endif /* WITH_INPUT_NDOF */
1345 
1348 /* -------------------------------------------------------------------- */
1352 static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1353 {
1355  WalkInfo *walk;
1356 
1358  return OPERATOR_CANCELLED;
1359  }
1360 
1361  walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation");
1362 
1363  op->customdata = walk;
1364 
1365  if (initWalkInfo(C, walk, op, event->mval) == false) {
1366  MEM_freeN(op->customdata);
1367  return OPERATOR_CANCELLED;
1368  }
1369 
1370  walkEvent(walk, event);
1371 
1373 
1374  return OPERATOR_RUNNING_MODAL;
1375 }
1376 
1377 static void walk_cancel(bContext *C, wmOperator *op)
1378 {
1379  WalkInfo *walk = op->customdata;
1380 
1381  walk->state = WALK_CANCEL;
1382  walkEnd(C, walk);
1383  op->customdata = NULL;
1384 }
1385 
1386 static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
1387 {
1388  int exit_code;
1389  bool do_draw = false;
1390  WalkInfo *walk = op->customdata;
1391  View3D *v3d = walk->v3d;
1392  RegionView3D *rv3d = walk->rv3d;
1394 
1395  walk->redraw = false;
1396 
1397  walkEvent(walk, event);
1398 
1399 #ifdef WITH_INPUT_NDOF
1400  if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */
1401  if (event->type == NDOF_MOTION) {
1402  walkApply_ndof(C, walk, false);
1403  }
1404  }
1405  else
1406 #endif /* WITH_INPUT_NDOF */
1407  if (event->type == TIMER && event->customdata == walk->timer) {
1408  walkApply(C, walk, false);
1409  }
1410 
1411  do_draw |= walk->redraw;
1412 
1413  exit_code = walkEnd(C, walk);
1414 
1415  if (exit_code != OPERATOR_RUNNING_MODAL) {
1416  do_draw = true;
1417  }
1418  if (exit_code == OPERATOR_FINISHED) {
1419  ED_view3d_camera_lock_undo_push(op->type->name, v3d, rv3d, C);
1420  }
1421 
1422  if (do_draw) {
1423  if (rv3d->persp == RV3D_CAMOB) {
1424  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, walk_object);
1425  }
1426 
1427  /* too frequent, commented with NDOF_WALK_DRAW_TOOMUCH for now */
1428  // puts("redraw!");
1430  }
1431  return exit_code;
1432 }
1433 
1435 {
1436  /* identifiers */
1437  ot->name = "Walk Navigation";
1438  ot->description = "Interactively walk around the scene";
1439  ot->idname = "VIEW3D_OT_walk";
1440 
1441  /* api callbacks */
1442  ot->invoke = walk_invoke;
1443  ot->cancel = walk_cancel;
1444  ot->modal = walk_modal;
1446 
1447  /* flags */
1448  /* NOTE: #OPTYPE_BLOCKING isn't used because this needs to grab & hide the cursor.
1449  * where as blocking confines the cursor to the window bounds, even when hidden. */
1450  ot->flag = 0;
1451 }
1452 
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:784
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:793
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
bool BKE_id_is_editable(const struct Main *bmain, const struct ID *id)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
#define BVH_RAYCAST_DIST_MAX
Definition: BLI_kdopbvh.h:89
MINLINE float min_ff(float a, float b)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void axis_angle_to_quat_single(float q[4], char axis, float angle)
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:46
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void negate_v3(float r[3])
MINLINE float normalize_v3_length(float r[3], float unit_scale)
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
Object is a sort of wrapper for general info.
#define USER_UNIT_NONE
#define PHYS_GLOBAL_GRAVITY
@ USER_WALK_MOUSE_REVERSE
@ USER_WALK_GRAVITY
#define RV3D_LOCK_FLAGS(rv3d)
#define RV3D_CAMOB
@ RV3D_LOCK_ANY_TRANSFORM
#define RV3D_PERSP
#define RV3D_NAVIGATING
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
bScreen * ED_screen_animation_playing(const struct wmWindowManager *wm)
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:655
bool ED_operator_region_view3d_active(struct bContext *C)
Definition: screen_ops.c:230
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:226
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:63
bool ED_region_draw_cb_exit(struct ARegionType *art, void *handle)
Definition: spacetypes.c:241
bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx, struct Depsgraph *depsgraph, const View3D *v3d, const struct SnapObjectParams *params, const float ray_origin[3], const float ray_direction[3], float *ray_depth, float r_co[3], float r_no[3])
SnapObjectContext * ED_transform_snap_object_context_create(struct Scene *scene, int flag)
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
bool ED_view3d_offset_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d)
bool ED_view3d_camera_lock_undo_push(const char *str, View3D *v3d, struct RegionView3D *rv3d, struct bContext *C)
Definition: view3d_utils.c:726
void ED_view3d_calc_camera_border(const struct Scene *scene, struct Depsgraph *depsgraph, const struct ARegion *region, const struct View3D *v3d, const struct RegionView3D *rv3d, struct rctf *r_viewborder, bool no_shift)
void immUniformThemeColorAlpha(int color_id, float a)
void immUnbindProgram(void)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2i(uint attr_id, int x, int y)
GPUVertFormat * immVertexFormat(void)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_FETCH_INT_TO_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_I32
Read Guarded memory(de)allocation.
Platform independent time functions.
#define C
Definition: RandGen.cpp:25
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:327
#define ND_TRANSFORM
Definition: WM_types.h:405
#define NC_OBJECT
Definition: WM_types.h:329
@ P_IN_PROGRESS
Definition: WM_types.h:763
@ P_STARTING
Definition: WM_types.h:762
@ P_FINISHING
Definition: WM_types.h:764
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
double time
uint pos
uint nor
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define asinf(x)
Definition: metal/compat.h:221
#define fabsf(x)
Definition: metal/compat.h:219
T distance(const T &a, const T &b)
return ret
struct ARegionType * type
void * first
Definition: DNA_listBase.h:31
ListBase constraints
short protectflag
float viewquat[4]
float viewmat[4][4]
float viewinv[4][4]
struct PhysicsSettings physics_settings
struct UnitSettings unit
struct Object * camera
struct Depsgraph * depsgraph
eWalkMethod navigation_mode
WalkTeleport teleport
float dvec_prev[3]
bool need_translation_keyframe
struct View3DCameraControl * v3d_camera_control
bool need_rotation_keyframe
eWalkGravityState gravity_state
void * draw_handle_pixel
eWalkLockState zlock
ARegion * region
struct SnapObjectContext * snap_context
RegionView3D * rv3d
eWalkMethod navigation_mode
eWalkTeleportState state
float xmin
Definition: DNA_vec_types.h:69
float ymin
Definition: DNA_vec_types.h:70
short val
Definition: WM_types.h:680
int mval[2]
Definition: WM_types.h:684
wmTabletData tablet
Definition: WM_types.h:705
short type
Definition: WM_types.h:678
void * customdata
Definition: WM_types.h:715
const void * modal_items
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:927
const char * description
Definition: WM_types.h:893
struct ReportList * reports
struct wmOperatorType * type
char is_motion_absolute
Definition: WM_types.h:632
double PIL_check_seconds_timer(void)
Definition: time.c:64
void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl, const bool use_autokey, struct bContext *C, const bool do_rotate, const bool do_translate)
Object * ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl)
struct View3DCameraControl * ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph, Scene *scene, View3D *v3d, RegionView3D *rv3d)
void ED_view3d_cameracontrol_release(View3DCameraControl *vctrl, const bool restore)
struct WalkTeleport WalkTeleport
struct WalkInfo WalkInfo
static void walkMoveCamera(bContext *C, WalkInfo *walk, const bool do_rotate, const bool do_translate, const bool is_confirm)
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int mval[2])
static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *region, void *arg)
static bool walk_floor_distance_get(RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance)
#define WALK_ROTATE_TABLET_FAC
#define JUMP_SPEED_MAX
#define WALK_MOVE_SPEED
static void walkEvent(WalkInfo *walk, const wmEvent *event)
#define WALK_ROTATE_CONSTANT_FAC
eWalkTeleportState
@ WALK_TELEPORT_STATE_ON
@ WALK_TELEPORT_STATE_OFF
static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int walkEnd(bContext *C, WalkInfo *walk)
static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void VIEW3D_OT_walk(wmOperatorType *ot)
static float userdef_speed
eWalkGravityState
@ WALK_GRAVITY_STATE_START
@ WALK_GRAVITY_STATE_JUMP
@ WALK_GRAVITY_STATE_OFF
@ WALK_GRAVITY_STATE_ON
@ WALK_MODAL_DECELERATE
@ WALK_MODAL_JUMP
@ WALK_MODAL_DIR_LEFT_STOP
@ WALK_MODAL_SLOW_DISABLE
@ WALK_MODAL_DIR_RIGHT
@ WALK_MODAL_SLOW_ENABLE
@ WALK_MODAL_DIR_DOWN_STOP
@ WALK_MODAL_CONFIRM
@ WALK_MODAL_DIR_LEFT
@ WALK_MODAL_FAST_ENABLE
@ WALK_MODAL_DIR_BACKWARD
@ WALK_MODAL_TELEPORT
@ WALK_MODAL_DIR_FORWARD_STOP
@ WALK_MODAL_DIR_UP
@ WALK_MODAL_JUMP_STOP
@ WALK_MODAL_DIR_DOWN
@ WALK_MODAL_GRAVITY_TOGGLE
@ WALK_MODAL_DIR_FORWARD
@ WALK_MODAL_DIR_BACKWARD_STOP
@ WALK_MODAL_DIR_RIGHT_STOP
@ WALK_MODAL_CANCEL
@ WALK_MODAL_ACCELERATE
@ WALK_MODAL_DIR_UP_STOP
@ WALK_MODAL_AXIS_LOCK_Z
@ WALK_MODAL_FAST_DISABLE
#define JUMP_TIME_MAX
@ WALK_MODE_GRAVITY
@ WALK_MODE_FREE
static void walk_cancel(bContext *C, wmOperator *op)
#define WALK_TOP_LIMIT
static float getFreeFallDistance(const float gravity, const float time)
@ WALK_RUNNING
@ WALK_CONFIRM
@ WALK_CANCEL
#define WALK_ZUP_CORRECT_ACCEL
static bool walk_ray_cast(RegionView3D *rv3d, WalkInfo *walk, float r_location[3], float r_normal[3], float *ray_distance)
#define WALK_ZUP_CORRECT_FAC
@ WALK_AXISLOCK_STATE_DONE
@ WALK_AXISLOCK_STATE_OFF
@ WALK_AXISLOCK_STATE_ACTIVE
#define WALK_BOOST_FACTOR
static float getVelocityZeroTime(const float gravity, const float velocity)
@ WALK_BIT_UP
@ WALK_BIT_RIGHT
@ WALK_BIT_DOWN
@ WALK_BIT_BACKWARD
@ WALK_BIT_LEFT
@ WALK_BIT_FORWARD
static int walkApply(bContext *C, struct WalkInfo *walk, bool is_confirm)
void walk_modal_keymap(wmKeyConfig *keyconf)
#define JUMP_SPEED_MIN
static float base_speed
static void walk_navigation_mode_set(WalkInfo *walk, eWalkMethod mode)
#define WALK_BOTTOM_LIMIT
void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4])
Definition: wm_cursors.c:226
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
#define ISMOUSE_MOTION(event_type)
@ TIMER
@ EVT_MODAL_MAP
@ NDOF_MOTION
wmOperatorType * ot
Definition: wm_files.c:3479
wmKeyMap * WM_modalkeymap_find(wmKeyConfig *keyconf, const char *idname)
Definition: wm_keymap.c:914
void WM_modalkeymap_assign(wmKeyMap *km, const char *opname)
Definition: wm_keymap.c:985
wmKeyMap * WM_modalkeymap_ensure(wmKeyConfig *keyconf, const char *idname, const EnumPropertyItem *items)
Definition: wm_keymap.c:888
void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer)
Definition: wm_window.c:1682
wmTimer * WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)
Definition: wm_window.c:1630