Blender V5.0
gizmo_library_utils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2015 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include "DNA_screen_types.h"
14#include "DNA_view3d_types.h"
15
16#include "BKE_context.hh"
17#include "BKE_global.hh"
18#include "BKE_main.hh"
19#include "BKE_screen.hh"
20
21#include "BLI_listbase.h"
22#include "BLI_math_geom.h"
23#include "BLI_math_matrix.h"
24#include "BLI_math_vector.h"
25
26#include "RNA_access.hh"
27
28#include "WM_api.hh"
29#include "WM_types.hh"
30
31#include "ED_screen.hh"
32#include "ED_view3d.hh"
33
34#include "CLG_log.h"
35
36/* own includes */
38
39static CLG_LogRef LOG = {"tool.gizmo"};
40
41/* factor for precision tweaking */
42#define GIZMO_PRECISION_FAC 0.05f
43
44BLI_INLINE float gizmo_offset_from_value_constr(const float range_fac,
45 const float min,
46 const float range,
47 const float value,
48 const bool inverted)
49{
50 return inverted ? (range_fac * (min + range - value) / range) : (range_fac * (value / range));
51}
52
53BLI_INLINE float gizmo_value_from_offset_constr(const float range_fac,
54 const float min,
55 const float range,
56 const float value,
57 const bool inverted)
58{
59 return inverted ? (min + range - (value * range / range_fac)) : (value * range / range_fac);
60}
61
63 const float value,
64 const bool constrained,
65 const bool inverted)
66{
67 if (constrained) {
69 data->range_fac, data->min, data->range, value, inverted);
70 }
71
72 return value;
73}
74
76 GizmoInteraction *inter,
77 const float offset,
78 const bool constrained,
79 const bool inverted,
80 const bool use_precision)
81{
82 const float max = data->min + data->range;
83
84 if (use_precision) {
85 /* add delta offset of this step to total precision_offset */
86 inter->precision_offset += offset - inter->prev_offset;
87 }
88 inter->prev_offset = offset;
89
90 float ofs_new = inter->init_offset + offset -
91 inter->precision_offset * (1.0f - GIZMO_PRECISION_FAC);
92 float value;
93
94 if (constrained) {
96 data->range_fac, data->min, data->range, ofs_new, inverted);
97 }
98 else {
99 value = ofs_new;
100 }
101
102 /* clamp to custom range */
103 if (data->is_custom_range_set) {
104 CLAMP(value, data->min, max);
105 }
106
107 return value;
108}
109
112 wmGizmoProperty *gz_prop,
113 const bool constrained,
114 const bool inverted)
115{
116 if (gz_prop->custom_func.value_get_fn != nullptr) {
117 /* Pass. */
118 }
119 else if (gz_prop->prop != nullptr) {
120 /* Pass. */
121 }
122 else {
123 data->offset = 0.0f;
124 return;
125 }
126
127 float value = WM_gizmo_target_property_float_get(gz, gz_prop);
128
129 if (constrained) {
130 if (data->is_custom_range_set == false) {
131 float range[2];
132 if (WM_gizmo_target_property_float_range_get(gz, gz_prop, range)) {
133 data->range = range[1] - range[0];
134 data->min = range[0];
135 }
136 else {
137 BLI_assert(0);
138 }
139 }
141 data->range_fac, data->min, data->range, value, inverted);
142 }
143 else {
144 data->offset = value;
145 }
146}
147
149 const wmGizmo *gz,
150 GizmoInteraction *inter,
151 wmGizmoProperty *gz_prop)
152{
153 WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init_value);
154}
155
156/* -------------------------------------------------------------------- */
157
158void gizmo_color_get(const wmGizmo *gz, const bool highlight, float r_color[4])
159{
160 if (highlight && !(gz->flag & WM_GIZMO_DRAW_HOVER)) {
161 copy_v4_v4(r_color, gz->color_hi);
162 }
163 else {
164 copy_v4_v4(r_color, gz->color);
165 }
166}
167
168/* -------------------------------------------------------------------- */
169
171 bContext *C, const wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2])
172{
173 float mat[4][4], imat[4][4];
174 {
175 float mat_identity[4][4];
176 WM_GizmoMatrixParams params = {nullptr};
177 if (use_offset == false) {
178 unit_m4(mat_identity);
179 params.matrix_offset = mat_identity;
180 }
182 }
183
184 if (!invert_m4_m4(imat, mat)) {
185 CLOG_WARN(&LOG,
186 "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
187 "(projection will fail)",
188 gz->type->idname,
190 }
191
192 /* rotate mouse in relation to the center and relocate it */
194 /* For 3d views, transform 2D mouse pos onto plane. */
195 ARegion *region = CTX_wm_region(C);
196
197 float plane[4], co[3];
198 plane_from_point_normal_v3(plane, mat[3], mat[2]);
199 bool clip_ray = ((RegionView3D *)region->regiondata)->is_persp;
200 if (ED_view3d_win_to_3d_on_plane(region, plane, mval, clip_ray, co)) {
201 mul_m4_v3(imat, co);
202 r_co[0] = co[(axis + 1) % 3];
203 r_co[1] = co[(axis + 2) % 3];
204 return true;
205 }
206 return false;
207 }
208
209 float co[3] = {mval[0], mval[1], 0.0f};
210 mul_m4_v3(imat, co);
211 copy_v2_v2(r_co, co);
212 return true;
213}
214
216 bContext *C, const wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3])
217{
218 float mat[4][4], imat[4][4];
219 {
220 float mat_identity[4][4];
221 WM_GizmoMatrixParams params = {nullptr};
222 if (use_offset == false) {
223 unit_m4(mat_identity);
224 params.matrix_offset = mat_identity;
225 }
227 }
228
229 if (!invert_m4_m4(imat, mat)) {
230 CLOG_WARN(&LOG,
231 "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
232 "(projection will fail)",
233 gz->type->idname,
235 }
236
238 View3D *v3d = CTX_wm_view3d(C);
239 ARegion *region = CTX_wm_region(C);
240 /* NOTE: we might want a custom reference point passed in,
241 * instead of the gizmo center. */
242 ED_view3d_win_to_3d(v3d, region, mat[3], mval, r_co);
243 mul_m4_v3(imat, r_co);
244 return true;
245 }
246
247 float co[3] = {mval[0], mval[1], 0.0f};
248 mul_m4_v3(imat, co);
249 copy_v2_v2(r_co, co);
250 return true;
251}
252
253/* -------------------------------------------------------------------- */
256
258 const int spacetype,
259 const int regionid)
260{
261 /* Based on #rna_GizmoProperties_find_operator. */
262
263 for (bScreen *screen = static_cast<bScreen *>(G_MAIN->screens.first); screen;
264 screen = static_cast<bScreen *>(screen->id.next))
265 {
266 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
267 if (!ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
268 continue;
269 }
270 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
271 if (region->runtime->gizmo_map == nullptr) {
272 continue;
273 }
274 if (!ELEM(regionid, RGN_TYPE_ANY, region->regiontype)) {
275 continue;
276 }
277
279 wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(region->runtime->gizmo_map))
280 {
281 LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
282 if (gz->properties == properties) {
283 return gz;
284 }
285 }
286 }
287 }
288 }
289 }
290 return nullptr;
291}
292
ARegion * CTX_wm_region(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
#define G_MAIN
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_INLINE
#define LISTBASE_FOREACH(type, var, list)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:217
void mul_m4_v3(const float M[4][4], float r[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void unit_m4(float m[4][4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
#define CLAMP(a, b, c)
#define ELEM(...)
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:189
#define RGN_TYPE_ANY
#define SPACE_TYPE_ANY
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
bool ED_view3d_win_to_3d_on_plane(const ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
#define C
Definition RandGen.cpp:29
@ WM_GIZMO_DRAW_HOVER
@ WM_GIZMOGROUPTYPE_3D
BMesh const char void * data
#define GIZMO_PRECISION_FAC
BLI_INLINE float gizmo_value_from_offset_constr(const float range_fac, const float min, const float range, const float value, const bool inverted)
wmGizmo * gizmo_find_from_properties(const IDProperty *properties, const int spacetype, const int regionid)
void gizmo_color_get(const wmGizmo *gz, const bool highlight, float r_color[4])
BLI_INLINE float gizmo_offset_from_value_constr(const float range_fac, const float min, const float range, const float value, const bool inverted)
bool gizmo_window_project_3d(bContext *C, const wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3])
float gizmo_value_from_offset(GizmoCommonData *data, GizmoInteraction *inter, const float offset, const bool constrained, const bool inverted, const bool use_precision)
void gizmo_property_data_update(wmGizmo *gz, GizmoCommonData *data, wmGizmoProperty *gz_prop, const bool constrained, const bool inverted)
bool gizmo_window_project_2d(bContext *C, const wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2])
float gizmo_offset_from_value(GizmoCommonData *data, const float value, const bool constrained, const bool inverted)
void gizmo_property_value_reset(bContext *C, const wmGizmo *gz, GizmoInteraction *inter, wmGizmoProperty *gz_prop)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define LOG(level)
Definition log.h:97
#define min(a, b)
Definition sort.cc:36
void * regiondata
const char * idname
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupType * type
PropertyRNA * prop
wmGizmoPropertyFnGet value_get_fn
struct wmGizmoProperty::@331027022007232055216276241130041346111314317052 custom_func
const char * idname
wmGizmoGroup * parent_gzgroup
const wmGizmoType * type
float color_hi[4]
float color[4]
eWM_GizmoFlag flag
max
Definition text_draw.cc:251
void WM_gizmo_calc_matrix_final_params(const wmGizmo *gz, const WM_GizmoMatrixParams *params, float r_mat[4][4])
Definition wm_gizmo.cc:522
const ListBase * WM_gizmomap_group_list(wmGizmoMap *gzmap)
void WM_gizmo_target_property_float_set(bContext *C, const wmGizmo *gz, wmGizmoProperty *gz_prop, const float value)
float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_prop)
bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz, wmGizmoProperty *gz_prop, float range[2])