Blender V4.3
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
9#include "MEM_guardedalloc.h"
10
11#include "BLI_math_rotation.h"
12
13#include "WM_api.hh"
14
15#include "RNA_access.hh"
16#include "RNA_define.hh"
17
18#include "view3d_intern.hh"
19
20#include "view3d_navigate.hh" /* own include */
21
22/* -------------------------------------------------------------------- */
28enum {
33};
34
36 {V3D_VIEW_STEPLEFT, "ORBITLEFT", 0, "Orbit Left", "Orbit the view around to the left"},
37 {V3D_VIEW_STEPRIGHT, "ORBITRIGHT", 0, "Orbit Right", "Orbit the view around to the right"},
38 {V3D_VIEW_STEPUP, "ORBITUP", 0, "Orbit Up", "Orbit the view up"},
39 {V3D_VIEW_STEPDOWN, "ORBITDOWN", 0, "Orbit Down", "Orbit the view down"},
40 {0, nullptr, 0, nullptr, nullptr},
41};
42
44{
45 float angle;
46 {
47 PropertyRNA *prop_angle = RNA_struct_find_property(op->ptr, "angle");
48 angle = RNA_property_is_set(op->ptr, prop_angle) ?
49 RNA_property_float_get(op->ptr, prop_angle) :
50 DEG2RADF(U.pad_rot_angle);
51 }
52
53 ViewOpsData vod = {};
54 vod.init_context(C);
55
57
58 /* support for switching to the opposite view (even when in locked views) */
59 char view_opposite = (fabsf(angle) == float(M_PI)) ?
61 char(RV3D_VIEW_USER);
62
63 if ((RV3D_LOCK_FLAGS(vod.rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {
64 /* no nullptr check is needed, poll checks */
66 vod.rv3d = static_cast<RegionView3D *>(vod.region->regiondata);
67 }
68
69 if ((RV3D_LOCK_FLAGS(vod.rv3d) & RV3D_LOCK_ROTATION) && (view_opposite == RV3D_VIEW_USER)) {
70 return OPERATOR_CANCELLED;
71 }
72
73 const bool is_camera_lock = ED_view3d_camera_lock_check(vod.v3d, vod.rv3d);
74 if (vod.rv3d->persp == RV3D_CAMOB && !is_camera_lock) {
75 return OPERATOR_CANCELLED;
76 }
77
78 vod.init_navigation(C, nullptr, &ViewOpsType_orbit, nullptr, false);
79
80 int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
81 float quat_mul[4];
82 float quat_new[4];
83
84 int orbitdir = RNA_enum_get(op->ptr, "type");
86 if (orbitdir == V3D_VIEW_STEPRIGHT) {
87 angle = -angle;
88 }
89
90 /* z-axis */
91 axis_angle_to_quat_single(quat_mul, 'Z', angle);
92 }
93 else {
94 if (orbitdir == V3D_VIEW_STEPDOWN) {
95 angle = -angle;
96 }
97
98 /* horizontal axis */
99 axis_angle_to_quat(quat_mul, vod.rv3d->viewinv[0], angle);
100 }
101
102 mul_qt_qtqt(quat_new, vod.curr.viewquat, quat_mul);
103
104 /* avoid precision loss over time */
105 normalize_qt(quat_new);
106
107 if (view_opposite != RV3D_VIEW_USER) {
108 vod.rv3d->view = view_opposite;
109 /* avoid float in-precision, just get a new orientation */
110 ED_view3d_quat_from_axis_view(view_opposite, vod.rv3d->view_axis_roll, quat_new);
111 }
112 else {
113 vod.rv3d->view = RV3D_VIEW_USER;
114 }
115
116 V3D_SmoothParams sview = {nullptr};
117 sview.quat = quat_new;
118 sview.lens = &vod.v3d->lens;
119 /* Group as successive orbit may run by holding a key. */
120 sview.undo_str = op->type->name;
121 sview.undo_grouped = true;
122
123 if (vod.use_dyn_ofs) {
124 sview.dyn_ofs = vod.dyn_ofs;
125 }
126
127 ED_view3d_smooth_view(C, vod.v3d, vod.region, smooth_viewtx, &sview);
128
129 vod.end_navigation(C);
130
131 return OPERATOR_FINISHED;
132}
133
135{
136 PropertyRNA *prop;
137
138 /* identifiers */
139 ot->name = "View Orbit";
140 ot->description = "Orbit the view";
142
143 /* api callbacks */
146
147 /* flags */
148 ot->flag = 0;
149
150 /* properties */
151 prop = RNA_def_float(ot->srna, "angle", 0, -FLT_MAX, FLT_MAX, "Roll", "", -FLT_MAX, FLT_MAX);
153
155 ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit");
156}
157
162 /*idname*/ "VIEW3D_OT_view_orbit",
163 /*poll_fn*/ nullptr,
164 /*init_fn*/ nullptr,
165 /*apply_fn*/ nullptr,
166};
#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])
#define DEG2RADF(_deg)
void mul_qt_qtqt(float q[4], const float a[4], const float b[4])
#define ELEM(...)
#define RV3D_LOCK_FLAGS(rv3d)
@ RV3D_CAMOB
@ RV3D_LOCK_ROTATION
@ RV3D_VIEW_USER
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:125
Read Guarded memory(de)allocation.
@ PROP_SKIP_SAVE
Definition RNA_types.hh:245
unsigned int U
Definition btGjkEpa3.h:78
#define fabsf(x)
draw_view in_light_buf[] float
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)
ARegion * region
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)
struct ViewOpsData::@545 curr
const char * idname
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(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
PropertyRNA * prop
Definition WM_types.hh:1092
StructRNA * srna
Definition WM_types.hh:1080
struct wmOperatorType * type
struct PointerRNA * ptr
void ED_view3d_smooth_view(bContext *C, View3D *v3d, ARegion *region, int smooth_viewtx, const V3D_SmoothParams *sview)
@ VIEWOPS_FLAG_ORBIT_SELECT
void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region)
const ViewOpsType ViewOpsType_orbit
void VIEW3D_OT_view_orbit(wmOperatorType *ot)
static int vieworbit_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem prop_view_orbit_items[]
wmOperatorType * ot
Definition wm_files.cc:4125
int WM_operator_smooth_viewtx_get(const wmOperator *op)