Blender  V2.93
view3d_walk.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
26 /* defines VIEW3D_OT_navigate - walk modal operator */
27 
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_kdopbvh.h"
35 #include "BLI_math.h"
36 #include "BLI_utildefines.h"
37 
38 #include "BKE_context.h"
39 #include "BKE_main.h"
40 #include "BKE_report.h"
41 
42 #include "BLT_translation.h"
43 
44 #include "WM_api.h"
45 #include "WM_types.h"
46 
47 #include "ED_screen.h"
48 #include "ED_space_api.h"
50 
51 #include "PIL_time.h" /* Smooth-view. */
52 
53 #include "UI_interface.h"
54 #include "UI_resources.h"
55 
56 #include "GPU_immediate.h"
57 
58 #include "DEG_depsgraph.h"
59 
60 #include "view3d_intern.h" /* own include */
61 
62 #ifdef WITH_INPUT_NDOF
63 //# define NDOF_WALK_DEBUG
64 /* is this needed for ndof? - commented so redraw doesn't thrash - campbell */
65 //# define NDOF_WALK_DRAW_TOOMUCH
66 #endif
67 
68 #define USE_TABLET_SUPPORT
69 
70 /* ensure the target position is one we can reach, see: T45771 */
71 #define USE_PIXELSIZE_NATIVE_SUPPORT
72 
73 /* -------------------------------------------------------------------- */
77 /* NOTE: these defines are saved in keymap files,
78  * do not change values but just add new ones */
79 enum {
104 };
105 
106 enum {
109  WALK_BIT_LEFT = 1 << 2,
110  WALK_BIT_RIGHT = 1 << 3,
111  WALK_BIT_UP = 1 << 4,
112  WALK_BIT_DOWN = 1 << 5,
113 };
114 
115 typedef enum eWalkTeleportState {
119 
120 typedef enum eWalkMethod {
124 
125 typedef enum eWalkGravityState {
131 
132 /* called in transform_ops.c, on each regeneration of keymaps */
134 {
135  static const EnumPropertyItem modal_items[] = {
136  {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
137  {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
138 
139  {WALK_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
140  {WALK_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
141  {WALK_MODAL_DIR_LEFT, "LEFT", 0, "Left", ""},
142  {WALK_MODAL_DIR_RIGHT, "RIGHT", 0, "Right", ""},
143  {WALK_MODAL_DIR_UP, "UP", 0, "Up", ""},
144  {WALK_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
145 
146  {WALK_MODAL_DIR_FORWARD_STOP, "FORWARD_STOP", 0, "Stop Move Forward", ""},
147  {WALK_MODAL_DIR_BACKWARD_STOP, "BACKWARD_STOP", 0, "Stop Mode Backward", ""},
148  {WALK_MODAL_DIR_LEFT_STOP, "LEFT_STOP", 0, "Stop Move Left", ""},
149  {WALK_MODAL_DIR_RIGHT_STOP, "RIGHT_STOP", 0, "Stop Mode Right", ""},
150  {WALK_MODAL_DIR_UP_STOP, "UP_STOP", 0, "Stop Move Up", ""},
151  {WALK_MODAL_DIR_DOWN_STOP, "DOWN_STOP", 0, "Stop Mode Down", ""},
152 
153  {WALK_MODAL_TELEPORT, "TELEPORT", 0, "Teleport", "Move forward a few units at once"},
154 
155  {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
156  {WALK_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
157 
158  {WALK_MODAL_FAST_ENABLE, "FAST_ENABLE", 0, "Fast", "Move faster (walk or fly)"},
159  {WALK_MODAL_FAST_DISABLE, "FAST_DISABLE", 0, "Fast (Off)", "Resume regular speed"},
160 
161  {WALK_MODAL_SLOW_ENABLE, "SLOW_ENABLE", 0, "Slow", "Move slower (walk or fly)"},
162  {WALK_MODAL_SLOW_DISABLE, "SLOW_DISABLE", 0, "Slow (Off)", "Resume regular speed"},
163 
164  {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"},
165  {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump (Off)", "Stop pushing jump"},
166 
167  {WALK_MODAL_TOGGLE, "GRAVITY_TOGGLE", 0, "Toggle Gravity", "Toggle gravity effect"},
168 
169  {0, NULL, 0, NULL, NULL},
170  };
171 
172  wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Walk Modal");
173 
174  /* this function is called for each spacetype, only needs to add map once */
175  if (keymap && keymap->modal_items) {
176  return;
177  }
178 
179  keymap = WM_modalkeymap_ensure(keyconf, "View3D Walk Modal", modal_items);
180 
181  /* assign map to operators */
182  WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk");
183 }
184 
187 /* -------------------------------------------------------------------- */
191 typedef struct WalkTeleport {
193  float duration; /* from user preferences */
194  float origin[3];
195  float direction[3];
196  double initial_time;
197  eWalkMethod navigation_mode; /* teleport always set FREE mode on */
198 
200 
201 typedef struct WalkInfo {
202  /* context stuff */
208 
211 
212  short state;
213  bool redraw;
214 
224 
226  int prev_mval[2];
228  int center_mval[2];
229 
230  int moffset[2];
231 
232 #ifdef WITH_INPUT_NDOF
234  wmNDOFMotionData *ndof;
235 #endif
236 
237  /* walk state state */
239  float base_speed;
241  float speed;
243  float grid;
244 
245  /* compare between last state */
248 
250 
251  /* use for some lag */
253  float dvec_prev[3];
254 
257 
258  /* teleport */
260 
262  float mouse_speed;
263 
265  bool is_fast;
266  bool is_slow;
267 
270 
271 #ifdef USE_TABLET_SUPPORT
274 
277 #endif
278 
281  float gravity;
282 
284  float view_height;
285 
288 
289  float speed_jump;
291  float jump_height;
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  &(const struct SnapObjectParams){
408  .snap_select = SNAP_ALL,
409  /* Avoid having to convert the edit-mesh to a regular mesh. */
410  .use_object_edit_cage = true,
411  },
412  ray_start,
413  ray_normal,
414  r_distance,
415  r_location,
416  r_normal_dummy);
417 
418  /* artificially scale the distance to the scene size */
419  *r_distance /= walk->grid;
420  return ret;
421 }
422 
428 static bool walk_ray_cast(RegionView3D *rv3d,
429  WalkInfo *walk,
430  float r_location[3],
431  float r_normal[3],
432  float *ray_distance)
433 {
434  float ray_normal[3] = {0, 0, -1}; /* forward */
435  float ray_start[3];
436  bool ret;
437 
438  *ray_distance = BVH_RAYCAST_DIST_MAX;
439 
440  copy_v3_v3(ray_start, rv3d->viewinv[3]);
441 
442  mul_mat3_m4_v3(rv3d->viewinv, ray_normal);
443 
444  normalize_v3(ray_normal);
445 
447  walk->depsgraph,
448  &(const struct SnapObjectParams){
449  .snap_select = SNAP_ALL,
450  },
451  ray_start,
452  ray_normal,
453  NULL,
454  r_location,
455  r_normal);
456 
457  /* dot is positive if both rays are facing the same direction */
458  if (dot_v3v3(ray_normal, r_normal) > 0) {
459  negate_v3(r_normal);
460  }
461 
462  /* artificially scale the distance to the scene size */
463  *ray_distance /= walk->grid;
464 
465  return ret;
466 }
467 
468 /* WalkInfo->state */
469 enum {
473 };
474 
475 /* keep the previous speed until user changes userpreferences */
476 static float base_speed = -1.0f;
477 static float userdef_speed = -1.0f;
478 
479 static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
480 {
482  wmWindow *win = CTX_wm_window(C);
483 
484  walk->rv3d = CTX_wm_region_view3d(C);
485  walk->v3d = CTX_wm_view3d(C);
486  walk->region = CTX_wm_region(C);
488  walk->scene = CTX_data_scene(C);
489 
490 #ifdef NDOF_WALK_DEBUG
491  puts("\n-- walk begin --");
492 #endif
493 
494  /* sanity check: for rare but possible case (if lib-linking the camera fails) */
495  if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) {
496  walk->rv3d->persp = RV3D_PERSP;
497  }
498 
499  if (walk->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(walk->v3d->camera)) {
500  BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library");
501  return false;
502  }
503 
504  if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) {
505  BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked");
506  return false;
507  }
508 
509  if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) {
510  BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints");
511  return false;
512  }
513 
514  walk->state = WALK_RUNNING;
515 
516  if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) {
517  base_speed = U.walk_navigation.walk_speed;
518  userdef_speed = U.walk_navigation.walk_speed;
519  }
520 
521  walk->speed = 0.0f;
522  walk->is_fast = false;
523  walk->is_slow = false;
524  walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ?
525  1.0f :
526  1.0f / walk->scene->unit.scale_length;
527 
528  /* user preference settings */
529  walk->teleport.duration = U.walk_navigation.teleport_time;
530  walk->mouse_speed = U.walk_navigation.mouse_speed;
531 
532  if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) {
534  }
535  else {
537  }
538 
539  walk->view_height = U.walk_navigation.view_height;
540  walk->jump_height = U.walk_navigation.jump_height;
541  walk->speed = U.walk_navigation.walk_speed;
542  walk->speed_factor = U.walk_navigation.walk_speed_factor;
543 
545 
547  walk->gravity = fabsf(walk->scene->physics_settings.gravity[2]);
548  }
549  else {
550  walk->gravity = 9.80668f; /* m/s2 */
551  }
552 
553  walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0);
554 
555 #ifdef USE_TABLET_SUPPORT
556  walk->is_cursor_first = true;
557 
558  walk->is_cursor_absolute = false;
559 #endif
560 
561  walk->active_directions = 0;
562 
563 #ifdef NDOF_WALK_DRAW_TOOMUCH
564  walk->redraw = 1;
565 #endif
566  zero_v3(walk->dvec_prev);
567 
568  walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
569 
570 #ifdef WITH_INPUT_NDOF
571  walk->ndof = NULL;
572 #endif
573 
575  walk->need_rotation_keyframe = false;
576  walk->need_translation_keyframe = false;
577 
579 
582 
583  walk->rv3d->rflag |= RV3D_NAVIGATING;
584 
586  walk->scene, 0, walk->region, walk->v3d);
587 
589  walk->depsgraph, walk->scene, walk->v3d, walk->rv3d);
590 
591  /* center the mouse */
592  walk->center_mval[0] = walk->region->winx * 0.5f;
593  walk->center_mval[1] = walk->region->winy * 0.5f;
594 
595 #ifdef USE_PIXELSIZE_NATIVE_SUPPORT
596  walk->center_mval[0] += walk->region->winrct.xmin;
597  walk->center_mval[1] += walk->region->winrct.ymin;
598 
599  WM_cursor_compatible_xy(win, &walk->center_mval[0], &walk->center_mval[1]);
600 
601  walk->center_mval[0] -= walk->region->winrct.xmin;
602  walk->center_mval[1] -= walk->region->winrct.ymin;
603 #endif
604 
605  copy_v2_v2_int(walk->prev_mval, walk->center_mval);
606 
607  WM_cursor_warp(win,
608  walk->region->winrct.xmin + walk->center_mval[0],
609  walk->region->winrct.ymin + walk->center_mval[1]);
610 
611  /* remove the mouse cursor temporarily */
613 
614  return 1;
615 }
616 
617 static int walkEnd(bContext *C, WalkInfo *walk)
618 {
619  wmWindow *win;
620  RegionView3D *rv3d;
621 
622  if (walk->state == WALK_RUNNING) {
623  return OPERATOR_RUNNING_MODAL;
624  }
625  if (walk->state == WALK_CONFIRM) {
626  /* Needed for auto_keyframe. */
627 #ifdef WITH_INPUT_NDOF
628  if (walk->ndof) {
629  walkApply_ndof(C, walk, true);
630  }
631  else
632 #endif /* WITH_INPUT_NDOF */
633  {
634  walkApply(C, walk, true);
635  }
636  }
637 
638 #ifdef NDOF_WALK_DEBUG
639  puts("\n-- walk end --");
640 #endif
641 
642  win = CTX_wm_window(C);
643  rv3d = walk->rv3d;
644 
646 
648 
650 
652 
653  rv3d->rflag &= ~RV3D_NAVIGATING;
654 
655 #ifdef WITH_INPUT_NDOF
656  if (walk->ndof) {
657  MEM_freeN(walk->ndof);
658  }
659 #endif
660 
661  /* restore the cursor */
663 
664 #ifdef USE_TABLET_SUPPORT
665  if (walk->is_cursor_absolute == false)
666 #endif
667  {
668  /* center the mouse */
669  WM_cursor_warp(win,
670  walk->region->winrct.xmin + walk->center_mval[0],
671  walk->region->winrct.ymin + walk->center_mval[1]);
672  }
673 
674  if (walk->state == WALK_CONFIRM) {
675  MEM_freeN(walk);
676  return OPERATOR_FINISHED;
677  }
678 
679  MEM_freeN(walk);
680  return OPERATOR_CANCELLED;
681 }
682 
683 static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
684 {
685  if (event->type == TIMER && event->customdata == walk->timer) {
686  walk->redraw = true;
687  }
688  else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
689 
690 #ifdef USE_TABLET_SUPPORT
691  if (walk->is_cursor_first) {
692  /* wait until we get the 'warp' event */
693  if ((walk->center_mval[0] == event->mval[0]) && (walk->center_mval[1] == event->mval[1])) {
694  walk->is_cursor_first = false;
695  }
696  else {
697  /* note, its possible the system isn't giving us the warp event
698  * ideally we shouldn't have to worry about this, see: T45361 */
699  wmWindow *win = CTX_wm_window(C);
700  WM_cursor_warp(win,
701  walk->region->winrct.xmin + walk->center_mval[0],
702  walk->region->winrct.ymin + walk->center_mval[1]);
703  }
704  return;
705  }
706 
707  if ((walk->is_cursor_absolute == false) && event->tablet.is_motion_absolute) {
708  walk->is_cursor_absolute = true;
709  copy_v2_v2_int(walk->prev_mval, event->mval);
710  copy_v2_v2_int(walk->center_mval, event->mval);
711  /* Without this we can't turn 180d with the default speed of 1.0. */
712  walk->mouse_speed *= 4.0f;
713  }
714 #endif /* USE_TABLET_SUPPORT */
715 
716  walk->moffset[0] += event->mval[0] - walk->prev_mval[0];
717  walk->moffset[1] += event->mval[1] - walk->prev_mval[1];
718 
719  copy_v2_v2_int(walk->prev_mval, event->mval);
720 
721  if ((walk->center_mval[0] != event->mval[0]) || (walk->center_mval[1] != event->mval[1])) {
722  walk->redraw = true;
723 
724 #ifdef USE_TABLET_SUPPORT
725  if (walk->is_cursor_absolute) {
726  /* pass */
727  }
728  else
729 #endif
730  if (WM_event_is_last_mousemove(event)) {
731  wmWindow *win = CTX_wm_window(C);
732 
733 #ifdef __APPLE__
734  if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) ||
735  (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2))
736 #endif
737  {
738  WM_cursor_warp(win,
739  walk->region->winrct.xmin + walk->center_mval[0],
740  walk->region->winrct.ymin + walk->center_mval[1]);
741  copy_v2_v2_int(walk->prev_mval, walk->center_mval);
742  }
743  }
744  }
745  }
746 #ifdef WITH_INPUT_NDOF
747  else if (event->type == NDOF_MOTION) {
748  /* do these automagically get delivered? yes. */
749  // puts("ndof motion detected in walk mode!");
750  // static const char *tag_name = "3D mouse position";
751 
752  const wmNDOFMotionData *incoming_ndof = event->customdata;
753  switch (incoming_ndof->progress) {
754  case P_STARTING:
755  /* start keeping track of 3D mouse position */
756 # ifdef NDOF_WALK_DEBUG
757  puts("start keeping track of 3D mouse position");
758 # endif
759  /* fall-through */
760  case P_IN_PROGRESS:
761  /* update 3D mouse position */
762 # ifdef NDOF_WALK_DEBUG
763  putchar('.');
764  fflush(stdout);
765 # endif
766  if (walk->ndof == NULL) {
767  // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
768  walk->ndof = MEM_dupallocN(incoming_ndof);
769  // walk->ndof = malloc(sizeof(wmNDOFMotionData));
770  }
771  else {
772  memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
773  }
774  break;
775  case P_FINISHING:
776  /* stop keeping track of 3D mouse position */
777 # ifdef NDOF_WALK_DEBUG
778  puts("stop keeping track of 3D mouse position");
779 # endif
780  if (walk->ndof) {
781  MEM_freeN(walk->ndof);
782  // free(walk->ndof);
783  walk->ndof = NULL;
784  }
785 
786  /* update the time else the view will jump when 2D mouse/timer resume */
788 
789  break;
790  default:
791  break; /* should always be one of the above 3 */
792  }
793  }
794 #endif /* WITH_INPUT_NDOF */
795  /* handle modal keymap first */
796  else if (event->type == EVT_MODAL_MAP) {
797  switch (event->val) {
798  case WALK_MODAL_CANCEL:
799  walk->state = WALK_CANCEL;
800  break;
801  case WALK_MODAL_CONFIRM:
802  walk->state = WALK_CONFIRM;
803  break;
804 
806  base_speed *= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
807  break;
809  base_speed /= 1.0f + (walk->is_slow ? 0.01f : 0.1f);
810  break;
811 
812  /* implement WASD keys */
815  break;
818  break;
819  case WALK_MODAL_DIR_LEFT:
821  break;
824  break;
825  case WALK_MODAL_DIR_UP:
827  break;
828  case WALK_MODAL_DIR_DOWN:
830  break;
831 
834  break;
837  break;
840  break;
843  break;
845  walk->active_directions &= ~WALK_BIT_UP;
846  break;
849  break;
850 
852  walk->is_fast = true;
853  break;
855  walk->is_fast = false;
856  break;
858  walk->is_slow = true;
859  break;
861  walk->is_slow = false;
862  break;
863 
864 #define JUMP_SPEED_MIN 1.0f
865 #define JUMP_TIME_MAX 0.2f /* s */
866 #define JUMP_SPEED_MAX sqrtf(2.0f * walk->gravity * walk->jump_height)
867 
869  if (walk->gravity_state == WALK_GRAVITY_STATE_JUMP) {
870  float t;
871 
872  /* delta time */
874 
875  /* Reduce the velocity, if JUMP wasn't hold for long enough. */
876  t = min_ff(t, JUMP_TIME_MAX);
877  walk->speed_jump = JUMP_SPEED_MIN +
879 
880  /* when jumping, duration is how long it takes before we start going down */
882 
883  /* no more increase of jump speed */
885  }
886  break;
887  case WALK_MODAL_JUMP:
888  if ((walk->navigation_mode == WALK_MODE_GRAVITY) &&
891  /* no need to check for ground,
892  * walk->gravity wouldn't be off
893  * if we were over a hole */
895  walk->speed_jump = JUMP_SPEED_MAX;
896 
898  copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
899 
900  /* using previous vec because WASD keys are not called when SPACE is */
901  copy_v2_v2(walk->teleport.direction, walk->dvec_prev);
902 
903  /* when jumping, duration is how long it takes before we start going down */
905  }
906 
907  break;
908 
909  case WALK_MODAL_TELEPORT: {
910  float loc[3], nor[3];
911  float distance;
912  bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance);
913 
914  /* in case we are teleporting middle way from a jump */
915  walk->speed_jump = 0.0f;
916 
917  if (ret) {
918  WalkTeleport *teleport = &walk->teleport;
919 
920  /* Store the current navigation mode if we are not already teleporting. */
921  if (teleport->state == WALK_TELEPORT_STATE_OFF) {
922  teleport->navigation_mode = walk->navigation_mode;
923  }
924  teleport->state = WALK_TELEPORT_STATE_ON;
926  teleport->duration = U.walk_navigation.teleport_time;
927 
929 
930  copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]);
931 
932  /* stop the camera from a distance (camera height) */
934  add_v3_v3(loc, nor);
935 
936  sub_v3_v3v3(teleport->direction, loc, teleport->origin);
937  }
938 
939  break;
940  }
941 
942 #undef JUMP_SPEED_MAX
943 #undef JUMP_TIME_MAX
944 #undef JUMP_SPEED_MIN
945 
946  case WALK_MODAL_TOGGLE:
947  if (walk->navigation_mode == WALK_MODE_GRAVITY) {
949  }
950  else { /* WALK_MODE_FREE */
952  }
953  break;
954  }
955  }
956 }
957 
958 static void walkMoveCamera(bContext *C,
959  WalkInfo *walk,
960  const bool do_rotate,
961  const bool do_translate,
962  const bool is_confirm)
963 {
964  /* we only consider autokeying on playback or if user confirmed walk on the same frame
965  * otherwise we get a keyframe even if the user cancels. */
966  const bool use_autokey = is_confirm || walk->anim_playing;
968  walk->v3d_camera_control, use_autokey, C, do_rotate, do_translate);
969  if (use_autokey) {
970  walk->need_rotation_keyframe = false;
971  walk->need_translation_keyframe = false;
972  }
973 }
974 
975 static float getFreeFallDistance(const float gravity, const float time)
976 {
977  return gravity * (time * time) * 0.5f;
978 }
979 
980 static float getVelocityZeroTime(const float gravity, const float velocity)
981 {
982  return velocity / gravity;
983 }
984 
985 static int walkApply(bContext *C, WalkInfo *walk, bool is_confirm)
986 {
987 #define WALK_ROTATE_RELATIVE_FAC 2.2f /* More is faster, relative to region size. */
988 #define WALK_ROTATE_CONSTANT_FAC DEG2RAD(0.15f) /* More is faster, radians per-pixel. */
989 #define WALK_TOP_LIMIT DEG2RADF(85.0f)
990 #define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f)
991 #define WALK_MOVE_SPEED base_speed
992 #define WALK_BOOST_FACTOR ((void)0, walk->speed_factor)
993 
994  /* walk mode - Ctrl+Shift+F
995  * a walk loop where the user can move move the view as if they are in a walk game
996  */
997  RegionView3D *rv3d = walk->rv3d;
998  ARegion *region = walk->region;
999 
1000  /* 3x3 copy of the view matrix so we can move along the view axis */
1001  float mat[3][3];
1002  /* this is the direction that's added to the view offset per redraw */
1003  float dvec[3] = {0.0f, 0.0f, 0.0f};
1004 
1005  int moffset[2]; /* mouse offset from the views center */
1006  float tmp_quat[4]; /* used for rotating the view */
1007 
1008 #ifdef NDOF_WALK_DEBUG
1009  {
1010  static uint iteration = 1;
1011  printf("walk timer %d\n", iteration++);
1012  }
1013 #endif
1014 
1015  {
1016  /* mouse offset from the center */
1017  copy_v2_v2_int(moffset, walk->moffset);
1018 
1019  /* apply moffset so we can re-accumulate */
1020  walk->moffset[0] = 0;
1021  walk->moffset[1] = 0;
1022 
1023  /* revert mouse */
1024  if (walk->is_reversed) {
1025  moffset[1] = -moffset[1];
1026  }
1027 
1028  /* Should we redraw? */
1029  if ((walk->active_directions) || moffset[0] || moffset[1] ||
1031  walk->gravity_state != WALK_GRAVITY_STATE_OFF || is_confirm) {
1032  float dvec_tmp[3];
1033 
1034  /* time how fast it takes for us to redraw,
1035  * this is so simple scenes don't walk too fast */
1036  double time_current;
1037  float time_redraw;
1038 #ifdef NDOF_WALK_DRAW_TOOMUCH
1039  walk->redraw = 1;
1040 #endif
1041  time_current = PIL_check_seconds_timer();
1042  time_redraw = (float)(time_current - walk->time_lastdraw);
1043 
1044  walk->time_lastdraw = time_current;
1045 
1046  /* base speed in m/s */
1047  walk->speed = WALK_MOVE_SPEED;
1048 
1049  if (walk->is_fast) {
1050  walk->speed *= WALK_BOOST_FACTOR;
1051  }
1052  else if (walk->is_slow) {
1053  walk->speed *= 1.0f / WALK_BOOST_FACTOR;
1054  }
1055 
1056  copy_m3_m4(mat, rv3d->viewinv);
1057 
1058  {
1059  /* rotate about the X axis- look up/down */
1060  if (moffset[1]) {
1061  float upvec[3];
1062  float angle;
1063  float y;
1064 
1065  /* relative offset */
1066  y = (float)moffset[1];
1067 
1068  /* Speed factor. */
1069 #ifdef USE_TABLET_SUPPORT
1070  if (walk->is_cursor_absolute) {
1071  y /= region->winy;
1073  }
1074  else
1075 #endif
1076  {
1078  }
1079 
1080  /* user adjustment factor */
1081  y *= walk->mouse_speed;
1082 
1083  /* clamp the angle limits */
1084  /* it ranges from 90.0f to -90.0f */
1085  angle = -asinf(rv3d->viewmat[2][2]);
1086 
1087  if (angle > WALK_TOP_LIMIT && y > 0.0f) {
1088  y = 0.0f;
1089  }
1090  else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) {
1091  y = 0.0f;
1092  }
1093 
1094  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
1095  mul_m3_v3(mat, upvec);
1096  /* Rotate about the relative up vec */
1097  axis_angle_to_quat(tmp_quat, upvec, -y);
1098  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
1099  }
1100 
1101  /* rotate about the Y axis- look left/right */
1102  if (moffset[0]) {
1103  float upvec[3];
1104  float x;
1105 
1106  /* if we're upside down invert the moffset */
1107  copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
1108  mul_m3_v3(mat, upvec);
1109 
1110  if (upvec[2] < 0.0f) {
1111  moffset[0] = -moffset[0];
1112  }
1113 
1114  /* relative offset */
1115  x = (float)moffset[0];
1116 
1117  /* Speed factor. */
1118 #ifdef USE_TABLET_SUPPORT
1119  if (walk->is_cursor_absolute) {
1120  x /= region->winx;
1122  }
1123  else
1124 #endif
1125  {
1127  }
1128 
1129  /* user adjustment factor */
1130  x *= walk->mouse_speed;
1131 
1132  /* Rotate about the relative up vec */
1133  axis_angle_to_quat_single(tmp_quat, 'Z', x);
1134  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
1135  }
1136  }
1137 
1138  /* WASD - 'move' translation code */
1139  if ((walk->active_directions) && (walk->gravity_state == WALK_GRAVITY_STATE_OFF)) {
1140 
1141  short direction;
1142  zero_v3(dvec);
1143 
1144  if ((walk->active_directions & WALK_BIT_FORWARD) ||
1146 
1147  direction = 0;
1148 
1149  if ((walk->active_directions & WALK_BIT_FORWARD)) {
1150  direction += 1;
1151  }
1152 
1153  if ((walk->active_directions & WALK_BIT_BACKWARD)) {
1154  direction -= 1;
1155  }
1156 
1157  copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
1158  mul_m3_v3(mat, dvec_tmp);
1159 
1160  if (walk->navigation_mode == WALK_MODE_GRAVITY) {
1161  dvec_tmp[2] = 0.0f;
1162  }
1163 
1164  normalize_v3(dvec_tmp);
1165  add_v3_v3(dvec, dvec_tmp);
1166  }
1167 
1168  if ((walk->active_directions & WALK_BIT_LEFT) ||
1169  (walk->active_directions & WALK_BIT_RIGHT)) {
1170 
1171  direction = 0;
1172 
1173  if ((walk->active_directions & WALK_BIT_LEFT)) {
1174  direction += 1;
1175  }
1176 
1177  if ((walk->active_directions & WALK_BIT_RIGHT)) {
1178  direction -= 1;
1179  }
1180 
1181  dvec_tmp[0] = direction * rv3d->viewinv[0][0];
1182  dvec_tmp[1] = direction * rv3d->viewinv[0][1];
1183  dvec_tmp[2] = 0.0f;
1184 
1185  normalize_v3(dvec_tmp);
1186  add_v3_v3(dvec, dvec_tmp);
1187  }
1188 
1189  if ((walk->active_directions & WALK_BIT_UP) || (walk->active_directions & WALK_BIT_DOWN)) {
1190 
1191  if (walk->navigation_mode == WALK_MODE_FREE) {
1192 
1193  direction = 0;
1194 
1195  if ((walk->active_directions & WALK_BIT_UP)) {
1196  direction -= 1;
1197  }
1198 
1199  if ((walk->active_directions & WALK_BIT_DOWN)) {
1200  direction = 1;
1201  }
1202 
1203  copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction);
1204  add_v3_v3(dvec, dvec_tmp);
1205  }
1206  }
1207 
1208  /* apply movement */
1209  mul_v3_fl(dvec, walk->speed * time_redraw);
1210  }
1211 
1212  /* stick to the floor */
1213  if (walk->navigation_mode == WALK_MODE_GRAVITY &&
1215 
1216  bool ret;
1217  float ray_distance;
1218  float difference = -100.0f;
1219  float fall_distance;
1220 
1221  ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
1222 
1223  if (ret) {
1224  difference = walk->view_height - ray_distance;
1225  }
1226 
1227  /* the distance we would fall naturally smoothly enough that we
1228  * can manually drop the object without activating gravity */
1229  fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR;
1230 
1231  if (fabsf(difference) < fall_distance) {
1232  /* slope/stairs */
1233  dvec[2] -= difference;
1234 
1235  /* in case we switched from FREE to GRAVITY too close to the ground */
1236  if (walk->gravity_state == WALK_GRAVITY_STATE_START) {
1238  }
1239  }
1240  else {
1241  /* hijack the teleport variables */
1244  walk->teleport.duration = 0.0f;
1245 
1246  copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]);
1247  copy_v2_v2(walk->teleport.direction, dvec);
1248  }
1249  }
1250 
1251  /* Falling or jumping) */
1253  float t;
1254  float z_cur, z_new;
1255  bool ret;
1256  float ray_distance, difference = -100.0f;
1257 
1258  /* delta time */
1260 
1261  /* keep moving if we were moving */
1262  copy_v2_v2(dvec, walk->teleport.direction);
1263 
1264  z_cur = walk->rv3d->viewinv[3][2];
1265  z_new = walk->teleport.origin[2] - getFreeFallDistance(walk->gravity, t) * walk->grid;
1266 
1267  /* jump */
1268  z_new += t * walk->speed_jump * walk->grid;
1269 
1270  /* duration is the jump duration */
1271  if (t > walk->teleport.duration) {
1272 
1273  /* check to see if we are landing */
1274  ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
1275 
1276  if (ret) {
1277  difference = walk->view_height - ray_distance;
1278  }
1279 
1280  if (difference > 0.0f) {
1281  /* quit falling, lands at "view_height" from the floor */
1282  dvec[2] -= difference;
1284  walk->speed_jump = 0.0f;
1285  }
1286  else {
1287  /* keep falling */
1288  dvec[2] = z_cur - z_new;
1289  }
1290  }
1291  else {
1292  /* keep going up (jump) */
1293  dvec[2] = z_cur - z_new;
1294  }
1295  }
1296 
1297  /* Teleport */
1298  else if (walk->teleport.state == WALK_TELEPORT_STATE_ON) {
1299  float t; /* factor */
1300  float new_loc[3];
1301  float cur_loc[3];
1302 
1303  /* linear interpolation */
1305  t /= walk->teleport.duration;
1306 
1307  /* clamp so we don't go past our limit */
1308  if (t >= 1.0f) {
1309  t = 1.0f;
1312  }
1313 
1314  mul_v3_v3fl(new_loc, walk->teleport.direction, t);
1315  add_v3_v3(new_loc, walk->teleport.origin);
1316 
1317  copy_v3_v3(cur_loc, walk->rv3d->viewinv[3]);
1318  sub_v3_v3v3(dvec, cur_loc, new_loc);
1319  }
1320 
1321  /* scale the movement to the scene size */
1322  mul_v3_v3fl(dvec_tmp, dvec, walk->grid);
1323  add_v3_v3(rv3d->ofs, dvec_tmp);
1324 
1325  if (rv3d->persp == RV3D_CAMOB) {
1326  walk->need_rotation_keyframe |= (moffset[0] || moffset[1]);
1327  walk->need_translation_keyframe |= (len_squared_v3(dvec_tmp) > FLT_EPSILON);
1329  C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
1330  }
1331  }
1332  else {
1333  /* we're not redrawing but we need to update the time else the view will jump */
1335  }
1336  /* end drawing */
1337  copy_v3_v3(walk->dvec_prev, dvec);
1338  }
1339 
1340  return OPERATOR_FINISHED;
1341 #undef WALK_ROTATE_RELATIVE_FAC
1342 #undef WALK_TOP_LIMIT
1343 #undef WALK_BOTTOM_LIMIT
1344 #undef WALK_MOVE_SPEED
1345 #undef WALK_BOOST_FACTOR
1346 }
1347 
1348 #ifdef WITH_INPUT_NDOF
1349 static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm)
1350 {
1352  bool has_translate, has_rotate;
1353 
1354  view3d_ndof_fly(walk->ndof,
1355  walk->v3d,
1356  walk->rv3d,
1357  walk->is_slow,
1358  lock_ob ? lock_ob->protectflag : 0,
1359  &has_translate,
1360  &has_rotate);
1361 
1362  if (has_translate || has_rotate) {
1363  walk->redraw = true;
1364 
1365  if (walk->rv3d->persp == RV3D_CAMOB) {
1366  walk->need_rotation_keyframe |= has_rotate;
1367  walk->need_translation_keyframe |= has_translate;
1369  C, walk, walk->need_rotation_keyframe, walk->need_translation_keyframe, is_confirm);
1370  }
1371  }
1372 }
1373 #endif /* WITH_INPUT_NDOF */
1374 
1377 /* -------------------------------------------------------------------- */
1381 static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1382 {
1384  WalkInfo *walk;
1385 
1387  return OPERATOR_CANCELLED;
1388  }
1389 
1390  walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation");
1391 
1392  op->customdata = walk;
1393 
1394  if (initWalkInfo(C, walk, op) == false) {
1395  MEM_freeN(op->customdata);
1396  return OPERATOR_CANCELLED;
1397  }
1398 
1399  walkEvent(C, walk, event);
1400 
1402 
1403  return OPERATOR_RUNNING_MODAL;
1404 }
1405 
1406 static void walk_cancel(bContext *C, wmOperator *op)
1407 {
1408  WalkInfo *walk = op->customdata;
1409 
1410  walk->state = WALK_CANCEL;
1411  walkEnd(C, walk);
1412  op->customdata = NULL;
1413 }
1414 
1415 static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
1416 {
1417  int exit_code;
1418  bool do_draw = false;
1419  WalkInfo *walk = op->customdata;
1420  RegionView3D *rv3d = walk->rv3d;
1422 
1423  walk->redraw = false;
1424 
1425  walkEvent(C, walk, event);
1426 
1427 #ifdef WITH_INPUT_NDOF
1428  if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */
1429  if (event->type == NDOF_MOTION) {
1430  walkApply_ndof(C, walk, false);
1431  }
1432  }
1433  else
1434 #endif /* WITH_INPUT_NDOF */
1435  if (event->type == TIMER && event->customdata == walk->timer) {
1436  walkApply(C, walk, false);
1437  }
1438 
1439  do_draw |= walk->redraw;
1440 
1441  exit_code = walkEnd(C, walk);
1442 
1443  if (exit_code != OPERATOR_RUNNING_MODAL) {
1444  do_draw = true;
1445  }
1446 
1447  if (do_draw) {
1448  if (rv3d->persp == RV3D_CAMOB) {
1449  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, walk_object);
1450  }
1451 
1452  /* too frequent, commented with NDOF_WALK_DRAW_TOOMUCH for now */
1453  // puts("redraw!");
1455  }
1456  return exit_code;
1457 }
1458 
1460 {
1461  /* identifiers */
1462  ot->name = "Walk Navigation";
1463  ot->description = "Interactively walk around the scene";
1464  ot->idname = "VIEW3D_OT_walk";
1465 
1466  /* api callbacks */
1467  ot->invoke = walk_invoke;
1468  ot->cancel = walk_cancel;
1469  ot->modal = walk_modal;
1471 
1472  /* flags */
1473  ot->flag = OPTYPE_BLOCKING;
1474 }
1475 
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Definition: context.c:769
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
#define BVH_RAYCAST_DIST_MAX
Definition: BLI_kdopbvh.h:105
MINLINE float min_ff(float a, float b)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void axis_angle_to_quat(float r[4], const float axis[3], const float angle)
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
Definition: math_rotation.c:65
void axis_angle_to_quat_single(float q[4], const char axis, const float angle)
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], const 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:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
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:667
bool ED_operator_region_view3d_active(struct bContext *C)
Definition: screen_ops.c:235
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
Definition: spacetypes.c:238
#define REGION_DRAW_POST_PIXEL
Definition: ED_space_api.h:67
void ED_region_draw_cb_exit(struct ARegionType *, void *)
Definition: spacetypes.c:253
bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx, struct Depsgraph *depsgraph, 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_view3d(struct Scene *scene, int flag, const struct ARegion *region, const struct View3D *v3d)
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
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, const bool no_shift)
bool ED_view3d_offset_lock_check(const struct View3D *v3d, const struct RegionView3D *rv3d)
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:36
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ 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:39
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:343
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
#define ND_TRANSFORM
Definition: WM_types.h:357
#define NC_OBJECT
Definition: WM_types.h:280
@ P_IN_PROGRESS
Definition: WM_types.h:654
@ P_STARTING
Definition: WM_types.h:653
@ P_FINISHING
Definition: WM_types.h:655
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
#define asinf(x)
#define fabsf(x)
format
Definition: logImageCore.h:47
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
return ret
struct ARegionType * type
void * first
Definition: DNA_listBase.h:47
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
int prev_mval[2]
Definition: view3d_walk.c:226
Scene * scene
Definition: view3d_walk.c:207
bool is_slow
Definition: view3d_walk.c:266
wmTimer * timer
Definition: view3d_walk.c:210
struct Depsgraph * depsgraph
Definition: view3d_walk.c:206
double time_lastdraw
Definition: view3d_walk.c:247
float mouse_speed
Definition: view3d_walk.c:262
eWalkMethod navigation_mode
Definition: view3d_walk.c:256
WalkTeleport teleport
Definition: view3d_walk.c:259
short state
Definition: view3d_walk.c:212
bool anim_playing
Definition: view3d_walk.c:221
float dvec_prev[3]
Definition: view3d_walk.c:253
float speed_jump
Definition: view3d_walk.c:289
float speed
Definition: view3d_walk.c:241
float gravity
Definition: view3d_walk.c:281
View3D * v3d
Definition: view3d_walk.c:204
bool need_translation_keyframe
Definition: view3d_walk.c:223
struct View3DCameraControl * v3d_camera_control
Definition: view3d_walk.c:297
bool need_rotation_keyframe
Definition: view3d_walk.c:222
float jump_height
Definition: view3d_walk.c:291
bool redraw
Definition: view3d_walk.c:213
float view_height
Definition: view3d_walk.c:284
bool is_fast
Definition: view3d_walk.c:265
eWalkGravityState gravity_state
Definition: view3d_walk.c:280
bool is_cursor_first
Definition: view3d_walk.c:273
int center_mval[2]
Definition: view3d_walk.c:228
void * draw_handle_pixel
Definition: view3d_walk.c:249
float base_speed
Definition: view3d_walk.c:239
bool is_reversed
Definition: view3d_walk.c:269
bool is_cursor_absolute
Definition: view3d_walk.c:276
int active_directions
Definition: view3d_walk.c:287
ARegion * region
Definition: view3d_walk.c:205
float speed_factor
Definition: view3d_walk.c:293
float grid
Definition: view3d_walk.c:243
struct SnapObjectContext * snap_context
Definition: view3d_walk.c:295
int moffset[2]
Definition: view3d_walk.c:230
RegionView3D * rv3d
Definition: view3d_walk.c:203
float direction[3]
Definition: view3d_walk.c:195
float duration
Definition: view3d_walk.c:193
float origin[3]
Definition: view3d_walk.c:194
double initial_time
Definition: view3d_walk.c:196
eWalkMethod navigation_mode
Definition: view3d_walk.c:197
eWalkTeleportState state
Definition: view3d_walk.c:192
float xmin
Definition: DNA_vec_types.h:85
float ymin
Definition: DNA_vec_types.h:86
int ymin
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
wmTabletData tablet
Definition: WM_types.h:623
short type
Definition: WM_types.h:577
void * customdata
Definition: WM_types.h:631
const void * modal_items
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
const char * description
Definition: WM_types.h:726
struct ReportList * reports
char is_motion_absolute
Definition: WM_types.h:547
double PIL_check_seconds_timer(void)
Definition: time.c:80
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float distance(const float2 &a, const float2 &b)
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)
Definition: view3d_walk.c:958
static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *region, void *arg)
Definition: view3d_walk.c:314
static bool walk_floor_distance_get(RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance)
Definition: view3d_walk.c:385
#define JUMP_SPEED_MAX
#define WALK_MOVE_SPEED
#define WALK_ROTATE_CONSTANT_FAC
#define WALK_ROTATE_RELATIVE_FAC
eWalkTeleportState
Definition: view3d_walk.c:115
@ WALK_TELEPORT_STATE_ON
Definition: view3d_walk.c:117
@ WALK_TELEPORT_STATE_OFF
Definition: view3d_walk.c:116
static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: view3d_walk.c:1415
@ WALK_BIT_UP
Definition: view3d_walk.c:111
@ WALK_BIT_RIGHT
Definition: view3d_walk.c:110
@ WALK_BIT_DOWN
Definition: view3d_walk.c:112
@ WALK_BIT_BACKWARD
Definition: view3d_walk.c:108
@ WALK_BIT_LEFT
Definition: view3d_walk.c:109
@ WALK_BIT_FORWARD
Definition: view3d_walk.c:107
static int walkEnd(bContext *C, WalkInfo *walk)
Definition: view3d_walk.c:617
static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: view3d_walk.c:1381
void VIEW3D_OT_walk(wmOperatorType *ot)
Definition: view3d_walk.c:1459
static float userdef_speed
Definition: view3d_walk.c:477
eWalkGravityState
Definition: view3d_walk.c:125
@ WALK_GRAVITY_STATE_START
Definition: view3d_walk.c:128
@ WALK_GRAVITY_STATE_JUMP
Definition: view3d_walk.c:127
@ WALK_GRAVITY_STATE_OFF
Definition: view3d_walk.c:126
@ WALK_GRAVITY_STATE_ON
Definition: view3d_walk.c:129
#define JUMP_TIME_MAX
eWalkMethod
Definition: view3d_walk.c:120
@ WALK_MODE_GRAVITY
Definition: view3d_walk.c:122
@ WALK_MODE_FREE
Definition: view3d_walk.c:121
static void walk_cancel(bContext *C, wmOperator *op)
Definition: view3d_walk.c:1406
#define WALK_TOP_LIMIT
static float getFreeFallDistance(const float gravity, const float time)
Definition: view3d_walk.c:975
static bool walk_ray_cast(RegionView3D *rv3d, WalkInfo *walk, float r_location[3], float r_normal[3], float *ray_distance)
Definition: view3d_walk.c:428
#define WALK_BOOST_FACTOR
static float getVelocityZeroTime(const float gravity, const float velocity)
Definition: view3d_walk.c:980
static void walkEvent(bContext *C, WalkInfo *walk, const wmEvent *event)
Definition: view3d_walk.c:683
static int walkApply(bContext *C, struct WalkInfo *walk, bool is_confirm)
Definition: view3d_walk.c:985
void walk_modal_keymap(wmKeyConfig *keyconf)
Definition: view3d_walk.c:133
@ WALK_MODAL_DECELERATE
Definition: view3d_walk.c:103
@ WALK_MODAL_JUMP
Definition: view3d_walk.c:98
@ WALK_MODAL_DIR_LEFT_STOP
Definition: view3d_walk.c:87
@ WALK_MODAL_SLOW_DISABLE
Definition: view3d_walk.c:97
@ WALK_MODAL_DIR_RIGHT
Definition: view3d_walk.c:88
@ WALK_MODAL_TOGGLE
Definition: view3d_walk.c:101
@ WALK_MODAL_SLOW_ENABLE
Definition: view3d_walk.c:96
@ WALK_MODAL_DIR_DOWN_STOP
Definition: view3d_walk.c:93
@ WALK_MODAL_CONFIRM
Definition: view3d_walk.c:81
@ WALK_MODAL_DIR_LEFT
Definition: view3d_walk.c:86
@ WALK_MODAL_FAST_ENABLE
Definition: view3d_walk.c:94
@ WALK_MODAL_DIR_BACKWARD
Definition: view3d_walk.c:84
@ WALK_MODAL_TELEPORT
Definition: view3d_walk.c:100
@ WALK_MODAL_DIR_FORWARD_STOP
Definition: view3d_walk.c:83
@ WALK_MODAL_DIR_UP
Definition: view3d_walk.c:90
@ WALK_MODAL_JUMP_STOP
Definition: view3d_walk.c:99
@ WALK_MODAL_DIR_DOWN
Definition: view3d_walk.c:92
@ WALK_MODAL_DIR_FORWARD
Definition: view3d_walk.c:82
@ WALK_MODAL_DIR_BACKWARD_STOP
Definition: view3d_walk.c:85
@ WALK_MODAL_DIR_RIGHT_STOP
Definition: view3d_walk.c:89
@ WALK_MODAL_CANCEL
Definition: view3d_walk.c:80
@ WALK_MODAL_ACCELERATE
Definition: view3d_walk.c:102
@ WALK_MODAL_DIR_UP_STOP
Definition: view3d_walk.c:91
@ WALK_MODAL_FAST_DISABLE
Definition: view3d_walk.c:95
static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op)
Definition: view3d_walk.c:479
#define JUMP_SPEED_MIN
static float base_speed
Definition: view3d_walk.c:476
@ WALK_RUNNING
Definition: view3d_walk.c:470
@ WALK_CONFIRM
Definition: view3d_walk.c:472
@ WALK_CANCEL
Definition: view3d_walk.c:471
static void walk_navigation_mode_set(WalkInfo *walk, eWalkMethod mode)
Definition: view3d_walk.c:370
#define WALK_BOTTOM_LIMIT
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:207
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:216
@ WM_CURSOR_NONE
Definition: wm_cursors.h:74
bool WM_event_is_last_mousemove(const wmEvent *event)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ TIMER
@ EVT_MODAL_MAP
@ MOUSEMOVE
@ NDOF_MOTION
@ INBETWEEN_MOUSEMOVE
wmOperatorType * ot
Definition: wm_files.c:3156
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:1669
void WM_cursor_compatible_xy(wmWindow *win, int *x, int *y)
Definition: wm_window.c:2110
void WM_cursor_warp(wmWindow *win, int x, int y)
Definition: wm_window.c:2091
wmTimer * WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)
Definition: wm_window.c:1632