Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / anim.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  */
23
24 #include "MEM_guardedalloc.h"
25
26 #include <stdlib.h>
27
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 #include "BLI_dlrbTree.h"
31
32 #include "BLT_translation.h"
33
34 #include "DNA_anim_types.h"
35 #include "DNA_armature_types.h"
36 #include "DNA_key_types.h"
37 #include "DNA_scene_types.h"
38
39 #include "BKE_anim.h"
40 #include "BKE_animsys.h"
41 #include "BKE_action.h"
42 #include "BKE_curve.h"
43 #include "BKE_key.h"
44 #include "BKE_main.h"
45 #include "BKE_object.h"
46 #include "BKE_particle.h"
47 #include "BKE_scene.h"
48 #include "BKE_report.h"
49
50 #include "DEG_depsgraph.h"
51 #include "DEG_depsgraph_query.h"
52 #include "DEG_depsgraph_build.h"
53
54 #include "GPU_batch.h"
55
56 #include "CLG_log.h"
57
58 static CLG_LogRef LOG = {"bke.anim"};
59
60 /* --------------------- */
61 /* forward declarations */
62
63 /* ******************************************************************** */
64 /* Animation Visualization */
65
66 /* Initialize the default settings for animation visualization */
67 void animviz_settings_init(bAnimVizSettings *avs)
68 {
69   /* sanity check */
70   if (avs == NULL) {
71     return;
72   }
73
74   /* path settings */
75   avs->path_bc = avs->path_ac = 10;
76
77   avs->path_sf = 1;   /* xxx - take from scene instead? */
78   avs->path_ef = 250; /* xxx - take from scene instead? */
79
80   avs->path_viewflag = (MOTIONPATH_VIEW_KFRAS | MOTIONPATH_VIEW_KFNOS);
81
82   avs->path_step = 1;
83
84   avs->path_bakeflag |= MOTIONPATH_BAKE_HEADS;
85 }
86
87 /* ------------------- */
88
89 /* Free the given motion path's cache */
90 void animviz_free_motionpath_cache(bMotionPath *mpath)
91 {
92   /* sanity check */
93   if (mpath == NULL) {
94     return;
95   }
96
97   /* free the path if necessary */
98   if (mpath->points) {
99     MEM_freeN(mpath->points);
100   }
101
102   GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
103   GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
104   GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
105
106   /* reset the relevant parameters */
107   mpath->points = NULL;
108   mpath->length = 0;
109 }
110
111 /* Free the given motion path instance and its data
112  * NOTE: this frees the motion path given!
113  */
114 void animviz_free_motionpath(bMotionPath *mpath)
115 {
116   /* sanity check */
117   if (mpath == NULL) {
118     return;
119   }
120
121   /* free the cache first */
122   animviz_free_motionpath_cache(mpath);
123
124   /* now the instance itself */
125   MEM_freeN(mpath);
126 }
127
128 /* ------------------- */
129
130 /* Make a copy of motionpath data, so that viewing with copy on write works */
131 bMotionPath *animviz_copy_motionpath(const bMotionPath *mpath_src)
132 {
133   bMotionPath *mpath_dst;
134
135   if (mpath_src == NULL) {
136     return NULL;
137   }
138
139   mpath_dst = MEM_dupallocN(mpath_src);
140   mpath_dst->points = MEM_dupallocN(mpath_src->points);
141
142   /* should get recreated on draw... */
143   mpath_dst->points_vbo = NULL;
144   mpath_dst->batch_line = NULL;
145   mpath_dst->batch_points = NULL;
146
147   return mpath_dst;
148 }
149
150 /* ------------------- */
151
152 /**
153  * Setup motion paths for the given data.
154  * \note Only used when explicitly calculating paths on bones which may/may not be consider already
155  *
156  * \param scene: Current scene (for frame ranges, etc.)
157  * \param ob: Object to add paths for (must be provided)
158  * \param pchan: Posechannel to add paths for (optional; if not provided, object-paths are assumed)
159  */
160 bMotionPath *animviz_verify_motionpaths(ReportList *reports,
161                                         Scene *scene,
162                                         Object *ob,
163                                         bPoseChannel *pchan)
164 {
165   bAnimVizSettings *avs;
166   bMotionPath *mpath, **dst;
167
168   /* sanity checks */
169   if (ELEM(NULL, scene, ob)) {
170     return NULL;
171   }
172
173   /* get destination data */
174   if (pchan) {
175     /* paths for posechannel - assume that posechannel belongs to the object */
176     avs = &ob->pose->avs;
177     dst = &pchan->mpath;
178   }
179   else {
180     /* paths for object */
181     avs = &ob->avs;
182     dst = &ob->mpath;
183   }
184
185   /* avoid 0 size allocs */
186   if (avs->path_sf >= avs->path_ef) {
187     BKE_reportf(reports,
188                 RPT_ERROR,
189                 "Motion path frame extents invalid for %s (%d to %d)%s",
190                 (pchan) ? pchan->name : ob->id.name,
191                 avs->path_sf,
192                 avs->path_ef,
193                 (avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : "");
194     return NULL;
195   }
196
197   /* if there is already a motionpath, just return that,
198    * provided it's settings are ok (saves extra free+alloc)
199    */
200   if (*dst != NULL) {
201     int expected_length = avs->path_ef - avs->path_sf;
202
203     mpath = *dst;
204
205     /* path is "valid" if length is valid, but must also be of the same length as is being requested */
206     if ((mpath->start_frame != mpath->end_frame) && (mpath->length > 0)) {
207       /* outer check ensures that we have some curve data for this path */
208       if (mpath->length == expected_length) {
209         /* return/use this as it is already valid length */
210         return mpath;
211       }
212       else {
213         /* clear the existing path (as the range has changed), and reallocate below */
214         animviz_free_motionpath_cache(mpath);
215       }
216     }
217   }
218   else {
219     /* create a new motionpath, and assign it */
220     mpath = MEM_callocN(sizeof(bMotionPath), "bMotionPath");
221     *dst = mpath;
222   }
223
224   /* set settings from the viz settings */
225   mpath->start_frame = avs->path_sf;
226   mpath->end_frame = avs->path_ef;
227
228   mpath->length = mpath->end_frame - mpath->start_frame;
229
230   if (avs->path_bakeflag & MOTIONPATH_BAKE_HEADS) {
231     mpath->flag |= MOTIONPATH_FLAG_BHEAD;
232   }
233   else {
234     mpath->flag &= ~MOTIONPATH_FLAG_BHEAD;
235   }
236
237   /* set default custom values */
238   mpath->color[0] = 1.0; /* Red */
239   mpath->color[1] = 0.0;
240   mpath->color[2] = 0.0;
241
242   mpath->line_thickness = 2;
243   mpath->flag |= MOTIONPATH_FLAG_LINES; /* draw lines by default */
244
245   /* allocate a cache */
246   mpath->points = MEM_callocN(sizeof(bMotionPathVert) * mpath->length, "bMotionPathVerts");
247
248   /* tag viz settings as currently having some path(s) which use it */
249   avs->path_bakeflag |= MOTIONPATH_BAKE_HAS_PATHS;
250
251   /* return it */
252   return mpath;
253 }
254
255 /* ******************************************************************** */
256 /* Curve Paths - for curve deforms and/or curve following */
257
258 /* free curve path data
259  * NOTE: frees the path itself!
260  * NOTE: this is increasingly inaccurate with non-uniform BevPoint subdivisions [#24633]
261  */
262 void free_path(Path *path)
263 {
264   if (path->data) {
265     MEM_freeN(path->data);
266   }
267   MEM_freeN(path);
268 }
269
270 /* calculate a curve-deform path for a curve
271  * - only called from displist.c -> do_makeDispListCurveTypes
272  */
273 void calc_curvepath(Object *ob, ListBase *nurbs)
274 {
275   BevList *bl;
276   BevPoint *bevp, *bevpn, *bevpfirst, *bevplast;
277   PathPoint *pp;
278   Nurb *nu;
279   Path *path;
280   float *fp, *dist, *maxdist, xyz[3];
281   float fac, d = 0, fac1, fac2;
282   int a, tot, cycl = 0;
283
284   /* in a path vertices are with equal differences: path->len = number of verts */
285   /* NOW WITH BEVELCURVE!!! */
286
287   if (ob == NULL || ob->type != OB_CURVE) {
288     return;
289   }
290
291   if (ob->runtime.curve_cache->path) {
292     free_path(ob->runtime.curve_cache->path);
293   }
294   ob->runtime.curve_cache->path = NULL;
295
296   /* weak! can only use first curve */
297   bl = ob->runtime.curve_cache->bev.first;
298   if (bl == NULL || !bl->nr) {
299     return;
300   }
301
302   nu = nurbs->first;
303
304   ob->runtime.curve_cache->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
305
306   /* if POLY: last vertice != first vertice */
307   cycl = (bl->poly != -1);
308
309   tot = cycl ? bl->nr : bl->nr - 1;
310
311   path->len = tot + 1;
312   /* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */
313   if (path->len < nu->resolu * SEGMENTSU(nu)) {
314     path->len = nu->resolu * SEGMENTSU(nu);
315   }
316
317   dist = (float *)MEM_mallocN(sizeof(float) * (tot + 1), "calcpathdist");
318
319   /* all lengths in *dist */
320   bevp = bevpfirst = bl->bevpoints;
321   fp = dist;
322   *fp = 0.0f;
323   for (a = 0; a < tot; a++) {
324     fp++;
325     if (cycl && a == tot - 1) {
326       sub_v3_v3v3(xyz, bevpfirst->vec, bevp->vec);
327     }
328     else {
329       sub_v3_v3v3(xyz, (bevp + 1)->vec, bevp->vec);
330     }
331
332     *fp = *(fp - 1) + len_v3(xyz);
333     bevp++;
334   }
335
336   path->totdist = *fp;
337
338   /* the path verts  in path->data */
339   /* now also with TILT value */
340   pp = path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint) * path->len, "pathdata");
341
342   bevp = bevpfirst;
343   bevpn = bevp + 1;
344   bevplast = bevpfirst + (bl->nr - 1);
345   if (UNLIKELY(bevpn > bevplast)) {
346     bevpn = cycl ? bevpfirst : bevplast;
347   }
348   fp = dist + 1;
349   maxdist = dist + tot;
350   fac = 1.0f / ((float)path->len - 1.0f);
351   fac = fac * path->totdist;
352
353   for (a = 0; a < path->len; a++) {
354
355     d = ((float)a) * fac;
356
357     /* we're looking for location (distance) 'd' in the array */
358     if (LIKELY(tot > 0)) {
359       while ((fp < maxdist) && (d >= *fp)) {
360         fp++;
361         if (bevp < bevplast) {
362           bevp++;
363         }
364         bevpn = bevp + 1;
365         if (UNLIKELY(bevpn > bevplast)) {
366           bevpn = cycl ? bevpfirst : bevplast;
367         }
368       }
369
370       fac1 = (*(fp)-d) / (*(fp) - *(fp - 1));
371       fac2 = 1.0f - fac1;
372     }
373     else {
374       fac1 = 1.0f;
375       fac2 = 0.0f;
376     }
377
378     interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
379     pp->vec[3] = fac1 * bevp->tilt + fac2 * bevpn->tilt;
380     pp->radius = fac1 * bevp->radius + fac2 * bevpn->radius;
381     pp->weight = fac1 * bevp->weight + fac2 * bevpn->weight;
382     interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
383     normalize_qt(pp->quat);
384
385     pp++;
386   }
387
388   MEM_freeN(dist);
389 }
390
391 static int interval_test(const int min, const int max, int p1, const int cycl)
392 {
393   if (cycl) {
394     p1 = mod_i(p1 - min, (max - min + 1)) + min;
395   }
396   else {
397     if (p1 < min) {
398       p1 = min;
399     }
400     else if (p1 > max) {
401       p1 = max;
402     }
403   }
404   return p1;
405 }
406
407 /* calculate the deformation implied by the curve path at a given parametric position,
408  * and returns whether this operation succeeded.
409  *
410  * note: ctime is normalized range <0-1>
411  *
412  * returns OK: 1/0
413  */
414 int where_on_path(Object *ob,
415                   float ctime,
416                   float vec[4],
417                   float dir[3],
418                   float quat[4],
419                   float *radius,
420                   float *weight)
421 {
422   Curve *cu;
423   Nurb *nu;
424   BevList *bl;
425   Path *path;
426   PathPoint *pp, *p0, *p1, *p2, *p3;
427   float fac;
428   float data[4];
429   int cycl = 0, s0, s1, s2, s3;
430   ListBase *nurbs;
431
432   if (ob == NULL || ob->type != OB_CURVE) {
433     return 0;
434   }
435   cu = ob->data;
436   if (ob->runtime.curve_cache == NULL || ob->runtime.curve_cache->path == NULL ||
437       ob->runtime.curve_cache->path->data == NULL) {
438     CLOG_WARN(&LOG, "no path!");
439     return 0;
440   }
441   path = ob->runtime.curve_cache->path;
442   pp = path->data;
443
444   /* test for cyclic */
445   bl = ob->runtime.curve_cache->bev.first;
446   if (!bl) {
447     return 0;
448   }
449   if (!bl->nr) {
450     return 0;
451   }
452   if (bl->poly > -1) {
453     cycl = 1;
454   }
455
456   /* values below zero for non-cyclic curves give strange results */
457   BLI_assert(cycl || ctime >= 0.0f);
458
459   ctime *= (path->len - 1);
460
461   s1 = (int)floor(ctime);
462   fac = (float)(s1 + 1) - ctime;
463
464   /* path->len is corrected for cyclic */
465   s0 = interval_test(0, path->len - 1 - cycl, s1 - 1, cycl);
466   s1 = interval_test(0, path->len - 1 - cycl, s1, cycl);
467   s2 = interval_test(0, path->len - 1 - cycl, s1 + 1, cycl);
468   s3 = interval_test(0, path->len - 1 - cycl, s1 + 2, cycl);
469
470   p0 = pp + s0;
471   p1 = pp + s1;
472   p2 = pp + s2;
473   p3 = pp + s3;
474
475   /* NOTE: commented out for follow constraint
476    *
477    *       If it's ever be uncommented watch out for curve_deform_verts()
478    *       which used to temporary set CU_FOLLOW flag for the curve and no
479    *       longer does it (because of threading issues of such a thing.
480    */
481   //if (cu->flag & CU_FOLLOW) {
482
483   key_curve_tangent_weights(1.0f - fac, data, KEY_BSPLINE);
484
485   interp_v3_v3v3v3v3(dir, p0->vec, p1->vec, p2->vec, p3->vec, data);
486
487   /* make compatible with vectoquat */
488   negate_v3(dir);
489   //}
490
491   nurbs = BKE_curve_editNurbs_get(cu);
492   if (!nurbs) {
493     nurbs = &cu->nurb;
494   }
495   nu = nurbs->first;
496
497   /* make sure that first and last frame are included in the vectors here  */
498   if (nu->type == CU_POLY) {
499     key_curve_position_weights(1.0f - fac, data, KEY_LINEAR);
500   }
501   else if (nu->type == CU_BEZIER) {
502     key_curve_position_weights(1.0f - fac, data, KEY_LINEAR);
503   }
504   else if (s0 == s1 || p2 == p3) {
505     key_curve_position_weights(1.0f - fac, data, KEY_CARDINAL);
506   }
507   else {
508     key_curve_position_weights(1.0f - fac, data, KEY_BSPLINE);
509   }
510
511   vec[0] = data[0] * p0->vec[0] + data[1] * p1->vec[0] + data[2] * p2->vec[0] +
512            data[3] * p3->vec[0]; /* X */
513   vec[1] = data[0] * p0->vec[1] + data[1] * p1->vec[1] + data[2] * p2->vec[1] +
514            data[3] * p3->vec[1]; /* Y */
515   vec[2] = data[0] * p0->vec[2] + data[1] * p1->vec[2] + data[2] * p2->vec[2] +
516            data[3] * p3->vec[2]; /* Z */
517   vec[3] = data[0] * p0->vec[3] + data[1] * p1->vec[3] + data[2] * p2->vec[3] +
518            data[3] * p3->vec[3]; /* Tilt, should not be needed since we have quat still used */
519
520   if (quat) {
521     float totfac, q1[4], q2[4];
522
523     totfac = data[0] + data[3];
524     if (totfac > FLT_EPSILON) {
525       interp_qt_qtqt(q1, p0->quat, p3->quat, data[3] / totfac);
526     }
527     else {
528       copy_qt_qt(q1, p1->quat);
529     }
530
531     totfac = data[1] + data[2];
532     if (totfac > FLT_EPSILON) {
533       interp_qt_qtqt(q2, p1->quat, p2->quat, data[2] / totfac);
534     }
535     else {
536       copy_qt_qt(q2, p3->quat);
537     }
538
539     totfac = data[0] + data[1] + data[2] + data[3];
540     if (totfac > FLT_EPSILON) {
541       interp_qt_qtqt(quat, q1, q2, (data[1] + data[2]) / totfac);
542     }
543     else {
544       copy_qt_qt(quat, q2);
545     }
546   }
547
548   if (radius) {
549     *radius = data[0] * p0->radius + data[1] * p1->radius + data[2] * p2->radius +
550               data[3] * p3->radius;
551   }
552
553   if (weight) {
554     *weight = data[0] * p0->weight + data[1] * p1->weight + data[2] * p2->weight +
555               data[3] * p3->weight;
556   }
557
558   return 1;
559 }