Blender V4.3
transform_snap_animation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
10#include "BLI_math_vector.h"
11
12#include "BKE_nla.hh"
13
14#include "ED_markers.hh"
15
16#include "transform.hh"
17#include "transform_snap.hh"
18
19using namespace blender;
20
21/* -------------------------------------------------------------------- */
26 const eSnapMode snap_mode,
27 const float val_initial,
28 const float val_final,
29 float *r_val_final)
30{
31 float deltax = val_final - val_initial;
32 /* This is needed for the FPS macro. */
33 const Scene *scene = t->scene;
34 const eSnapFlag snap_flag = t->tsnap.flag;
35
36 switch (snap_mode) {
37 case SCE_SNAP_TO_FRAME: {
38 if (snap_flag & SCE_SNAP_ABS_TIME_STEP) {
39 *r_val_final = floorf(val_final + 0.5f);
40 }
41 else {
42 deltax = floorf(deltax + 0.5f);
43 *r_val_final = val_initial + deltax;
44 }
45 break;
46 }
47 case SCE_SNAP_TO_SECOND: {
48 if (snap_flag & SCE_SNAP_ABS_TIME_STEP) {
49 *r_val_final = floorf((val_final / FPS) + 0.5) * FPS;
50 }
51 else {
52 deltax = float(floor((deltax / FPS) + 0.5) * FPS);
53 *r_val_final = val_initial + deltax;
54 }
55 break;
56 }
58 /* Snap to nearest marker. */
59 /* TODO: need some more careful checks for where data comes from. */
60 const float nearest_marker_time = float(
62 *r_val_final = nearest_marker_time;
63 break;
64 }
65 default: {
66 *r_val_final = val_final;
67 break;
68 }
69 }
70}
71
73 TransInfo *t, TransData *td, float val, const eSnapMode snap_mode, float *r_val_final)
74{
76
77 float ival = td->iloc[0];
78
79 AnimData *adt = nullptr;
80 if (!ELEM(t->spacetype, SPACE_NLA, SPACE_SEQ) && !(td->flag & TD_GREASE_PENCIL_FRAME)) {
81 /* #TD_GREASE_PENCIL_FRAME stores #blender::bke::greasepencil::Layer* in
82 * `td->extra`, and not the #AnimData. */
83 adt = static_cast<AnimData *>(td->extra);
84 }
85
86 /* Convert frame to nla-action time (if needed). */
87 if (adt) {
90 }
91
92 snapFrameTransform(t, snap_mode, ival, val, &val);
93
94 /* Convert frame out of nla-action time. */
95 if (adt) {
97 }
98
99 *r_val_final = val;
100}
101
103 TransData *td,
104 const eSnapMode snap_mode,
105 float *r_val_final)
106{
107 transform_snap_anim_flush_data_ex(t, td, td->loc[0], snap_mode, r_val_final);
108}
109
110static void invert_snap(eSnapMode &snap_mode)
111{
112 if (snap_mode & SCE_SNAP_TO_FRAME) {
113 snap_mode &= ~SCE_SNAP_TO_FRAME;
114 snap_mode |= SCE_SNAP_TO_SECOND;
115 }
116 else if (snap_mode & SCE_SNAP_TO_SECOND) {
117 snap_mode &= ~SCE_SNAP_TO_SECOND;
118 snap_mode |= SCE_SNAP_TO_FRAME;
119 }
120}
121
122/* WORKAROUND: The source position is based on the transformed elements.
123 * However, at this stage, the transformation has not yet been applied.
124 * So apply the transformation here. */
125static float2 nla_transform_apply(TransInfo *t, const float *vec, const float2 &ival)
126{
128
129 float values_final_prev[4];
130 const size_t values_final_size = sizeof(*t->values_final) * size_t(t->idx_max + 1);
131 memcpy(values_final_prev, t->values_final, values_final_size);
132 memcpy(t->values_final, vec, values_final_size);
133
134 mat[3][0] = ival[0];
135 mat[3][1] = ival[1];
136 transform_apply_matrix(t, mat.ptr());
137
138 memcpy(t->values_final, values_final_prev, values_final_size);
139
140 return mat.location().xy();
141}
142
144{
146
147 eSnapMode snap_mode = t->tsnap.mode;
148 if (t->modifiers & MOD_SNAP_INVERT) {
149 invert_snap(snap_mode);
150 }
151
152 float best_dist = FLT_MAX;
153 float2 best_source = float2(0);
154 float2 best_target = float2(0);
155 bool found = false;
156
157 for (int i = 0; i < tc->data_len; i++) {
158 TransData *td = &tc->data[i];
159 float2 snap_source = td->iloc;
160 float2 snap_target = nla_transform_apply(t, vec, snap_source);
161
162 transform_snap_anim_flush_data_ex(t, td, snap_target[0], snap_mode, &snap_target[0]);
163 const int dist = abs(snap_target[0] - snap_source[0]);
164 if (dist < best_dist) {
165 if (dist != 0) {
166 /* Prioritize non-zero dist for scale. */
167 best_dist = dist;
168 }
169 else if (found) {
170 continue;
171 }
172 best_source = snap_source;
173 best_target = snap_target;
174 found = true;
175 }
176 }
177
178 copy_v2_v2(t->tsnap.snap_source, best_source);
179 copy_v2_v2(t->tsnap.snap_target, best_target);
180 return found;
181}
182
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode)
@ NLATIME_CONVERT_MAP
Definition BKE_nla.hh:516
@ NLATIME_CONVERT_UNMAP
Definition BKE_nla.hh:513
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE void copy_v2_v2(float r[2], const float a[2])
#define ELEM(...)
@ SCE_SNAP_ABS_TIME_STEP
#define FPS
@ SCE_SNAP_TO_MARKERS
@ SCE_SNAP_TO_FRAME
@ SCE_SNAP_TO_SECOND
@ SPACE_NLA
@ SPACE_SEQ
int ED_markers_find_nearest_marker_time(ListBase *markers, float x)
#define floorf(x)
bool transform_apply_matrix(TransInfo *t, float mat[4][4])
draw_view in_light_buf[] float
ccl_device_inline float2 floor(const float2 a)
VecBase< float, 2 > float2
#define FLT_MAX
Definition stdcycles.h:14
ListBase markers
TransData * data
Definition transform.hh:445
char spacetype
Definition transform.hh:582
TransSnap tsnap
Definition transform.hh:537
short idx_max
Definition transform.hh:559
eTModifier modifiers
Definition transform.hh:525
Scene * scene
Definition transform.hh:654
float values_final[4]
Definition transform.hh:632
eSnapFlag flag
Definition transform.hh:310
float snap_target[3]
Definition transform.hh:327
float snap_source[3]
Definition transform.hh:325
eSnapMode mode
Definition transform.hh:312
const c_style_mat & ptr() const
VecBase< T, 2 > xy() const
@ MOD_SNAP_INVERT
Definition transform.hh:164
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:851
@ TD_GREASE_PENCIL_FRAME
void snapFrameTransform(TransInfo *t, const eSnapMode snap_mode, const float val_initial, const float val_final, float *r_val_final)
static float2 nla_transform_apply(TransInfo *t, const float *vec, const float2 &ival)
static void transform_snap_anim_flush_data_ex(TransInfo *t, TransData *td, float val, const eSnapMode snap_mode, float *r_val_final)
void transform_snap_anim_flush_data(TransInfo *t, TransData *td, const eSnapMode snap_mode, float *r_val_final)
static void invert_snap(eSnapMode &snap_mode)
bool transform_snap_nla_calc(TransInfo *t, float *vec)
ccl_device_inline int abs(int x)
Definition util/math.h:120