Blender V5.0
view3d_navigate_view_orbit.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
8
9#include "BLI_math_base.h"
10#include "BLI_math_rotation.h"
11
12#include "DNA_userdef_types.h"
13
14#include "WM_api.hh"
15
16#include "RNA_access.hh"
17#include "RNA_define.hh"
18
19#include "view3d_intern.hh"
20
21#include "view3d_navigate.hh" /* own include */
22
23/* -------------------------------------------------------------------- */
28
29enum {
34};
35
37 {V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the left"},
38 {V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the right"},
39 {V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view up"},
40 {V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view down"},
41 {0, nullptr, 0, nullptr, nullptr},
42};
43
45{
46 float angle;
47 {
48 PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
49 angle = RNA_property_is_set(op->ptr, prop_angle) ?
50 RNA_property_float_get(op->ptr, prop_angle) :
51 DEG2RADF(U.pad_rot_angle);
52 }
53
54 ViewOpsData vod = {};
55 vod.init_context(C);
56
58
59 /* support for switching to the opposite view (even when in locked views) */
60 char view_opposite = (fabsf(angle) == float(M_PI)) ?
62 char(RV3D_VIEW_USER);
63
64 if ((RV3D_LOCK_FLAGS(vod.rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {
65 /* no nullptr check is needed, poll checks */
67 vod.rv3d = static_cast<RegionView3D *>(vod.region->regiondata);
68
70 }
71
72 if ((RV3D_LOCK_FLAGS(vod.rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {
73 return OPERATOR_CANCELLED;
74 }
75
76 const bool is_camera_lock = ED_view3d_camera_lock_check(vod.v3d, vod.rv3d);
77 if (vod.rv3d->persp == RV3D_CAMOB && !is_camera_lock) {
78 return OPERATOR_CANCELLED;
79 }
80
81 vod.init_navigation(C, nullptr, &ViewOpsType_orbit, nullptr, false);
82
83 int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
84 float quat_mul[4];
85 float quat_new[4];
86
87 int orbitdir = RNA_enum_get(op->ptr, "type");
89 if (orbitdir == V3D_VIEW_STEPRIGHT) {
90 angle = -angle;
91 }
92
93 /* z-axis */
94 axis_angle_to_quat_single(quat_mul, 'Z', angle);
95 }
96 else {
97 if (orbitdir == V3D_VIEW_STEPDOWN) {
98 angle = -angle;
99 }
100
101 /* horizontal axis */
102 axis_angle_to_quat(quat_mul, vod.rv3d->viewinv[0], angle);
103 }
104
105 mul_qt_qtqt(quat_new, vod.curr.viewquat, quat_mul);
106
107 /* avoid precision loss over time */
108 normalize_qt(quat_new);
109
110 if (view_opposite != RV3D_VIEW_USER) {
111 vod.rv3d->view = view_opposite;
112 /* avoid float in-precision, just get a new orientation */
113 ED_view3d_quat_from_axis_view(view_opposite, vod.rv3d->view_axis_roll, quat_new);
114 }
115 else {
116 vod.rv3d->view = RV3D_VIEW_USER;
117 }
118
119 V3D_SmoothParams sview = {nullptr};
120 sview.quat = quat_new;
121 sview.lens = &vod.v3d->lens;
122 /* Group as successive orbit may run by holding a key. */
123 sview.undo_str = op->type->name;
124 sview.undo_grouped = true;
125
126 if (vod.use_dyn_ofs) {
127 sview.dyn_ofs = vod.dyn_ofs;
128 }
129
130 ED_view3d_smooth_view(C, vod.v3d, vod.region, smooth_viewtx, &sview);
131
132 vod.end_navigation(C);
133
134 return OPERATOR_FINISHED;
135}
136
138{
139 PropertyRNA *prop;
140
141 /* identifiers */
142 ot->name = "View Orbit";
143 ot->description = "Orbit the view";
144 ot->idname = ViewOpsType_orbit.idname;
145
146 /* API callbacks. */
147 ot->exec = vieworbit_exec;
149
150 /* flags */
151 ot->flag = 0;
152
153 /* properties */
154 prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
156
157 ot->prop = RNA_def_enum(
158 ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
159}
160
162
165 /*idname*/ "VIEW3D_OT_view_orbit",
166 /*poll_fn*/ nullptr,
167 /*init_fn*/ nullptr,
168 /*apply_fn*/ nullptr,
169};
#define DEG2RADF(_deg)
#define M_PI
void axis_angle_to_quat(float r[4], const float axis[3], float angle)
void axis_angle_to_quat_single(float q[4], char axis, float angle)
float normalize_qt(float q[4])
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
#define ELEM(...)
@ RV3D_VIEW_USER
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_CAMOB
@ RV3D_LOCK_ROTATION
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
char ED_view3d_axis_view_opposite(char view)
bool ED_view3d_context_user_region(bContext *C, View3D **r_v3d, ARegion **r_region)
bool ED_view3d_quat_from_axis_view(char view, char view_axis_roll, float r_quat[4])
bool ED_view3d_camera_lock_check(const View3D *v3d, const RegionView3D *rv3d)
bool ED_operator_rv3d_user_region_poll(bContext *C)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
#define C
Definition RandGen.cpp:29
#define U
nullptr float
#define fabsf
float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
#define FLT_MAX
Definition stdcycles.h:14
void * regiondata
float viewinv[4][4]
const char * undo_str
const float * dyn_ofs
void end_navigation(bContext *C)
struct ViewOpsData::@041211063176270354313167244105136234141004235041 curr
RegionView3D * rv3d
void init_navigation(bContext *C, const wmEvent *event, const ViewOpsType *nav_type, const float dyn_ofs_override[3]=nullptr, const bool use_cursor_init=false)
void init_context(bContext *C)
const char * name
Definition WM_types.hh:1033
struct wmOperatorType * type
struct PointerRNA * ptr
void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *region, int smooth_viewtx, const V3D_SmoothParams *sview)
const ViewOpsType ViewOpsType_orbit
@ VIEWOPS_FLAG_ORBIT_SELECT
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
static wmOperatorStatus vieworbit_exec(bContext *C, wmOperator *op)
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
static const EnumPropertyItem prop_view_orbit_items[]
wmOperatorType * ot
Definition wm_files.cc:4237
int WM_operator_smooth_viewtx_get(const wmOperator *op)