Blender V4.3
view3d_navigate_smoothview.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DNA_camera_types.h"
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_listbase.h"
14#include "BLI_math_rotation.h"
15#include "BLI_math_vector.h"
16
17#include "BKE_context.hh"
18
20
21#include "WM_api.hh"
22
23#include "ED_screen.hh"
24
25#include "view3d_intern.hh"
26#include "view3d_navigate.hh" /* Own include. */
27
29 bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor);
30
31/* -------------------------------------------------------------------- */
47{
48 const View3D *v3d = static_cast<const View3D *>(area->spacedata.first);
49 Object *camera = v3d->camera;
50 if (!camera) {
51 return;
52 }
53
54 /* Tag the camera object so it's known smooth-view is applied to the view-ports camera
55 * (needed to detect when a locked camera is being manipulated).
56 * NOTE: It doesn't matter if the actual object being manipulated is the camera or not. */
57 camera->id.tag &= ~ID_TAG_DOIT;
58
59 LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) {
60 if (region->regiontype != RGN_TYPE_WINDOW) {
61 continue;
62 }
63 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
64 if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) {
65 camera->id.tag |= ID_TAG_DOIT;
66 break;
67 }
68 }
69}
70
72 const ScrArea *area,
73 const char *undo_str,
74 const bool undo_grouped)
75{
76 View3D *v3d = static_cast<View3D *>(area->spacedata.first);
77 Object *camera = v3d->camera;
78 if (!camera) {
79 return;
80 }
81 if (camera->id.tag & ID_TAG_DOIT) {
82 /* Smooth view didn't touch the camera. */
83 camera->id.tag &= ~ID_TAG_DOIT;
84 return;
85 }
86
87 if ((U.uiflag & USER_GLOBALUNDO) == 0) {
88 return;
89 }
90
91 /* NOTE(@ideasman42): It is not possible that a single viewport references different cameras
92 * so even in the case there is a quad-view with multiple camera views set, these will all
93 * reference the same camera. In this case it doesn't matter which region is used.
94 * If in the future multiple cameras are supported, this logic can be extended. */
95 const ARegion *region_camera = nullptr;
96
97 /* An undo push should be performed. */
98 bool is_interactive = false;
99 LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) {
100 if (region->regiontype != RGN_TYPE_WINDOW) {
101 continue;
102 }
103 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
104 if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) {
105 region_camera = region;
106 if (rv3d->sms) {
107 is_interactive = true;
108 }
109 }
110 }
111
112 if (region_camera == nullptr) {
113 return;
114 }
115
116 RegionView3D *rv3d = static_cast<RegionView3D *>(region_camera->regiondata);
117
118 /* Fast forward, undo push, then rewind. */
119 if (is_interactive) {
120 view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 1.0f);
121 }
122
123 if (undo_grouped) {
124 ED_view3d_camera_lock_undo_grouped_push(undo_str, v3d, rv3d, C);
125 }
126 else {
127 ED_view3d_camera_lock_undo_push(undo_str, v3d, rv3d, C);
128 }
129
130 if (is_interactive) {
131 view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 0.0f);
132 }
133}
134
137/* -------------------------------------------------------------------- */
148 float dist;
149 float lens;
150 float quat[4];
151 float ofs[3];
152};
153
184
186 const View3D *v3d,
187 const RegionView3D *rv3d)
188{
189 copy_v3_v3(sms_state->ofs, rv3d->ofs);
190 copy_qt_qt(sms_state->quat, rv3d->viewquat);
191 sms_state->dist = rv3d->dist;
192 sms_state->lens = v3d->lens;
193}
194
196 View3D *v3d,
197 RegionView3D *rv3d)
198{
199 copy_v3_v3(rv3d->ofs, sms_state->ofs);
200 copy_qt_qt(rv3d->viewquat, sms_state->quat);
201 rv3d->dist = sms_state->dist;
202 v3d->lens = sms_state->lens;
203}
204
206 /* Avoid passing in the context. */
207 const Depsgraph *depsgraph,
208 wmWindowManager *wm,
209 wmWindow *win,
210 ScrArea *area,
211 View3D *v3d,
212 ARegion *region,
213 const int smooth_viewtx,
214 const V3D_SmoothParams *sview)
215{
216 /* Will start a timer if appropriate. */
217
218 /* In this case use #ED_view3d_smooth_view_undo_begin & end functions
219 * instead of passing in undo. */
220 BLI_assert_msg(sview->undo_str == nullptr,
221 "Only the 'ED_view3d_smooth_view' version of this function handles undo!");
222
223 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
224 SmoothView3DStore sms = {{0}};
225
226 /* Initialize `sms`. */
227 view3d_smooth_view_state_backup(&sms.dst, v3d, rv3d);
228 view3d_smooth_view_state_backup(&sms.src, v3d, rv3d);
229 /* If smooth-view runs multiple times. */
230 if (rv3d->sms == nullptr) {
231 view3d_smooth_view_state_backup(&sms.org, v3d, rv3d);
232 }
233 else {
234 sms.org = rv3d->sms->org;
235 }
236 sms.org_view = rv3d->view;
238
239 // sms.to_camera = false; /* Initialized to zero anyway. */
240
241 /* NOTE: Regarding camera locking: This is a little confusing but works OK.
242 * We may be changing the view 'as if' there is no active camera, but in fact
243 * there is an active camera which is locked to the view.
244 *
245 * In the case where smooth view is moving _to_ a camera we don't want that
246 * camera to be moved or changed, so only when the camera is not being set should
247 * we allow camera option locking to initialize the view settings from the camera. */
248 if (sview->camera == nullptr && sview->camera_old == nullptr) {
250 }
251
252 /* Store the options we want to end with. */
253 if (sview->ofs) {
254 copy_v3_v3(sms.dst.ofs, sview->ofs);
255 }
256 if (sview->quat) {
257 copy_qt_qt(sms.dst.quat, sview->quat);
258 }
259 if (sview->dist) {
260 sms.dst.dist = *sview->dist;
261 }
262 if (sview->lens) {
263 sms.dst.lens = *sview->lens;
264 }
265
266 if (sview->dyn_ofs) {
267 BLI_assert(sview->ofs == nullptr);
268 BLI_assert(sview->quat != nullptr);
269
270 copy_v3_v3(sms.dyn_ofs, sview->dyn_ofs);
271 sms.use_dyn_ofs = true;
272
273 /* Calculate the final destination offset. */
274 view3d_orbit_apply_dyn_ofs(sms.dst.ofs, sms.src.ofs, sms.src.quat, sms.dst.quat, sms.dyn_ofs);
275 }
276
277 if (sview->camera) {
278 Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
279 if (sview->ofs != nullptr) {
281 ob_camera_eval->object_to_world().ptr(), sview->ofs, VIEW3D_DIST_FALLBACK);
282 }
283 ED_view3d_from_object(ob_camera_eval, sms.dst.ofs, sms.dst.quat, &sms.dst.dist, &sms.dst.lens);
284 /* Restore view3d values in end. */
285 sms.to_camera = true;
286 }
287
288 if ((sview->camera_old == sview->camera) && /* Camera. */
289 (sms.dst.dist == rv3d->dist) && /* Distance. */
290 (sms.dst.lens == v3d->lens) && /* Lens. */
291 equals_v3v3(sms.dst.ofs, rv3d->ofs) && /* Offset. */
292 equals_v4v4(sms.dst.quat, rv3d->viewquat) /* Rotation. */
293 )
294 {
295 /* Early return if nothing changed. */
296 return;
297 }
298
299 /* Skip smooth viewing for external render engine draw. */
300 if (smooth_viewtx && !(v3d->shading.type == OB_RENDER && rv3d->view_render)) {
301
302 /* Original values. */
303 if (sview->camera_old) {
304 Object *ob_camera_old_eval = DEG_get_evaluated_object(depsgraph, sview->camera_old);
305 if (sview->ofs != nullptr) {
307 ob_camera_old_eval->object_to_world().ptr(), sview->ofs, 0.0f);
308 }
310 ob_camera_old_eval, sms.src.ofs, sms.src.quat, &sms.src.dist, &sms.src.lens);
311 }
312 /* Grid draw as floor. */
313 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
314 /* Use existing if exists, means multiple calls to smooth view
315 * won't lose the original 'view' setting. */
316 rv3d->view = RV3D_VIEW_USER;
317 }
318
319 sms.time_allowed = double(smooth_viewtx / 1000.0);
320
321 /* If this is view rotation only we can decrease the time allowed by the angle between
322 * quaternions this means small rotations won't lag. */
323 if (sview->quat && !sview->ofs && !sview->dist) {
324 /* Scale the time allowed by the rotation (180 degrees == 1.0). */
326 M_PI;
327 }
328
329 /* Ensure it shows correct. */
330 if (sms.to_camera) {
331 /* Use orthographic if we move from an orthographic view to an orthographic camera. */
332 Object *ob_camera_eval = DEG_get_evaluated_object(depsgraph, sview->camera);
333 rv3d->persp = ((rv3d->is_persp == false) && (ob_camera_eval->type == OB_CAMERA) &&
334 (static_cast<Camera *>(ob_camera_eval->data)->type == CAM_ORTHO)) ?
335 RV3D_ORTHO :
337 }
338
339 rv3d->rflag |= RV3D_NAVIGATING;
340
341 /* Not essential but in some cases the caller will tag the area for redraw, and in that
342 * case we can get a flicker of the 'org' user view but we want to see 'src'. */
343 view3d_smooth_view_state_restore(&sms.src, v3d, rv3d);
344
345 /* Keep track of running timer! */
346 if (rv3d->sms == nullptr) {
347 rv3d->sms = static_cast<SmoothView3DStore *>(
348 MEM_mallocN(sizeof(SmoothView3DStore), "smoothview v3d"));
349 }
350 *rv3d->sms = sms;
351 if (rv3d->smooth_timer) {
352 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
353 }
354 /* #TIMER1 is hard-coded in key-map. */
355 rv3d->smooth_timer = WM_event_timer_add(wm, win, TIMER1, 1.0 / 100.0);
356 }
357 else {
358 /* Animation is disabled, apply immediately. */
359 if (sms.to_camera == false) {
360 copy_v3_v3(rv3d->ofs, sms.dst.ofs);
361 copy_qt_qt(rv3d->viewquat, sms.dst.quat);
362 rv3d->dist = sms.dst.dist;
363 v3d->lens = sms.dst.lens;
364
366 }
367
368 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
369 view3d_boxview_copy(area, region);
370 }
371
372 ED_region_tag_redraw(region);
373
375 }
376
377 if (sms.to_camera == false) {
378 /* See comments in #ED_view3d_smooth_view_undo_begin for why this is needed. */
379 if (v3d->camera) {
380 v3d->camera->id.tag &= ~ID_TAG_DOIT;
381 }
382 }
383}
384
386 View3D *v3d,
387 ARegion *region,
388 const int smooth_viewtx,
389 const V3D_SmoothParams *sview)
390{
393 wmWindow *win = CTX_wm_window(C);
394 ScrArea *area = CTX_wm_area(C);
395
396 /* #ED_view3d_smooth_view_ex asserts this is not set as it doesn't support undo. */
397 V3D_SmoothParams sview_no_undo = *sview;
398 sview_no_undo.undo_str = nullptr;
399 sview_no_undo.undo_grouped = false;
400
401 const bool do_undo = (sview->undo_str != nullptr);
402 if (do_undo) {
404 }
405
406 ED_view3d_smooth_view_ex(depsgraph, wm, win, area, v3d, region, smooth_viewtx, &sview_no_undo);
407
408 if (do_undo) {
410 }
411}
412
417 bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor)
418{
419 SmoothView3DStore *sms = rv3d->sms;
420
421 interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, factor);
422
423 if (sms->use_dyn_ofs) {
425 rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs);
426 }
427 else {
428 interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, factor);
429 }
430
431 rv3d->dist = interpf(sms->dst.dist, sms->src.dist, factor);
432 v3d->lens = interpf(sms->dst.lens, sms->src.lens, factor);
433
435 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
436 if (use_autokey) {
437 ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true);
438 }
439 }
440}
441
446 wmWindow *win,
447 View3D *v3d,
448 RegionView3D *rv3d,
449 bContext *C_for_camera_lock)
450{
451 SmoothView3DStore *sms = rv3d->sms;
452
453 /* If we went to camera, store the original. */
454 if (sms->to_camera) {
455 rv3d->persp = RV3D_CAMOB;
456 view3d_smooth_view_state_restore(&sms->org, v3d, rv3d);
457 }
458 else {
459 view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d);
460
461 if (C_for_camera_lock) {
462 const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C_for_camera_lock);
463 if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) {
464 ED_view3d_camera_lock_autokey(v3d, rv3d, C_for_camera_lock, true, true);
465 }
466 }
467 }
468
469 if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) {
470 rv3d->view = sms->org_view;
472 }
473
474 MEM_freeN(rv3d->sms);
475 rv3d->sms = nullptr;
476
477 WM_event_timer_remove(wm, win, rv3d->smooth_timer);
478 rv3d->smooth_timer = nullptr;
479 rv3d->rflag &= ~RV3D_NAVIGATING;
480
481 /* Event handling won't know if a UI item has been moved under the pointer. */
483
484 /* NOTE: this doesn't work right because the `v3d->lens` is used in orthographic mode,
485 * when switching camera in quad-view the other orthographic views would zoom & reset.
486 *
487 * For now only redraw all regions when smooth-view finishes. */
489}
490
492{
494 wmWindow *win = CTX_wm_window(C);
495 view3d_smoothview_apply_and_finish_ex(wm, win, v3d, rv3d, C);
496}
497
499{
501 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
502 SmoothView3DStore *sms = rv3d->sms;
503 float factor;
504
505 if (sms->time_allowed != 0.0) {
506 factor = float(rv3d->smooth_timer->time_duration / sms->time_allowed);
507 }
508 else {
509 factor = 1.0f;
510 }
511 if (factor >= 1.0f) {
513 }
514 else {
515 /* Ease in/out smoothing. */
516 factor = (3.0f * factor * factor - 2.0f * factor * factor * factor);
517 const bool use_autokey = ED_screen_animation_playing(wm);
518 view3d_smoothview_apply_with_interp(C, v3d, rv3d, use_autokey, factor);
519 }
520
521 if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) {
523 }
524
525 ED_region_tag_redraw(region);
526}
527
528static int view3d_smoothview_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *event)
529{
530 View3D *v3d = CTX_wm_view3d(C);
531 ARegion *region = CTX_wm_region(C);
532 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
533
534 /* Escape if not our timer. */
535 if (rv3d->smooth_timer == nullptr || rv3d->smooth_timer != event->customdata) {
537 }
538
540
541 return OPERATOR_FINISHED;
542}
543
545 wmWindowManager *wm,
546 wmWindow *win,
547 const Scene *scene,
548 View3D *v3d,
549 ARegion *region,
550 bContext *C_for_camera_lock)
551{
552 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
553 BLI_assert(rv3d && rv3d->sms);
554
555 view3d_smoothview_apply_and_finish_ex(wm, win, v3d, rv3d, C_for_camera_lock);
556
557 if (depsgraph) {
558 /* Force update of view matrix so tools that run immediately after
559 * can use them without redrawing first. */
560 ED_view3d_update_viewmat(depsgraph, scene, v3d, region, nullptr, nullptr, nullptr, false);
561 }
562}
563
565{
566 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
567 if (rv3d && rv3d->sms) {
568
570 Scene *scene = CTX_data_scene(C);
572 wmWindow *win = CTX_wm_window(C);
573
574 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, C);
575 }
576}
577
579 wmWindowManager *wm,
580 wmWindow *win,
581 const Scene *scene,
582 View3D *v3d,
583 ARegion *region)
584{
585
586 /* NOTE(@ideasman42): Ideally we would *always* apply the camera lock.
587 * Failing to do so results in incorrect behavior when a user performs
588 * a camera-locked view-port manipulation & immediately enters enters local-view
589 * before the operation is completed.
590 * In this case the camera isn't key-framed when it should be.
591 *
592 * A generic solution that supports forcing modal operators to finish their
593 * work may be best, but needs to be investigated.
594 *
595 * It's worth noting this *is* a corner case, while not ideal,
596 * rarely happens unless a motivated users is trying to cause it to fail.
597 * Even when it does occur, it simply misses completing & auto-keying the action. */
598
599 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
600 if (rv3d && rv3d->sms) {
601 view3d_smooth_view_force_finish_ex(depsgraph, wm, win, scene, v3d, region, nullptr);
602 }
603}
604
606{
607 /* Identifiers. */
608 ot->name = "Smooth View";
609 ot->idname = "VIEW3D_OT_smoothview";
610
611 /* API callbacks. */
614
615 /* Flags. */
617}
618
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define LISTBASE_FOREACH(type, var, list)
MINLINE float interpf(float target, float origin, float t)
#define M_PI
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void copy_qt_qt(float q[4], const float a[4])
MINLINE bool equals_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition math_vector.c:36
MINLINE bool equals_v4v4(const float v1[4], const float v2[4]) ATTR_WARN_UNUSED_RESULT
typedef double(DMatrix)[4][4]
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
@ ID_TAG_DOIT
Definition DNA_ID.h:1003
@ CAM_ORTHO
@ OB_RENDER
@ OB_CAMERA
@ RGN_TYPE_WINDOW
@ USER_GLOBALUNDO
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_NAVIGATING
@ RV3D_CAMOB
@ RV3D_PERSP
@ RV3D_ORTHO
@ RV3D_LOCK_ROTATION
@ RV3D_BOXVIEW
@ RV3D_VIEW_USER
@ OPERATOR_PASS_THROUGH
bool ED_operator_view3d_active(bContext *C)
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:634
bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
void ED_view3d_from_object(const Object *ob, float ofs[3], float quat[4], const float *dist, float *lens)
#define VIEW3D_DIST_FALLBACK
float ED_view3d_offset_distance(const float mat[4][4], const float ofs[3], float fallback_dist)
bool ED_view3d_camera_lock_undo_push(const char *str, const View3D *v3d, const RegionView3D *rv3d, bContext *C)
void ED_view3d_camera_lock_init(const Depsgraph *depsgraph, View3D *v3d, RegionView3D *rv3d)
bool ED_view3d_camera_lock_autokey(View3D *v3d, RegionView3D *rv3d, bContext *C, bool do_rotate, bool do_translate)
void ED_view3d_update_viewmat(const Depsgraph *depsgraph, const Scene *scene, View3D *v3d, ARegion *region, const float viewmat[4][4], const float winmat[4][4], const rcti *rect, bool offscreen)
bool ED_view3d_camera_lock_undo_test(const View3D *v3d, const RegionView3D *rv3d, bContext *C)
bool ED_view3d_camera_lock_undo_grouped_push(const char *str, const View3D *v3d, const RegionView3D *rv3d, bContext *C)
Read Guarded memory(de)allocation.
@ OPTYPE_INTERNAL
Definition WM_types.hh:182
#define ND_SPACE_VIEW3D
Definition WM_types.hh:494
#define NC_SPACE
Definition WM_types.hh:359
unsigned int U
Definition btGjkEpa3.h:78
const Depsgraph * depsgraph
#define fabsf(x)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void * regiondata
int tag
Definition DNA_ID.h:434
struct SmoothView3DStore * sms
struct ViewRender * view_render
struct wmTimer * smooth_timer
const char * undo_str
const float * dyn_ofs
struct Object * camera
View3DShading shading
void * customdata
Definition WM_types.hh:772
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
double time_duration
Definition WM_types.hh:925
void view3d_boxview_copy(ScrArea *area, ARegion *region)
void view3d_orbit_apply_dyn_ofs(float r_ofs[3], const float ofs_old[3], const float viewquat_old[4], const float viewquat_new[4], const float dyn_ofs[3])
void ED_view3d_smooth_view_undo_begin(bContext *C, const ScrArea *area)
void ED_view3d_smooth_view_undo_end(bContext *C, const ScrArea *area, const char *undo_str, const bool undo_grouped)
void ED_view3d_smooth_view_force_finish_no_camera_lock(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, View3D *v3d, ARegion *region)
static void view3d_smoothview_apply_and_finish_ex(wmWindowManager *wm, wmWindow *win, View3D *v3d, RegionView3D *rv3d, bContext *C_for_camera_lock)
static void view3d_smoothview_apply_from_timer(bContext *C, View3D *v3d, ARegion *region)
static void view3d_smoothview_apply_with_interp(bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor)
static void view3d_smooth_view_state_backup(SmoothView3DState *sms_state, const View3D *v3d, const RegionView3D *rv3d)
static void view3d_smooth_view_state_restore(const SmoothView3DState *sms_state, View3D *v3d, RegionView3D *rv3d)
static void view3d_smoothview_apply_and_finish(bContext *C, View3D *v3d, RegionView3D *rv3d)
void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *region, const int smooth_viewtx, const V3D_SmoothParams *sview)
void ED_view3d_smooth_view_ex(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, ScrArea *area, View3D *v3d, ARegion *region, const int smooth_viewtx, const V3D_SmoothParams *sview)
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
static int view3d_smoothview_invoke(bContext *C, wmOperator *, const wmEvent *event)
static void view3d_smooth_view_force_finish_ex(const Depsgraph *depsgraph, wmWindowManager *wm, wmWindow *win, const Scene *scene, View3D *v3d, ARegion *region, bContext *C_for_camera_lock)
void VIEW3D_OT_smoothview(wmOperatorType *ot)
void WM_main_add_notifier(uint type, void *reference)
void WM_event_add_mousemove(wmWindow *win)
@ TIMER1
wmOperatorType * ot
Definition wm_files.cc:4125
void WM_event_timer_remove(wmWindowManager *wm, wmWindow *, wmTimer *timer)
wmTimer * WM_event_timer_add(wmWindowManager *wm, wmWindow *win, const int event_type, const double time_step)