Blender  V3.3
transform_mode_timeslide.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <stdlib.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "DNA_anim_types.h"
13 
14 #include "BLI_math.h"
15 #include "BLI_string.h"
16 
17 #include "BKE_context.h"
18 #include "BKE_nla.h"
19 #include "BKE_unit.h"
20 
21 #include "ED_screen.h"
22 
23 #include "UI_interface.h"
24 #include "UI_view2d.h"
25 
26 #include "BLT_translation.h"
27 
28 #include "transform.h"
29 #include "transform_convert.h"
30 
31 #include "transform_mode.h"
32 
33 /* -------------------------------------------------------------------- */
37 static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR])
38 {
39  char tvec[NUM_STR_REP_LEN * 3];
40 
41  if (hasNumInput(&t->num)) {
42  outputNumInput(&(t->num), tvec, &t->scene->unit);
43  }
44  else {
45  const float *range = t->custom.mode.data;
46  float minx = range[0];
47  float maxx = range[1];
48  float cval = t->values_final[0];
49  float val;
50 
51  val = 2.0f * (cval - sval) / (maxx - minx);
52  CLAMP(val, -1.0f, 1.0f);
53 
54  BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
55  }
56 
57  BLI_snprintf(str, UI_MAX_DRAW_STR, TIP_("TimeSlide: %s"), &tvec[0]);
58 }
59 
60 static void applyTimeSlideValue(TransInfo *t, float sval, float cval)
61 {
62  int i;
63  const float *range = t->custom.mode.data;
64  float minx = range[0];
65  float maxx = range[1];
66 
67  /* set value for drawing black line */
68  if (t->spacetype == SPACE_ACTION) {
69  SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
70  saction->timeslide = cval;
71  }
72 
73  /* It doesn't matter whether we apply to t->data or
74  * t->data2d, but t->data2d is more convenient. */
76  TransData *td = tc->data;
77  for (i = 0; i < tc->data_len; i++, td++) {
78  /* it is assumed that td->extra is a pointer to the AnimData,
79  * whose active action is where this keyframe comes from
80  * (this is only valid when not in NLA)
81  */
82  AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
83 
84  /* only apply to data if in range */
85  if ((sval > minx) && (sval < maxx)) {
86  float cvalc = CLAMPIS(cval, minx, maxx);
87  float ival = td->ival;
88  float timefac;
89 
90  /* NLA mapping magic here works as follows:
91  * - "ival" goes from strip time to global time
92  * - calculation is performed into td->val in global time
93  * (since sval and min/max are all in global time)
94  * - "td->val" then gets put back into strip time
95  */
96  if (adt) {
97  /* strip to global */
99  }
100 
101  /* left half? */
102  if (ival < sval) {
103  timefac = (sval - ival) / (sval - minx);
104  *(td->val) = cvalc - timefac * (cvalc - minx);
105  }
106  else {
107  timefac = (ival - sval) / (maxx - sval);
108  *(td->val) = cvalc + timefac * (maxx - cvalc);
109  }
110 
111  if (adt) {
112  /* global to strip */
113  *(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
114  }
115  }
116  }
117  }
118 }
119 
120 static void applyTimeSlide(TransInfo *t, const int mval[2])
121 {
122  View2D *v2d = (View2D *)t->view;
123  float cval[2], sval[2];
124  const float *range = t->custom.mode.data;
125  float minx = range[0];
126  float maxx = range[1];
127  char str[UI_MAX_DRAW_STR];
128 
129  /* calculate mouse co-ordinates */
130  UI_view2d_region_to_view(v2d, mval[0], mval[1], &cval[0], &cval[1]);
131  UI_view2d_region_to_view(v2d, t->mouse.imval[0], t->mouse.imval[1], &sval[0], &sval[1]);
132 
133  /* t->values_final[0] stores cval[0], which is the current mouse-pointer location (in frames) */
134  /* XXX Need to be able to repeat this. */
135  /* t->values_final[0] = cval[0]; */ /* UNUSED (reset again later). */
136 
137  /* handle numeric-input stuff */
138  t->vec[0] = 2.0f * (cval[0] - sval[0]) / (maxx - minx);
139  applyNumInput(&t->num, &t->vec[0]);
140  t->values_final[0] = (maxx - minx) * t->vec[0] / 2.0f + sval[0];
141 
142  headerTimeSlide(t, sval[0], str);
143  applyTimeSlideValue(t, sval[0], t->values_final[0]);
144 
145  recalcData(t);
146 
147  ED_area_status_text(t->area, str);
148 }
149 
151 {
152  /* this tool is only really available in the Action Editor... */
153  if (t->spacetype == SPACE_ACTION) {
154  SpaceAction *saction = (SpaceAction *)t->area->spacedata.first;
155 
156  /* set flag for drawing stuff */
157  saction->flag |= SACTION_MOVING;
158  }
159  else {
160  t->state = TRANS_CANCEL;
161  }
162 
163  t->mode = TFM_TIME_SLIDE;
164  t->transform = applyTimeSlide;
165 
166  initMouseInputMode(t, &t->mouse, INPUT_NONE);
167 
168  {
169  Scene *scene = t->scene;
170  float *range;
171  t->custom.mode.data = range = MEM_mallocN(sizeof(float[2]), "TimeSlide Min/Max");
172  t->custom.mode.use_free = true;
173 
174  float min = 999999999.0f, max = -999999999.0f;
175  int i;
177  TransData *td = tc->data;
178  for (i = 0; i < tc->data_len; i++, td++) {
179  AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
180  float val = *(td->val);
181 
182  /* strip/action time to global (mapped) time */
183  if (adt) {
185  }
186 
187  if (min > val) {
188  min = val;
189  }
190  if (max < val) {
191  max = val;
192  }
193  }
194  }
195 
196  if (min == max) {
197  /* just use the current frame ranges */
198  min = (float)PSFRA;
199  max = (float)PEFRA;
200  }
201 
202  range[0] = min;
203  range[1] = max;
204  }
205 
206  /* Numeric-input has max of (n-1). */
207  t->idx_max = 0;
208  t->num.flag = 0;
209  t->num.idx_max = t->idx_max;
210 
211  /* Initialize snap like for everything else. */
212  t->snap[0] = t->snap[1] = 1.0f;
213 
214  copy_v3_fl(t->num.val_inc, t->snap[0]);
215  t->num.unit_sys = t->scene->unit.system;
216  /* No time unit supporting frames currently. */
217  t->num.unit_type[0] = B_UNIT_NONE;
218 }
219 
typedef float(TangentPoint)[2]
@ NLATIME_CONVERT_MAP
Definition: BKE_nla.h:360
@ NLATIME_CONVERT_UNMAP
Definition: BKE_nla.h:357
float BKE_nla_tweakedit_remap(struct AnimData *adt, float cframe, short mode)
Definition: nla.c:642
@ B_UNIT_NONE
Definition: BKE_unit.h:100
MINLINE void copy_v3_fl(float r[3], float f)
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define CLAMPIS(a, b, c)
#define TIP_(msgid)
@ SACTION_MOVING
#define PSFRA
#define PEFRA
@ SPACE_ACTION
@ SPACE_NLA
void outputNumInput(NumInput *n, char *str, struct UnitSettings *unit_settings)
Definition: numinput.c:87
#define NUM_STR_REP_LEN
Definition: ED_numinput.h:13
bool applyNumInput(NumInput *n, float *vec)
Definition: numinput.c:189
bool hasNumInput(const NumInput *n)
Definition: numinput.c:170
void ED_area_status_text(ScrArea *area, const char *str)
Definition: area.c:792
@ TFM_TIME_SLIDE
Definition: ED_transform.h:51
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
#define UI_MAX_DRAW_STR
Definition: UI_interface.h:91
void UI_view2d_region_to_view(const struct View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Scene scene
#define str(s)
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define min(a, b)
Definition: sort.c:35
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
float * val
void recalcData(TransInfo *t)
conversion and adaptation of different datablocks to a common struct.
float max
transform modes used by different operators.
static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR])
static void applyTimeSlideValue(TransInfo *t, float sval, float cval)
void initTimeSlide(TransInfo *t)
static void applyTimeSlide(TransInfo *t, const int mval[2])