Blender  V2.93
view3d_fly.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 
25 /* defines VIEW3D_OT_fly modal operator */
26 
27 #ifdef WITH_INPUT_NDOF
28 //# define NDOF_FLY_DEBUG
29 /* is this needed for ndof? - commented so redraw doesn't thrash - campbell */
30 //# define NDOF_FLY_DRAW_TOOMUCH
31 #endif /* WITH_INPUT_NDOF */
32 
33 #include "DNA_object_types.h"
34 
35 #include "MEM_guardedalloc.h"
36 
37 #include "BLI_blenlib.h"
38 #include "BLI_math.h"
39 
40 #include "BKE_context.h"
41 #include "BKE_report.h"
42 
43 #include "BLT_translation.h"
44 
45 #include "WM_api.h"
46 #include "WM_types.h"
47 
48 #include "ED_screen.h"
49 #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 /* -------------------------------------------------------------------- */
66 /* NOTE: these defines are saved in keymap files,
67  * do not change values but just add new ones */
68 enum {
87  FLY_MODAL_SPEED, /* mouse-pan typically. */
88 };
89 
90 /* relative view axis locking - xlock, zlock */
91 typedef enum eFlyPanState {
92  /* disabled */
94 
95  /* enabled but not checking because mouse hasn't moved outside the margin since locking was
96  * checked an not needed when the mouse moves, locking is set to 2 so checks are done. */
98 
99  /* mouse moved and checking needed,
100  * if no view altering is done its changed back to #FLY_AXISLOCK_STATE_IDLE */
103 
104 /* called in transform_ops.c, on each regeneration of keymaps */
106 {
107  static const EnumPropertyItem modal_items[] = {
108  {FLY_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
109  {FLY_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
110 
111  {FLY_MODAL_DIR_FORWARD, "FORWARD", 0, "Forward", ""},
112  {FLY_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Backward", ""},
113  {FLY_MODAL_DIR_LEFT, "LEFT", 0, "Left", ""},
114  {FLY_MODAL_DIR_RIGHT, "RIGHT", 0, "Right", ""},
115  {FLY_MODAL_DIR_UP, "UP", 0, "Up", ""},
116  {FLY_MODAL_DIR_DOWN, "DOWN", 0, "Down", ""},
117 
118  {FLY_MODAL_PAN_ENABLE, "PAN_ENABLE", 0, "Pan", ""},
119  {FLY_MODAL_PAN_DISABLE, "PAN_DISABLE", 0, "Pan (Off)", ""},
120 
121  {FLY_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""},
122  {FLY_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""},
123 
124  {FLY_MODAL_AXIS_LOCK_X, "AXIS_LOCK_X", 0, "X Axis Correction", "X axis correction (toggle)"},
125  {FLY_MODAL_AXIS_LOCK_Z, "AXIS_LOCK_Z", 0, "X Axis Correction", "Z axis correction (toggle)"},
126 
127  {FLY_MODAL_PRECISION_ENABLE, "PRECISION_ENABLE", 0, "Precision", ""},
128  {FLY_MODAL_PRECISION_DISABLE, "PRECISION_DISABLE", 0, "Precision (Off)", ""},
129 
130  {FLY_MODAL_FREELOOK_ENABLE, "FREELOOK_ENABLE", 0, "Rotation", ""},
131  {FLY_MODAL_FREELOOK_DISABLE, "FREELOOK_DISABLE", 0, "Rotation (Off)", ""},
132 
133  {0, NULL, 0, NULL, NULL},
134  };
135 
136  wmKeyMap *keymap = WM_modalkeymap_find(keyconf, "View3D Fly Modal");
137 
138  /* this function is called for each spacetype, only needs to add map once */
139  if (keymap && keymap->modal_items) {
140  return;
141  }
142 
143  keymap = WM_modalkeymap_ensure(keyconf, "View3D Fly Modal", modal_items);
144 
145  /* assign map to operators */
146  WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly");
147 }
148 
151 /* -------------------------------------------------------------------- */
155 typedef struct FlyInfo {
156  /* context stuff */
162 
165 
166  short state;
167  bool redraw;
171 
179 
181  int mval[2];
183  int center_mval[2];
185  float width, height;
186 
187 #ifdef WITH_INPUT_NDOF
189  wmNDOFMotionData *ndof;
190 #endif
191 
192  /* fly state state */
194  float speed;
196  short axis;
198  bool pan_view;
199 
204  float grid;
205 
206  /* compare between last state */
211 
213 
214  /* use for some lag */
216  float dvec_prev[3];
217 
219 
221 
224 /* -------------------------------------------------------------------- */
228 /* prototypes */
229 #ifdef WITH_INPUT_NDOF
230 static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm);
231 #endif /* WITH_INPUT_NDOF */
232 static int flyApply(bContext *C, struct FlyInfo *fly, bool is_confirm);
233 
234 static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
235 {
236  FlyInfo *fly = arg;
237  rctf viewborder;
238  int xoff, yoff;
239  float x1, x2, y1, y2;
240 
243  fly->scene, fly->depsgraph, fly->region, fly->v3d, fly->rv3d, &viewborder, false);
244  xoff = viewborder.xmin;
245  yoff = viewborder.ymin;
246  }
247  else {
248  xoff = 0;
249  yoff = 0;
250  }
251 
252  /* draws 4 edge brackets that frame the safe area where the
253  * mouse can move during fly mode without spinning the view */
254 
255  x1 = xoff + 0.45f * fly->width;
256  y1 = yoff + 0.45f * fly->height;
257  x2 = xoff + 0.55f * fly->width;
258  y2 = yoff + 0.55f * fly->height;
259 
262 
264 
266 
268 
269  /* bottom left */
270  immVertex2f(pos, x1, y1);
271  immVertex2f(pos, x1, y1 + 5);
272 
273  immVertex2f(pos, x1, y1);
274  immVertex2f(pos, x1 + 5, y1);
275 
276  /* top right */
277  immVertex2f(pos, x2, y2);
278  immVertex2f(pos, x2, y2 - 5);
279 
280  immVertex2f(pos, x2, y2);
281  immVertex2f(pos, x2 - 5, y2);
282 
283  /* top left */
284  immVertex2f(pos, x1, y2);
285  immVertex2f(pos, x1, y2 - 5);
286 
287  immVertex2f(pos, x1, y2);
288  immVertex2f(pos, x1 + 5, y2);
289 
290  /* bottom right */
291  immVertex2f(pos, x2, y1);
292  immVertex2f(pos, x2, y1 + 5);
293 
294  immVertex2f(pos, x2, y1);
295  immVertex2f(pos, x2 - 5, y1);
296 
297  immEnd();
299 }
300 
303 /* -------------------------------------------------------------------- */
307 /* FlyInfo->state */
308 enum {
312 };
313 
314 static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
315 {
317  wmWindow *win = CTX_wm_window(C);
318  rctf viewborder;
319 
320  float upvec[3]; /* tmp */
321  float mat[3][3];
322 
323  fly->rv3d = CTX_wm_region_view3d(C);
324  fly->v3d = CTX_wm_view3d(C);
325  fly->region = CTX_wm_region(C);
327  fly->scene = CTX_data_scene(C);
328 
329 #ifdef NDOF_FLY_DEBUG
330  puts("\n-- fly begin --");
331 #endif
332 
333  /* sanity check: for rare but possible case (if lib-linking the camera fails) */
334  if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
335  fly->rv3d->persp = RV3D_PERSP;
336  }
337 
338  if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) {
339  BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
340  return false;
341  }
342 
343  if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) {
344  BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked");
345  return false;
346  }
347 
348  if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
349  BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
350  return false;
351  }
352 
353  fly->state = FLY_RUNNING;
354  fly->speed = 0.0f;
355  fly->axis = 2;
356  fly->pan_view = false;
359  fly->xlock_momentum = 0.0f;
360  fly->zlock_momentum = 0.0f;
361  fly->grid = 1.0f;
362  fly->use_precision = false;
363  fly->use_freelook = false;
365 
366 #ifdef NDOF_FLY_DRAW_TOOMUCH
367  fly->redraw = 1;
368 #endif
369  zero_v3(fly->dvec_prev);
370 
371  fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);
372 
373  copy_v2_v2_int(fly->mval, event->mval);
374 
375 #ifdef WITH_INPUT_NDOF
376  fly->ndof = NULL;
377 #endif
378 
380 
383 
384  fly->rv3d->rflag |= RV3D_NAVIGATING;
385 
386  /* detect whether to start with Z locking */
387  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
388  copy_m3_m4(mat, fly->rv3d->viewinv);
389  mul_m3_v3(mat, upvec);
390  if (fabsf(upvec[2]) < 0.1f) {
392  }
393 
395  fly->depsgraph, fly->scene, fly->v3d, fly->rv3d);
396 
397  /* calculate center */
400  fly->scene, fly->depsgraph, fly->region, fly->v3d, fly->rv3d, &viewborder, false);
401 
402  fly->width = BLI_rctf_size_x(&viewborder);
403  fly->height = BLI_rctf_size_y(&viewborder);
404 
405  fly->center_mval[0] = viewborder.xmin + fly->width / 2;
406  fly->center_mval[1] = viewborder.ymin + fly->height / 2;
407  }
408  else {
409  fly->width = fly->region->winx;
410  fly->height = fly->region->winy;
411 
412  fly->center_mval[0] = fly->width / 2;
413  fly->center_mval[1] = fly->height / 2;
414  }
415 
416  /* center the mouse, probably the UI mafia are against this but without its quite annoying */
417  WM_cursor_warp(win,
418  fly->region->winrct.xmin + fly->center_mval[0],
419  fly->region->winrct.ymin + fly->center_mval[1]);
420 
421  return 1;
422 }
423 
424 static int flyEnd(bContext *C, FlyInfo *fly)
425 {
426  wmWindow *win;
427  RegionView3D *rv3d;
428 
429  if (fly->state == FLY_RUNNING) {
430  return OPERATOR_RUNNING_MODAL;
431  }
432  if (fly->state == FLY_CONFIRM) {
433  /* Needed for auto_keyframe. */
434 #ifdef WITH_INPUT_NDOF
435  if (fly->ndof) {
436  flyApply_ndof(C, fly, true);
437  }
438  else
439 #endif /* WITH_INPUT_NDOF */
440  {
441  flyApply(C, fly, true);
442  }
443  }
444 
445 #ifdef NDOF_FLY_DEBUG
446  puts("\n-- fly end --");
447 #endif
448 
449  win = CTX_wm_window(C);
450  rv3d = fly->rv3d;
451 
453 
455 
457 
458  rv3d->rflag &= ~RV3D_NAVIGATING;
459 
460 #ifdef WITH_INPUT_NDOF
461  if (fly->ndof) {
462  MEM_freeN(fly->ndof);
463  }
464 #endif
465 
466  if (fly->state == FLY_CONFIRM) {
467  MEM_freeN(fly);
468  return OPERATOR_FINISHED;
469  }
470 
471  MEM_freeN(fly);
472  return OPERATOR_CANCELLED;
473 }
474 
475 static void flyEvent(FlyInfo *fly, const wmEvent *event)
476 {
477  if (event->type == TIMER && event->customdata == fly->timer) {
478  fly->redraw = 1;
479  }
480  else if (event->type == MOUSEMOVE) {
481  copy_v2_v2_int(fly->mval, event->mval);
482  }
483 #ifdef WITH_INPUT_NDOF
484  else if (event->type == NDOF_MOTION) {
485  /* do these automagically get delivered? yes. */
486  // puts("ndof motion detected in fly mode!");
487  // static const char *tag_name = "3D mouse position";
488 
489  const wmNDOFMotionData *incoming_ndof = event->customdata;
490  switch (incoming_ndof->progress) {
491  case P_STARTING:
492  /* start keeping track of 3D mouse position */
493 # ifdef NDOF_FLY_DEBUG
494  puts("start keeping track of 3D mouse position");
495 # endif
496  /* fall-through */
497  case P_IN_PROGRESS:
498  /* update 3D mouse position */
499 # ifdef NDOF_FLY_DEBUG
500  putchar('.');
501  fflush(stdout);
502 # endif
503  if (fly->ndof == NULL) {
504  // fly->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name);
505  fly->ndof = MEM_dupallocN(incoming_ndof);
506  // fly->ndof = malloc(sizeof(wmNDOFMotionData));
507  }
508  else {
509  memcpy(fly->ndof, incoming_ndof, sizeof(wmNDOFMotionData));
510  }
511  break;
512  case P_FINISHING:
513  /* stop keeping track of 3D mouse position */
514 # ifdef NDOF_FLY_DEBUG
515  puts("stop keeping track of 3D mouse position");
516 # endif
517  if (fly->ndof) {
518  MEM_freeN(fly->ndof);
519  // free(fly->ndof);
520  fly->ndof = NULL;
521  }
522  /* update the time else the view will jump when 2D mouse/timer resume */
524  break;
525  default:
526  break; /* should always be one of the above 3 */
527  }
528  }
529 #endif /* WITH_INPUT_NDOF */
530  /* handle modal keymap first */
531  else if (event->type == EVT_MODAL_MAP) {
532  switch (event->val) {
533  case FLY_MODAL_CANCEL:
534  fly->state = FLY_CANCEL;
535  break;
536  case FLY_MODAL_CONFIRM:
537  fly->state = FLY_CONFIRM;
538  break;
539 
540  /* Speed adjusting with mouse-pan (track-pad). */
541  case FLY_MODAL_SPEED: {
542  float fac = 0.02f * (event->prevy - event->y);
543 
544  /* allowing to brake immediate */
545  if (fac > 0.0f && fly->speed < 0.0f) {
546  fly->speed = 0.0f;
547  }
548  else if (fac < 0.0f && fly->speed > 0.0f) {
549  fly->speed = 0.0f;
550  }
551  else {
552  fly->speed += fly->grid * fac;
553  }
554 
555  break;
556  }
557  case FLY_MODAL_ACCELERATE: {
558  double time_currwheel;
559  float time_wheel;
560 
561  /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
562  if (fly->axis == -1) {
563  fly->axis = 2;
564  fly->speed = fabsf(fly->speed);
565  }
566 
567  time_currwheel = PIL_check_seconds_timer();
568  time_wheel = (float)(time_currwheel - fly->time_lastwheel);
569  fly->time_lastwheel = time_currwheel;
570  /* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast) */
571  /* 0-0.5 -> 0-5.0 */
572  time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
573 
574  if (fly->speed < 0.0f) {
575  fly->speed = 0.0f;
576  }
577  else {
578  fly->speed += fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
579  }
580  break;
581  }
582  case FLY_MODAL_DECELERATE: {
583  double time_currwheel;
584  float time_wheel;
585 
586  /* not quite correct but avoids confusion WASD/arrow keys 'locking up' */
587  if (fly->axis == -1) {
588  fly->axis = 2;
589  fly->speed = -fabsf(fly->speed);
590  }
591 
592  time_currwheel = PIL_check_seconds_timer();
593  time_wheel = (float)(time_currwheel - fly->time_lastwheel);
594  fly->time_lastwheel = time_currwheel;
595  /* 0-0.5 -> 0-5.0 */
596  time_wheel = 1.0f + (10.0f - (20.0f * min_ff(time_wheel, 0.5f)));
597 
598  if (fly->speed > 0.0f) {
599  fly->speed = 0;
600  }
601  else {
602  fly->speed -= fly->grid * time_wheel * (fly->use_precision ? 0.1f : 1.0f);
603  }
604  break;
605  }
607  fly->pan_view = true;
608  break;
610  fly->pan_view = false;
611  break;
612 
613  /* implement WASD keys,
614  * comments only for 'forward '*/
616  if (fly->axis == 2 && fly->speed < 0.0f) {
617  /* reverse direction stops, tap again to continue */
618  fly->axis = -1;
619  }
620  else {
621  /* Flip speed rather than stopping, game like motion,
622  * else increase like mouse-wheel if we're already moving in that direction. */
623  if (fly->speed < 0.0f) {
624  fly->speed = -fly->speed;
625  }
626  else if (fly->axis == 2) {
627  fly->speed += fly->grid;
628  }
629  fly->axis = 2;
630  }
631  break;
633  if (fly->axis == 2 && fly->speed > 0.0f) {
634  fly->axis = -1;
635  }
636  else {
637  if (fly->speed > 0.0f) {
638  fly->speed = -fly->speed;
639  }
640  else if (fly->axis == 2) {
641  fly->speed -= fly->grid;
642  }
643 
644  fly->axis = 2;
645  }
646  break;
647  case FLY_MODAL_DIR_LEFT:
648  if (fly->axis == 0 && fly->speed < 0.0f) {
649  fly->axis = -1;
650  }
651  else {
652  if (fly->speed < 0.0f) {
653  fly->speed = -fly->speed;
654  }
655  else if (fly->axis == 0) {
656  fly->speed += fly->grid;
657  }
658 
659  fly->axis = 0;
660  }
661  break;
662  case FLY_MODAL_DIR_RIGHT:
663  if (fly->axis == 0 && fly->speed > 0.0f) {
664  fly->axis = -1;
665  }
666  else {
667  if (fly->speed > 0.0f) {
668  fly->speed = -fly->speed;
669  }
670  else if (fly->axis == 0) {
671  fly->speed -= fly->grid;
672  }
673 
674  fly->axis = 0;
675  }
676  break;
677  case FLY_MODAL_DIR_DOWN:
678  if (fly->axis == 1 && fly->speed < 0.0f) {
679  fly->axis = -1;
680  }
681  else {
682  if (fly->speed < 0.0f) {
683  fly->speed = -fly->speed;
684  }
685  else if (fly->axis == 1) {
686  fly->speed += fly->grid;
687  }
688  fly->axis = 1;
689  }
690  break;
691  case FLY_MODAL_DIR_UP:
692  if (fly->axis == 1 && fly->speed > 0.0f) {
693  fly->axis = -1;
694  }
695  else {
696  if (fly->speed > 0.0f) {
697  fly->speed = -fly->speed;
698  }
699  else if (fly->axis == 1) {
700  fly->speed -= fly->grid;
701  }
702  fly->axis = 1;
703  }
704  break;
705 
707  if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
709  }
710  else {
712  fly->xlock_momentum = 0.0;
713  }
714  break;
716  if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
718  }
719  else {
721  fly->zlock_momentum = 0.0;
722  }
723  break;
724 
726  fly->use_precision = true;
727  break;
729  fly->use_precision = false;
730  break;
731 
733  fly->use_freelook = true;
734  break;
736  fly->use_freelook = false;
737  break;
738  }
739  }
740 }
741 
742 static void flyMoveCamera(bContext *C,
743  FlyInfo *fly,
744  const bool do_rotate,
745  const bool do_translate,
746  const bool is_confirm)
747 {
748  /* we only consider autokeying on playback or if user confirmed fly on the same frame
749  * otherwise we get a keyframe even if the user cancels. */
750  const bool use_autokey = is_confirm || fly->anim_playing;
751  ED_view3d_cameracontrol_update(fly->v3d_camera_control, use_autokey, C, do_rotate, do_translate);
752 }
753 
754 static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
755 {
756 #define FLY_ROTATE_FAC 10.0f /* more is faster */
757 #define FLY_ZUP_CORRECT_FAC 0.1f /* amount to correct per step */
758 #define FLY_ZUP_CORRECT_ACCEL 0.05f /* increase upright momentum each step */
759 #define FLY_SMOOTH_FAC 20.0f /* higher value less lag */
760 
761  /* fly mode - Shift+F
762  * a fly loop where the user can move move the view as if they are flying
763  */
764  RegionView3D *rv3d = fly->rv3d;
765 
766  /* 3x3 copy of the view matrix so we can move along the view axis */
767  float mat[3][3];
768  /* this is the direction that's added to the view offset per redraw */
769  float dvec[3] = {0, 0, 0};
770 
771  /* Camera Up-righting variables. */
772  float moffset[2]; /* mouse offset from the views center */
773  float tmp_quat[4]; /* used for rotating the view */
774 
775  /* x and y margin are define the safe area where the mouses movement wont rotate the view */
776  int xmargin, ymargin;
777 
778 #ifdef NDOF_FLY_DEBUG
779  {
780  static uint iteration = 1;
781  printf("fly timer %d\n", iteration++);
782  }
783 #endif
784 
785  xmargin = fly->width / 20.0f;
786  ymargin = fly->height / 20.0f;
787 
788  {
789 
790  /* mouse offset from the center */
791  moffset[0] = fly->mval[0] - fly->center_mval[0];
792  moffset[1] = fly->mval[1] - fly->center_mval[1];
793 
794  /* enforce a view margin */
795  if (moffset[0] > xmargin) {
796  moffset[0] -= xmargin;
797  }
798  else if (moffset[0] < -xmargin) {
799  moffset[0] += xmargin;
800  }
801  else {
802  moffset[0] = 0;
803  }
804 
805  if (moffset[1] > ymargin) {
806  moffset[1] -= ymargin;
807  }
808  else if (moffset[1] < -ymargin) {
809  moffset[1] += ymargin;
810  }
811  else {
812  moffset[1] = 0;
813  }
814 
815  /* scale the mouse movement by this value - scales mouse movement to the view size
816  * moffset[0] / (region->winx-xmargin * 2) - window size minus margin (same for y)
817  *
818  * the mouse moves isn't linear */
819 
820  if (moffset[0]) {
821  moffset[0] /= fly->width - (xmargin * 2);
822  moffset[0] *= fabsf(moffset[0]);
823  }
824 
825  if (moffset[1]) {
826  moffset[1] /= fly->height - (ymargin * 2);
827  moffset[1] *= fabsf(moffset[1]);
828  }
829 
830  /* Should we redraw? */
831  if ((fly->speed != 0.0f) || moffset[0] || moffset[1] ||
832  (fly->zlock != FLY_AXISLOCK_STATE_OFF) || (fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
833  dvec[0] || dvec[1] || dvec[2]) {
834  float dvec_tmp[3];
835 
836  /* time how fast it takes for us to redraw,
837  * this is so simple scenes don't fly too fast */
838  double time_current;
839  float time_redraw;
840  float time_redraw_clamped;
841 #ifdef NDOF_FLY_DRAW_TOOMUCH
842  fly->redraw = 1;
843 #endif
844  time_current = PIL_check_seconds_timer();
845  time_redraw = (float)(time_current - fly->time_lastdraw);
846 
847  /* clamp redraw time to avoid jitter in roll correction */
848  time_redraw_clamped = min_ff(0.05f, time_redraw);
849 
850  fly->time_lastdraw = time_current;
851 
852  /* Scale the time to use shift to scale the speed down- just like
853  * shift slows many other areas of blender down */
854  if (fly->use_precision) {
855  fly->speed = fly->speed * (1.0f - time_redraw_clamped);
856  }
857 
858  copy_m3_m4(mat, rv3d->viewinv);
859 
860  if (fly->pan_view == true) {
861  /* pan only */
862  copy_v3_fl3(dvec_tmp, -moffset[0], -moffset[1], 0.0f);
863 
864  if (fly->use_precision) {
865  dvec_tmp[0] *= 0.1f;
866  dvec_tmp[1] *= 0.1f;
867  }
868 
869  mul_m3_v3(mat, dvec_tmp);
870  mul_v3_fl(dvec_tmp, time_redraw * 200.0f * fly->grid);
871  }
872  else {
873  float roll; /* similar to the angle between the camera's up and the Z-up,
874  * but its very rough so just roll */
875 
876  /* rotate about the X axis- look up/down */
877  if (moffset[1]) {
878  float upvec[3];
879  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
880  mul_m3_v3(mat, upvec);
881  /* Rotate about the relative up vec */
882  axis_angle_to_quat(tmp_quat, upvec, moffset[1] * time_redraw * -FLY_ROTATE_FAC);
883  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
884 
885  if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
886  fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
887  }
888  if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
890  }
891  fly->xlock_momentum = 0.0f;
892  }
893 
894  /* rotate about the Y axis- look left/right */
895  if (moffset[0]) {
896  float upvec[3];
897  /* if we're upside down invert the moffset */
898  copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
899  mul_m3_v3(mat, upvec);
900 
901  if (upvec[2] < 0.0f) {
902  moffset[0] = -moffset[0];
903  }
904 
905  /* make the lock vectors */
906  if (fly->zlock) {
907  copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
908  }
909  else {
910  copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f);
911  mul_m3_v3(mat, upvec);
912  }
913 
914  /* Rotate about the relative up vec */
915  axis_angle_to_quat(tmp_quat, upvec, moffset[0] * time_redraw * FLY_ROTATE_FAC);
916  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
917 
918  if (fly->xlock != FLY_AXISLOCK_STATE_OFF) {
919  fly->xlock = FLY_AXISLOCK_STATE_ACTIVE; /* check for rotation */
920  }
921  if (fly->zlock != FLY_AXISLOCK_STATE_OFF) {
923  }
924  }
925 
926  if (fly->zlock == FLY_AXISLOCK_STATE_ACTIVE) {
927  float upvec[3];
928  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
929  mul_m3_v3(mat, upvec);
930 
931  /* make sure we have some z rolling */
932  if (fabsf(upvec[2]) > 0.00001f) {
933  roll = upvec[2] * 5.0f;
934  /* rotate the view about this axis */
935  copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
936  mul_m3_v3(mat, upvec);
937  /* Rotate about the relative up vec */
938  axis_angle_to_quat(tmp_quat,
939  upvec,
940  roll * time_redraw_clamped * fly->zlock_momentum *
942  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
943 
945  }
946  else {
947  /* don't check until the view rotates again */
949  fly->zlock_momentum = 0.0f;
950  }
951  }
952 
953  /* Only apply X-axis correction when mouse isn't applying x rotation. */
954  if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) {
955  float upvec[3];
956  copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f);
957  mul_m3_v3(mat, upvec);
958  /* make sure we have some z rolling */
959  if (fabsf(upvec[2]) > 0.00001f) {
960  roll = upvec[2] * -5.0f;
961  /* rotate the view about this axis */
962  copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
963  mul_m3_v3(mat, upvec);
964 
965  /* Rotate about the relative up vec */
967  tmp_quat, upvec, roll * time_redraw_clamped * fly->xlock_momentum * 0.1f);
968  mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat);
969 
970  fly->xlock_momentum += 0.05f;
971  }
972  else {
973  fly->xlock = FLY_AXISLOCK_STATE_IDLE; /* see above */
974  fly->xlock_momentum = 0.0f;
975  }
976  }
977 
978  if (fly->axis == -1) {
979  /* pause */
980  zero_v3(dvec_tmp);
981  }
982  else if (!fly->use_freelook) {
983  /* Normal operation */
984  /* define dvec, view direction vector */
985  zero_v3(dvec_tmp);
986  /* move along the current axis */
987  dvec_tmp[fly->axis] = 1.0f;
988 
989  mul_m3_v3(mat, dvec_tmp);
990  }
991  else {
992  normalize_v3_v3(dvec_tmp, fly->dvec_prev);
993  if (fly->speed < 0.0f) {
994  negate_v3(dvec_tmp);
995  }
996  }
997 
998  mul_v3_fl(dvec_tmp, fly->speed * time_redraw * 0.25f);
999  }
1000 
1001  /* impose a directional lag */
1003  dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC))));
1004 
1005  add_v3_v3(rv3d->ofs, dvec);
1006 
1007  if (rv3d->persp == RV3D_CAMOB) {
1008  const bool do_rotate = ((fly->xlock != FLY_AXISLOCK_STATE_OFF) ||
1009  (fly->zlock != FLY_AXISLOCK_STATE_OFF) ||
1010  ((moffset[0] || moffset[1]) && !fly->pan_view));
1011  const bool do_translate = (fly->speed != 0.0f || fly->pan_view);
1012  flyMoveCamera(C, fly, do_rotate, do_translate, is_confirm);
1013  }
1014  }
1015  else {
1016  /* we're not redrawing but we need to update the time else the view will jump */
1018  }
1019  /* end drawing */
1020  copy_v3_v3(fly->dvec_prev, dvec);
1021  }
1022 
1023  return OPERATOR_FINISHED;
1024 }
1025 
1026 #ifdef WITH_INPUT_NDOF
1027 static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm)
1028 {
1030  bool has_translate, has_rotate;
1031 
1032  view3d_ndof_fly(fly->ndof,
1033  fly->v3d,
1034  fly->rv3d,
1035  fly->use_precision,
1036  lock_ob ? lock_ob->protectflag : 0,
1037  &has_translate,
1038  &has_rotate);
1039 
1040  if (has_translate || has_rotate) {
1041  fly->redraw = true;
1042 
1043  if (fly->rv3d->persp == RV3D_CAMOB) {
1044  flyMoveCamera(C, fly, has_rotate, has_translate, is_confirm);
1045  }
1046  }
1047 }
1048 #endif /* WITH_INPUT_NDOF */
1049 
1052 /* -------------------------------------------------------------------- */
1056 static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1057 {
1059  FlyInfo *fly;
1060 
1062  return OPERATOR_CANCELLED;
1063  }
1064 
1065  fly = MEM_callocN(sizeof(FlyInfo), "FlyOperation");
1066 
1067  op->customdata = fly;
1068 
1069  if (initFlyInfo(C, fly, op, event) == false) {
1070  MEM_freeN(op->customdata);
1071  return OPERATOR_CANCELLED;
1072  }
1073 
1074  flyEvent(fly, event);
1075 
1077 
1078  return OPERATOR_RUNNING_MODAL;
1079 }
1080 
1081 static void fly_cancel(bContext *C, wmOperator *op)
1082 {
1083  FlyInfo *fly = op->customdata;
1084 
1085  fly->state = FLY_CANCEL;
1086  flyEnd(C, fly);
1087  op->customdata = NULL;
1088 }
1089 
1090 static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
1091 {
1092  int exit_code;
1093  bool do_draw = false;
1094  FlyInfo *fly = op->customdata;
1095  RegionView3D *rv3d = fly->rv3d;
1097 
1098  fly->redraw = 0;
1099 
1100  flyEvent(fly, event);
1101 
1102 #ifdef WITH_INPUT_NDOF
1103  if (fly->ndof) { /* 3D mouse overrules [2D mouse + timer] */
1104  if (event->type == NDOF_MOTION) {
1105  flyApply_ndof(C, fly, false);
1106  }
1107  }
1108  else
1109 #endif /* WITH_INPUT_NDOF */
1110  if (event->type == TIMER && event->customdata == fly->timer) {
1111  flyApply(C, fly, false);
1112  }
1113 
1114  do_draw |= fly->redraw;
1115 
1116  exit_code = flyEnd(C, fly);
1117 
1118  if (exit_code != OPERATOR_RUNNING_MODAL) {
1119  do_draw = true;
1120  }
1121 
1122  if (do_draw) {
1123  if (rv3d->persp == RV3D_CAMOB) {
1125  }
1126 
1127  // puts("redraw!"); // too frequent, commented with NDOF_FLY_DRAW_TOOMUCH for now
1129  }
1130 
1131  return exit_code;
1132 }
1133 
1135 {
1136  /* identifiers */
1137  ot->name = "Fly Navigation";
1138  ot->description = "Interactively fly around the scene";
1139  ot->idname = "VIEW3D_OT_fly";
1140 
1141  /* api callbacks */
1142  ot->invoke = fly_invoke;
1143  ot->cancel = fly_cancel;
1144  ot->modal = fly_modal;
1146 
1147  /* flags */
1148  ot->flag = OPTYPE_BLOCKING;
1149 }
1150 
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 View3D * CTX_wm_view3d(const bContext *C)
Definition: context.c:760
struct Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
Definition: context.c:1415
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
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 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 interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
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 void negate_v3(float r[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
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)
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 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
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 immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniformThemeColor3(int color_id)
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 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 y1
_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 x2
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
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
uint pos
#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
struct ARegionType * type
double time_lastdraw
Definition: view3d_fly.c:210
bool anim_playing
Definition: view3d_fly.c:178
eFlyPanState xlock
Definition: view3d_fly.c:200
wmTimer * timer
Definition: view3d_fly.c:164
RegionView3D * rv3d
Definition: view3d_fly.c:157
Scene * scene
Definition: view3d_fly.c:161
View3D * v3d
Definition: view3d_fly.c:158
bool use_freelook
Definition: view3d_fly.c:170
float dvec_prev[3]
Definition: view3d_fly.c:216
struct View3DCameraControl * v3d_camera_control
Definition: view3d_fly.c:218
bool redraw
Definition: view3d_fly.c:167
float grid
Definition: view3d_fly.c:204
double time_lastwheel
Definition: view3d_fly.c:208
float width
Definition: view3d_fly.c:185
short state
Definition: view3d_fly.c:166
eFlyPanState zlock
Definition: view3d_fly.c:200
float zlock_momentum
Definition: view3d_fly.c:202
ARegion * region
Definition: view3d_fly.c:159
float height
Definition: view3d_fly.c:185
bool pan_view
Definition: view3d_fly.c:198
float speed
Definition: view3d_fly.c:194
int mval[2]
Definition: view3d_fly.c:181
int center_mval[2]
Definition: view3d_fly.c:183
bool use_precision
Definition: view3d_fly.c:168
struct Depsgraph * depsgraph
Definition: view3d_fly.c:160
short axis
Definition: view3d_fly.c:196
float xlock_momentum
Definition: view3d_fly.c:202
void * draw_handle_pixel
Definition: view3d_fly.c:212
void * first
Definition: DNA_listBase.h:47
ListBase constraints
short protectflag
float viewquat[4]
float viewinv[4][4]
struct Object * camera
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
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
double PIL_check_seconds_timer(void)
Definition: time.c:80
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)
#define FLY_ZUP_CORRECT_ACCEL
#define FLY_SMOOTH_FAC
static void flyEvent(FlyInfo *fly, const wmEvent *event)
Definition: view3d_fly.c:475
eFlyPanState
Definition: view3d_fly.c:91
@ FLY_AXISLOCK_STATE_OFF
Definition: view3d_fly.c:93
@ FLY_AXISLOCK_STATE_ACTIVE
Definition: view3d_fly.c:101
@ FLY_AXISLOCK_STATE_IDLE
Definition: view3d_fly.c:97
static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
Definition: view3d_fly.c:234
static int flyEnd(bContext *C, FlyInfo *fly)
Definition: view3d_fly.c:424
void fly_modal_keymap(wmKeyConfig *keyconf)
Definition: view3d_fly.c:105
@ FLY_MODAL_CANCEL
Definition: view3d_fly.c:69
@ FLY_MODAL_ACCELERATE
Definition: view3d_fly.c:71
@ FLY_MODAL_SPEED
Definition: view3d_fly.c:87
@ FLY_MODAL_DIR_DOWN
Definition: view3d_fly.c:80
@ FLY_MODAL_PRECISION_ENABLE
Definition: view3d_fly.c:83
@ FLY_MODAL_AXIS_LOCK_Z
Definition: view3d_fly.c:82
@ FLY_MODAL_PAN_DISABLE
Definition: view3d_fly.c:74
@ FLY_MODAL_DIR_RIGHT
Definition: view3d_fly.c:78
@ FLY_MODAL_DIR_UP
Definition: view3d_fly.c:79
@ FLY_MODAL_FREELOOK_DISABLE
Definition: view3d_fly.c:86
@ FLY_MODAL_FREELOOK_ENABLE
Definition: view3d_fly.c:85
@ FLY_MODAL_DIR_FORWARD
Definition: view3d_fly.c:75
@ FLY_MODAL_PRECISION_DISABLE
Definition: view3d_fly.c:84
@ FLY_MODAL_AXIS_LOCK_X
Definition: view3d_fly.c:81
@ FLY_MODAL_DIR_LEFT
Definition: view3d_fly.c:77
@ FLY_MODAL_DIR_BACKWARD
Definition: view3d_fly.c:76
@ FLY_MODAL_DECELERATE
Definition: view3d_fly.c:72
@ FLY_MODAL_PAN_ENABLE
Definition: view3d_fly.c:73
@ FLY_MODAL_CONFIRM
Definition: view3d_fly.c:70
#define FLY_ZUP_CORRECT_FAC
static void fly_cancel(bContext *C, wmOperator *op)
Definition: view3d_fly.c:1081
static int flyApply(bContext *C, struct FlyInfo *fly, bool is_confirm)
Definition: view3d_fly.c:754
#define FLY_ROTATE_FAC
struct FlyInfo FlyInfo
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
Definition: view3d_fly.c:314
void VIEW3D_OT_fly(wmOperatorType *ot)
Definition: view3d_fly.c:1134
static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
Definition: view3d_fly.c:1090
@ FLY_CONFIRM
Definition: view3d_fly.c:311
@ FLY_CANCEL
Definition: view3d_fly.c:310
@ FLY_RUNNING
Definition: view3d_fly.c:309
static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: view3d_fly.c:1056
static void flyMoveCamera(bContext *C, FlyInfo *fly, const bool do_rotate, const bool do_translate, const bool is_confirm)
Definition: view3d_fly.c:742
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
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_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