Blender V4.3
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
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
20#include "BLI_math_geom.h"
21#include "BLI_math_matrix.h"
22#include "BLI_math_vector.h"
23
24#include "RNA_access.hh"
25
26#include "WM_api.hh"
27#include "WM_types.hh"
28
29#include "ED_screen.hh"
30#include "ED_view3d.hh"
31
32#include "CLG_log.h"
33
34/* own includes */
36
37static CLG_LogRef LOG = {"ed.gizmo.library_utils"};
38
39/* factor for precision tweaking */
40#define GIZMO_PRECISION_FAC 0.05f
41
42BLI_INLINE float gizmo_offset_from_value_constr(const float range_fac,
43 const float min,
44 const float range,
45 const float value,
46 const bool inverted)
47{
48 return inverted ? (range_fac * (min + range - value) / range) : (range_fac * (value / range));
49}
50
51BLI_INLINE float gizmo_value_from_offset_constr(const float range_fac,
52 const float min,
53 const float range,
54 const float value,
55 const bool inverted)
56{
57 return inverted ? (min + range - (value * range / range_fac)) : (value * range / range_fac);
58}
59
61 const float value,
62 const bool constrained,
63 const bool inverted)
64{
65 if (constrained) {
67 data->range_fac, data->min, data->range, value, inverted);
68 }
69
70 return value;
71}
72
74 GizmoInteraction *inter,
75 const float offset,
76 const bool constrained,
77 const bool inverted,
78 const bool use_precision)
79{
80 const float max = data->min + data->range;
81
82 if (use_precision) {
83 /* add delta offset of this step to total precision_offset */
84 inter->precision_offset += offset - inter->prev_offset;
85 }
86 inter->prev_offset = offset;
87
88 float ofs_new = inter->init_offset + offset -
89 inter->precision_offset * (1.0f - GIZMO_PRECISION_FAC);
90 float value;
91
92 if (constrained) {
94 data->range_fac, data->min, data->range, ofs_new, inverted);
95 }
96 else {
97 value = ofs_new;
98 }
99
100 /* clamp to custom range */
101 if (data->is_custom_range_set) {
102 CLAMP(value, data->min, max);
103 }
104
105 return value;
106}
107
109 GizmoCommonData *data,
110 wmGizmoProperty *gz_prop,
111 const bool constrained,
112 const bool inverted)
113{
114 if (gz_prop->custom_func.value_get_fn != nullptr) {
115 /* Pass. */
116 }
117 else if (gz_prop->prop != nullptr) {
118 /* Pass. */
119 }
120 else {
121 data->offset = 0.0f;
122 return;
123 }
124
125 float value = WM_gizmo_target_property_float_get(gz, gz_prop);
126
127 if (constrained) {
128 if (data->is_custom_range_set == false) {
129 float range[2];
130 if (WM_gizmo_target_property_float_range_get(gz, gz_prop, range)) {
131 data->range = range[1] - range[0];
132 data->min = range[0];
133 }
134 else {
135 BLI_assert(0);
136 }
137 }
138 data->offset = gizmo_offset_from_value_constr(
139 data->range_fac, data->min, data->range, value, inverted);
140 }
141 else {
142 data->offset = value;
143 }
144}
145
147 const wmGizmo *gz,
148 GizmoInteraction *inter,
149 wmGizmoProperty *gz_prop)
150{
151 WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init_value);
152}
153
154/* -------------------------------------------------------------------- */
155
156void gizmo_color_get(const wmGizmo *gz, const bool highlight, float r_color[4])
157{
158 if (highlight && !(gz->flag & WM_GIZMO_DRAW_HOVER)) {
159 copy_v4_v4(r_color, gz->color_hi);
160 }
161 else {
162 copy_v4_v4(r_color, gz->color);
163 }
164}
165
166/* -------------------------------------------------------------------- */
167
169 bContext *C, const wmGizmo *gz, const float mval[2], int axis, bool use_offset, float r_co[2])
170{
171 float mat[4][4], imat[4][4];
172 {
173 float mat_identity[4][4];
174 WM_GizmoMatrixParams params = {nullptr};
175 if (use_offset == false) {
176 unit_m4(mat_identity);
177 params.matrix_offset = mat_identity;
178 }
180 }
181
182 if (!invert_m4_m4(imat, mat)) {
183 CLOG_WARN(&LOG,
184 "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
185 "(projection will fail)",
186 gz->type->idname,
188 }
189
190 /* rotate mouse in relation to the center and relocate it */
192 /* For 3d views, transform 2D mouse pos onto plane. */
193 ARegion *region = CTX_wm_region(C);
194
195 float plane[4], co[3];
196 plane_from_point_normal_v3(plane, mat[3], mat[2]);
197 bool clip_ray = ((RegionView3D *)region->regiondata)->is_persp;
198 if (ED_view3d_win_to_3d_on_plane(region, plane, mval, clip_ray, co)) {
199 mul_m4_v3(imat, co);
200 r_co[0] = co[(axis + 1) % 3];
201 r_co[1] = co[(axis + 2) % 3];
202 return true;
203 }
204 return false;
205 }
206
207 float co[3] = {mval[0], mval[1], 0.0f};
208 mul_m4_v3(imat, co);
209 copy_v2_v2(r_co, co);
210 return true;
211}
212
214 bContext *C, const wmGizmo *gz, const float mval[2], bool use_offset, float r_co[3])
215{
216 float mat[4][4], imat[4][4];
217 {
218 float mat_identity[4][4];
219 WM_GizmoMatrixParams params = {nullptr};
220 if (use_offset == false) {
221 unit_m4(mat_identity);
222 params.matrix_offset = mat_identity;
223 }
225 }
226
227 if (!invert_m4_m4(imat, mat)) {
228 CLOG_WARN(&LOG,
229 "Gizmo \"%s\" of group \"%s\" has matrix that could not be inverted "
230 "(projection will fail)",
231 gz->type->idname,
233 }
234
236 View3D *v3d = CTX_wm_view3d(C);
237 ARegion *region = CTX_wm_region(C);
238 /* NOTE: we might want a custom reference point passed in,
239 * instead of the gizmo center. */
240 ED_view3d_win_to_3d(v3d, region, mat[3], mval, r_co);
241 mul_m4_v3(imat, r_co);
242 return true;
243 }
244
245 float co[3] = {mval[0], mval[1], 0.0f};
246 mul_m4_v3(imat, co);
247 copy_v2_v2(r_co, co);
248 return true;
249}
250
251/* -------------------------------------------------------------------- */
255/* Based on 'rna_GizmoProperties_find_operator'. */
257 const int spacetype,
258 const int regionid)
259{
260 for (bScreen *screen = static_cast<bScreen *>(G_MAIN->screens.first); screen;
261 screen = static_cast<bScreen *>(screen->id.next))
262 {
263 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
264 if (!ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) {
265 continue;
266 }
267 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
268 if (region->gizmo_map == nullptr) {
269 continue;
270 }
271 if (!ELEM(regionid, RGN_TYPE_ANY, region->regiontype)) {
272 continue;
273 }
274
275 LISTBASE_FOREACH (wmGizmoGroup *, gzgroup, WM_gizmomap_group_list(region->gizmo_map)) {
276 LISTBASE_FOREACH (wmGizmo *, gz, &gzgroup->gizmos) {
277 if (gz->properties == properties) {
278 return gz;
279 }
280 }
281 }
282 }
283 }
284 }
285 return nullptr;
286}
287
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:50
#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:215
void unit_m4(float m[4][4])
Definition rct.c:1127
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])
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:181
#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])
@ WM_GIZMO_DRAW_HOVER
@ WM_GIZMOGROUPTYPE_3D
#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)
static CLG_LogRef LOG
void gizmo_property_value_reset(bContext *C, const wmGizmo *gz, GizmoInteraction *inter, wmGizmoProperty *gz_prop)
IndexRange range
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
#define min(a, b)
Definition sort.c:32
const char * idname
eWM_GizmoFlagGroupTypeFlag flag
wmGizmoGroupType * type
PropertyRNA * prop
wmGizmoPropertyFnGet value_get_fn
struct wmGizmoProperty::@1373 custom_func
const char * idname
wmGizmoGroup * parent_gzgroup
const wmGizmoType * type
float color_hi[4]
float color[4]
eWM_GizmoFlag flag
void WM_gizmo_calc_matrix_final_params(const wmGizmo *gz, const WM_GizmoMatrixParams *params, float r_mat[4][4])
Definition wm_gizmo.cc:519
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])