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 <float.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_blenlib.h"
33 #include "BLI_kdopbvh.h"
34 #include "BLI_math.h"
35 #include "BLI_string_utils.h"
36 #include "BLI_utildefines.h"
37 #include "BLT_translation.h"
38
39 #include "DNA_action_types.h"
40 #include "DNA_armature_types.h"
41 #include "DNA_cachefile_types.h"
42 #include "DNA_constraint_types.h"
43 #include "DNA_curve_types.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_modifier_types.h"
47 #include "DNA_object_types.h"
48
49 #include "DNA_lattice_types.h"
50 #include "DNA_movieclip_types.h"
51 #include "DNA_scene_types.h"
52 #include "DNA_tracking_types.h"
53
54 #include "BKE_action.h"
55 #include "BKE_anim_path.h"
56 #include "BKE_animsys.h"
57 #include "BKE_armature.h"
58 #include "BKE_bvhutils.h"
59 #include "BKE_cachefile.h"
60 #include "BKE_camera.h"
61 #include "BKE_constraint.h"
62 #include "BKE_curve.h"
63 #include "BKE_deform.h"
64 #include "BKE_displist.h"
65 #include "BKE_editmesh.h"
66 #include "BKE_fcurve_driver.h"
67 #include "BKE_global.h"
68 #include "BKE_idprop.h"
69 #include "BKE_lib_id.h"
70 #include "BKE_mesh_runtime.h"
71 #include "BKE_movieclip.h"
72 #include "BKE_object.h"
73 #include "BKE_scene.h"
74 #include "BKE_shrinkwrap.h"
75 #include "BKE_tracking.h"
76
77 #include "BIK_api.h"
78
79 #include "DEG_depsgraph.h"
80 #include "DEG_depsgraph_query.h"
81
82 #include "CLG_log.h"
83
84 #ifdef WITH_PYTHON
85 # include "BPY_extern.h"
86 #endif
87
88 #ifdef WITH_ALEMBIC
89 # include "ABC_alembic.h"
90 #endif
91
92 /* ---------------------------------------------------------------------------- */
93 /* Useful macros for testing various common flag combinations */
94
95 /* Constraint Target Macros */
96 #define VALID_CONS_TARGET(ct) ((ct) && (ct->tar))
97
98 static CLG_LogRef LOG = {"bke.constraint"};
99
100 /* ************************ Constraints - General Utilities *************************** */
101 /* These functions here don't act on any specific constraints, and are therefore should/will
102 * not require any of the special function-pointers afforded by the relevant constraint
103 * type-info structs.
104 */
105
106 static void damptrack_do_transform(float matrix[4][4], const float tarvec[3], int track_axis);
107
108 static bConstraint *constraint_find_original(Object *ob,
109 bPoseChannel *pchan,
110 bConstraint *con,
111 Object **r_orig_ob);
112 static bConstraint *constraint_find_original_for_update(bConstraintOb *cob, bConstraint *con);
113
114 /* -------------- Naming -------------- */
115
116 /* Find the first available, non-duplicate name for a given constraint */
BKE_constraint_unique_name(bConstraint * con,ListBase * list)117 void BKE_constraint_unique_name(bConstraint *con, ListBase *list)
118 {
119 BLI_uniquename(list, con, DATA_("Const"), '.', offsetof(bConstraint, name), sizeof(con->name));
120 }
121
122 /* ----------------- Evaluation Loop Preparation --------------- */
123
124 /* package an object/bone for use in constraint evaluation */
125 /* This function MEM_calloc's a bConstraintOb struct,
126 * that will need to be freed after evaluation */
BKE_constraints_make_evalob(Depsgraph * depsgraph,Scene * scene,Object * ob,void * subdata,short datatype)127 bConstraintOb *BKE_constraints_make_evalob(
128 Depsgraph *depsgraph, Scene *scene, Object *ob, void *subdata, short datatype)
129 {
130 bConstraintOb *cob;
131
132 /* create regardless of whether we have any data! */
133 cob = MEM_callocN(sizeof(bConstraintOb), "bConstraintOb");
134
135 /* for system time, part of deglobalization, code nicer later with local time (ton) */
136 cob->scene = scene;
137 cob->depsgraph = depsgraph;
138
139 /* based on type of available data */
140 switch (datatype) {
141 case CONSTRAINT_OBTYPE_OBJECT: {
142 /* disregard subdata... calloc should set other values right */
143 if (ob) {
144 cob->ob = ob;
145 cob->type = datatype;
146
147 if (cob->ob->rotmode > 0) {
148 /* Should be some kind of Euler order, so use it */
149 /* NOTE: Versions <= 2.76 assumed that "default" order
150 * would always get used, so we may seem some rig
151 * breakage as a result. However, this change here
152 * is needed to fix T46599
153 */
154 cob->rotOrder = ob->rotmode;
155 }
156 else {
157 /* Quats/Axis-Angle, so Eulers should just use default order */
158 cob->rotOrder = EULER_ORDER_DEFAULT;
159 }
160 copy_m4_m4(cob->matrix, ob->obmat);
161 }
162 else {
163 unit_m4(cob->matrix);
164 }
165
166 copy_m4_m4(cob->startmat, cob->matrix);
167 break;
168 }
169 case CONSTRAINT_OBTYPE_BONE: {
170 /* only set if we have valid bone, otherwise default */
171 if (ob && subdata) {
172 cob->ob = ob;
173 cob->pchan = (bPoseChannel *)subdata;
174 cob->type = datatype;
175
176 if (cob->pchan->rotmode > 0) {
177 /* should be some type of Euler order */
178 cob->rotOrder = cob->pchan->rotmode;
179 }
180 else {
181 /* Quats, so eulers should just use default order */
182 cob->rotOrder = EULER_ORDER_DEFAULT;
183 }
184
185 /* matrix in world-space */
186 mul_m4_m4m4(cob->matrix, ob->obmat, cob->pchan->pose_mat);
187 }
188 else {
189 unit_m4(cob->matrix);
190 }
191
192 copy_m4_m4(cob->startmat, cob->matrix);
193 break;
194 }
195 default: /* other types not yet handled */
196 unit_m4(cob->matrix);
197 unit_m4(cob->startmat);
198 break;
199 }
200
201 return cob;
202 }
203
204 /* cleanup after constraint evaluation */
BKE_constraints_clear_evalob(bConstraintOb * cob)205 void BKE_constraints_clear_evalob(bConstraintOb *cob)
206 {
207 float delta[4][4], imat[4][4];
208
209 /* prevent crashes */
210 if (cob == NULL) {
211 return;
212 }
213
214 /* calculate delta of constraints evaluation */
215 invert_m4_m4(imat, cob->startmat);
216 /* XXX This would seem to be in wrong order. However, it does not work in 'right' order -
217 * would be nice to understand why premul is needed here instead of usual postmul?
218 * In any case, we **do not get a delta** here (e.g. startmat & matrix having same location,
219 * still gives a 'delta' with non-null translation component :/ ).*/
220 mul_m4_m4m4(delta, cob->matrix, imat);
221
222 /* copy matrices back to source */
223 switch (cob->type) {
224 case CONSTRAINT_OBTYPE_OBJECT: {
225 /* cob->ob might not exist! */
226 if (cob->ob) {
227 /* copy new ob-matrix back to owner */
228 copy_m4_m4(cob->ob->obmat, cob->matrix);
229
230 /* copy inverse of delta back to owner */
231 invert_m4_m4(cob->ob->constinv, delta);
232 }
233 break;
234 }
235 case CONSTRAINT_OBTYPE_BONE: {
236 /* cob->ob or cob->pchan might not exist */
237 if (cob->ob && cob->pchan) {
238 /* copy new pose-matrix back to owner */
239 mul_m4_m4m4(cob->pchan->pose_mat, cob->ob->imat, cob->matrix);
240
241 /* copy inverse of delta back to owner */
242 invert_m4_m4(cob->pchan->constinv, delta);
243 }
244 break;
245 }
246 }
247
248 /* free tempolary struct */
249 MEM_freeN(cob);
250 }
251
252 /* -------------- Space-Conversion API -------------- */
253
254 /* This function is responsible for the correct transformations/conversions
255 * of a matrix from one space to another for constraint evaluation.
256 * For now, this is only implemented for Objects and PoseChannels.
257 */
BKE_constraint_mat_convertspace(Object * ob,bPoseChannel * pchan,float mat[4][4],short from,short to,const bool keep_scale)258 void BKE_constraint_mat_convertspace(
259 Object *ob, bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale)
260 {
261 float diff_mat[4][4];
262 float imat[4][4];
263
264 /* prevent crashes in these unlikely events */
265 if (ob == NULL || mat == NULL) {
266 return;
267 }
268 /* optimize trick - check if need to do anything */
269 if (from == to) {
270 return;
271 }
272
273 /* are we dealing with pose-channels or objects */
274 if (pchan) {
275 /* pose channels */
276 switch (from) {
277 case CONSTRAINT_SPACE_WORLD: /* ---------- FROM WORLDSPACE ---------- */
278 {
279 /* world to pose */
280 invert_m4_m4(imat, ob->obmat);
281 mul_m4_m4m4(mat, imat, mat);
282
283 /* use pose-space as stepping stone for other spaces... */
284 if (ELEM(to, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_PARLOCAL)) {
285 /* call self with slightly different values */
286 BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
287 }
288 break;
289 }
290 case CONSTRAINT_SPACE_POSE: /* ---------- FROM POSESPACE ---------- */
291 {
292 /* pose to world */
293 if (to == CONSTRAINT_SPACE_WORLD) {
294 mul_m4_m4m4(mat, ob->obmat, mat);
295 }
296 /* pose to local */
297 else if (to == CONSTRAINT_SPACE_LOCAL) {
298 if (pchan->bone) {
299 BKE_armature_mat_pose_to_bone(pchan, mat, mat);
300 }
301 }
302 /* pose to local with parent */
303 else if (to == CONSTRAINT_SPACE_PARLOCAL) {
304 if (pchan->bone) {
305 invert_m4_m4(imat, pchan->bone->arm_mat);
306 mul_m4_m4m4(mat, imat, mat);
307 }
308 }
309 break;
310 }
311 case CONSTRAINT_SPACE_LOCAL: /* ------------ FROM LOCALSPACE --------- */
312 {
313 /* local to pose - do inverse procedure that was done for pose to local */
314 if (pchan->bone) {
315 /* we need the posespace_matrix = local_matrix + (parent_posespace_matrix + restpos) */
316 BKE_armature_mat_bone_to_pose(pchan, mat, mat);
317 }
318
319 /* use pose-space as stepping stone for other spaces */
320 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_PARLOCAL)) {
321 /* call self with slightly different values */
322 BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
323 }
324 break;
325 }
326 case CONSTRAINT_SPACE_PARLOCAL: /* -------------- FROM LOCAL WITH PARENT ---------- */
327 {
328 /* local + parent to pose */
329 if (pchan->bone) {
330 mul_m4_m4m4(mat, pchan->bone->arm_mat, mat);
331 }
332
333 /* use pose-space as stepping stone for other spaces */
334 if (ELEM(to, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL)) {
335 /* call self with slightly different values */
336 BKE_constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, to, keep_scale);
337 }
338 break;
339 }
340 }
341 }
342 else {
343 /* objects */
344 if (from == CONSTRAINT_SPACE_WORLD && to == CONSTRAINT_SPACE_LOCAL) {
345 /* check if object has a parent */
346 if (ob->parent) {
347 /* 'subtract' parent's effects from owner */
348 mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
349 invert_m4_m4_safe(imat, diff_mat);
350 mul_m4_m4m4(mat, imat, mat);
351 }
352 else {
353 /* Local space in this case will have to be defined as local to the owner's
354 * transform-property-rotated axes. So subtract this rotation component.
355 */
356 /* XXX This is actually an ugly hack, local space of a parent-less object *is* the same as
357 * global space!
358 * Think what we want actually here is some kind of 'Final Space', i.e
359 * . once transformations are applied - users are often confused about this too,
360 * this is not consistent with bones
361 * local space either... Meh :|
362 * --mont29
363 */
364 BKE_object_to_mat4(ob, diff_mat);
365 if (!keep_scale) {
366 normalize_m4(diff_mat);
367 }
368 zero_v3(diff_mat[3]);
369
370 invert_m4_m4_safe(imat, diff_mat);
371 mul_m4_m4m4(mat, imat, mat);
372 }
373 }
374 else if (from == CONSTRAINT_SPACE_LOCAL && to == CONSTRAINT_SPACE_WORLD) {
375 /* check that object has a parent - otherwise this won't work */
376 if (ob->parent) {
377 /* 'add' parent's effect back to owner */
378 mul_m4_m4m4(diff_mat, ob->parent->obmat, ob->parentinv);
379 mul_m4_m4m4(mat, diff_mat, mat);
380 }
381 else {
382 /* Local space in this case will have to be defined as local to the owner's
383 * transform-property-rotated axes. So add back this rotation component.
384 */
385 /* XXX See comment above for world->local case... */
386 BKE_object_to_mat4(ob, diff_mat);
387 if (!keep_scale) {
388 normalize_m4(diff_mat);
389 }
390 zero_v3(diff_mat[3]);
391
392 mul_m4_m4m4(mat, diff_mat, mat);
393 }
394 }
395 }
396 }
397
398 /* ------------ General Target Matrix Tools ---------- */
399
400 /* function that sets the given matrix based on given vertex group in mesh */
contarget_get_mesh_mat(Object * ob,const char * substring,float mat[4][4])401 static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[4][4])
402 {
403 /* when not in EditMode, use the 'final' evaluated mesh, depsgraph
404 * ensures we build with CD_MDEFORMVERT layer
405 */
406 Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
407 BMEditMesh *em = BKE_editmesh_from_object(ob);
408 float plane[3];
409 float imat[3][3], tmat[3][3];
410 const int defgroup = BKE_object_defgroup_name_index(ob, substring);
411
412 /* initialize target matrix using target matrix */
413 copy_m4_m4(mat, ob->obmat);
414
415 /* get index of vertex group */
416 if (defgroup == -1) {
417 return;
418 }
419
420 float vec[3] = {0.0f, 0.0f, 0.0f};
421 float normal[3] = {0.0f, 0.0f, 0.0f};
422 float weightsum = 0.0f;
423 if (me_eval) {
424 MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
425 int numVerts = me_eval->totvert;
426
427 /* check that dvert is a valid pointers (just in case) */
428 if (dvert) {
429 MDeformVert *dv = dvert;
430 MVert *mv = me_eval->mvert;
431
432 /* get the average of all verts with that are in the vertex-group */
433 for (int i = 0; i < numVerts; i++, dv++, mv++) {
434 MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
435
436 if (dw && dw->weight > 0.0f) {
437 float nor[3];
438 normal_short_to_float_v3(nor, mv->no);
439 madd_v3_v3fl(vec, mv->co, dw->weight);
440 madd_v3_v3fl(normal, nor, dw->weight);
441 weightsum += dw->weight;
442 }
443 }
444 }
445 }
446 else if (em) {
447 if (CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) {
448 BMVert *v;
449 BMIter iter;
450
451 BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
452 MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, v->head.data, CD_MDEFORMVERT);
453 MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
454
455 if (dw && dw->weight > 0.0f) {
456 madd_v3_v3fl(vec, v->co, dw->weight);
457 madd_v3_v3fl(normal, v->no, dw->weight);
458 weightsum += dw->weight;
459 }
460 }
461 }
462 }
463 else {
464 /* No valid edit or evaluated mesh, just abort. */
465 return;
466 }
467
468 /* calculate averages of normal and coordinates */
469 if (weightsum > 0) {
470 mul_v3_fl(vec, 1.0f / weightsum);
471 mul_v3_fl(normal, 1.0f / weightsum);
472 }
473
474 /* derive the rotation from the average normal:
475 * - code taken from transform_gizmo.c,
476 * calc_gizmo_stats, V3D_ORIENT_NORMAL case */
477
478 /* We need the transpose of the inverse for a normal. */
479 copy_m3_m4(imat, ob->obmat);
480
481 invert_m3_m3(tmat, imat);
482 transpose_m3(tmat);
483 mul_m3_v3(tmat, normal);
484
485 normalize_v3(normal);
486 copy_v3_v3(plane, tmat[1]);
487
488 cross_v3_v3v3(mat[0], normal, plane);
489 if (len_squared_v3(mat[0]) < square_f(1e-3f)) {
490 copy_v3_v3(plane, tmat[0]);
491 cross_v3_v3v3(mat[0], normal, plane);
492 }
493
494 copy_v3_v3(mat[2], normal);
495 cross_v3_v3v3(mat[1], mat[2], mat[0]);
496
497 normalize_m4(mat);
498
499 /* apply the average coordinate as the new location */
500 mul_v3_m4v3(mat[3], ob->obmat, vec);
501 }
502
503 /* function that sets the given matrix based on given vertex group in lattice */
contarget_get_lattice_mat(Object * ob,const char * substring,float mat[4][4])504 static void contarget_get_lattice_mat(Object *ob, const char *substring, float mat[4][4])
505 {
506 Lattice *lt = (Lattice *)ob->data;
507
508 DispList *dl = ob->runtime.curve_cache ?
509 BKE_displist_find(&ob->runtime.curve_cache->disp, DL_VERTS) :
510 NULL;
511 const float *co = dl ? dl->verts : NULL;
512 BPoint *bp = lt->def;
513
514 MDeformVert *dv = lt->dvert;
515 int tot_verts = lt->pntsu * lt->pntsv * lt->pntsw;
516 float vec[3] = {0.0f, 0.0f, 0.0f}, tvec[3];
517 int grouped = 0;
518 int i, n;
519 const int defgroup = BKE_object_defgroup_name_index(ob, substring);
520
521 /* initialize target matrix using target matrix */
522 copy_m4_m4(mat, ob->obmat);
523
524 /* get index of vertex group */
525 if (defgroup == -1) {
526 return;
527 }
528 if (dv == NULL) {
529 return;
530 }
531
532 /* 1. Loop through control-points checking if in nominated vertex-group.
533 * 2. If it is, add it to vec to find the average point.
534 */
535 for (i = 0; i < tot_verts; i++, dv++) {
536 for (n = 0; n < dv->totweight; n++) {
537 MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
538 if (dw && dw->weight > 0.0f) {
539 /* copy coordinates of point to temporary vector, then add to find average */
540 memcpy(tvec, co ? co : bp->vec, sizeof(float[3]));
541
542 add_v3_v3(vec, tvec);
543 grouped++;
544 }
545 }
546
547 /* advance pointer to coordinate data */
548 if (co) {
549 co += 3;
550 }
551 else {
552 bp++;
553 }
554 }
555
556 /* find average location, then multiply by ob->obmat to find world-space location */
557 if (grouped) {
558 mul_v3_fl(vec, 1.0f / grouped);
559 }
560 mul_v3_m4v3(tvec, ob->obmat, vec);
561
562 /* copy new location to matrix */
563 copy_v3_v3(mat[3], tvec);
564 }
565
566 /* generic function to get the appropriate matrix for most target cases */
567 /* The cases where the target can be object data have not been implemented */
constraint_target_to_mat4(Object * ob,const char * substring,float mat[4][4],short from,short to,short flag,float headtail)568 static void constraint_target_to_mat4(Object *ob,
569 const char *substring,
570 float mat[4][4],
571 short from,
572 short to,
573 short flag,
574 float headtail)
575 {
576 /* Case OBJECT */
577 if (substring[0] == '\0') {
578 copy_m4_m4(mat, ob->obmat);
579 BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
580 }
581 /* Case VERTEXGROUP */
582 /* Current method just takes the average location of all the points in the
583 * VertexGroup, and uses that as the location value of the targets. Where
584 * possible, the orientation will also be calculated, by calculating an
585 * 'average' vertex normal, and deriving the rotation from that.
586 *
587 * NOTE: EditMode is not currently supported, and will most likely remain that
588 * way as constraints can only really affect things on object/bone level.
589 */
590 else if (ob->type == OB_MESH) {
591 contarget_get_mesh_mat(ob, substring, mat);
592 BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
593 }
594 else if (ob->type == OB_LATTICE) {
595 contarget_get_lattice_mat(ob, substring, mat);
596 BKE_constraint_mat_convertspace(ob, NULL, mat, from, to, false);
597 }
598 /* Case BONE */
599 else {
600 bPoseChannel *pchan;
601
602 pchan = BKE_pose_channel_find_name(ob->pose, substring);
603 if (pchan) {
604 /* Multiply the PoseSpace accumulation/final matrix for this
605 * PoseChannel by the Armature Object's Matrix to get a world-space matrix.
606 */
607 bool is_bbone = (pchan->bone) && (pchan->bone->segments > 1) &&
608 (flag & CONSTRAINT_BBONE_SHAPE);
609 bool full_bbone = (flag & CONSTRAINT_BBONE_SHAPE_FULL) != 0;
610
611 if (headtail < 0.000001f && !(is_bbone && full_bbone)) {
612 /* skip length interpolation if set to head */
613 mul_m4_m4m4(mat, ob->obmat, pchan->pose_mat);
614 }
615 else if (is_bbone && pchan->bone->segments == pchan->runtime.bbone_segments) {
616 /* use point along bbone */
617 Mat4 *bbone = pchan->runtime.bbone_pose_mats;
618 float tempmat[4][4];
619 float loc[3], fac;
620 int index;
621
622 /* figure out which segment(s) the headtail value falls in */
623 BKE_pchan_bbone_deform_segment_index(pchan, headtail, &index, &fac);
624
625 /* apply full transformation of the segment if requested */
626 if (full_bbone) {
627 interp_m4_m4m4(tempmat, bbone[index].mat, bbone[index + 1].mat, fac);
628
629 mul_m4_m4m4(tempmat, pchan->pose_mat, tempmat);
630 }
631 /* only interpolate location */
632 else {
633 interp_v3_v3v3(loc, bbone[index].mat[3], bbone[index + 1].mat[3], fac);
634
635 copy_m4_m4(tempmat, pchan->pose_mat);
636 mul_v3_m4v3(tempmat[3], pchan->pose_mat, loc);
637 }
638
639 mul_m4_m4m4(mat, ob->obmat, tempmat);
640 }
641 else {
642 float tempmat[4][4], loc[3];
643
644 /* interpolate along length of bone */
645 interp_v3_v3v3(loc, pchan->pose_head, pchan->pose_tail, headtail);
646
647 /* use interpolated distance for subtarget */
648 copy_m4_m4(tempmat, pchan->pose_mat);
649 copy_v3_v3(tempmat[3], loc);
650
651 mul_m4_m4m4(mat, ob->obmat, tempmat);
652 }
653 }
654 else {
655 copy_m4_m4(mat, ob->obmat);
656 }
657
658 /* convert matrix space as required */
659 BKE_constraint_mat_convertspace(ob, pchan, mat, from, to, false);
660 }
661 }
662
663 /* ************************* Specific Constraints ***************************** */
664 /* Each constraint defines a set of functions, which will be called at the appropriate
665 * times. In addition to this, each constraint should have a type-info struct, where
666 * its functions are attached for use.
667 */
668
669 /* Template for type-info data:
670 * - make a copy of this when creating new constraints, and just change the functions
671 * pointed to as necessary
672 * - although the naming of functions doesn't matter, it would help for code
673 * readability, to follow the same naming convention as is presented here
674 * - any functions that a constraint doesn't need to define, don't define
675 * for such cases, just use NULL
676 * - these should be defined after all the functions have been defined, so that
677 * forward-definitions/prototypes don't need to be used!
678 * - keep this copy #if-def'd so that future constraints can get based off this
679 */
680 #if 0
681 static bConstraintTypeInfo CTI_CONSTRNAME = {
682 CONSTRAINT_TYPE_CONSTRNAME, /* type */
683 sizeof(bConstrNameConstraint), /* size */
684 "ConstrName", /* name */
685 "bConstrNameConstraint", /* struct name */
686 constrname_free, /* free data */
687 constrname_id_looper, /* id looper */
688 constrname_copy, /* copy data */
689 constrname_new_data, /* new data */
690 constrname_get_tars, /* get constraint targets */
691 constrname_flush_tars, /* flush constraint targets */
692 constrname_get_tarmat, /* get target matrix */
693 constrname_evaluate, /* evaluate */
694 };
695 #endif
696
697 /* This function should be used for the get_target_matrix member of all
698 * constraints that are not picky about what happens to their target matrix.
699 */
default_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))700 static void default_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
701 bConstraint *con,
702 bConstraintOb *UNUSED(cob),
703 bConstraintTarget *ct,
704 float UNUSED(ctime))
705 {
706 if (VALID_CONS_TARGET(ct)) {
707 constraint_target_to_mat4(ct->tar,
708 ct->subtarget,
709 ct->matrix,
710 CONSTRAINT_SPACE_WORLD,
711 ct->space,
712 con->flag,
713 con->headtail);
714 }
715 else if (ct) {
716 unit_m4(ct->matrix);
717 }
718 }
719
720 /* This is a variant that extracts full transformation from B-Bone segments.
721 */
default_get_tarmat_full_bbone(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))722 static void default_get_tarmat_full_bbone(struct Depsgraph *UNUSED(depsgraph),
723 bConstraint *con,
724 bConstraintOb *UNUSED(cob),
725 bConstraintTarget *ct,
726 float UNUSED(ctime))
727 {
728 if (VALID_CONS_TARGET(ct)) {
729 constraint_target_to_mat4(ct->tar,
730 ct->subtarget,
731 ct->matrix,
732 CONSTRAINT_SPACE_WORLD,
733 ct->space,
734 con->flag | CONSTRAINT_BBONE_SHAPE_FULL,
735 con->headtail);
736 }
737 else if (ct) {
738 unit_m4(ct->matrix);
739 }
740 }
741
742 /* This following macro should be used for all standard single-target *_get_tars functions
743 * to save typing and reduce maintenance woes.
744 * (Hopefully all compilers will be happy with the lines with just a space on them.
745 * Those are really just to help this code easier to read).
746 */
747 /* TODO: cope with getting rotation order... */
748 #define SINGLETARGET_GET_TARS(con, datatar, datasubtarget, ct, list) \
749 { \
750 ct = MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
751 \
752 ct->tar = datatar; \
753 BLI_strncpy(ct->subtarget, datasubtarget, sizeof(ct->subtarget)); \
754 ct->space = con->tarspace; \
755 ct->flag = CONSTRAINT_TAR_TEMP; \
756 \
757 if (ct->tar) { \
758 if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) { \
759 bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget); \
760 ct->type = CONSTRAINT_OBTYPE_BONE; \
761 ct->rotOrder = (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \
762 } \
763 else if (OB_TYPE_SUPPORT_VGROUP(ct->tar->type) && (ct->subtarget[0])) { \
764 ct->type = CONSTRAINT_OBTYPE_VERT; \
765 ct->rotOrder = EULER_ORDER_DEFAULT; \
766 } \
767 else { \
768 ct->type = CONSTRAINT_OBTYPE_OBJECT; \
769 ct->rotOrder = ct->tar->rotmode; \
770 } \
771 } \
772 \
773 BLI_addtail(list, ct); \
774 } \
775 (void)0
776
777 /* This following macro should be used for all standard single-target *_get_tars functions
778 * to save typing and reduce maintenance woes. It does not do the subtarget related operations
779 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
780 * really just to help this code easier to read)
781 */
782 /* TODO: cope with getting rotation order... */
783 #define SINGLETARGETNS_GET_TARS(con, datatar, ct, list) \
784 { \
785 ct = MEM_callocN(sizeof(bConstraintTarget), "tempConstraintTarget"); \
786 \
787 ct->tar = datatar; \
788 ct->space = con->tarspace; \
789 ct->flag = CONSTRAINT_TAR_TEMP; \
790 \
791 if (ct->tar) { \
792 ct->type = CONSTRAINT_OBTYPE_OBJECT; \
793 } \
794 BLI_addtail(list, ct); \
795 } \
796 (void)0
797
798 /* This following macro should be used for all standard single-target *_flush_tars functions
799 * to save typing and reduce maintenance woes.
800 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
801 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
802 * really just to help this code easier to read)
803 */
804 #define SINGLETARGET_FLUSH_TARS(con, datatar, datasubtarget, ct, list, no_copy) \
805 { \
806 if (ct) { \
807 bConstraintTarget *ctn = ct->next; \
808 if (no_copy == 0) { \
809 datatar = ct->tar; \
810 BLI_strncpy(datasubtarget, ct->subtarget, sizeof(datasubtarget)); \
811 con->tarspace = (char)ct->space; \
812 } \
813 \
814 BLI_freelinkN(list, ct); \
815 ct = ctn; \
816 } \
817 } \
818 (void)0
819
820 /* This following macro should be used for all standard single-target *_flush_tars functions
821 * to save typing and reduce maintenance woes. It does not do the subtarget related operations.
822 * Note: the pointer to ct will be changed to point to the next in the list (as it gets removed)
823 * (Hopefully all compilers will be happy with the lines with just a space on them. Those are
824 * really just to help this code easier to read)
825 */
826 #define SINGLETARGETNS_FLUSH_TARS(con, datatar, ct, list, no_copy) \
827 { \
828 if (ct) { \
829 bConstraintTarget *ctn = ct->next; \
830 if (no_copy == 0) { \
831 datatar = ct->tar; \
832 con->tarspace = (char)ct->space; \
833 } \
834 \
835 BLI_freelinkN(list, ct); \
836 ct = ctn; \
837 } \
838 } \
839 (void)0
840
841 /* --------- ChildOf Constraint ------------ */
842
childof_new_data(void * cdata)843 static void childof_new_data(void *cdata)
844 {
845 bChildOfConstraint *data = (bChildOfConstraint *)cdata;
846
847 data->flag = (CHILDOF_LOCX | CHILDOF_LOCY | CHILDOF_LOCZ | CHILDOF_ROTX | CHILDOF_ROTY |
848 CHILDOF_ROTZ | CHILDOF_SIZEX | CHILDOF_SIZEY | CHILDOF_SIZEZ |
849 CHILDOF_SET_INVERSE);
850 unit_m4(data->invmat);
851 }
852
childof_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)853 static void childof_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
854 {
855 bChildOfConstraint *data = con->data;
856
857 /* target only */
858 func(con, (ID **)&data->tar, false, userdata);
859 }
860
childof_get_tars(bConstraint * con,ListBase * list)861 static int childof_get_tars(bConstraint *con, ListBase *list)
862 {
863 if (con && list) {
864 bChildOfConstraint *data = con->data;
865 bConstraintTarget *ct;
866
867 /* standard target-getting macro for single-target constraints */
868 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
869
870 return 1;
871 }
872
873 return 0;
874 }
875
childof_flush_tars(bConstraint * con,ListBase * list,bool no_copy)876 static void childof_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
877 {
878 if (con && list) {
879 bChildOfConstraint *data = con->data;
880 bConstraintTarget *ct = list->first;
881
882 /* the following macro is used for all standard single-target constraints */
883 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
884 }
885 }
886
childof_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)887 static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
888 {
889 bChildOfConstraint *data = con->data;
890 bConstraintTarget *ct = targets->first;
891
892 /* only evaluate if there is a target */
893 if (!VALID_CONS_TARGET(ct)) {
894 return;
895 }
896
897 float parmat[4][4];
898 float inverse_matrix[4][4];
899 /* Simple matrix parenting. */
900 if ((data->flag & CHILDOF_ALL) == CHILDOF_ALL) {
901 copy_m4_m4(parmat, ct->matrix);
902 copy_m4_m4(inverse_matrix, data->invmat);
903 }
904 /* Filter the parent matrix by channel. */
905 else {
906 float loc[3], eul[3], size[3];
907 float loco[3], eulo[3], sizeo[3];
908
909 /* extract components of both matrices */
910 copy_v3_v3(loc, ct->matrix[3]);
911 mat4_to_eulO(eul, ct->rotOrder, ct->matrix);
912 mat4_to_size(size, ct->matrix);
913
914 copy_v3_v3(loco, data->invmat[3]);
915 mat4_to_eulO(eulo, cob->rotOrder, data->invmat);
916 mat4_to_size(sizeo, data->invmat);
917
918 /* Reset the locked channels to their no-op values. */
919 if (!(data->flag & CHILDOF_LOCX)) {
920 loc[0] = loco[0] = 0.0f;
921 }
922 if (!(data->flag & CHILDOF_LOCY)) {
923 loc[1] = loco[1] = 0.0f;
924 }
925 if (!(data->flag & CHILDOF_LOCZ)) {
926 loc[2] = loco[2] = 0.0f;
927 }
928 if (!(data->flag & CHILDOF_ROTX)) {
929 eul[0] = eulo[0] = 0.0f;
930 }
931 if (!(data->flag & CHILDOF_ROTY)) {
932 eul[1] = eulo[1] = 0.0f;
933 }
934 if (!(data->flag & CHILDOF_ROTZ)) {
935 eul[2] = eulo[2] = 0.0f;
936 }
937 if (!(data->flag & CHILDOF_SIZEX)) {
938 size[0] = sizeo[0] = 1.0f;
939 }
940 if (!(data->flag & CHILDOF_SIZEY)) {
941 size[1] = sizeo[1] = 1.0f;
942 }
943 if (!(data->flag & CHILDOF_SIZEZ)) {
944 size[2] = sizeo[2] = 1.0f;
945 }
946
947 /* Construct the new matrices given the disabled channels. */
948 loc_eulO_size_to_mat4(parmat, loc, eul, size, ct->rotOrder);
949 loc_eulO_size_to_mat4(inverse_matrix, loco, eulo, sizeo, cob->rotOrder);
950 }
951
952 /* If requested, compute the inverse matrix from the computed parent matrix. */
953 if (data->flag & CHILDOF_SET_INVERSE) {
954 invert_m4_m4(data->invmat, parmat);
955 if (cob->pchan != NULL) {
956 mul_m4_series(data->invmat, data->invmat, cob->ob->obmat);
957 }
958
959 copy_m4_m4(inverse_matrix, data->invmat);
960
961 data->flag &= ~CHILDOF_SET_INVERSE;
962
963 /* Write the computed matrix back to the master copy if in COW evaluation. */
964 bConstraint *orig_con = constraint_find_original_for_update(cob, con);
965
966 if (orig_con != NULL) {
967 bChildOfConstraint *orig_data = orig_con->data;
968
969 copy_m4_m4(orig_data->invmat, data->invmat);
970 orig_data->flag &= ~CHILDOF_SET_INVERSE;
971 }
972 }
973
974 /* Multiply together the target (parent) matrix, parent inverse,
975 * and the owner transform matrix to get the effect of this constraint
976 * (i.e. owner is 'parented' to parent). */
977 float orig_cob_matrix[4][4];
978 copy_m4_m4(orig_cob_matrix, cob->matrix);
979 mul_m4_series(cob->matrix, parmat, inverse_matrix, orig_cob_matrix);
980
981 /* Without this, changes to scale and rotation can change location
982 * of a parentless bone or a disconnected bone. Even though its set
983 * to zero above. */
984 if (!(data->flag & CHILDOF_LOCX)) {
985 cob->matrix[3][0] = orig_cob_matrix[3][0];
986 }
987 if (!(data->flag & CHILDOF_LOCY)) {
988 cob->matrix[3][1] = orig_cob_matrix[3][1];
989 }
990 if (!(data->flag & CHILDOF_LOCZ)) {
991 cob->matrix[3][2] = orig_cob_matrix[3][2];
992 }
993 }
994
995 /* XXX note, con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in readfile.c */
996 static bConstraintTypeInfo CTI_CHILDOF = {
997 CONSTRAINT_TYPE_CHILDOF, /* type */
998 sizeof(bChildOfConstraint), /* size */
999 "Child Of", /* name */
1000 "bChildOfConstraint", /* struct name */
1001 NULL, /* free data */
1002 childof_id_looper, /* id looper */
1003 NULL, /* copy data */
1004 childof_new_data, /* new data */
1005 childof_get_tars, /* get constraint targets */
1006 childof_flush_tars, /* flush constraint targets */
1007 default_get_tarmat, /* get a target matrix */
1008 childof_evaluate, /* evaluate */
1009 };
1010
1011 /* -------- TrackTo Constraint ------- */
1012
trackto_new_data(void * cdata)1013 static void trackto_new_data(void *cdata)
1014 {
1015 bTrackToConstraint *data = (bTrackToConstraint *)cdata;
1016
1017 data->reserved1 = TRACK_nZ;
1018 data->reserved2 = UP_Y;
1019 }
1020
trackto_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1021 static void trackto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1022 {
1023 bTrackToConstraint *data = con->data;
1024
1025 /* target only */
1026 func(con, (ID **)&data->tar, false, userdata);
1027 }
1028
trackto_get_tars(bConstraint * con,ListBase * list)1029 static int trackto_get_tars(bConstraint *con, ListBase *list)
1030 {
1031 if (con && list) {
1032 bTrackToConstraint *data = con->data;
1033 bConstraintTarget *ct;
1034
1035 /* standard target-getting macro for single-target constraints */
1036 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
1037
1038 return 1;
1039 }
1040
1041 return 0;
1042 }
1043
trackto_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1044 static void trackto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1045 {
1046 if (con && list) {
1047 bTrackToConstraint *data = con->data;
1048 bConstraintTarget *ct = list->first;
1049
1050 /* the following macro is used for all standard single-target constraints */
1051 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
1052 }
1053 }
1054
basis_cross(int n,int m)1055 static int basis_cross(int n, int m)
1056 {
1057 switch (n - m) {
1058 case 1:
1059 case -2:
1060 return 1;
1061
1062 case -1:
1063 case 2:
1064 return -1;
1065
1066 default:
1067 return 0;
1068 }
1069 }
1070
vectomat(const float vec[3],const float target_up[3],short axis,short upflag,short flags,float m[3][3])1071 static void vectomat(const float vec[3],
1072 const float target_up[3],
1073 short axis,
1074 short upflag,
1075 short flags,
1076 float m[3][3])
1077 {
1078 float n[3];
1079 float u[3]; /* vector specifying the up axis */
1080 float proj[3];
1081 float right[3];
1082 float neg = -1;
1083 int right_index;
1084
1085 if (normalize_v3_v3(n, vec) == 0.0f) {
1086 n[0] = 0.0f;
1087 n[1] = 0.0f;
1088 n[2] = 1.0f;
1089 }
1090 if (axis > 2) {
1091 axis -= 3;
1092 }
1093 else {
1094 negate_v3(n);
1095 }
1096
1097 /* n specifies the transformation of the track axis */
1098 if (flags & TARGET_Z_UP) {
1099 /* target Z axis is the global up axis */
1100 copy_v3_v3(u, target_up);
1101 }
1102 else {
1103 /* world Z axis is the global up axis */
1104 u[0] = 0;
1105 u[1] = 0;
1106 u[2] = 1;
1107 }
1108
1109 /* note: even though 'n' is normalized, don't use 'project_v3_v3v3_normalized' below
1110 * because precision issues cause a problem in near degenerate states, see: T53455. */
1111
1112 /* project the up vector onto the plane specified by n */
1113 project_v3_v3v3(proj, u, n); /* first u onto n... */
1114 sub_v3_v3v3(proj, u, proj); /* then onto the plane */
1115 /* proj specifies the transformation of the up axis */
1116
1117 if (normalize_v3(proj) == 0.0f) { /* degenerate projection */
1118 proj[0] = 0.0f;
1119 proj[1] = 1.0f;
1120 proj[2] = 0.0f;
1121 }
1122
1123 /* Normalized cross product of n and proj specifies transformation of the right axis */
1124 cross_v3_v3v3(right, proj, n);
1125 normalize_v3(right);
1126
1127 if (axis != upflag) {
1128 right_index = 3 - axis - upflag;
1129 neg = (float)basis_cross(axis, upflag);
1130
1131 /* account for up direction, track direction */
1132 m[right_index][0] = neg * right[0];
1133 m[right_index][1] = neg * right[1];
1134 m[right_index][2] = neg * right[2];
1135
1136 copy_v3_v3(m[upflag], proj);
1137
1138 copy_v3_v3(m[axis], n);
1139 }
1140 /* identity matrix - don't do anything if the two axes are the same */
1141 else {
1142 unit_m3(m);
1143 }
1144 }
1145
trackto_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)1146 static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
1147 {
1148 bTrackToConstraint *data = con->data;
1149 bConstraintTarget *ct = targets->first;
1150
1151 if (VALID_CONS_TARGET(ct)) {
1152 float size[3], vec[3];
1153 float totmat[3][3];
1154
1155 /* Get size property, since ob->scale is only the object's own relative size,
1156 * not its global one. */
1157 mat4_to_size(size, cob->matrix);
1158
1159 /* Clear the object's rotation */
1160 cob->matrix[0][0] = size[0];
1161 cob->matrix[0][1] = 0;
1162 cob->matrix[0][2] = 0;
1163 cob->matrix[1][0] = 0;
1164 cob->matrix[1][1] = size[1];
1165 cob->matrix[1][2] = 0;
1166 cob->matrix[2][0] = 0;
1167 cob->matrix[2][1] = 0;
1168 cob->matrix[2][2] = size[2];
1169
1170 /* targetmat[2] instead of ownermat[2] is passed to vectomat
1171 * for backwards compatibility it seems... (Aligorith)
1172 */
1173 sub_v3_v3v3(vec, cob->matrix[3], ct->matrix[3]);
1174 vectomat(
1175 vec, ct->matrix[2], (short)data->reserved1, (short)data->reserved2, data->flags, totmat);
1176
1177 mul_m4_m3m4(cob->matrix, totmat, cob->matrix);
1178 }
1179 }
1180
1181 static bConstraintTypeInfo CTI_TRACKTO = {
1182 CONSTRAINT_TYPE_TRACKTO, /* type */
1183 sizeof(bTrackToConstraint), /* size */
1184 "Track To", /* name */
1185 "bTrackToConstraint", /* struct name */
1186 NULL, /* free data */
1187 trackto_id_looper, /* id looper */
1188 NULL, /* copy data */
1189 trackto_new_data, /* new data */
1190 trackto_get_tars, /* get constraint targets */
1191 trackto_flush_tars, /* flush constraint targets */
1192 default_get_tarmat, /* get target matrix */
1193 trackto_evaluate, /* evaluate */
1194 };
1195
1196 /* --------- Inverse-Kinematics --------- */
1197
kinematic_new_data(void * cdata)1198 static void kinematic_new_data(void *cdata)
1199 {
1200 bKinematicConstraint *data = (bKinematicConstraint *)cdata;
1201
1202 data->weight = 1.0f;
1203 data->orientweight = 1.0f;
1204 data->iterations = 500;
1205 data->dist = 1.0f;
1206 data->flag = CONSTRAINT_IK_TIP | CONSTRAINT_IK_STRETCH | CONSTRAINT_IK_POS;
1207 }
1208
kinematic_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1209 static void kinematic_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1210 {
1211 bKinematicConstraint *data = con->data;
1212
1213 /* chain target */
1214 func(con, (ID **)&data->tar, false, userdata);
1215
1216 /* poletarget */
1217 func(con, (ID **)&data->poletar, false, userdata);
1218 }
1219
kinematic_get_tars(bConstraint * con,ListBase * list)1220 static int kinematic_get_tars(bConstraint *con, ListBase *list)
1221 {
1222 if (con && list) {
1223 bKinematicConstraint *data = con->data;
1224 bConstraintTarget *ct;
1225
1226 /* standard target-getting macro for single-target constraints is used twice here */
1227 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
1228 SINGLETARGET_GET_TARS(con, data->poletar, data->polesubtarget, ct, list);
1229
1230 return 2;
1231 }
1232
1233 return 0;
1234 }
1235
kinematic_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1236 static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1237 {
1238 if (con && list) {
1239 bKinematicConstraint *data = con->data;
1240 bConstraintTarget *ct = list->first;
1241
1242 /* the following macro is used for all standard single-target constraints */
1243 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
1244 SINGLETARGET_FLUSH_TARS(con, data->poletar, data->polesubtarget, ct, list, no_copy);
1245 }
1246 }
1247
kinematic_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * cob,bConstraintTarget * ct,float UNUSED (ctime))1248 static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
1249 bConstraint *con,
1250 bConstraintOb *cob,
1251 bConstraintTarget *ct,
1252 float UNUSED(ctime))
1253 {
1254 bKinematicConstraint *data = con->data;
1255
1256 if (VALID_CONS_TARGET(ct)) {
1257 constraint_target_to_mat4(ct->tar,
1258 ct->subtarget,
1259 ct->matrix,
1260 CONSTRAINT_SPACE_WORLD,
1261 ct->space,
1262 con->flag,
1263 con->headtail);
1264 }
1265 else if (ct) {
1266 if (data->flag & CONSTRAINT_IK_AUTO) {
1267 Object *ob = cob->ob;
1268
1269 if (ob == NULL) {
1270 unit_m4(ct->matrix);
1271 }
1272 else {
1273 float vec[3];
1274 /* move grabtarget into world space */
1275 mul_v3_m4v3(vec, ob->obmat, data->grabtarget);
1276 copy_m4_m4(ct->matrix, ob->obmat);
1277 copy_v3_v3(ct->matrix[3], vec);
1278 }
1279 }
1280 else {
1281 unit_m4(ct->matrix);
1282 }
1283 }
1284 }
1285
1286 static bConstraintTypeInfo CTI_KINEMATIC = {
1287 CONSTRAINT_TYPE_KINEMATIC, /* type */
1288 sizeof(bKinematicConstraint), /* size */
1289 "IK", /* name */
1290 "bKinematicConstraint", /* struct name */
1291 NULL, /* free data */
1292 kinematic_id_looper, /* id looper */
1293 NULL, /* copy data */
1294 kinematic_new_data, /* new data */
1295 kinematic_get_tars, /* get constraint targets */
1296 kinematic_flush_tars, /* flush constraint targets */
1297 kinematic_get_tarmat, /* get target matrix */
1298 NULL, /* evaluate - solved as separate loop */
1299 };
1300
1301 /* -------- Follow-Path Constraint ---------- */
1302
followpath_new_data(void * cdata)1303 static void followpath_new_data(void *cdata)
1304 {
1305 bFollowPathConstraint *data = (bFollowPathConstraint *)cdata;
1306
1307 data->trackflag = TRACK_Y;
1308 data->upflag = UP_Z;
1309 data->offset = 0;
1310 data->followflag = 0;
1311 }
1312
followpath_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1313 static void followpath_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1314 {
1315 bFollowPathConstraint *data = con->data;
1316
1317 /* target only */
1318 func(con, (ID **)&data->tar, false, userdata);
1319 }
1320
followpath_get_tars(bConstraint * con,ListBase * list)1321 static int followpath_get_tars(bConstraint *con, ListBase *list)
1322 {
1323 if (con && list) {
1324 bFollowPathConstraint *data = con->data;
1325 bConstraintTarget *ct;
1326
1327 /* standard target-getting macro for single-target constraints without subtargets */
1328 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list);
1329
1330 return 1;
1331 }
1332
1333 return 0;
1334 }
1335
followpath_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1336 static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1337 {
1338 if (con && list) {
1339 bFollowPathConstraint *data = con->data;
1340 bConstraintTarget *ct = list->first;
1341
1342 /* the following macro is used for all standard single-target constraints */
1343 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
1344 }
1345 }
1346
followpath_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))1347 static void followpath_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
1348 bConstraint *con,
1349 bConstraintOb *UNUSED(cob),
1350 bConstraintTarget *ct,
1351 float UNUSED(ctime))
1352 {
1353 bFollowPathConstraint *data = con->data;
1354
1355 if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
1356 Curve *cu = ct->tar->data;
1357 float vec[4], dir[3], radius;
1358 float curvetime;
1359
1360 unit_m4(ct->matrix);
1361
1362 /* note: when creating constraints that follow path, the curve gets the CU_PATH set now,
1363 * currently for paths to work it needs to go through the bevlist/displist system (ton)
1364 */
1365
1366 if (ct->tar->runtime.curve_cache && ct->tar->runtime.curve_cache->path &&
1367 ct->tar->runtime.curve_cache->path->data) {
1368 float quat[4];
1369 if ((data->followflag & FOLLOWPATH_STATIC) == 0) {
1370 /* animated position along curve depending on time */
1371 Nurb *nu = cu->nurb.first;
1372 curvetime = cu->ctime - data->offset;
1373
1374 /* ctime is now a proper var setting of Curve which gets set by Animato like any other var
1375 * that's animated, but this will only work if it actually is animated...
1376 *
1377 * we divide the curvetime calculated in the previous step by the length of the path,
1378 * to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range. */
1379 curvetime /= cu->pathlen;
1380
1381 if (nu && nu->flagu & CU_NURB_CYCLIC) {
1382 /* If the curve is cyclic, enable looping around if the time is
1383 * outside the bounds 0..1 */
1384 if ((curvetime < 0.0f) || (curvetime > 1.0f)) {
1385 curvetime -= floorf(curvetime);
1386 }
1387 }
1388 else {
1389 /* The curve is not cyclic, so clamp to the begin/end points. */
1390 CLAMP(curvetime, 0.0f, 1.0f);
1391 }
1392 }
1393 else {
1394 /* fixed position along curve */
1395 curvetime = data->offset_fac;
1396 }
1397
1398 if (where_on_path(ct->tar,
1399 curvetime,
1400 vec,
1401 dir,
1402 (data->followflag & FOLLOWPATH_FOLLOW) ? quat : NULL,
1403 &radius,
1404 NULL)) { /* quat_pt is quat or NULL*/
1405 float totmat[4][4];
1406 unit_m4(totmat);
1407
1408 if (data->followflag & FOLLOWPATH_FOLLOW) {
1409 quat_apply_track(quat, data->trackflag, data->upflag);
1410 quat_to_mat4(totmat, quat);
1411 }
1412
1413 if (data->followflag & FOLLOWPATH_RADIUS) {
1414 float tmat[4][4], rmat[4][4];
1415 scale_m4_fl(tmat, radius);
1416 mul_m4_m4m4(rmat, tmat, totmat);
1417 copy_m4_m4(totmat, rmat);
1418 }
1419
1420 copy_v3_v3(totmat[3], vec);
1421
1422 mul_m4_m4m4(ct->matrix, ct->tar->obmat, totmat);
1423 }
1424 }
1425 }
1426 else if (ct) {
1427 unit_m4(ct->matrix);
1428 }
1429 }
1430
followpath_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)1431 static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
1432 {
1433 bConstraintTarget *ct = targets->first;
1434
1435 /* only evaluate if there is a target */
1436 if (VALID_CONS_TARGET(ct)) {
1437 float obmat[4][4];
1438 float size[3];
1439 bFollowPathConstraint *data = con->data;
1440
1441 /* get Object transform (loc/rot/size) to determine transformation from path */
1442 /* TODO: this used to be local at one point, but is probably more useful as-is */
1443 copy_m4_m4(obmat, cob->matrix);
1444
1445 /* get scaling of object before applying constraint */
1446 mat4_to_size(size, cob->matrix);
1447
1448 /* apply targetmat - containing location on path, and rotation */
1449 mul_m4_m4m4(cob->matrix, ct->matrix, obmat);
1450
1451 /* un-apply scaling caused by path */
1452 if ((data->followflag & FOLLOWPATH_RADIUS) == 0) {
1453 /* XXX: Assume that scale correction means that radius
1454 * will have some scale error in it - Campbell. */
1455 float obsize[3];
1456
1457 mat4_to_size(obsize, cob->matrix);
1458 if (obsize[0]) {
1459 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
1460 }
1461 if (obsize[1]) {
1462 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
1463 }
1464 if (obsize[2]) {
1465 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
1466 }
1467 }
1468 }
1469 }
1470
1471 static bConstraintTypeInfo CTI_FOLLOWPATH = {
1472 CONSTRAINT_TYPE_FOLLOWPATH, /* type */
1473 sizeof(bFollowPathConstraint), /* size */
1474 "Follow Path", /* name */
1475 "bFollowPathConstraint", /* struct name */
1476 NULL, /* free data */
1477 followpath_id_looper, /* id looper */
1478 NULL, /* copy data */
1479 followpath_new_data, /* new data */
1480 followpath_get_tars, /* get constraint targets */
1481 followpath_flush_tars, /* flush constraint targets */
1482 followpath_get_tarmat, /* get target matrix */
1483 followpath_evaluate, /* evaluate */
1484 };
1485
1486 /* --------- Limit Location --------- */
1487
loclimit_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))1488 static void loclimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1489 {
1490 bLocLimitConstraint *data = con->data;
1491
1492 if (data->flag & LIMIT_XMIN) {
1493 if (cob->matrix[3][0] < data->xmin) {
1494 cob->matrix[3][0] = data->xmin;
1495 }
1496 }
1497 if (data->flag & LIMIT_XMAX) {
1498 if (cob->matrix[3][0] > data->xmax) {
1499 cob->matrix[3][0] = data->xmax;
1500 }
1501 }
1502 if (data->flag & LIMIT_YMIN) {
1503 if (cob->matrix[3][1] < data->ymin) {
1504 cob->matrix[3][1] = data->ymin;
1505 }
1506 }
1507 if (data->flag & LIMIT_YMAX) {
1508 if (cob->matrix[3][1] > data->ymax) {
1509 cob->matrix[3][1] = data->ymax;
1510 }
1511 }
1512 if (data->flag & LIMIT_ZMIN) {
1513 if (cob->matrix[3][2] < data->zmin) {
1514 cob->matrix[3][2] = data->zmin;
1515 }
1516 }
1517 if (data->flag & LIMIT_ZMAX) {
1518 if (cob->matrix[3][2] > data->zmax) {
1519 cob->matrix[3][2] = data->zmax;
1520 }
1521 }
1522 }
1523
1524 static bConstraintTypeInfo CTI_LOCLIMIT = {
1525 CONSTRAINT_TYPE_LOCLIMIT, /* type */
1526 sizeof(bLocLimitConstraint), /* size */
1527 "Limit Location", /* name */
1528 "bLocLimitConstraint", /* struct name */
1529 NULL, /* free data */
1530 NULL, /* id looper */
1531 NULL, /* copy data */
1532 NULL, /* new data */
1533 NULL, /* get constraint targets */
1534 NULL, /* flush constraint targets */
1535 NULL, /* get target matrix */
1536 loclimit_evaluate, /* evaluate */
1537 };
1538
1539 /* -------- Limit Rotation --------- */
1540
rotlimit_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))1541 static void rotlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1542 {
1543 bRotLimitConstraint *data = con->data;
1544 float loc[3];
1545 float eul[3];
1546 float size[3];
1547
1548 copy_v3_v3(loc, cob->matrix[3]);
1549 mat4_to_size(size, cob->matrix);
1550
1551 mat4_to_eulO(eul, cob->rotOrder, cob->matrix);
1552
1553 /* constraint data uses radians internally */
1554
1555 /* limiting of euler values... */
1556 if (data->flag & LIMIT_XROT) {
1557 if (eul[0] < data->xmin) {
1558 eul[0] = data->xmin;
1559 }
1560
1561 if (eul[0] > data->xmax) {
1562 eul[0] = data->xmax;
1563 }
1564 }
1565 if (data->flag & LIMIT_YROT) {
1566 if (eul[1] < data->ymin) {
1567 eul[1] = data->ymin;
1568 }
1569
1570 if (eul[1] > data->ymax) {
1571 eul[1] = data->ymax;
1572 }
1573 }
1574 if (data->flag & LIMIT_ZROT) {
1575 if (eul[2] < data->zmin) {
1576 eul[2] = data->zmin;
1577 }
1578
1579 if (eul[2] > data->zmax) {
1580 eul[2] = data->zmax;
1581 }
1582 }
1583
1584 loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
1585 }
1586
1587 static bConstraintTypeInfo CTI_ROTLIMIT = {
1588 CONSTRAINT_TYPE_ROTLIMIT, /* type */
1589 sizeof(bRotLimitConstraint), /* size */
1590 "Limit Rotation", /* name */
1591 "bRotLimitConstraint", /* struct name */
1592 NULL, /* free data */
1593 NULL, /* id looper */
1594 NULL, /* copy data */
1595 NULL, /* new data */
1596 NULL, /* get constraint targets */
1597 NULL, /* flush constraint targets */
1598 NULL, /* get target matrix */
1599 rotlimit_evaluate, /* evaluate */
1600 };
1601
1602 /* --------- Limit Scale --------- */
1603
sizelimit_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))1604 static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
1605 {
1606 bSizeLimitConstraint *data = con->data;
1607 float obsize[3], size[3];
1608
1609 mat4_to_size(size, cob->matrix);
1610 mat4_to_size(obsize, cob->matrix);
1611
1612 if (data->flag & LIMIT_XMIN) {
1613 if (size[0] < data->xmin) {
1614 size[0] = data->xmin;
1615 }
1616 }
1617 if (data->flag & LIMIT_XMAX) {
1618 if (size[0] > data->xmax) {
1619 size[0] = data->xmax;
1620 }
1621 }
1622 if (data->flag & LIMIT_YMIN) {
1623 if (size[1] < data->ymin) {
1624 size[1] = data->ymin;
1625 }
1626 }
1627 if (data->flag & LIMIT_YMAX) {
1628 if (size[1] > data->ymax) {
1629 size[1] = data->ymax;
1630 }
1631 }
1632 if (data->flag & LIMIT_ZMIN) {
1633 if (size[2] < data->zmin) {
1634 size[2] = data->zmin;
1635 }
1636 }
1637 if (data->flag & LIMIT_ZMAX) {
1638 if (size[2] > data->zmax) {
1639 size[2] = data->zmax;
1640 }
1641 }
1642
1643 if (obsize[0]) {
1644 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
1645 }
1646 if (obsize[1]) {
1647 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
1648 }
1649 if (obsize[2]) {
1650 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
1651 }
1652 }
1653
1654 static bConstraintTypeInfo CTI_SIZELIMIT = {
1655 CONSTRAINT_TYPE_SIZELIMIT, /* type */
1656 sizeof(bSizeLimitConstraint), /* size */
1657 "Limit Scale", /* name */
1658 "bSizeLimitConstraint", /* struct name */
1659 NULL, /* free data */
1660 NULL, /* id looper */
1661 NULL, /* copy data */
1662 NULL, /* new data */
1663 NULL, /* get constraint targets */
1664 NULL, /* flush constraint targets */
1665 NULL, /* get target matrix */
1666 sizelimit_evaluate, /* evaluate */
1667 };
1668
1669 /* ----------- Copy Location ------------- */
1670
loclike_new_data(void * cdata)1671 static void loclike_new_data(void *cdata)
1672 {
1673 bLocateLikeConstraint *data = (bLocateLikeConstraint *)cdata;
1674
1675 data->flag = LOCLIKE_X | LOCLIKE_Y | LOCLIKE_Z;
1676 }
1677
loclike_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1678 static void loclike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1679 {
1680 bLocateLikeConstraint *data = con->data;
1681
1682 /* target only */
1683 func(con, (ID **)&data->tar, false, userdata);
1684 }
1685
loclike_get_tars(bConstraint * con,ListBase * list)1686 static int loclike_get_tars(bConstraint *con, ListBase *list)
1687 {
1688 if (con && list) {
1689 bLocateLikeConstraint *data = con->data;
1690 bConstraintTarget *ct;
1691
1692 /* standard target-getting macro for single-target constraints */
1693 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
1694
1695 return 1;
1696 }
1697
1698 return 0;
1699 }
1700
loclike_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1701 static void loclike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1702 {
1703 if (con && list) {
1704 bLocateLikeConstraint *data = con->data;
1705 bConstraintTarget *ct = list->first;
1706
1707 /* the following macro is used for all standard single-target constraints */
1708 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
1709 }
1710 }
1711
loclike_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)1712 static void loclike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
1713 {
1714 bLocateLikeConstraint *data = con->data;
1715 bConstraintTarget *ct = targets->first;
1716
1717 if (VALID_CONS_TARGET(ct)) {
1718 float offset[3] = {0.0f, 0.0f, 0.0f};
1719
1720 if (data->flag & LOCLIKE_OFFSET) {
1721 copy_v3_v3(offset, cob->matrix[3]);
1722 }
1723
1724 if (data->flag & LOCLIKE_X) {
1725 cob->matrix[3][0] = ct->matrix[3][0];
1726
1727 if (data->flag & LOCLIKE_X_INVERT) {
1728 cob->matrix[3][0] *= -1;
1729 }
1730 cob->matrix[3][0] += offset[0];
1731 }
1732 if (data->flag & LOCLIKE_Y) {
1733 cob->matrix[3][1] = ct->matrix[3][1];
1734
1735 if (data->flag & LOCLIKE_Y_INVERT) {
1736 cob->matrix[3][1] *= -1;
1737 }
1738 cob->matrix[3][1] += offset[1];
1739 }
1740 if (data->flag & LOCLIKE_Z) {
1741 cob->matrix[3][2] = ct->matrix[3][2];
1742
1743 if (data->flag & LOCLIKE_Z_INVERT) {
1744 cob->matrix[3][2] *= -1;
1745 }
1746 cob->matrix[3][2] += offset[2];
1747 }
1748 }
1749 }
1750
1751 static bConstraintTypeInfo CTI_LOCLIKE = {
1752 CONSTRAINT_TYPE_LOCLIKE, /* type */
1753 sizeof(bLocateLikeConstraint), /* size */
1754 "Copy Location", /* name */
1755 "bLocateLikeConstraint", /* struct name */
1756 NULL, /* free data */
1757 loclike_id_looper, /* id looper */
1758 NULL, /* copy data */
1759 loclike_new_data, /* new data */
1760 loclike_get_tars, /* get constraint targets */
1761 loclike_flush_tars, /* flush constraint targets */
1762 default_get_tarmat, /* get target matrix */
1763 loclike_evaluate, /* evaluate */
1764 };
1765
1766 /* ----------- Copy Rotation ------------- */
1767
rotlike_new_data(void * cdata)1768 static void rotlike_new_data(void *cdata)
1769 {
1770 bRotateLikeConstraint *data = (bRotateLikeConstraint *)cdata;
1771
1772 data->flag = ROTLIKE_X | ROTLIKE_Y | ROTLIKE_Z;
1773 }
1774
rotlike_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1775 static void rotlike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1776 {
1777 bRotateLikeConstraint *data = con->data;
1778
1779 /* target only */
1780 func(con, (ID **)&data->tar, false, userdata);
1781 }
1782
rotlike_get_tars(bConstraint * con,ListBase * list)1783 static int rotlike_get_tars(bConstraint *con, ListBase *list)
1784 {
1785 if (con && list) {
1786 bRotateLikeConstraint *data = con->data;
1787 bConstraintTarget *ct;
1788
1789 /* standard target-getting macro for single-target constraints */
1790 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
1791
1792 return 1;
1793 }
1794
1795 return 0;
1796 }
1797
rotlike_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1798 static void rotlike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1799 {
1800 if (con && list) {
1801 bRotateLikeConstraint *data = con->data;
1802 bConstraintTarget *ct = list->first;
1803
1804 /* the following macro is used for all standard single-target constraints */
1805 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
1806 }
1807 }
1808
rotlike_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)1809 static void rotlike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
1810 {
1811 bRotateLikeConstraint *data = con->data;
1812 bConstraintTarget *ct = targets->first;
1813
1814 if (VALID_CONS_TARGET(ct)) {
1815 float loc[3], size[3], oldrot[3][3], newrot[3][3];
1816 float eul[3], obeul[3], defeul[3];
1817
1818 mat4_to_loc_rot_size(loc, oldrot, size, cob->matrix);
1819
1820 /* Select the Euler rotation order, defaulting to the owner. */
1821 short rot_order = cob->rotOrder;
1822
1823 if (data->euler_order != CONSTRAINT_EULER_AUTO) {
1824 rot_order = data->euler_order;
1825 }
1826
1827 /* To allow compatible rotations, must get both rotations in the order of the owner... */
1828 mat4_to_eulO(obeul, rot_order, cob->matrix);
1829 /* We must get compatible eulers from the beginning because
1830 * some of them can be modified below (see bug T21875). */
1831 mat4_to_compatible_eulO(eul, obeul, rot_order, ct->matrix);
1832
1833 /* Prepare the copied euler rotation. */
1834 bool legacy_offset = false;
1835
1836 switch (data->mix_mode) {
1837 case ROTLIKE_MIX_OFFSET:
1838 legacy_offset = true;
1839 copy_v3_v3(defeul, obeul);
1840 break;
1841
1842 case ROTLIKE_MIX_REPLACE:
1843 copy_v3_v3(defeul, obeul);
1844 break;
1845
1846 default:
1847 zero_v3(defeul);
1848 }
1849
1850 if ((data->flag & ROTLIKE_X) == 0) {
1851 eul[0] = defeul[0];
1852 }
1853 else {
1854 if (legacy_offset) {
1855 rotate_eulO(eul, rot_order, 'X', obeul[0]);
1856 }
1857
1858 if (data->flag & ROTLIKE_X_INVERT) {
1859 eul[0] *= -1;
1860 }
1861 }
1862
1863 if ((data->flag & ROTLIKE_Y) == 0) {
1864 eul[1] = defeul[1];
1865 }
1866 else {
1867 if (legacy_offset) {
1868 rotate_eulO(eul, rot_order, 'Y', obeul[1]);
1869 }
1870
1871 if (data->flag & ROTLIKE_Y_INVERT) {
1872 eul[1] *= -1;
1873 }
1874 }
1875
1876 if ((data->flag & ROTLIKE_Z) == 0) {
1877 eul[2] = defeul[2];
1878 }
1879 else {
1880 if (legacy_offset) {
1881 rotate_eulO(eul, rot_order, 'Z', obeul[2]);
1882 }
1883
1884 if (data->flag & ROTLIKE_Z_INVERT) {
1885 eul[2] *= -1;
1886 }
1887 }
1888
1889 /* Add the euler components together if needed. */
1890 if (data->mix_mode == ROTLIKE_MIX_ADD) {
1891 add_v3_v3(eul, obeul);
1892 }
1893
1894 /* Good to make eulers compatible again,
1895 * since we don't know how much they were changed above. */
1896 compatible_eul(eul, obeul);
1897 eulO_to_mat3(newrot, eul, rot_order);
1898
1899 /* Mix the rotation matrices: */
1900 switch (data->mix_mode) {
1901 case ROTLIKE_MIX_REPLACE:
1902 case ROTLIKE_MIX_OFFSET:
1903 case ROTLIKE_MIX_ADD:
1904 break;
1905
1906 case ROTLIKE_MIX_BEFORE:
1907 mul_m3_m3m3(newrot, newrot, oldrot);
1908 break;
1909
1910 case ROTLIKE_MIX_AFTER:
1911 mul_m3_m3m3(newrot, oldrot, newrot);
1912 break;
1913
1914 default:
1915 BLI_assert(false);
1916 }
1917
1918 loc_rot_size_to_mat4(cob->matrix, loc, newrot, size);
1919 }
1920 }
1921
1922 static bConstraintTypeInfo CTI_ROTLIKE = {
1923 CONSTRAINT_TYPE_ROTLIKE, /* type */
1924 sizeof(bRotateLikeConstraint), /* size */
1925 "Copy Rotation", /* name */
1926 "bRotateLikeConstraint", /* struct name */
1927 NULL, /* free data */
1928 rotlike_id_looper, /* id looper */
1929 NULL, /* copy data */
1930 rotlike_new_data, /* new data */
1931 rotlike_get_tars, /* get constraint targets */
1932 rotlike_flush_tars, /* flush constraint targets */
1933 default_get_tarmat, /* get target matrix */
1934 rotlike_evaluate, /* evaluate */
1935 };
1936
1937 /* ---------- Copy Scale ---------- */
1938
sizelike_new_data(void * cdata)1939 static void sizelike_new_data(void *cdata)
1940 {
1941 bSizeLikeConstraint *data = (bSizeLikeConstraint *)cdata;
1942
1943 data->flag = SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z | SIZELIKE_MULTIPLY;
1944 data->power = 1.0f;
1945 }
1946
sizelike_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)1947 static void sizelike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
1948 {
1949 bSizeLikeConstraint *data = con->data;
1950
1951 /* target only */
1952 func(con, (ID **)&data->tar, false, userdata);
1953 }
1954
sizelike_get_tars(bConstraint * con,ListBase * list)1955 static int sizelike_get_tars(bConstraint *con, ListBase *list)
1956 {
1957 if (con && list) {
1958 bSizeLikeConstraint *data = con->data;
1959 bConstraintTarget *ct;
1960
1961 /* standard target-getting macro for single-target constraints */
1962 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
1963
1964 return 1;
1965 }
1966
1967 return 0;
1968 }
1969
sizelike_flush_tars(bConstraint * con,ListBase * list,bool no_copy)1970 static void sizelike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
1971 {
1972 if (con && list) {
1973 bSizeLikeConstraint *data = con->data;
1974 bConstraintTarget *ct = list->first;
1975
1976 /* the following macro is used for all standard single-target constraints */
1977 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
1978 }
1979 }
1980
sizelike_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)1981 static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
1982 {
1983 bSizeLikeConstraint *data = con->data;
1984 bConstraintTarget *ct = targets->first;
1985
1986 if (VALID_CONS_TARGET(ct)) {
1987 float obsize[3], size[3];
1988
1989 mat4_to_size(obsize, cob->matrix);
1990
1991 /* Compute one uniform scale factor to apply to all three axes. */
1992 if (data->flag & SIZELIKE_UNIFORM) {
1993 const int all_axes = SIZELIKE_X | SIZELIKE_Y | SIZELIKE_Z;
1994 float total = 1.0f;
1995
1996 /* If all axes are selected, use the determinant. */
1997 if ((data->flag & all_axes) == all_axes) {
1998 total = fabsf(mat4_to_volume_scale(ct->matrix));
1999 }
2000 /* Otherwise multiply individual values. */
2001 else {
2002 mat4_to_size(size, ct->matrix);
2003
2004 if (data->flag & SIZELIKE_X) {
2005 total *= size[0];
2006 }
2007 if (data->flag & SIZELIKE_Y) {
2008 total *= size[1];
2009 }
2010 if (data->flag & SIZELIKE_Z) {
2011 total *= size[2];
2012 }
2013 }
2014
2015 copy_v3_fl(size, cbrt(total));
2016 }
2017 /* Regular per-axis scaling. */
2018 else {
2019 mat4_to_size(size, ct->matrix);
2020 }
2021
2022 for (int i = 0; i < 3; i++) {
2023 size[i] = powf(size[i], data->power);
2024 }
2025
2026 if (data->flag & SIZELIKE_OFFSET) {
2027 /* Scale is a multiplicative quantity, so adding it makes no sense.
2028 * However, the additive mode has to stay for backward compatibility. */
2029 if (data->flag & SIZELIKE_MULTIPLY) {
2030 /* size[i] *= obsize[i] */
2031 mul_v3_v3(size, obsize);
2032 }
2033 else {
2034 /* 2.7 compatibility mode: size[i] += (obsize[i] - 1.0f) */
2035 add_v3_v3(size, obsize);
2036 add_v3_fl(size, -1.0f);
2037 }
2038 }
2039
2040 if ((data->flag & (SIZELIKE_X | SIZELIKE_UNIFORM)) && (obsize[0] != 0)) {
2041 mul_v3_fl(cob->matrix[0], size[0] / obsize[0]);
2042 }
2043 if ((data->flag & (SIZELIKE_Y | SIZELIKE_UNIFORM)) && (obsize[1] != 0)) {
2044 mul_v3_fl(cob->matrix[1], size[1] / obsize[1]);
2045 }
2046 if ((data->flag & (SIZELIKE_Z | SIZELIKE_UNIFORM)) && (obsize[2] != 0)) {
2047 mul_v3_fl(cob->matrix[2], size[2] / obsize[2]);
2048 }
2049 }
2050 }
2051
2052 static bConstraintTypeInfo CTI_SIZELIKE = {
2053 CONSTRAINT_TYPE_SIZELIKE, /* type */
2054 sizeof(bSizeLikeConstraint), /* size */
2055 "Copy Scale", /* name */
2056 "bSizeLikeConstraint", /* struct name */
2057 NULL, /* free data */
2058 sizelike_id_looper, /* id looper */
2059 NULL, /* copy data */
2060 sizelike_new_data, /* new data */
2061 sizelike_get_tars, /* get constraint targets */
2062 sizelike_flush_tars, /* flush constraint targets */
2063 default_get_tarmat, /* get target matrix */
2064 sizelike_evaluate, /* evaluate */
2065 };
2066
2067 /* ----------- Copy Transforms ------------- */
2068
translike_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)2069 static void translike_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
2070 {
2071 bTransLikeConstraint *data = con->data;
2072
2073 /* target only */
2074 func(con, (ID **)&data->tar, false, userdata);
2075 }
2076
translike_get_tars(bConstraint * con,ListBase * list)2077 static int translike_get_tars(bConstraint *con, ListBase *list)
2078 {
2079 if (con && list) {
2080 bTransLikeConstraint *data = con->data;
2081 bConstraintTarget *ct;
2082
2083 /* standard target-getting macro for single-target constraints */
2084 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
2085
2086 return 1;
2087 }
2088
2089 return 0;
2090 }
2091
translike_flush_tars(bConstraint * con,ListBase * list,bool no_copy)2092 static void translike_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
2093 {
2094 if (con && list) {
2095 bTransLikeConstraint *data = con->data;
2096 bConstraintTarget *ct = list->first;
2097
2098 /* the following macro is used for all standard single-target constraints */
2099 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
2100 }
2101 }
2102
translike_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)2103 static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
2104 {
2105 bTransLikeConstraint *data = con->data;
2106 bConstraintTarget *ct = targets->first;
2107
2108 if (VALID_CONS_TARGET(ct)) {
2109 switch (data->mix_mode) {
2110 case TRANSLIKE_MIX_REPLACE:
2111 copy_m4_m4(cob->matrix, ct->matrix);
2112 break;
2113
2114 case TRANSLIKE_MIX_BEFORE:
2115 mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix);
2116 break;
2117
2118 case TRANSLIKE_MIX_AFTER:
2119 mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, ct->matrix);
2120 break;
2121
2122 default:
2123 BLI_assert(!"Unknown Copy Transforms mix mode");
2124 }
2125 }
2126 }
2127
2128 static bConstraintTypeInfo CTI_TRANSLIKE = {
2129 CONSTRAINT_TYPE_TRANSLIKE, /* type */
2130 sizeof(bTransLikeConstraint), /* size */
2131 "Copy Transforms", /* name */
2132 "bTransLikeConstraint", /* struct name */
2133 NULL, /* free data */
2134 translike_id_looper, /* id looper */
2135 NULL, /* copy data */
2136 NULL, /* new data */
2137 translike_get_tars, /* get constraint targets */
2138 translike_flush_tars, /* flush constraint targets */
2139 default_get_tarmat_full_bbone, /* get target matrix */
2140 translike_evaluate, /* evaluate */
2141 };
2142
2143 /* ---------- Maintain Volume ---------- */
2144
samevolume_new_data(void * cdata)2145 static void samevolume_new_data(void *cdata)
2146 {
2147 bSameVolumeConstraint *data = (bSameVolumeConstraint *)cdata;
2148
2149 data->free_axis = SAMEVOL_Y;
2150 data->volume = 1.0f;
2151 }
2152
samevolume_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))2153 static void samevolume_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
2154 {
2155 bSameVolumeConstraint *data = con->data;
2156
2157 float volume = data->volume;
2158 float fac = 1.0f, total_scale = 1.0f;
2159 float obsize[3];
2160
2161 mat4_to_size(obsize, cob->matrix);
2162
2163 /* calculate normalizing scale factor for non-essential values */
2164 switch (data->mode) {
2165 case SAMEVOL_STRICT:
2166 total_scale = obsize[0] * obsize[1] * obsize[2];
2167 break;
2168 case SAMEVOL_UNIFORM:
2169 total_scale = pow3f(obsize[data->free_axis]);
2170 break;
2171 case SAMEVOL_SINGLE_AXIS:
2172 total_scale = obsize[data->free_axis];
2173 break;
2174 }
2175
2176 if (total_scale != 0) {
2177 fac = sqrtf(volume / total_scale);
2178 }
2179
2180 /* apply scaling factor to the channels not being kept */
2181 switch (data->free_axis) {
2182 case SAMEVOL_X:
2183 mul_v3_fl(cob->matrix[1], fac);
2184 mul_v3_fl(cob->matrix[2], fac);
2185 break;
2186 case SAMEVOL_Y:
2187 mul_v3_fl(cob->matrix[0], fac);
2188 mul_v3_fl(cob->matrix[2], fac);
2189 break;
2190 case SAMEVOL_Z:
2191 mul_v3_fl(cob->matrix[0], fac);
2192 mul_v3_fl(cob->matrix[1], fac);
2193 break;
2194 }
2195 }
2196
2197 static bConstraintTypeInfo CTI_SAMEVOL = {
2198 CONSTRAINT_TYPE_SAMEVOL, /* type */
2199 sizeof(bSameVolumeConstraint), /* size */
2200 "Maintain Volume", /* name */
2201 "bSameVolumeConstraint", /* struct name */
2202 NULL, /* free data */
2203 NULL, /* id looper */
2204 NULL, /* copy data */
2205 samevolume_new_data, /* new data */
2206 NULL, /* get constraint targets */
2207 NULL, /* flush constraint targets */
2208 NULL, /* get target matrix */
2209 samevolume_evaluate, /* evaluate */
2210 };
2211
2212 /* ----------- Python Constraint -------------- */
2213
pycon_free(bConstraint * con)2214 static void pycon_free(bConstraint *con)
2215 {
2216 bPythonConstraint *data = con->data;
2217
2218 /* id-properties */
2219 IDP_FreeProperty(data->prop);
2220
2221 /* multiple targets */
2222 BLI_freelistN(&data->targets);
2223 }
2224
pycon_copy(bConstraint * con,bConstraint * srccon)2225 static void pycon_copy(bConstraint *con, bConstraint *srccon)
2226 {
2227 bPythonConstraint *pycon = (bPythonConstraint *)con->data;
2228 bPythonConstraint *opycon = (bPythonConstraint *)srccon->data;
2229
2230 pycon->prop = IDP_CopyProperty(opycon->prop);
2231 BLI_duplicatelist(&pycon->targets, &opycon->targets);
2232 }
2233
pycon_new_data(void * cdata)2234 static void pycon_new_data(void *cdata)
2235 {
2236 bPythonConstraint *data = (bPythonConstraint *)cdata;
2237
2238 /* everything should be set correctly by calloc, except for the prop->type constant.*/
2239 data->prop = MEM_callocN(sizeof(IDProperty), "PyConstraintProps");
2240 data->prop->type = IDP_GROUP;
2241 }
2242
pycon_get_tars(bConstraint * con,ListBase * list)2243 static int pycon_get_tars(bConstraint *con, ListBase *list)
2244 {
2245 if (con && list) {
2246 bPythonConstraint *data = con->data;
2247
2248 list->first = data->targets.first;
2249 list->last = data->targets.last;
2250
2251 return data->tarnum;
2252 }
2253
2254 return 0;
2255 }
2256
pycon_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)2257 static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
2258 {
2259 bPythonConstraint *data = con->data;
2260 bConstraintTarget *ct;
2261
2262 /* targets */
2263 for (ct = data->targets.first; ct; ct = ct->next) {
2264 func(con, (ID **)&ct->tar, false, userdata);
2265 }
2266
2267 /* script */
2268 func(con, (ID **)&data->text, true, userdata);
2269 }
2270
2271 /* Whether this approach is maintained remains to be seen (aligorith) */
pycon_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))2272 static void pycon_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
2273 bConstraint *con,
2274 bConstraintOb *UNUSED(cob),
2275 bConstraintTarget *ct,
2276 float UNUSED(ctime))
2277 {
2278 #ifdef WITH_PYTHON
2279 bPythonConstraint *data = con->data;
2280 #endif
2281
2282 if (VALID_CONS_TARGET(ct)) {
2283 if (ct->tar->type == OB_CURVE && ct->tar->runtime.curve_cache == NULL) {
2284 unit_m4(ct->matrix);
2285 return;
2286 }
2287
2288 /* firstly calculate the matrix the normal way, then let the py-function override
2289 * this matrix if it needs to do so
2290 */
2291 constraint_target_to_mat4(ct->tar,
2292 ct->subtarget,
2293 ct->matrix,
2294 CONSTRAINT_SPACE_WORLD,
2295 ct->space,
2296 con->flag,
2297 con->headtail);
2298
2299 /* only execute target calculation if allowed */
2300 #ifdef WITH_PYTHON
2301 if (G.f & G_FLAG_SCRIPT_AUTOEXEC) {
2302 BPY_pyconstraint_target(data, ct);
2303 }
2304 #endif
2305 }
2306 else if (ct) {
2307 unit_m4(ct->matrix);
2308 }
2309 }
2310
pycon_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)2311 static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
2312 {
2313 #ifndef WITH_PYTHON
2314 UNUSED_VARS(con, cob, targets);
2315 return;
2316 #else
2317 bPythonConstraint *data = con->data;
2318
2319 /* only evaluate in python if we're allowed to do so */
2320 if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) {
2321 return;
2322 }
2323
2324 /* Now, run the actual 'constraint' function, which should only access the matrices */
2325 BPY_pyconstraint_exec(data, cob, targets);
2326 #endif /* WITH_PYTHON */
2327 }
2328
2329 static bConstraintTypeInfo CTI_PYTHON = {
2330 CONSTRAINT_TYPE_PYTHON, /* type */
2331 sizeof(bPythonConstraint), /* size */
2332 "Script", /* name */
2333 "bPythonConstraint", /* struct name */
2334 pycon_free, /* free data */
2335 pycon_id_looper, /* id looper */
2336 pycon_copy, /* copy data */
2337 pycon_new_data, /* new data */
2338 pycon_get_tars, /* get constraint targets */
2339 NULL, /* flush constraint targets */
2340 pycon_get_tarmat, /* get target matrix */
2341 pycon_evaluate, /* evaluate */
2342 };
2343
2344 /* ----------- Armature Constraint -------------- */
2345
armdef_free(bConstraint * con)2346 static void armdef_free(bConstraint *con)
2347 {
2348 bArmatureConstraint *data = con->data;
2349
2350 /* Target list. */
2351 BLI_freelistN(&data->targets);
2352 }
2353
armdef_copy(bConstraint * con,bConstraint * srccon)2354 static void armdef_copy(bConstraint *con, bConstraint *srccon)
2355 {
2356 bArmatureConstraint *pcon = (bArmatureConstraint *)con->data;
2357 bArmatureConstraint *opcon = (bArmatureConstraint *)srccon->data;
2358
2359 BLI_duplicatelist(&pcon->targets, &opcon->targets);
2360 }
2361
armdef_get_tars(bConstraint * con,ListBase * list)2362 static int armdef_get_tars(bConstraint *con, ListBase *list)
2363 {
2364 if (con && list) {
2365 bArmatureConstraint *data = con->data;
2366
2367 *list = data->targets;
2368
2369 return BLI_listbase_count(&data->targets);
2370 }
2371
2372 return 0;
2373 }
2374
armdef_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)2375 static void armdef_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
2376 {
2377 bArmatureConstraint *data = con->data;
2378 bConstraintTarget *ct;
2379
2380 /* Target list. */
2381 for (ct = data->targets.first; ct; ct = ct->next) {
2382 func(con, (ID **)&ct->tar, false, userdata);
2383 }
2384 }
2385
2386 /* Compute the world space pose matrix of the target bone. */
armdef_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * UNUSED (con),bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))2387 static void armdef_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
2388 bConstraint *UNUSED(con),
2389 bConstraintOb *UNUSED(cob),
2390 bConstraintTarget *ct,
2391 float UNUSED(ctime))
2392 {
2393 if (ct != NULL) {
2394 if (ct->tar && ct->tar->type == OB_ARMATURE) {
2395 bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
2396
2397 if (pchan != NULL) {
2398 mul_m4_m4m4(ct->matrix, ct->tar->obmat, pchan->pose_mat);
2399 return;
2400 }
2401 }
2402
2403 unit_m4(ct->matrix);
2404 }
2405 }
2406
armdef_accumulate_matrix(const float obmat[4][4],const float iobmat[4][4],const float basemat[4][4],const float bonemat[4][4],float weight,float r_sum_mat[4][4],DualQuat * r_sum_dq)2407 static void armdef_accumulate_matrix(const float obmat[4][4],
2408 const float iobmat[4][4],
2409 const float basemat[4][4],
2410 const float bonemat[4][4],
2411 float weight,
2412 float r_sum_mat[4][4],
2413 DualQuat *r_sum_dq)
2414 {
2415 if (weight == 0.0f) {
2416 return;
2417 }
2418
2419 /* Convert the selected matrix into object space. */
2420 float mat[4][4];
2421 mul_m4_series(mat, obmat, bonemat, iobmat);
2422
2423 /* Accumulate the transformation. */
2424 if (r_sum_dq != NULL) {
2425 DualQuat tmpdq;
2426
2427 mat4_to_dquat(&tmpdq, basemat, mat);
2428 add_weighted_dq_dq(r_sum_dq, &tmpdq, weight);
2429 }
2430 else {
2431 madd_m4_m4m4fl(r_sum_mat, r_sum_mat, mat, weight);
2432 }
2433 }
2434
2435 /* Compute and accumulate transformation for a single target bone. */
armdef_accumulate_bone(bConstraintTarget * ct,bPoseChannel * pchan,const float wco[3],bool force_envelope,float * r_totweight,float r_sum_mat[4][4],DualQuat * r_sum_dq)2436 static void armdef_accumulate_bone(bConstraintTarget *ct,
2437 bPoseChannel *pchan,
2438 const float wco[3],
2439 bool force_envelope,
2440 float *r_totweight,
2441 float r_sum_mat[4][4],
2442 DualQuat *r_sum_dq)
2443 {
2444 float iobmat[4][4], basemat[4][4], co[3];
2445 Bone *bone = pchan->bone;
2446 float weight = ct->weight;
2447
2448 /* Our object's location in target pose space. */
2449 invert_m4_m4(iobmat, ct->tar->obmat);
2450 mul_v3_m4v3(co, iobmat, wco);
2451
2452 /* Multiply by the envelope weight when appropriate. */
2453 if (force_envelope || (bone->flag & BONE_MULT_VG_ENV)) {
2454 weight *= distfactor_to_bone(
2455 co, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
2456 }
2457
2458 /* Compute the quaternion base matrix. */
2459 if (r_sum_dq != NULL) {
2460 mul_m4_series(basemat, ct->tar->obmat, bone->arm_mat, iobmat);
2461 }
2462
2463 /* Find the correct bone transform matrix in world space. */
2464 if (bone->segments > 1 && bone->segments == pchan->runtime.bbone_segments) {
2465 Mat4 *b_bone_mats = pchan->runtime.bbone_deform_mats;
2466 float(*iamat)[4] = b_bone_mats[0].mat;
2467
2468 /* The target is a B-Bone:
2469 * FIRST: find the segment (see b_bone_deform in armature.c)
2470 * Need to transform co back to bone-space, only need y. */
2471 float y = iamat[0][1] * co[0] + iamat[1][1] * co[1] + iamat[2][1] * co[2] + iamat[3][1];
2472
2473 /* Blend the matrix. */
2474 int index;
2475 float blend;
2476 BKE_pchan_bbone_deform_segment_index(pchan, y / bone->length, &index, &blend);
2477
2478 armdef_accumulate_matrix(ct->tar->obmat,
2479 iobmat,
2480 basemat,
2481 b_bone_mats[index + 1].mat,
2482 weight * (1.0f - blend),
2483 r_sum_mat,
2484 r_sum_dq);
2485 armdef_accumulate_matrix(ct->tar->obmat,
2486 iobmat,
2487 basemat,
2488 b_bone_mats[index + 2].mat,
2489 weight * blend,
2490 r_sum_mat,
2491 r_sum_dq);
2492 }
2493 else {
2494 /* Simple bone. This requires DEG_OPCODE_BONE_DONE dependency due to chan_mat. */
2495 armdef_accumulate_matrix(
2496 ct->tar->obmat, iobmat, basemat, pchan->chan_mat, weight, r_sum_mat, r_sum_dq);
2497 }
2498
2499 /* Accumulate the weight. */
2500 *r_totweight += weight;
2501 }
2502
armdef_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)2503 static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
2504 {
2505 bArmatureConstraint *data = con->data;
2506
2507 float sum_mat[4][4], input_co[3];
2508 DualQuat sum_dq;
2509 float weight = 0.0f;
2510
2511 /* Prepare for blending. */
2512 zero_m4(sum_mat);
2513 memset(&sum_dq, 0, sizeof(sum_dq));
2514
2515 DualQuat *pdq = (data->flag & CONSTRAINT_ARMATURE_QUATERNION) ? &sum_dq : NULL;
2516 bool use_envelopes = (data->flag & CONSTRAINT_ARMATURE_ENVELOPE) != 0;
2517
2518 if (cob->pchan && cob->pchan->bone && !(data->flag & CONSTRAINT_ARMATURE_CUR_LOCATION)) {
2519 /* For constraints on bones, use the rest position to bind b-bone segments
2520 * and envelopes, to allow safely changing the bone location as if parented. */
2521 copy_v3_v3(input_co, cob->pchan->bone->arm_head);
2522 mul_m4_v3(cob->ob->obmat, input_co);
2523 }
2524 else {
2525 copy_v3_v3(input_co, cob->matrix[3]);
2526 }
2527
2528 /* Process all targets. This can't use ct->matrix, as armdef_get_tarmat is not
2529 * called in solve for efficiency because the constraint needs bone data anyway. */
2530 LISTBASE_FOREACH (bConstraintTarget *, ct, targets) {
2531 if (ct->weight <= 0.0f) {
2532 continue;
2533 }
2534
2535 /* Lookup the bone and abort if failed. */
2536 if (!VALID_CONS_TARGET(ct) || ct->tar->type != OB_ARMATURE) {
2537 return;
2538 }
2539
2540 bPoseChannel *pchan = BKE_pose_channel_find_name(ct->tar->pose, ct->subtarget);
2541
2542 if (pchan == NULL || pchan->bone == NULL) {
2543 return;
2544 }
2545
2546 armdef_accumulate_bone(ct, pchan, input_co, use_envelopes, &weight, sum_mat, pdq);
2547 }
2548
2549 /* Compute the final transform. */
2550 if (weight > 0.0f) {
2551 if (pdq != NULL) {
2552 normalize_dq(pdq, weight);
2553 dquat_to_mat4(sum_mat, pdq);
2554 }
2555 else {
2556 mul_m4_fl(sum_mat, 1.0f / weight);
2557 }
2558
2559 /* Apply the transform to the result matrix. */
2560 mul_m4_m4m4(cob->matrix, sum_mat, cob->matrix);
2561 }
2562 }
2563
2564 static bConstraintTypeInfo CTI_ARMATURE = {
2565 CONSTRAINT_TYPE_ARMATURE, /* type */
2566 sizeof(bArmatureConstraint), /* size */
2567 "Armature", /* name */
2568 "bArmatureConstraint", /* struct name */
2569 armdef_free, /* free data */
2570 armdef_id_looper, /* id looper */
2571 armdef_copy, /* copy data */
2572 NULL, /* new data */
2573 armdef_get_tars, /* get constraint targets */
2574 NULL, /* flush constraint targets */
2575 armdef_get_tarmat, /* get target matrix */
2576 armdef_evaluate, /* evaluate */
2577 };
2578
2579 /* -------- Action Constraint ----------- */
2580
actcon_new_data(void * cdata)2581 static void actcon_new_data(void *cdata)
2582 {
2583 bActionConstraint *data = (bActionConstraint *)cdata;
2584
2585 /* set type to 20 (Loc X), as 0 is Rot X for backwards compatibility */
2586 data->type = 20;
2587
2588 /* Set the mix mode to After Original with anti-shear scale handling. */
2589 data->mix_mode = ACTCON_MIX_AFTER;
2590 }
2591
actcon_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)2592 static void actcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
2593 {
2594 bActionConstraint *data = con->data;
2595
2596 /* target */
2597 func(con, (ID **)&data->tar, false, userdata);
2598
2599 /* action */
2600 func(con, (ID **)&data->act, true, userdata);
2601 }
2602
actcon_get_tars(bConstraint * con,ListBase * list)2603 static int actcon_get_tars(bConstraint *con, ListBase *list)
2604 {
2605 if (con && list) {
2606 bActionConstraint *data = con->data;
2607 bConstraintTarget *ct;
2608
2609 /* standard target-getting macro for single-target constraints */
2610 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
2611
2612 return 1;
2613 }
2614
2615 return 0;
2616 }
2617
actcon_flush_tars(bConstraint * con,ListBase * list,bool no_copy)2618 static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
2619 {
2620 if (con && list) {
2621 bActionConstraint *data = con->data;
2622 bConstraintTarget *ct = list->first;
2623
2624 /* the following macro is used for all standard single-target constraints */
2625 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
2626 }
2627 }
2628
actcon_get_tarmat(struct Depsgraph * depsgraph,bConstraint * con,bConstraintOb * cob,bConstraintTarget * ct,float UNUSED (ctime))2629 static void actcon_get_tarmat(struct Depsgraph *depsgraph,
2630 bConstraint *con,
2631 bConstraintOb *cob,
2632 bConstraintTarget *ct,
2633 float UNUSED(ctime))
2634 {
2635 bActionConstraint *data = con->data;
2636
2637 if (VALID_CONS_TARGET(ct) || data->flag & ACTCON_USE_EVAL_TIME) {
2638 float tempmat[4][4], vec[3];
2639 float s, t;
2640 short axis;
2641
2642 /* initialize return matrix */
2643 unit_m4(ct->matrix);
2644
2645 /* Skip targets if we're using local float property to set action time */
2646 if (data->flag & ACTCON_USE_EVAL_TIME) {
2647 s = data->eval_time;
2648 }
2649 else {
2650 /* get the transform matrix of the target */
2651 constraint_target_to_mat4(ct->tar,
2652 ct->subtarget,
2653 tempmat,
2654 CONSTRAINT_SPACE_WORLD,
2655 ct->space,
2656 con->flag,
2657 con->headtail);
2658
2659 /* determine where in transform range target is */
2660 /* data->type is mapped as follows for backwards compatibility:
2661 * 00,01,02 - rotation (it used to be like this)
2662 * 10,11,12 - scaling
2663 * 20,21,22 - location
2664 */
2665 if (data->type < 10) {
2666 /* extract rotation (is in whatever space target should be in) */
2667 mat4_to_eul(vec, tempmat);
2668 mul_v3_fl(vec, RAD2DEGF(1.0f)); /* rad -> deg */
2669 axis = data->type;
2670 }
2671 else if (data->type < 20) {
2672 /* extract scaling (is in whatever space target should be in) */
2673 mat4_to_size(vec, tempmat);
2674 axis = data->type - 10;
2675 }
2676 else {
2677 /* extract location */
2678 copy_v3_v3(vec, tempmat[3]);
2679 axis = data->type - 20;
2680 }
2681
2682 BLI_assert((unsigned int)axis < 3);
2683
2684 /* Target defines the animation */
2685 s = (vec[axis] - data->min) / (data->max - data->min);
2686 }
2687
2688 CLAMP(s, 0, 1);
2689 t = (s * (data->end - data->start)) + data->start;
2690 const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph,
2691 t);
2692
2693 if (G.debug & G_DEBUG) {
2694 printf("do Action Constraint %s - Ob %s Pchan %s\n",
2695 con->name,
2696 cob->ob->id.name + 2,
2697 (cob->pchan) ? cob->pchan->name : NULL);
2698 }
2699
2700 /* Get the appropriate information from the action */
2701 if (cob->type == CONSTRAINT_OBTYPE_OBJECT || (data->flag & ACTCON_BONE_USE_OBJECT_ACTION)) {
2702 Object workob;
2703
2704 /* evaluate using workob */
2705 /* FIXME: we don't have any consistent standards on limiting effects on object... */
2706 what_does_obaction(cob->ob, &workob, NULL, data->act, NULL, &anim_eval_context);
2707 BKE_object_to_mat4(&workob, ct->matrix);
2708 }
2709 else if (cob->type == CONSTRAINT_OBTYPE_BONE) {
2710 Object workob;
2711 bPose pose = {{0}};
2712 bPoseChannel *pchan, *tchan;
2713
2714 /* make a copy of the bone of interest in the temp pose before evaluating action,
2715 * so that it can get set - we need to manually copy over a few settings,
2716 * including rotation order, otherwise this fails. */
2717 pchan = cob->pchan;
2718
2719 tchan = BKE_pose_channel_verify(&pose, pchan->name);
2720 tchan->rotmode = pchan->rotmode;
2721
2722 /* evaluate action using workob (it will only set the PoseChannel in question) */
2723 what_does_obaction(cob->ob, &workob, &pose, data->act, pchan->name, &anim_eval_context);
2724
2725 /* convert animation to matrices for use here */
2726 BKE_pchan_calc_mat(tchan);
2727 copy_m4_m4(ct->matrix, tchan->chan_mat);
2728
2729 /* Clean up */
2730 BKE_pose_free_data(&pose);
2731 }
2732 else {
2733 /* behavior undefined... */
2734 puts("Error: unknown owner type for Action Constraint");
2735 }
2736 }
2737 }
2738
actcon_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)2739 static void actcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
2740 {
2741 bActionConstraint *data = con->data;
2742 bConstraintTarget *ct = targets->first;
2743
2744 if (VALID_CONS_TARGET(ct) || data->flag & ACTCON_USE_EVAL_TIME) {
2745 switch (data->mix_mode) {
2746 case ACTCON_MIX_BEFORE:
2747 mul_m4_m4m4_aligned_scale(cob->matrix, ct->matrix, cob->matrix);
2748 break;
2749
2750 case ACTCON_MIX_AFTER:
2751 mul_m4_m4m4_aligned_scale(cob->matrix, cob->matrix, ct->matrix);
2752 break;
2753
2754 case ACTCON_MIX_AFTER_FULL:
2755 mul_m4_m4m4(cob->matrix, cob->matrix, ct->matrix);
2756 break;
2757
2758 default:
2759 BLI_assert(!"Unknown Action mix mode");
2760 }
2761 }
2762 }
2763
2764 static bConstraintTypeInfo CTI_ACTION = {
2765 CONSTRAINT_TYPE_ACTION, /* type */
2766 sizeof(bActionConstraint), /* size */
2767 "Action", /* name */
2768 "bActionConstraint", /* struct name */
2769 NULL, /* free data */
2770 actcon_id_looper, /* id looper */
2771 NULL, /* copy data */
2772 actcon_new_data, /* new data */
2773 actcon_get_tars, /* get constraint targets */
2774 actcon_flush_tars, /* flush constraint targets */
2775 actcon_get_tarmat, /* get target matrix */
2776 actcon_evaluate, /* evaluate */
2777 };
2778
2779 /* --------- Locked Track ---------- */
2780
locktrack_new_data(void * cdata)2781 static void locktrack_new_data(void *cdata)
2782 {
2783 bLockTrackConstraint *data = (bLockTrackConstraint *)cdata;
2784
2785 data->trackflag = TRACK_Y;
2786 data->lockflag = LOCK_Z;
2787 }
2788
locktrack_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)2789 static void locktrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
2790 {
2791 bLockTrackConstraint *data = con->data;
2792
2793 /* target only */
2794 func(con, (ID **)&data->tar, false, userdata);
2795 }
2796
locktrack_get_tars(bConstraint * con,ListBase * list)2797 static int locktrack_get_tars(bConstraint *con, ListBase *list)
2798 {
2799 if (con && list) {
2800 bLockTrackConstraint *data = con->data;
2801 bConstraintTarget *ct;
2802
2803 /* the following macro is used for all standard single-target constraints */
2804 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
2805
2806 return 1;
2807 }
2808
2809 return 0;
2810 }
2811
locktrack_flush_tars(bConstraint * con,ListBase * list,bool no_copy)2812 static void locktrack_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
2813 {
2814 if (con && list) {
2815 bLockTrackConstraint *data = con->data;
2816 bConstraintTarget *ct = list->first;
2817
2818 /* the following macro is used for all standard single-target constraints */
2819 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
2820 }
2821 }
2822
locktrack_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)2823 static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
2824 {
2825 bLockTrackConstraint *data = con->data;
2826 bConstraintTarget *ct = targets->first;
2827
2828 if (VALID_CONS_TARGET(ct)) {
2829 float vec[3], vec2[3];
2830 float totmat[3][3];
2831 float tmpmat[3][3];
2832 float invmat[3][3];
2833 float mdet;
2834
2835 /* Vector object -> target */
2836 sub_v3_v3v3(vec, ct->matrix[3], cob->matrix[3]);
2837 switch (data->lockflag) {
2838 case LOCK_X: /* LOCK X */
2839 {
2840 switch (data->trackflag) {
2841 case TRACK_Y: /* LOCK X TRACK Y */
2842 {
2843 /* Projection of Vector on the plane */
2844 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2845 sub_v3_v3v3(totmat[1], vec, vec2);
2846 normalize_v3(totmat[1]);
2847
2848 /* the x axis is fixed */
2849 normalize_v3_v3(totmat[0], cob->matrix[0]);
2850
2851 /* the z axis gets mapped onto a third orthogonal vector */
2852 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2853 break;
2854 }
2855 case TRACK_Z: /* LOCK X TRACK Z */
2856 {
2857 /* Projection of Vector on the plane */
2858 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2859 sub_v3_v3v3(totmat[2], vec, vec2);
2860 normalize_v3(totmat[2]);
2861
2862 /* the x axis is fixed */
2863 normalize_v3_v3(totmat[0], cob->matrix[0]);
2864
2865 /* the z axis gets mapped onto a third orthogonal vector */
2866 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2867 break;
2868 }
2869 case TRACK_nY: /* LOCK X TRACK -Y */
2870 {
2871 /* Projection of Vector on the plane */
2872 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2873 sub_v3_v3v3(totmat[1], vec, vec2);
2874 normalize_v3(totmat[1]);
2875 negate_v3(totmat[1]);
2876
2877 /* the x axis is fixed */
2878 normalize_v3_v3(totmat[0], cob->matrix[0]);
2879
2880 /* the z axis gets mapped onto a third orthogonal vector */
2881 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2882 break;
2883 }
2884 case TRACK_nZ: /* LOCK X TRACK -Z */
2885 {
2886 /* Projection of Vector on the plane */
2887 project_v3_v3v3(vec2, vec, cob->matrix[0]);
2888 sub_v3_v3v3(totmat[2], vec, vec2);
2889 normalize_v3(totmat[2]);
2890 negate_v3(totmat[2]);
2891
2892 /* the x axis is fixed */
2893 normalize_v3_v3(totmat[0], cob->matrix[0]);
2894
2895 /* the z axis gets mapped onto a third orthogonal vector */
2896 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2897 break;
2898 }
2899 default: {
2900 unit_m3(totmat);
2901 break;
2902 }
2903 }
2904 break;
2905 }
2906 case LOCK_Y: /* LOCK Y */
2907 {
2908 switch (data->trackflag) {
2909 case TRACK_X: /* LOCK Y TRACK X */
2910 {
2911 /* Projection of Vector on the plane */
2912 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2913 sub_v3_v3v3(totmat[0], vec, vec2);
2914 normalize_v3(totmat[0]);
2915
2916 /* the y axis is fixed */
2917 normalize_v3_v3(totmat[1], cob->matrix[1]);
2918
2919 /* the z axis gets mapped onto a third orthogonal vector */
2920 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2921 break;
2922 }
2923 case TRACK_Z: /* LOCK Y TRACK Z */
2924 {
2925 /* Projection of Vector on the plane */
2926 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2927 sub_v3_v3v3(totmat[2], vec, vec2);
2928 normalize_v3(totmat[2]);
2929
2930 /* the y axis is fixed */
2931 normalize_v3_v3(totmat[1], cob->matrix[1]);
2932
2933 /* the z axis gets mapped onto a third orthogonal vector */
2934 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2935 break;
2936 }
2937 case TRACK_nX: /* LOCK Y TRACK -X */
2938 {
2939 /* Projection of Vector on the plane */
2940 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2941 sub_v3_v3v3(totmat[0], vec, vec2);
2942 normalize_v3(totmat[0]);
2943 negate_v3(totmat[0]);
2944
2945 /* the y axis is fixed */
2946 normalize_v3_v3(totmat[1], cob->matrix[1]);
2947
2948 /* the z axis gets mapped onto a third orthogonal vector */
2949 cross_v3_v3v3(totmat[2], totmat[0], totmat[1]);
2950 break;
2951 }
2952 case TRACK_nZ: /* LOCK Y TRACK -Z */
2953 {
2954 /* Projection of Vector on the plane */
2955 project_v3_v3v3(vec2, vec, cob->matrix[1]);
2956 sub_v3_v3v3(totmat[2], vec, vec2);
2957 normalize_v3(totmat[2]);
2958 negate_v3(totmat[2]);
2959
2960 /* the y axis is fixed */
2961 normalize_v3_v3(totmat[1], cob->matrix[1]);
2962
2963 /* the z axis gets mapped onto a third orthogonal vector */
2964 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
2965 break;
2966 }
2967 default: {
2968 unit_m3(totmat);
2969 break;
2970 }
2971 }
2972 break;
2973 }
2974 case LOCK_Z: /* LOCK Z */
2975 {
2976 switch (data->trackflag) {
2977 case TRACK_X: /* LOCK Z TRACK X */
2978 {
2979 /* Projection of Vector on the plane */
2980 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2981 sub_v3_v3v3(totmat[0], vec, vec2);
2982 normalize_v3(totmat[0]);
2983
2984 /* the z axis is fixed */
2985 normalize_v3_v3(totmat[2], cob->matrix[2]);
2986
2987 /* the x axis gets mapped onto a third orthogonal vector */
2988 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
2989 break;
2990 }
2991 case TRACK_Y: /* LOCK Z TRACK Y */
2992 {
2993 /* Projection of Vector on the plane */
2994 project_v3_v3v3(vec2, vec, cob->matrix[2]);
2995 sub_v3_v3v3(totmat[1], vec, vec2);
2996 normalize_v3(totmat[1]);
2997
2998 /* the z axis is fixed */
2999 normalize_v3_v3(totmat[2], cob->matrix[2]);
3000
3001 /* the x axis gets mapped onto a third orthogonal vector */
3002 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
3003 break;
3004 }
3005 case TRACK_nX: /* LOCK Z TRACK -X */
3006 {
3007 /* Projection of Vector on the plane */
3008 project_v3_v3v3(vec2, vec, cob->matrix[2]);
3009 sub_v3_v3v3(totmat[0], vec, vec2);
3010 normalize_v3(totmat[0]);
3011 negate_v3(totmat[0]);
3012
3013 /* the z axis is fixed */
3014 normalize_v3_v3(totmat[2], cob->matrix[2]);
3015
3016 /* the x axis gets mapped onto a third orthogonal vector */
3017 cross_v3_v3v3(totmat[1], totmat[2], totmat[0]);
3018 break;
3019 }
3020 case TRACK_nY: /* LOCK Z TRACK -Y */
3021 {
3022 /* Projection of Vector on the plane */
3023 project_v3_v3v3(vec2, vec, cob->matrix[2]);
3024 sub_v3_v3v3(totmat[1], vec, vec2);
3025 normalize_v3(totmat[1]);
3026 negate_v3(totmat[1]);
3027
3028 /* the z axis is fixed */
3029 normalize_v3_v3(totmat[2], cob->matrix[2]);
3030
3031 /* the x axis gets mapped onto a third orthogonal vector */
3032 cross_v3_v3v3(totmat[0], totmat[1], totmat[2]);
3033 break;
3034 }
3035 default: {
3036 unit_m3(totmat);
3037 break;
3038 }
3039 }
3040 break;
3041 }
3042 default: {
3043 unit_m3(totmat);
3044 break;
3045 }
3046 }
3047 /* Block to keep matrix heading */
3048 copy_m3_m4(tmpmat, cob->matrix);
3049 normalize_m3(tmpmat);
3050 invert_m3_m3(invmat, tmpmat);
3051 mul_m3_m3m3(tmpmat, totmat, invmat);
3052 totmat[0][0] = tmpmat[0][0];
3053 totmat[0][1] = tmpmat[0][1];
3054 totmat[0][2] = tmpmat[0][2];
3055 totmat[1][0] = tmpmat[1][0];
3056 totmat[1][1] = tmpmat[1][1];
3057 totmat[1][2] = tmpmat[1][2];
3058 totmat[2][0] = tmpmat[2][0];
3059 totmat[2][1] = tmpmat[2][1];
3060 totmat[2][2] = tmpmat[2][2];
3061
3062 mdet = determinant_m3(totmat[0][0],
3063 totmat[0][1],
3064 totmat[0][2],
3065 totmat[1][0],
3066 totmat[1][1],
3067 totmat[1][2],
3068 totmat[2][0],
3069 totmat[2][1],
3070 totmat[2][2]);
3071 if (mdet == 0) {
3072 unit_m3(totmat);
3073 }
3074
3075 /* apply out transformation to the object */
3076 mul_m4_m3m4(cob->matrix, totmat, cob->matrix);
3077 }
3078 }
3079
3080 static bConstraintTypeInfo CTI_LOCKTRACK = {
3081 CONSTRAINT_TYPE_LOCKTRACK, /* type */
3082 sizeof(bLockTrackConstraint), /* size */
3083 "Locked Track", /* name */
3084 "bLockTrackConstraint", /* struct name */
3085 NULL, /* free data */
3086 locktrack_id_looper, /* id looper */
3087 NULL, /* copy data */
3088 locktrack_new_data, /* new data */
3089 locktrack_get_tars, /* get constraint targets */
3090 locktrack_flush_tars, /* flush constraint targets */
3091 default_get_tarmat, /* get target matrix */
3092 locktrack_evaluate, /* evaluate */
3093 };
3094
3095 /* ---------- Limit Distance Constraint ----------- */
3096
distlimit_new_data(void * cdata)3097 static void distlimit_new_data(void *cdata)
3098 {
3099 bDistLimitConstraint *data = (bDistLimitConstraint *)cdata;
3100
3101 data->dist = 0.0f;
3102 }
3103
distlimit_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3104 static void distlimit_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3105 {
3106 bDistLimitConstraint *data = con->data;
3107
3108 /* target only */
3109 func(con, (ID **)&data->tar, false, userdata);
3110 }
3111
distlimit_get_tars(bConstraint * con,ListBase * list)3112 static int distlimit_get_tars(bConstraint *con, ListBase *list)
3113 {
3114 if (con && list) {
3115 bDistLimitConstraint *data = con->data;
3116 bConstraintTarget *ct;
3117
3118 /* standard target-getting macro for single-target constraints */
3119 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
3120
3121 return 1;
3122 }
3123
3124 return 0;
3125 }
3126
distlimit_flush_tars(bConstraint * con,ListBase * list,bool no_copy)3127 static void distlimit_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
3128 {
3129 if (con && list) {
3130 bDistLimitConstraint *data = con->data;
3131 bConstraintTarget *ct = list->first;
3132
3133 /* the following macro is used for all standard single-target constraints */
3134 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
3135 }
3136 }
3137
distlimit_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)3138 static void distlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
3139 {
3140 bDistLimitConstraint *data = con->data;
3141 bConstraintTarget *ct = targets->first;
3142
3143 /* only evaluate if there is a target */
3144 if (VALID_CONS_TARGET(ct)) {
3145 float dvec[3], dist, sfac = 1.0f;
3146 short clamp_surf = 0;
3147
3148 /* calculate our current distance from the target */
3149 dist = len_v3v3(cob->matrix[3], ct->matrix[3]);
3150
3151 /* set distance (flag is only set when user demands it) */
3152 if (data->dist == 0) {
3153 data->dist = dist;
3154
3155 /* Write the computed distance back to the master copy if in COW evaluation. */
3156 bConstraint *orig_con = constraint_find_original_for_update(cob, con);
3157
3158 if (orig_con != NULL) {
3159 bDistLimitConstraint *orig_data = orig_con->data;
3160
3161 orig_data->dist = data->dist;
3162 }
3163 }
3164
3165 /* check if we're which way to clamp from, and calculate interpolation factor (if needed) */
3166 if (data->mode == LIMITDIST_OUTSIDE) {
3167 /* if inside, then move to surface */
3168 if (dist <= data->dist) {
3169 clamp_surf = 1;
3170 if (dist != 0.0f) {
3171 sfac = data->dist / dist;
3172 }
3173 }
3174 /* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
3175 else if (data->flag & LIMITDIST_USESOFT) {
3176 if (dist <= (data->dist + data->soft)) {
3177 /* pass */
3178 }
3179 }
3180 }
3181 else if (data->mode == LIMITDIST_INSIDE) {
3182 /* if outside, then move to surface */
3183 if (dist >= data->dist) {
3184 clamp_surf = 1;
3185 if (dist != 0.0f) {
3186 sfac = data->dist / dist;
3187 }
3188 }
3189 /* if soft-distance is enabled, start fading once owner is dist-soft from the target */
3190 else if (data->flag & LIMITDIST_USESOFT) {
3191 /* FIXME: there's a problem with "jumping" when this kicks in */
3192 if (dist >= (data->dist - data->soft)) {
3193 sfac = (float)(data->soft * (1.0f - expf(-(dist - data->dist) / data->soft)) +
3194 data->dist);
3195 if (dist != 0.0f) {
3196 sfac /= dist;
3197 }
3198
3199 clamp_surf = 1;
3200 }
3201 }
3202 }
3203 else {
3204 if (IS_EQF(dist, data->dist) == 0) {
3205 clamp_surf = 1;
3206 if (dist != 0.0f) {
3207 sfac = data->dist / dist;
3208 }
3209 }
3210 }
3211
3212 /* clamp to 'surface' (i.e. move owner so that dist == data->dist) */
3213 if (clamp_surf) {
3214 /* simply interpolate along line formed by target -> owner */
3215 interp_v3_v3v3(dvec, ct->matrix[3], cob->matrix[3], sfac);
3216
3217 /* copy new vector onto owner */
3218 copy_v3_v3(cob->matrix[3], dvec);
3219 }
3220 }
3221 }
3222
3223 static bConstraintTypeInfo CTI_DISTLIMIT = {
3224 CONSTRAINT_TYPE_DISTLIMIT, /* type */
3225 sizeof(bDistLimitConstraint), /* size */
3226 "Limit Distance", /* name */
3227 "bDistLimitConstraint", /* struct name */
3228 NULL, /* free data */
3229 distlimit_id_looper, /* id looper */
3230 NULL, /* copy data */
3231 distlimit_new_data, /* new data */
3232 distlimit_get_tars, /* get constraint targets */
3233 distlimit_flush_tars, /* flush constraint targets */
3234 default_get_tarmat, /* get a target matrix */
3235 distlimit_evaluate, /* evaluate */
3236 };
3237
3238 /* ---------- Stretch To ------------ */
3239
stretchto_new_data(void * cdata)3240 static void stretchto_new_data(void *cdata)
3241 {
3242 bStretchToConstraint *data = (bStretchToConstraint *)cdata;
3243
3244 data->volmode = 0;
3245 data->plane = 0;
3246 data->orglength = 0.0;
3247 data->bulge = 1.0;
3248 data->bulge_max = 1.0f;
3249 data->bulge_min = 1.0f;
3250 }
3251
stretchto_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3252 static void stretchto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3253 {
3254 bStretchToConstraint *data = con->data;
3255
3256 /* target only */
3257 func(con, (ID **)&data->tar, false, userdata);
3258 }
3259
stretchto_get_tars(bConstraint * con,ListBase * list)3260 static int stretchto_get_tars(bConstraint *con, ListBase *list)
3261 {
3262 if (con && list) {
3263 bStretchToConstraint *data = con->data;
3264 bConstraintTarget *ct;
3265
3266 /* standard target-getting macro for single-target constraints */
3267 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
3268
3269 return 1;
3270 }
3271
3272 return 0;
3273 }
3274
stretchto_flush_tars(bConstraint * con,ListBase * list,bool no_copy)3275 static void stretchto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
3276 {
3277 if (con && list) {
3278 bStretchToConstraint *data = con->data;
3279 bConstraintTarget *ct = list->first;
3280
3281 /* the following macro is used for all standard single-target constraints */
3282 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
3283 }
3284 }
3285
stretchto_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)3286 static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
3287 {
3288 bStretchToConstraint *data = con->data;
3289 bConstraintTarget *ct = targets->first;
3290
3291 /* only evaluate if there is a target */
3292 if (VALID_CONS_TARGET(ct)) {
3293 float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
3294 float dist, bulge;
3295
3296 /* Remove shear if using the Damped Track mode; the other modes
3297 * do it as a side effect, which is relied on by rigs. */
3298 if (data->plane == SWING_Y) {
3299 orthogonalize_m4_stable(cob->matrix, 1, false);
3300 }
3301
3302 /* store scaling before destroying obmat */
3303 normalize_m4_ex(cob->matrix, size);
3304
3305 /* store X orientation before destroying obmat */
3306 copy_v3_v3(xx, cob->matrix[0]);
3307
3308 /* store Z orientation before destroying obmat */
3309 copy_v3_v3(zz, cob->matrix[2]);
3310
3311 /* Compute distance and direction to target. */
3312 sub_v3_v3v3(vec, ct->matrix[3], cob->matrix[3]);
3313
3314 dist = normalize_v3(vec);
3315
3316 /* Only Y constrained object axis scale should be used, to keep same length when scaling it. */
3317 dist /= size[1];
3318
3319 /* data->orglength==0 occurs on first run, and after 'R' button is clicked */
3320 if (data->orglength == 0) {
3321 data->orglength = dist;
3322
3323 /* Write the computed length back to the master copy if in COW evaluation. */
3324 bConstraint *orig_con = constraint_find_original_for_update(cob, con);
3325
3326 if (orig_con != NULL) {
3327 bStretchToConstraint *orig_data = orig_con->data;
3328
3329 orig_data->orglength = data->orglength;
3330 }
3331 }
3332
3333 scale[1] = dist / data->orglength;
3334
3335 bulge = powf(data->orglength / dist, data->bulge);
3336
3337 if (bulge > 1.0f) {
3338 if (data->flag & STRETCHTOCON_USE_BULGE_MAX) {
3339 float bulge_max = max_ff(data->bulge_max, 1.0f);
3340 float hard = min_ff(bulge, bulge_max);
3341
3342 float range = bulge_max - 1.0f;
3343 float scale_fac = (range > 0.0f) ? 1.0f / range : 0.0f;
3344 float soft = 1.0f + range * atanf((bulge - 1.0f) * scale_fac) / (float)M_PI_2;
3345
3346 bulge = interpf(soft, hard, data->bulge_smooth);
3347 }
3348 }
3349 if (bulge < 1.0f) {
3350 if (data->flag & STRETCHTOCON_USE_BULGE_MIN) {
3351 float bulge_min = CLAMPIS(data->bulge_min, 0.0f, 1.0f);
3352 float hard = max_ff(bulge, bulge_min);
3353
3354 float range = 1.0f - bulge_min;
3355 float scale_fac = (range > 0.0f) ? 1.0f / range : 0.0f;
3356 float soft = 1.0f - range * atanf((1.0f - bulge) * scale_fac) / (float)M_PI_2;
3357
3358 bulge = interpf(soft, hard, data->bulge_smooth);
3359 }
3360 }
3361
3362 switch (data->volmode) {
3363 /* volume preserving scaling */
3364 case VOLUME_XZ:
3365 scale[0] = sqrtf(bulge);
3366 scale[2] = scale[0];
3367 break;
3368 case VOLUME_X:
3369 scale[0] = bulge;
3370 scale[2] = 1.0;
3371 break;
3372 case VOLUME_Z:
3373 scale[0] = 1.0;
3374 scale[2] = bulge;
3375 break;
3376 /* don't care for volume */
3377 case NO_VOLUME:
3378 scale[0] = 1.0;
3379 scale[2] = 1.0;
3380 break;
3381 default: /* should not happen, but in case*/
3382 return;
3383 } /* switch (data->volmode) */
3384
3385 /* Compute final scale. */
3386 mul_v3_v3(size, scale);
3387
3388 switch (data->plane) {
3389 case SWING_Y:
3390 /* Point the Y axis using Damped Track math. */
3391 damptrack_do_transform(cob->matrix, vec, TRACK_Y);
3392 break;
3393 case PLANE_X:
3394 /* new Y aligns object target connection*/
3395 copy_v3_v3(cob->matrix[1], vec);
3396
3397 /* build new Z vector */
3398 /* othogonal to "new Y" "old X! plane */
3399 cross_v3_v3v3(orth, xx, vec);
3400 normalize_v3(orth);
3401
3402 /* new Z*/
3403 copy_v3_v3(cob->matrix[2], orth);
3404
3405 /* we decided to keep X plane*/
3406 cross_v3_v3v3(xx, vec, orth);
3407 normalize_v3_v3(cob->matrix[0], xx);
3408 break;
3409 case PLANE_Z:
3410 /* new Y aligns object target connection*/
3411 copy_v3_v3(cob->matrix[1], vec);
3412
3413 /* build new X vector */
3414 /* othogonal to "new Y" "old Z! plane */
3415 cross_v3_v3v3(orth, zz, vec);
3416 normalize_v3(orth);
3417
3418 /* new X */
3419 negate_v3_v3(cob->matrix[0], orth);
3420
3421 /* we decided to keep Z */
3422 cross_v3_v3v3(zz, vec, orth);
3423 normalize_v3_v3(cob->matrix[2], zz);
3424 break;
3425 } /* switch (data->plane) */
3426
3427 rescale_m4(cob->matrix, size);
3428 }
3429 }
3430
3431 static bConstraintTypeInfo CTI_STRETCHTO = {
3432 CONSTRAINT_TYPE_STRETCHTO, /* type */
3433 sizeof(bStretchToConstraint), /* size */
3434 "Stretch To", /* name */
3435 "bStretchToConstraint", /* struct name */
3436 NULL, /* free data */
3437 stretchto_id_looper, /* id looper */
3438 NULL, /* copy data */
3439 stretchto_new_data, /* new data */
3440 stretchto_get_tars, /* get constraint targets */
3441 stretchto_flush_tars, /* flush constraint targets */
3442 default_get_tarmat, /* get target matrix */
3443 stretchto_evaluate, /* evaluate */
3444 };
3445
3446 /* ---------- Floor ------------ */
3447
minmax_new_data(void * cdata)3448 static void minmax_new_data(void *cdata)
3449 {
3450 bMinMaxConstraint *data = (bMinMaxConstraint *)cdata;
3451
3452 data->minmaxflag = TRACK_Z;
3453 data->offset = 0.0f;
3454 data->flag = 0;
3455 }
3456
minmax_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3457 static void minmax_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3458 {
3459 bMinMaxConstraint *data = con->data;
3460
3461 /* target only */
3462 func(con, (ID **)&data->tar, false, userdata);
3463 }
3464
minmax_get_tars(bConstraint * con,ListBase * list)3465 static int minmax_get_tars(bConstraint *con, ListBase *list)
3466 {
3467 if (con && list) {
3468 bMinMaxConstraint *data = con->data;
3469 bConstraintTarget *ct;
3470
3471 /* standard target-getting macro for single-target constraints */
3472 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
3473
3474 return 1;
3475 }
3476
3477 return 0;
3478 }
3479
minmax_flush_tars(bConstraint * con,ListBase * list,bool no_copy)3480 static void minmax_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
3481 {
3482 if (con && list) {
3483 bMinMaxConstraint *data = con->data;
3484 bConstraintTarget *ct = list->first;
3485
3486 /* the following macro is used for all standard single-target constraints */
3487 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
3488 }
3489 }
3490
minmax_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)3491 static void minmax_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
3492 {
3493 bMinMaxConstraint *data = con->data;
3494 bConstraintTarget *ct = targets->first;
3495
3496 /* only evaluate if there is a target */
3497 if (VALID_CONS_TARGET(ct)) {
3498 float obmat[4][4], imat[4][4], tarmat[4][4], tmat[4][4];
3499 float val1, val2;
3500 int index;
3501
3502 copy_m4_m4(obmat, cob->matrix);
3503 copy_m4_m4(tarmat, ct->matrix);
3504
3505 if (data->flag & MINMAX_USEROT) {
3506 /* take rotation of target into account by doing the transaction in target's localspace */
3507 invert_m4_m4(imat, tarmat);
3508 mul_m4_m4m4(tmat, imat, obmat);
3509 copy_m4_m4(obmat, tmat);
3510 unit_m4(tarmat);
3511 }
3512
3513 switch (data->minmaxflag) {
3514 case TRACK_Z:
3515 val1 = tarmat[3][2];
3516 val2 = obmat[3][2] - data->offset;
3517 index = 2;
3518 break;
3519 case TRACK_Y:
3520 val1 = tarmat[3][1];
3521 val2 = obmat[3][1] - data->offset;
3522 index = 1;
3523 break;
3524 case TRACK_X:
3525 val1 = tarmat[3][0];
3526 val2 = obmat[3][0] - data->offset;
3527 index = 0;
3528 break;
3529 case TRACK_nZ:
3530 val2 = tarmat[3][2];
3531 val1 = obmat[3][2] - data->offset;
3532 index = 2;
3533 break;
3534 case TRACK_nY:
3535 val2 = tarmat[3][1];
3536 val1 = obmat[3][1] - data->offset;
3537 index = 1;
3538 break;
3539 case TRACK_nX:
3540 val2 = tarmat[3][0];
3541 val1 = obmat[3][0] - data->offset;
3542 index = 0;
3543 break;
3544 default:
3545 return;
3546 }
3547
3548 if (val1 > val2) {
3549 obmat[3][index] = tarmat[3][index] + data->offset;
3550 if (data->flag & MINMAX_USEROT) {
3551 /* get out of localspace */
3552 mul_m4_m4m4(tmat, ct->matrix, obmat);
3553 copy_m4_m4(cob->matrix, tmat);
3554 }
3555 else {
3556 copy_v3_v3(cob->matrix[3], obmat[3]);
3557 }
3558 }
3559 }
3560 }
3561
3562 static bConstraintTypeInfo CTI_MINMAX = {
3563 CONSTRAINT_TYPE_MINMAX, /* type */
3564 sizeof(bMinMaxConstraint), /* size */
3565 "Floor", /* name */
3566 "bMinMaxConstraint", /* struct name */
3567 NULL, /* free data */
3568 minmax_id_looper, /* id looper */
3569 NULL, /* copy data */
3570 minmax_new_data, /* new data */
3571 minmax_get_tars, /* get constraint targets */
3572 minmax_flush_tars, /* flush constraint targets */
3573 default_get_tarmat, /* get target matrix */
3574 minmax_evaluate, /* evaluate */
3575 };
3576
3577 /* -------- Clamp To ---------- */
3578
clampto_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3579 static void clampto_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3580 {
3581 bClampToConstraint *data = con->data;
3582
3583 /* target only */
3584 func(con, (ID **)&data->tar, false, userdata);
3585 }
3586
clampto_get_tars(bConstraint * con,ListBase * list)3587 static int clampto_get_tars(bConstraint *con, ListBase *list)
3588 {
3589 if (con && list) {
3590 bClampToConstraint *data = con->data;
3591 bConstraintTarget *ct;
3592
3593 /* standard target-getting macro for single-target constraints without subtargets */
3594 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list);
3595
3596 return 1;
3597 }
3598
3599 return 0;
3600 }
3601
clampto_flush_tars(bConstraint * con,ListBase * list,bool no_copy)3602 static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
3603 {
3604 if (con && list) {
3605 bClampToConstraint *data = con->data;
3606 bConstraintTarget *ct = list->first;
3607
3608 /* the following macro is used for all standard single-target constraints */
3609 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
3610 }
3611 }
3612
clampto_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * UNUSED (con),bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))3613 static void clampto_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
3614 bConstraint *UNUSED(con),
3615 bConstraintOb *UNUSED(cob),
3616 bConstraintTarget *ct,
3617 float UNUSED(ctime))
3618 {
3619 /* technically, this isn't really needed for evaluation, but we don't know what else
3620 * might end up calling this...
3621 */
3622 if (ct) {
3623 unit_m4(ct->matrix);
3624 }
3625 }
3626
clampto_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)3627 static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
3628 {
3629 bClampToConstraint *data = con->data;
3630 bConstraintTarget *ct = targets->first;
3631
3632 /* only evaluate if there is a target and it is a curve */
3633 if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_CURVE)) {
3634 float obmat[4][4], ownLoc[3];
3635 float curveMin[3], curveMax[3];
3636 float targetMatrix[4][4];
3637
3638 copy_m4_m4(obmat, cob->matrix);
3639 copy_v3_v3(ownLoc, obmat[3]);
3640
3641 unit_m4(targetMatrix);
3642 INIT_MINMAX(curveMin, curveMax);
3643 /* XXX - don't think this is good calling this here - campbell */
3644 BKE_object_minmax(ct->tar, curveMin, curveMax, true);
3645
3646 /* get targetmatrix */
3647 if (data->tar->runtime.curve_cache && data->tar->runtime.curve_cache->path &&
3648 data->tar->runtime.curve_cache->path->data) {
3649 float vec[4], dir[3], totmat[4][4];
3650 float curvetime;
3651 short clamp_axis;
3652
3653 /* find best position on curve */
3654 /* 1. determine which axis to sample on? */
3655 if (data->flag == CLAMPTO_AUTO) {
3656 float size[3];
3657 sub_v3_v3v3(size, curveMax, curveMin);
3658
3659 /* find axis along which the bounding box has the greatest
3660 * extent. Otherwise, default to the x-axis, as that is quite
3661 * frequently used.
3662 */
3663 if ((size[2] > size[0]) && (size[2] > size[1])) {
3664 clamp_axis = CLAMPTO_Z - 1;
3665 }
3666 else if ((size[1] > size[0]) && (size[1] > size[2])) {
3667 clamp_axis = CLAMPTO_Y - 1;
3668 }
3669 else {
3670 clamp_axis = CLAMPTO_X - 1;
3671 }
3672 }
3673 else {
3674 clamp_axis = data->flag - 1;
3675 }
3676
3677 /* 2. determine position relative to curve on a 0-1 scale based on bounding box */
3678 if (data->flag2 & CLAMPTO_CYCLIC) {
3679 /* cyclic, so offset within relative bounding box is used */
3680 float len = (curveMax[clamp_axis] - curveMin[clamp_axis]);
3681 float offset;
3682
3683 /* check to make sure len is not so close to zero that it'll cause errors */
3684 if (IS_EQF(len, 0.0f) == false) {
3685 /* find bounding-box range where target is located */
3686 if (ownLoc[clamp_axis] < curveMin[clamp_axis]) {
3687 /* bounding-box range is before */
3688 offset = curveMin[clamp_axis] -
3689 ceilf((curveMin[clamp_axis] - ownLoc[clamp_axis]) / len) * len;
3690
3691 /* Now, we calculate as per normal,
3692 * except using offset instead of curveMin[clamp_axis]. */
3693 curvetime = (ownLoc[clamp_axis] - offset) / (len);
3694 }
3695 else if (ownLoc[clamp_axis] > curveMax[clamp_axis]) {
3696 /* bounding-box range is after */
3697 offset = curveMax[clamp_axis] +
3698 (int)((ownLoc[clamp_axis] - curveMax[clamp_axis]) / len) * len;
3699
3700 /* Now, we calculate as per normal,
3701 * except using offset instead of curveMax[clamp_axis]. */
3702 curvetime = (ownLoc[clamp_axis] - offset) / (len);
3703 }
3704 else {
3705 /* as the location falls within bounds, just calculate */
3706 curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) / (len);
3707 }
3708 }
3709 else {
3710 /* as length is close to zero, curvetime by default should be 0 (i.e. the start) */
3711 curvetime = 0.0f;
3712 }
3713 }
3714 else {
3715 /* no cyclic, so position is clamped to within the bounding box */
3716 if (ownLoc[clamp_axis] <= curveMin[clamp_axis]) {
3717 curvetime = 0.0f;
3718 }
3719 else if (ownLoc[clamp_axis] >= curveMax[clamp_axis]) {
3720 curvetime = 1.0f;
3721 }
3722 else if (IS_EQF((curveMax[clamp_axis] - curveMin[clamp_axis]), 0.0f) == false) {
3723 curvetime = (ownLoc[clamp_axis] - curveMin[clamp_axis]) /
3724 (curveMax[clamp_axis] - curveMin[clamp_axis]);
3725 }
3726 else {
3727 curvetime = 0.0f;
3728 }
3729 }
3730
3731 /* 3. position on curve */
3732 if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL, NULL)) {
3733 unit_m4(totmat);
3734 copy_v3_v3(totmat[3], vec);
3735
3736 mul_m4_m4m4(targetMatrix, ct->tar->obmat, totmat);
3737 }
3738 }
3739
3740 /* obtain final object position */
3741 copy_v3_v3(cob->matrix[3], targetMatrix[3]);
3742 }
3743 }
3744
3745 static bConstraintTypeInfo CTI_CLAMPTO = {
3746 CONSTRAINT_TYPE_CLAMPTO, /* type */
3747 sizeof(bClampToConstraint), /* size */
3748 "Clamp To", /* name */
3749 "bClampToConstraint", /* struct name */
3750 NULL, /* free data */
3751 clampto_id_looper, /* id looper */
3752 NULL, /* copy data */
3753 NULL, /* new data */
3754 clampto_get_tars, /* get constraint targets */
3755 clampto_flush_tars, /* flush constraint targets */
3756 clampto_get_tarmat, /* get target matrix */
3757 clampto_evaluate, /* evaluate */
3758 };
3759
3760 /* ---------- Transform Constraint ----------- */
3761
transform_new_data(void * cdata)3762 static void transform_new_data(void *cdata)
3763 {
3764 bTransformConstraint *data = (bTransformConstraint *)cdata;
3765
3766 data->map[0] = 0;
3767 data->map[1] = 1;
3768 data->map[2] = 2;
3769
3770 for (int i = 0; i < 3; i++) {
3771 data->from_min_scale[i] = data->from_max_scale[i] = 1.0f;
3772 data->to_min_scale[i] = data->to_max_scale[i] = 1.0f;
3773 }
3774 }
3775
transform_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3776 static void transform_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3777 {
3778 bTransformConstraint *data = con->data;
3779
3780 /* target only */
3781 func(con, (ID **)&data->tar, false, userdata);
3782 }
3783
transform_get_tars(bConstraint * con,ListBase * list)3784 static int transform_get_tars(bConstraint *con, ListBase *list)
3785 {
3786 if (con && list) {
3787 bTransformConstraint *data = con->data;
3788 bConstraintTarget *ct;
3789
3790 /* standard target-getting macro for single-target constraints */
3791 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
3792
3793 return 1;
3794 }
3795
3796 return 0;
3797 }
3798
transform_flush_tars(bConstraint * con,ListBase * list,bool no_copy)3799 static void transform_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
3800 {
3801 if (con && list) {
3802 bTransformConstraint *data = con->data;
3803 bConstraintTarget *ct = list->first;
3804
3805 /* the following macro is used for all standard single-target constraints */
3806 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
3807 }
3808 }
3809
transform_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)3810 static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
3811 {
3812 bTransformConstraint *data = con->data;
3813 bConstraintTarget *ct = targets->first;
3814
3815 /* only evaluate if there is a target */
3816 if (VALID_CONS_TARGET(ct)) {
3817 float *from_min, *from_max, *to_min, *to_max;
3818 float loc[3], rot[3][3], oldeul[3], size[3];
3819 float newloc[3], newrot[3][3], neweul[3], newsize[3];
3820 float dbuf[4], sval[3];
3821 float *const dvec = dbuf + 1;
3822
3823 /* obtain target effect */
3824 switch (data->from) {
3825 case TRANS_SCALE:
3826 mat4_to_size(dvec, ct->matrix);
3827
3828 if (is_negative_m4(ct->matrix)) {
3829 /* Bugfix T27886: (this is a limitation that riggers will have to live with for now).
3830 * We can't be sure which axis/axes are negative,
3831 * though we know that something is negative.
3832 * Assume we don't care about negativity of separate axes. */
3833 negate_v3(dvec);
3834 }
3835 from_min = data->from_min_scale;
3836 from_max = data->from_max_scale;
3837 break;
3838 case TRANS_ROTATION:
3839 BKE_driver_target_matrix_to_rot_channels(
3840 ct->matrix, cob->rotOrder, data->from_rotation_mode, -1, true, dbuf);
3841 from_min = data->from_min_rot;
3842 from_max = data->from_max_rot;
3843 break;
3844 case TRANS_LOCATION:
3845 default:
3846 copy_v3_v3(dvec, ct->matrix[3]);
3847 from_min = data->from_min;
3848 from_max = data->from_max;
3849 break;
3850 }
3851
3852 /* Select the output Euler rotation order, defaulting to the owner. */
3853 short rot_order = cob->rotOrder;
3854
3855 if (data->to == TRANS_ROTATION && data->to_euler_order != CONSTRAINT_EULER_AUTO) {
3856 rot_order = data->to_euler_order;
3857 }
3858
3859 /* extract components of owner's matrix */
3860 mat4_to_loc_rot_size(loc, rot, size, cob->matrix);
3861
3862 /* determine where in range current transforms lie */
3863 if (data->expo) {
3864 for (int i = 0; i < 3; i++) {
3865 if (from_max[i] - from_min[i]) {
3866 sval[i] = (dvec[i] - from_min[i]) / (from_max[i] - from_min[i]);
3867 }
3868 else {
3869 sval[i] = 0.0f;
3870 }
3871 }
3872 }
3873 else {
3874 /* clamp transforms out of range */
3875 for (int i = 0; i < 3; i++) {
3876 CLAMP(dvec[i], from_min[i], from_max[i]);
3877 if (from_max[i] - from_min[i]) {
3878 sval[i] = (dvec[i] - from_min[i]) / (from_max[i] - from_min[i]);
3879 }
3880 else {
3881 sval[i] = 0.0f;
3882 }
3883 }
3884 }
3885
3886 /* apply transforms */
3887 switch (data->to) {
3888 case TRANS_SCALE:
3889 to_min = data->to_min_scale;
3890 to_max = data->to_max_scale;
3891 for (int i = 0; i < 3; i++) {
3892 newsize[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
3893 }
3894 switch (data->mix_mode_scale) {
3895 case TRANS_MIXSCALE_MULTIPLY:
3896 mul_v3_v3(size, newsize);
3897 break;
3898 case TRANS_MIXSCALE_REPLACE:
3899 default:
3900 copy_v3_v3(size, newsize);
3901 break;
3902 }
3903 break;
3904 case TRANS_ROTATION:
3905 to_min = data->to_min_rot;
3906 to_max = data->to_max_rot;
3907 for (int i = 0; i < 3; i++) {
3908 neweul[i] = to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i]));
3909 }
3910 switch (data->mix_mode_rot) {
3911 case TRANS_MIXROT_REPLACE:
3912 eulO_to_mat3(rot, neweul, rot_order);
3913 break;
3914 case TRANS_MIXROT_BEFORE:
3915 eulO_to_mat3(newrot, neweul, rot_order);
3916 mul_m3_m3m3(rot, newrot, rot);
3917 break;
3918 case TRANS_MIXROT_AFTER:
3919 eulO_to_mat3(newrot, neweul, rot_order);
3920 mul_m3_m3m3(rot, rot, newrot);
3921 break;
3922 case TRANS_MIXROT_ADD:
3923 default:
3924 mat3_to_eulO(oldeul, rot_order, rot);
3925 add_v3_v3(neweul, oldeul);
3926 eulO_to_mat3(rot, neweul, rot_order);
3927 break;
3928 }
3929 break;
3930 case TRANS_LOCATION:
3931 default:
3932 to_min = data->to_min;
3933 to_max = data->to_max;
3934 for (int i = 0; i < 3; i++) {
3935 newloc[i] = (to_min[i] + (sval[(int)data->map[i]] * (to_max[i] - to_min[i])));
3936 }
3937 switch (data->mix_mode_loc) {
3938 case TRANS_MIXLOC_REPLACE:
3939 copy_v3_v3(loc, newloc);
3940 break;
3941 case TRANS_MIXLOC_ADD:
3942 default:
3943 add_v3_v3(loc, newloc);
3944 break;
3945 }
3946 break;
3947 }
3948
3949 /* apply to matrix */
3950 loc_rot_size_to_mat4(cob->matrix, loc, rot, size);
3951 }
3952 }
3953
3954 static bConstraintTypeInfo CTI_TRANSFORM = {
3955 CONSTRAINT_TYPE_TRANSFORM, /* type */
3956 sizeof(bTransformConstraint), /* size */
3957 "Transformation", /* name */
3958 "bTransformConstraint", /* struct name */
3959 NULL, /* free data */
3960 transform_id_looper, /* id looper */
3961 NULL, /* copy data */
3962 transform_new_data, /* new data */
3963 transform_get_tars, /* get constraint targets */
3964 transform_flush_tars, /* flush constraint targets */
3965 default_get_tarmat, /* get a target matrix */
3966 transform_evaluate, /* evaluate */
3967 };
3968
3969 /* ---------- Shrinkwrap Constraint ----------- */
3970
shrinkwrap_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)3971 static void shrinkwrap_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
3972 {
3973 bShrinkwrapConstraint *data = con->data;
3974
3975 /* target only */
3976 func(con, (ID **)&data->target, false, userdata);
3977 }
3978
shrinkwrap_new_data(void * cdata)3979 static void shrinkwrap_new_data(void *cdata)
3980 {
3981 bShrinkwrapConstraint *data = (bShrinkwrapConstraint *)cdata;
3982
3983 data->projAxis = OB_POSZ;
3984 data->projAxisSpace = CONSTRAINT_SPACE_LOCAL;
3985 }
3986
shrinkwrap_get_tars(bConstraint * con,ListBase * list)3987 static int shrinkwrap_get_tars(bConstraint *con, ListBase *list)
3988 {
3989 if (con && list) {
3990 bShrinkwrapConstraint *data = con->data;
3991 bConstraintTarget *ct;
3992
3993 SINGLETARGETNS_GET_TARS(con, data->target, ct, list);
3994
3995 return 1;
3996 }
3997
3998 return 0;
3999 }
4000
shrinkwrap_flush_tars(bConstraint * con,ListBase * list,bool no_copy)4001 static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
4002 {
4003 if (con && list) {
4004 bShrinkwrapConstraint *data = con->data;
4005 bConstraintTarget *ct = list->first;
4006
4007 SINGLETARGETNS_FLUSH_TARS(con, data->target, ct, list, no_copy);
4008 }
4009 }
4010
shrinkwrap_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * con,bConstraintOb * cob,bConstraintTarget * ct,float UNUSED (ctime))4011 static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
4012 bConstraint *con,
4013 bConstraintOb *cob,
4014 bConstraintTarget *ct,
4015 float UNUSED(ctime))
4016 {
4017 bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *)con->data;
4018
4019 if (VALID_CONS_TARGET(ct) && (ct->tar->type == OB_MESH)) {
4020
4021 bool fail = false;
4022 float co[3] = {0.0f, 0.0f, 0.0f};
4023 bool track_normal = false;
4024 float track_no[3] = {0.0f, 0.0f, 0.0f};
4025
4026 SpaceTransform transform;
4027 Mesh *target_eval = BKE_object_get_evaluated_mesh(ct->tar);
4028
4029 copy_m4_m4(ct->matrix, cob->matrix);
4030
4031 bool do_track_normal = (scon->flag & CON_SHRINKWRAP_TRACK_NORMAL) != 0;
4032 ShrinkwrapTreeData tree;
4033
4034 if (BKE_shrinkwrap_init_tree(
4035 &tree, target_eval, scon->shrinkType, scon->shrinkMode, do_track_normal)) {
4036 BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->obmat);
4037
4038 switch (scon->shrinkType) {
4039 case MOD_SHRINKWRAP_NEAREST_SURFACE:
4040 case MOD_SHRINKWRAP_NEAREST_VERTEX:
4041 case MOD_SHRINKWRAP_TARGET_PROJECT: {
4042 BVHTreeNearest nearest;
4043
4044 nearest.index = -1;
4045 nearest.dist_sq = FLT_MAX;
4046
4047 BLI_space_transform_apply(&transform, co);
4048
4049 BKE_shrinkwrap_find_nearest_surface(&tree, &nearest, co, scon->shrinkType);
4050
4051 if (nearest.index < 0) {
4052 fail = true;
4053 break;
4054 }
4055
4056 if (scon->shrinkType != MOD_SHRINKWRAP_NEAREST_VERTEX) {
4057 if (do_track_normal) {
4058 track_normal = true;
4059 BKE_shrinkwrap_compute_smooth_normal(
4060 &tree, NULL, nearest.index, nearest.co, nearest.no, track_no);
4061 BLI_space_transform_invert_normal(&transform, track_no);
4062 }
4063
4064 BKE_shrinkwrap_snap_point_to_surface(&tree,
4065 NULL,
4066 scon->shrinkMode,
4067 nearest.index,
4068 nearest.co,
4069 nearest.no,
4070 scon->dist,
4071 co,
4072 co);
4073 }
4074 else {
4075 const float dist = len_v3v3(co, nearest.co);
4076
4077 if (dist != 0.0f) {
4078 interp_v3_v3v3(
4079 co, co, nearest.co, (dist - scon->dist) / dist); /* linear interpolation */
4080 }
4081 }
4082
4083 BLI_space_transform_invert(&transform, co);
4084 break;
4085 }
4086 case MOD_SHRINKWRAP_PROJECT: {
4087 BVHTreeRayHit hit;
4088
4089 float mat[4][4];
4090 float no[3] = {0.0f, 0.0f, 0.0f};
4091
4092 /* TODO should use FLT_MAX.. but normal projection doenst yet supports it */
4093 hit.index = -1;
4094 hit.dist = (scon->projLimit == 0.0f) ? BVH_RAYCAST_DIST_MAX : scon->projLimit;
4095
4096 switch (scon->projAxis) {
4097 case OB_POSX:
4098 case OB_POSY:
4099 case OB_POSZ:
4100 no[scon->projAxis - OB_POSX] = 1.0f;
4101 break;
4102 case OB_NEGX:
4103 case OB_NEGY:
4104 case OB_NEGZ:
4105 no[scon->projAxis - OB_NEGX] = -1.0f;
4106 break;
4107 }
4108
4109 /* Transform normal into requested space */
4110 /* Note that in this specific case, we need to keep scaling in non-parented 'local2world'
4111 * object case, because SpaceTransform also takes it into account when handling normals.
4112 * See T42447. */
4113 unit_m4(mat);
4114 BKE_constraint_mat_convertspace(
4115 cob->ob, cob->pchan, mat, CONSTRAINT_SPACE_LOCAL, scon->projAxisSpace, true);
4116 invert_m4(mat);
4117 mul_mat3_m4_v3(mat, no);
4118
4119 if (normalize_v3(no) < FLT_EPSILON) {
4120 fail = true;
4121 break;
4122 }
4123
4124 char cull_mode = scon->flag & CON_SHRINKWRAP_PROJECT_CULL_MASK;
4125
4126 BKE_shrinkwrap_project_normal(cull_mode, co, no, 0.0f, &transform, &tree, &hit);
4127
4128 if (scon->flag & CON_SHRINKWRAP_PROJECT_OPPOSITE) {
4129 float inv_no[3];
4130 negate_v3_v3(inv_no, no);
4131
4132 if ((scon->flag & CON_SHRINKWRAP_PROJECT_INVERT_CULL) && (cull_mode != 0)) {
4133 cull_mode ^= CON_SHRINKWRAP_PROJECT_CULL_MASK;
4134 }
4135
4136 BKE_shrinkwrap_project_normal(cull_mode, co, inv_no, 0.0f, &transform, &tree, &hit);
4137 }
4138
4139 if (hit.index < 0) {
4140 fail = true;
4141 break;
4142 }
4143
4144 if (do_track_normal) {
4145 track_normal = true;
4146 BKE_shrinkwrap_compute_smooth_normal(
4147 &tree, &transform, hit.index, hit.co, hit.no, track_no);
4148 }
4149
4150 BKE_shrinkwrap_snap_point_to_surface(
4151 &tree, &transform, scon->shrinkMode, hit.index, hit.co, hit.no, scon->dist, co, co);
4152 break;
4153 }
4154 }
4155
4156 BKE_shrinkwrap_free_tree(&tree);
4157
4158 if (fail == true) {
4159 /* Don't move the point */
4160 zero_v3(co);
4161 }
4162
4163 /* co is in local object coordinates, change it to global and update target position */
4164 mul_m4_v3(cob->matrix, co);
4165 copy_v3_v3(ct->matrix[3], co);
4166
4167 if (track_normal) {
4168 mul_mat3_m4_v3(cob->matrix, track_no);
4169 damptrack_do_transform(ct->matrix, track_no, scon->trackAxis);
4170 }
4171 }
4172 }
4173 }
4174
shrinkwrap_evaluate(bConstraint * UNUSED (con),bConstraintOb * cob,ListBase * targets)4175 static void shrinkwrap_evaluate(bConstraint *UNUSED(con), bConstraintOb *cob, ListBase *targets)
4176 {
4177 bConstraintTarget *ct = targets->first;
4178
4179 /* only evaluate if there is a target */
4180 if (VALID_CONS_TARGET(ct)) {
4181 copy_m4_m4(cob->matrix, ct->matrix);
4182 }
4183 }
4184
4185 static bConstraintTypeInfo CTI_SHRINKWRAP = {
4186 CONSTRAINT_TYPE_SHRINKWRAP, /* type */
4187 sizeof(bShrinkwrapConstraint), /* size */
4188 "Shrinkwrap", /* name */
4189 "bShrinkwrapConstraint", /* struct name */
4190 NULL, /* free data */
4191 shrinkwrap_id_looper, /* id looper */
4192 NULL, /* copy data */
4193 shrinkwrap_new_data, /* new data */
4194 shrinkwrap_get_tars, /* get constraint targets */
4195 shrinkwrap_flush_tars, /* flush constraint targets */
4196 shrinkwrap_get_tarmat, /* get a target matrix */
4197 shrinkwrap_evaluate, /* evaluate */
4198 };
4199
4200 /* --------- Damped Track ---------- */
4201
damptrack_new_data(void * cdata)4202 static void damptrack_new_data(void *cdata)
4203 {
4204 bDampTrackConstraint *data = (bDampTrackConstraint *)cdata;
4205
4206 data->trackflag = TRACK_Y;
4207 }
4208
damptrack_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)4209 static void damptrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4210 {
4211 bDampTrackConstraint *data = con->data;
4212
4213 /* target only */
4214 func(con, (ID **)&data->tar, false, userdata);
4215 }
4216
damptrack_get_tars(bConstraint * con,ListBase * list)4217 static int damptrack_get_tars(bConstraint *con, ListBase *list)
4218 {
4219 if (con && list) {
4220 bDampTrackConstraint *data = con->data;
4221 bConstraintTarget *ct;
4222
4223 /* the following macro is used for all standard single-target constraints */
4224 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
4225
4226 return 1;
4227 }
4228
4229 return 0;
4230 }
4231
damptrack_flush_tars(bConstraint * con,ListBase * list,bool no_copy)4232 static void damptrack_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
4233 {
4234 if (con && list) {
4235 bDampTrackConstraint *data = con->data;
4236 bConstraintTarget *ct = list->first;
4237
4238 /* the following macro is used for all standard single-target constraints */
4239 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
4240 }
4241 }
4242
4243 /* array of direction vectors for the tracking flags */
4244 static const float track_dir_vecs[6][3] = {
4245 {+1, 0, 0},
4246 {0, +1, 0},
4247 {0, 0, +1}, /* TRACK_X, TRACK_Y, TRACK_Z */
4248 {-1, 0, 0},
4249 {0, -1, 0},
4250 {0, 0, -1} /* TRACK_NX, TRACK_NY, TRACK_NZ */
4251 };
4252
damptrack_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)4253 static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
4254 {
4255 bDampTrackConstraint *data = con->data;
4256 bConstraintTarget *ct = targets->first;
4257
4258 if (VALID_CONS_TARGET(ct)) {
4259 float tarvec[3];
4260
4261 /* find the (unit) direction vector going from the owner to the target */
4262 sub_v3_v3v3(tarvec, ct->matrix[3], cob->matrix[3]);
4263
4264 damptrack_do_transform(cob->matrix, tarvec, data->trackflag);
4265 }
4266 }
4267
damptrack_do_transform(float matrix[4][4],const float tarvec_in[3],int track_axis)4268 static void damptrack_do_transform(float matrix[4][4], const float tarvec_in[3], int track_axis)
4269 {
4270 /* find the (unit) direction vector going from the owner to the target */
4271 float tarvec[3];
4272
4273 if (normalize_v3_v3(tarvec, tarvec_in) != 0.0f) {
4274 float obvec[3], obloc[3];
4275 float raxis[3], rangle;
4276 float rmat[3][3], tmat[4][4];
4277
4278 /* find the (unit) direction that the axis we're interested in currently points
4279 * - mul_mat3_m4_v3() only takes the 3x3 (rotation+scaling) components of the 4x4 matrix
4280 * - the normalization step at the end should take care of any unwanted scaling
4281 * left over in the 3x3 matrix we used
4282 */
4283 copy_v3_v3(obvec, track_dir_vecs[track_axis]);
4284 mul_mat3_m4_v3(matrix, obvec);
4285
4286 if (normalize_v3(obvec) == 0.0f) {
4287 /* exceptional case - just use the track vector as appropriate */
4288 copy_v3_v3(obvec, track_dir_vecs[track_axis]);
4289 }
4290
4291 copy_v3_v3(obloc, matrix[3]);
4292
4293 /* determine the axis-angle rotation, which represents the smallest possible rotation
4294 * between the two rotation vectors (i.e. the 'damping' referred to in the name)
4295 * - we take this to be the rotation around the normal axis/vector to the plane defined
4296 * by the current and destination vectors, which will 'map' the current axis to the
4297 * destination vector
4298 * - the min/max wrappers around (obvec . tarvec) result (stored temporarily in rangle)
4299 * are used to ensure that the smallest angle is chosen
4300 */
4301 cross_v3_v3v3_hi_prec(raxis, obvec, tarvec);
4302
4303 rangle = dot_v3v3(obvec, tarvec);
4304 rangle = acosf(max_ff(-1.0f, min_ff(1.0f, rangle)));
4305
4306 /* construct rotation matrix from the axis-angle rotation found above
4307 * - this call takes care to make sure that the axis provided is a unit vector first
4308 */
4309 float norm = normalize_v3(raxis);
4310
4311 if (norm < FLT_EPSILON) {
4312 /* if dot product is nonzero, while cross is zero, we have two opposite vectors!
4313 * - this is an ambiguity in the math that needs to be resolved arbitrarily,
4314 * or there will be a case where damped track strangely does nothing
4315 * - to do that, rotate around a different local axis
4316 */
4317 float tmpvec[3];
4318
4319 if (fabsf(rangle) < M_PI - 0.01f) {
4320 return;
4321 }
4322
4323 rangle = M_PI;
4324 copy_v3_v3(tmpvec, track_dir_vecs[(track_axis + 1) % 6]);
4325 mul_mat3_m4_v3(matrix, tmpvec);
4326 cross_v3_v3v3(raxis, obvec, tmpvec);
4327
4328 if (normalize_v3(raxis) == 0.0f) {
4329 return;
4330 }
4331 }
4332 else if (norm < 0.1f) {
4333 /* near 0 and Pi arcsin has way better precision than arccos */
4334 rangle = (rangle > M_PI_2) ? M_PI - asinf(norm) : asinf(norm);
4335 }
4336
4337 axis_angle_normalized_to_mat3(rmat, raxis, rangle);
4338
4339 /* rotate the owner in the way defined by this rotation matrix, then reapply the location since
4340 * we may have destroyed that in the process of multiplying the matrix
4341 */
4342 unit_m4(tmat);
4343 mul_m4_m3m4(tmat, rmat, matrix); /* m1, m3, m2 */
4344
4345 copy_m4_m4(matrix, tmat);
4346 copy_v3_v3(matrix[3], obloc);
4347 }
4348 }
4349
4350 static bConstraintTypeInfo CTI_DAMPTRACK = {
4351 CONSTRAINT_TYPE_DAMPTRACK, /* type */
4352 sizeof(bDampTrackConstraint), /* size */
4353 "Damped Track", /* name */
4354 "bDampTrackConstraint", /* struct name */
4355 NULL, /* free data */
4356 damptrack_id_looper, /* id looper */
4357 NULL, /* copy data */
4358 damptrack_new_data, /* new data */
4359 damptrack_get_tars, /* get constraint targets */
4360 damptrack_flush_tars, /* flush constraint targets */
4361 default_get_tarmat, /* get target matrix */
4362 damptrack_evaluate, /* evaluate */
4363 };
4364
4365 /* ----------- Spline IK ------------ */
4366
splineik_free(bConstraint * con)4367 static void splineik_free(bConstraint *con)
4368 {
4369 bSplineIKConstraint *data = con->data;
4370
4371 /* binding array */
4372 if (data->points) {
4373 MEM_freeN(data->points);
4374 }
4375 }
4376
splineik_copy(bConstraint * con,bConstraint * srccon)4377 static void splineik_copy(bConstraint *con, bConstraint *srccon)
4378 {
4379 bSplineIKConstraint *src = srccon->data;
4380 bSplineIKConstraint *dst = con->data;
4381
4382 /* copy the binding array */
4383 dst->points = MEM_dupallocN(src->points);
4384 }
4385
splineik_new_data(void * cdata)4386 static void splineik_new_data(void *cdata)
4387 {
4388 bSplineIKConstraint *data = (bSplineIKConstraint *)cdata;
4389
4390 data->chainlen = 1;
4391 data->bulge = 1.0;
4392 data->bulge_max = 1.0f;
4393 data->bulge_min = 1.0f;
4394
4395 data->yScaleMode = CONSTRAINT_SPLINEIK_YS_FIT_CURVE;
4396 data->flag = CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE;
4397 }
4398
splineik_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)4399 static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4400 {
4401 bSplineIKConstraint *data = con->data;
4402
4403 /* target only */
4404 func(con, (ID **)&data->tar, false, userdata);
4405 }
4406
splineik_get_tars(bConstraint * con,ListBase * list)4407 static int splineik_get_tars(bConstraint *con, ListBase *list)
4408 {
4409 if (con && list) {
4410 bSplineIKConstraint *data = con->data;
4411 bConstraintTarget *ct;
4412
4413 /* standard target-getting macro for single-target constraints without subtargets */
4414 SINGLETARGETNS_GET_TARS(con, data->tar, ct, list);
4415
4416 return 1;
4417 }
4418
4419 return 0;
4420 }
4421
splineik_flush_tars(bConstraint * con,ListBase * list,bool no_copy)4422 static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
4423 {
4424 if (con && list) {
4425 bSplineIKConstraint *data = con->data;
4426 bConstraintTarget *ct = list->first;
4427
4428 /* the following macro is used for all standard single-target constraints */
4429 SINGLETARGETNS_FLUSH_TARS(con, data->tar, ct, list, no_copy);
4430 }
4431 }
4432
splineik_get_tarmat(struct Depsgraph * UNUSED (depsgraph),bConstraint * UNUSED (con),bConstraintOb * UNUSED (cob),bConstraintTarget * ct,float UNUSED (ctime))4433 static void splineik_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
4434 bConstraint *UNUSED(con),
4435 bConstraintOb *UNUSED(cob),
4436 bConstraintTarget *ct,
4437 float UNUSED(ctime))
4438 {
4439 /* technically, this isn't really needed for evaluation, but we don't know what else
4440 * might end up calling this...
4441 */
4442 if (ct) {
4443 unit_m4(ct->matrix);
4444 }
4445 }
4446
4447 static bConstraintTypeInfo CTI_SPLINEIK = {
4448 CONSTRAINT_TYPE_SPLINEIK, /* type */
4449 sizeof(bSplineIKConstraint), /* size */
4450 "Spline IK", /* name */
4451 "bSplineIKConstraint", /* struct name */
4452 splineik_free, /* free data */
4453 splineik_id_looper, /* id looper */
4454 splineik_copy, /* copy data */
4455 splineik_new_data, /* new data */
4456 splineik_get_tars, /* get constraint targets */
4457 splineik_flush_tars, /* flush constraint targets */
4458 splineik_get_tarmat, /* get target matrix */
4459 NULL, /* evaluate - solved as separate loop */
4460 };
4461
4462 /* ----------- Pivot ------------- */
4463
pivotcon_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)4464 static void pivotcon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4465 {
4466 bPivotConstraint *data = con->data;
4467
4468 /* target only */
4469 func(con, (ID **)&data->tar, false, userdata);
4470 }
4471
pivotcon_get_tars(bConstraint * con,ListBase * list)4472 static int pivotcon_get_tars(bConstraint *con, ListBase *list)
4473 {
4474 if (con && list) {
4475 bPivotConstraint *data = con->data;
4476 bConstraintTarget *ct;
4477
4478 /* standard target-getting macro for single-target constraints */
4479 SINGLETARGET_GET_TARS(con, data->tar, data->subtarget, ct, list);
4480
4481 return 1;
4482 }
4483
4484 return 0;
4485 }
4486
pivotcon_flush_tars(bConstraint * con,ListBase * list,bool no_copy)4487 static void pivotcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
4488 {
4489 if (con && list) {
4490 bPivotConstraint *data = con->data;
4491 bConstraintTarget *ct = list->first;
4492
4493 /* the following macro is used for all standard single-target constraints */
4494 SINGLETARGET_FLUSH_TARS(con, data->tar, data->subtarget, ct, list, no_copy);
4495 }
4496 }
4497
pivotcon_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)4498 static void pivotcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
4499 {
4500 bPivotConstraint *data = con->data;
4501 bConstraintTarget *ct = targets->first;
4502
4503 float pivot[3], vec[3];
4504 float rotMat[3][3];
4505
4506 /* pivot correction */
4507 float axis[3], angle;
4508
4509 /* firstly, check if pivoting should take place based on the current rotation */
4510 if (data->rotAxis != PIVOTCON_AXIS_NONE) {
4511 float rot[3];
4512
4513 /* extract euler-rotation of target */
4514 mat4_to_eulO(rot, cob->rotOrder, cob->matrix);
4515
4516 /* check which range might be violated */
4517 if (data->rotAxis < PIVOTCON_AXIS_X) {
4518 /* negative rotations (data->rotAxis = 0 -> 2) */
4519 if (rot[data->rotAxis] > 0.0f) {
4520 return;
4521 }
4522 }
4523 else {
4524 /* positive rotations (data->rotAxis = 3 -> 5 */
4525 if (rot[data->rotAxis - PIVOTCON_AXIS_X] < 0.0f) {
4526 return;
4527 }
4528 }
4529 }
4530
4531 /* find the pivot-point to use */
4532 if (VALID_CONS_TARGET(ct)) {
4533 /* apply offset to target location */
4534 add_v3_v3v3(pivot, ct->matrix[3], data->offset);
4535 }
4536 else {
4537 /* no targets to worry about... */
4538 if ((data->flag & PIVOTCON_FLAG_OFFSET_ABS) == 0) {
4539 /* offset is relative to owner */
4540 add_v3_v3v3(pivot, cob->matrix[3], data->offset);
4541 }
4542 else {
4543 /* directly use the 'offset' specified as an absolute position instead */
4544 copy_v3_v3(pivot, data->offset);
4545 }
4546 }
4547
4548 /* get rotation matrix representing the rotation of the owner */
4549 /* TODO: perhaps we might want to include scaling based on the pivot too? */
4550 copy_m3_m4(rotMat, cob->matrix);
4551 normalize_m3(rotMat);
4552
4553 /* correct the pivot by the rotation axis otherwise the pivot translates when it shouldnt */
4554 mat3_normalized_to_axis_angle(axis, &angle, rotMat);
4555 if (angle) {
4556 float dvec[3];
4557 sub_v3_v3v3(vec, pivot, cob->matrix[3]);
4558 project_v3_v3v3(dvec, vec, axis);
4559 sub_v3_v3(pivot, dvec);
4560 }
4561
4562 /* perform the pivoting... */
4563 /* 1. take the vector from owner to the pivot */
4564 sub_v3_v3v3(vec, cob->matrix[3], pivot);
4565 /* 2. rotate this vector by the rotation of the object... */
4566 mul_m3_v3(rotMat, vec);
4567 /* 3. make the rotation in terms of the pivot now */
4568 add_v3_v3v3(cob->matrix[3], pivot, vec);
4569 }
4570
4571 static bConstraintTypeInfo CTI_PIVOT = {
4572 CONSTRAINT_TYPE_PIVOT, /* type */
4573 sizeof(bPivotConstraint), /* size */
4574 "Pivot", /* name */
4575 "bPivotConstraint", /* struct name */
4576 NULL, /* free data */
4577 pivotcon_id_looper, /* id looper */
4578 NULL, /* copy data */
4579 NULL,
4580 /* new data */ /* XXX: might be needed to get 'normal' pivot behavior... */
4581 pivotcon_get_tars, /* get constraint targets */
4582 pivotcon_flush_tars, /* flush constraint targets */
4583 default_get_tarmat, /* get target matrix */
4584 pivotcon_evaluate, /* evaluate */
4585 };
4586
4587 /* ----------- Follow Track ------------- */
4588
followtrack_new_data(void * cdata)4589 static void followtrack_new_data(void *cdata)
4590 {
4591 bFollowTrackConstraint *data = (bFollowTrackConstraint *)cdata;
4592
4593 data->clip = NULL;
4594 data->flag |= FOLLOWTRACK_ACTIVECLIP;
4595 }
4596
followtrack_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)4597 static void followtrack_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
4598 {
4599 bFollowTrackConstraint *data = con->data;
4600
4601 func(con, (ID **)&data->clip, true, userdata);
4602 func(con, (ID **)&data->camera, false, userdata);
4603 func(con, (ID **)&data->depth_ob, false, userdata);
4604 }
4605
followtrack_tracking_clip_get(bConstraint * con,bConstraintOb * cob)4606 static MovieClip *followtrack_tracking_clip_get(bConstraint *con, bConstraintOb *cob)
4607 {
4608 bFollowTrackConstraint *data = con->data;
4609
4610 if (data->flag & FOLLOWTRACK_ACTIVECLIP) {
4611 Scene *scene = cob->scene;
4612 return scene->clip;
4613 }
4614
4615 return data->clip;
4616 }
4617
followtrack_tracking_object_get(bConstraint * con,bConstraintOb * cob)4618 static MovieTrackingObject *followtrack_tracking_object_get(bConstraint *con, bConstraintOb *cob)
4619 {
4620 MovieClip *clip = followtrack_tracking_clip_get(con, cob);
4621 MovieTracking *tracking = &clip->tracking;
4622 bFollowTrackConstraint *data = con->data;
4623
4624 if (data->object[0]) {
4625 return BKE_tracking_object_get_named(tracking, data->object);
4626 }
4627 return BKE_tracking_object_get_camera(tracking);
4628 }
4629
followtrack_camera_object_get(bConstraint * con,bConstraintOb * cob)4630 static Object *followtrack_camera_object_get(bConstraint *con, bConstraintOb *cob)
4631 {
4632 bFollowTrackConstraint *data = con->data;
4633
4634 if (data->camera == NULL) {
4635 Scene *scene = cob->scene;
4636 return scene->camera;
4637 }
4638
4639 return data->camera;
4640 }
4641
4642 typedef struct FollowTrackContext {
4643 int flag;
4644 int frame_method;
4645
4646 Depsgraph *depsgraph;
4647 Scene *scene;
4648
4649 MovieClip *clip;
4650 Object *camera_object;
4651 Object *depth_object;
4652
4653 MovieTracking *tracking;
4654 MovieTrackingObject *tracking_object;
4655 MovieTrackingTrack *track;
4656
4657 float depsgraph_time;
4658 float clip_frame;
4659 } FollowTrackContext;
4660
followtrack_context_init(FollowTrackContext * context,bConstraint * con,bConstraintOb * cob)4661 static bool followtrack_context_init(FollowTrackContext *context,
4662 bConstraint *con,
4663 bConstraintOb *cob)
4664 {
4665 bFollowTrackConstraint *data = con->data;
4666
4667 context->flag = data->flag;
4668 context->frame_method = data->frame_method;
4669
4670 context->depsgraph = cob->depsgraph;
4671 context->scene = cob->scene;
4672
4673 context->clip = followtrack_tracking_clip_get(con, cob);
4674 context->camera_object = followtrack_camera_object_get(con, cob);
4675 if (context->clip == NULL || context->camera_object == NULL) {
4676 return false;
4677 }
4678 context->depth_object = data->depth_ob;
4679
4680 context->tracking = &context->clip->tracking;
4681 context->tracking_object = followtrack_tracking_object_get(con, cob);
4682 if (context->tracking_object == NULL) {
4683 return false;
4684 }
4685
4686 context->track = BKE_tracking_track_get_named(
4687 context->tracking, context->tracking_object, data->track);
4688 if (context->track == NULL) {
4689 return false;
4690 }
4691
4692 context->depsgraph_time = DEG_get_ctime(context->depsgraph);
4693 context->clip_frame = BKE_movieclip_remap_scene_to_clip_frame(context->clip,
4694 context->depsgraph_time);
4695
4696 return true;
4697 }
4698
followtrack_evaluate_using_3d_position_object(FollowTrackContext * context,bConstraintOb * cob)4699 static void followtrack_evaluate_using_3d_position_object(FollowTrackContext *context,
4700 bConstraintOb *cob)
4701 {
4702 Object *camera_object = context->camera_object;
4703 MovieTracking *tracking = context->tracking;
4704 MovieTrackingTrack *track = context->track;
4705 MovieTrackingObject *tracking_object = context->tracking_object;
4706
4707 /* Matrix of the object which is being solved prior to this constraint. */
4708 float obmat[4][4];
4709 copy_m4_m4(obmat, cob->matrix);
4710
4711 /* Object matrix of the camera. */
4712 float camera_obmat[4][4];
4713 copy_m4_m4(camera_obmat, camera_object->obmat);
4714
4715 /* Calculate inverted matrix of the solved camera at the current time. */
4716 float reconstructed_camera_mat[4][4];
4717 BKE_tracking_camera_get_reconstructed_interpolate(
4718 tracking, tracking_object, context->clip_frame, reconstructed_camera_mat);
4719 float reconstructed_camera_mat_inv[4][4];
4720 invert_m4_m4(reconstructed_camera_mat_inv, reconstructed_camera_mat);
4721
4722 mul_m4_series(cob->matrix, obmat, camera_obmat, reconstructed_camera_mat_inv);
4723 translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
4724 }
4725
followtrack_evaluate_using_3d_position_camera(FollowTrackContext * context,bConstraintOb * cob)4726 static void followtrack_evaluate_using_3d_position_camera(FollowTrackContext *context,
4727 bConstraintOb *cob)
4728 {
4729 Object *camera_object = context->camera_object;
4730 MovieTrackingTrack *track = context->track;
4731
4732 /* Matrix of the object which is being solved prior to this constraint. */
4733 float obmat[4][4];
4734 copy_m4_m4(obmat, cob->matrix);
4735
4736 float reconstructed_camera_mat[4][4];
4737 BKE_tracking_get_camera_object_matrix(camera_object, reconstructed_camera_mat);
4738
4739 mul_m4_m4m4(cob->matrix, obmat, reconstructed_camera_mat);
4740 translate_m4(cob->matrix, track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]);
4741 }
4742
followtrack_evaluate_using_3d_position(FollowTrackContext * context,bConstraintOb * cob)4743 static void followtrack_evaluate_using_3d_position(FollowTrackContext *context, bConstraintOb *cob)
4744 {
4745 MovieTrackingTrack *track = context->track;
4746 if ((track->flag & TRACK_HAS_BUNDLE) == 0) {
4747 return;
4748 }
4749
4750 if ((context->tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) {
4751 followtrack_evaluate_using_3d_position_object(context, cob);
4752 return;
4753 }
4754
4755 followtrack_evaluate_using_3d_position_camera(context, cob);
4756 }
4757
4758 /* Apply undistortion if it is enabled in constraint settings. */
followtrack_undistort_if_needed(FollowTrackContext * context,const int clip_width,const int clip_height,float marker_position[2])4759 static void followtrack_undistort_if_needed(FollowTrackContext *context,
4760 const int clip_width,
4761 const int clip_height,
4762 float marker_position[2])
4763 {
4764 if ((context->flag & FOLLOWTRACK_USE_UNDISTORTION) == 0) {
4765 return;
4766 }
4767
4768 /* Undistortion need to happen in pixel space. */
4769 marker_position[0] *= clip_width;
4770 marker_position[1] *= clip_height;
4771
4772 BKE_tracking_undistort_v2(
4773 context->tracking, clip_width, clip_height, marker_position, marker_position);
4774
4775 /* Normalize pixel coordinates back. */
4776 marker_position[0] /= clip_width;
4777 marker_position[1] /= clip_height;
4778 }
4779
4780 /* Modify the marker position matching the frame fitting method. */
followtrack_fit_frame(FollowTrackContext * context,const int clip_width,const int clip_height,float marker_position[2])4781 static void followtrack_fit_frame(FollowTrackContext *context,
4782 const int clip_width,
4783 const int clip_height,
4784 float marker_position[2])
4785 {
4786 if (context->frame_method == FOLLOWTRACK_FRAME_STRETCH) {
4787 return;
4788 }
4789
4790 Scene *scene = context->scene;
4791 MovieClip *clip = context->clip;
4792
4793 /* apply clip display aspect */
4794 const float w_src = clip_width * clip->aspx;
4795 const float h_src = clip_height * clip->aspy;
4796
4797 const float w_dst = scene->r.xsch * scene->r.xasp;
4798 const float h_dst = scene->r.ysch * scene->r.yasp;
4799
4800 const float asp_src = w_src / h_src;
4801 const float asp_dst = w_dst / h_dst;
4802
4803 if (fabsf(asp_src - asp_dst) < FLT_EPSILON) {
4804 return;
4805 }
4806
4807 if ((asp_src > asp_dst) == (context->frame_method == FOLLOWTRACK_FRAME_CROP)) {
4808 /* fit X */
4809 float div = asp_src / asp_dst;
4810 float cent = (float)clip_width / 2.0f;
4811
4812 marker_position[0] = (((marker_position[0] * clip_width - cent) * div) + cent) / clip_width;
4813 }
4814 else {
4815 /* fit Y */
4816 float div = asp_dst / asp_src;
4817 float cent = (float)clip_height / 2.0f;
4818
4819 marker_position[1] = (((marker_position[1] * clip_height - cent) * div) + cent) / clip_height;
4820 }
4821 }
4822
4823 /* Effectively this is a Z-depth of the object form the movie clip camera.
4824 * The idea is to preserve this depth while moving the object in 2D. */
followtrack_distance_from_viewplane_get(FollowTrackContext * context,bConstraintOb * cob)4825 static float followtrack_distance_from_viewplane_get(FollowTrackContext *context,
4826 bConstraintOb *cob)
4827 {
4828 Object *camera_object = context->camera_object;
4829
4830 float camera_matrix[4][4];
4831 BKE_object_where_is_calc_mat4(camera_object, camera_matrix);
4832
4833 const float z_axis[3] = {0.0f, 0.0f, 1.0f};
4834
4835 /* Direction of camera's local Z axis in the world space. */
4836 float camera_axis[3];
4837 mul_v3_mat3_m4v3(camera_axis, camera_matrix, z_axis);
4838
4839 /* Distance to projection plane. */
4840 float vec[3];
4841 copy_v3_v3(vec, cob->matrix[3]);
4842 sub_v3_v3(vec, camera_matrix[3]);
4843
4844 float projection[3];
4845 project_v3_v3v3(projection, vec, camera_axis);
4846
4847 return len_v3(projection);
4848 }
4849
4850 /* For the evaluated constraint object project it to the surface of the depth object. */
followtrack_project_to_depth_object_if_needed(FollowTrackContext * context,bConstraintOb * cob)4851 static void followtrack_project_to_depth_object_if_needed(FollowTrackContext *context,
4852 bConstraintOb *cob)
4853 {
4854 if (context->depth_object == NULL) {
4855 return;
4856 }
4857
4858 Object *depth_object = context->depth_object;
4859 Mesh *depth_mesh = BKE_object_get_evaluated_mesh(depth_object);
4860 if (depth_mesh == NULL) {
4861 return;
4862 }
4863
4864 float depth_object_mat_inv[4][4];
4865 invert_m4_m4(depth_object_mat_inv, depth_object->obmat);
4866
4867 float ray_start[3], ray_end[3];
4868 mul_v3_m4v3(ray_start, depth_object_mat_inv, context->camera_object->obmat[3]);
4869 mul_v3_m4v3(ray_end, depth_object_mat_inv, cob->matrix[3]);
4870
4871 float ray_direction[3];
4872 sub_v3_v3v3(ray_direction, ray_end, ray_start);
4873 normalize_v3(ray_direction);
4874
4875 BVHTreeFromMesh tree_data = NULL_BVHTreeFromMesh;
4876 BKE_bvhtree_from_mesh_get(&tree_data, depth_mesh, BVHTREE_FROM_LOOPTRI, 4);
4877
4878 BVHTreeRayHit hit;
4879 hit.dist = BVH_RAYCAST_DIST_MAX;
4880 hit.index = -1;
4881
4882 const int result = BLI_bvhtree_ray_cast(tree_data.tree,
4883 ray_start,
4884 ray_direction,
4885 0.0f,
4886 &hit,
4887 tree_data.raycast_callback,
4888 &tree_data);
4889
4890 if (result != -1) {
4891 mul_v3_m4v3(cob->matrix[3], depth_object->obmat, hit.co);
4892 }
4893
4894 free_bvhtree_from_mesh(&tree_data);
4895 }
4896
followtrack_evaluate_using_2d_position(FollowTrackContext * context,bConstraintOb * cob)4897 static void followtrack_evaluate_using_2d_position(FollowTrackContext *context, bConstraintOb *cob)
4898 {
4899 Scene *scene = context->scene;
4900 MovieClip *clip = context->clip;
4901 MovieTrackingTrack *track = context->track;
4902 Object *camera_object = context->camera_object;
4903 const float clip_frame = context->clip_frame;
4904 const float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
4905
4906 const float object_depth = followtrack_distance_from_viewplane_get(context, cob);
4907 if (object_depth < FLT_EPSILON) {
4908 return;
4909 }
4910
4911 int clip_width, clip_height;
4912 BKE_movieclip_get_size(clip, NULL, &clip_width, &clip_height);
4913
4914 float marker_position[2];
4915 BKE_tracking_marker_get_subframe_position(track, clip_frame, marker_position);
4916
4917 followtrack_undistort_if_needed(context, clip_width, clip_height, marker_position);
4918 followtrack_fit_frame(context, clip_width, clip_height, marker_position);
4919
4920 float rmat[4][4];
4921 CameraParams params;
4922 BKE_camera_params_init(¶ms);
4923 BKE_camera_params_from_object(¶ms, camera_object);
4924
4925 if (params.is_ortho) {
4926 float vec[3];
4927 vec[0] = params.ortho_scale * (marker_position[0] - 0.5f + params.shiftx);
4928 vec[1] = params.ortho_scale * (marker_position[1] - 0.5f + params.shifty);
4929 vec[2] = -object_depth;
4930
4931 if (aspect > 1.0f) {
4932 vec[1] /= aspect;
4933 }
4934 else {
4935 vec[0] *= aspect;
4936 }
4937
4938 float disp[3];
4939 mul_v3_m4v3(disp, camera_object->obmat, vec);
4940
4941 copy_m4_m4(rmat, camera_object->obmat);
4942 zero_v3(rmat[3]);
4943 mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
4944
4945 copy_v3_v3(cob->matrix[3], disp);
4946 }
4947 else {
4948 const float d = (object_depth * params.sensor_x) / (2.0f * params.lens);
4949
4950 float vec[3];
4951 vec[0] = d * (2.0f * (marker_position[0] + params.shiftx) - 1.0f);
4952 vec[1] = d * (2.0f * (marker_position[1] + params.shifty) - 1.0f);
4953 vec[2] = -object_depth;
4954
4955 if (aspect > 1.0f) {
4956 vec[1] /= aspect;
4957 }
4958 else {
4959 vec[0] *= aspect;
4960 }
4961
4962 float disp[3];
4963 mul_v3_m4v3(disp, camera_object->obmat, vec);
4964
4965 /* apply camera rotation so Z-axis would be co-linear */
4966 copy_m4_m4(rmat, camera_object->obmat);
4967 zero_v3(rmat[3]);
4968 mul_m4_m4m4(cob->matrix, cob->matrix, rmat);
4969
4970 copy_v3_v3(cob->matrix[3], disp);
4971 }
4972
4973 followtrack_project_to_depth_object_if_needed(context, cob);
4974 }
4975
followtrack_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))4976 static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
4977 {
4978 FollowTrackContext context;
4979 if (!followtrack_context_init(&context, con, cob)) {
4980 return;
4981 }
4982
4983 bFollowTrackConstraint *data = con->data;
4984 if (data->flag & FOLLOWTRACK_USE_3D_POSITION) {
4985 followtrack_evaluate_using_3d_position(&context, cob);
4986 return;
4987 }
4988
4989 followtrack_evaluate_using_2d_position(&context, cob);
4990 }
4991
4992 static bConstraintTypeInfo CTI_FOLLOWTRACK = {
4993 CONSTRAINT_TYPE_FOLLOWTRACK, /* type */
4994 sizeof(bFollowTrackConstraint), /* size */
4995 "Follow Track", /* name */
4996 "bFollowTrackConstraint", /* struct name */
4997 NULL, /* free data */
4998 followtrack_id_looper, /* id looper */
4999 NULL, /* copy data */
5000 followtrack_new_data, /* new data */
5001 NULL, /* get constraint targets */
5002 NULL, /* flush constraint targets */
5003 NULL, /* get target matrix */
5004 followtrack_evaluate, /* evaluate */
5005 };
5006
5007 /* ----------- Camera Solver ------------- */
5008
camerasolver_new_data(void * cdata)5009 static void camerasolver_new_data(void *cdata)
5010 {
5011 bCameraSolverConstraint *data = (bCameraSolverConstraint *)cdata;
5012
5013 data->clip = NULL;
5014 data->flag |= CAMERASOLVER_ACTIVECLIP;
5015 }
5016
camerasolver_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)5017 static void camerasolver_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
5018 {
5019 bCameraSolverConstraint *data = con->data;
5020
5021 func(con, (ID **)&data->clip, true, userdata);
5022 }
5023
camerasolver_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))5024 static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
5025 {
5026 Depsgraph *depsgraph = cob->depsgraph;
5027 Scene *scene = cob->scene;
5028 bCameraSolverConstraint *data = con->data;
5029 MovieClip *clip = data->clip;
5030
5031 if (data->flag & CAMERASOLVER_ACTIVECLIP) {
5032 clip = scene->clip;
5033 }
5034
5035 if (clip) {
5036 float mat[4][4], obmat[4][4];
5037 MovieTracking *tracking = &clip->tracking;
5038 MovieTrackingObject *object = BKE_tracking_object_get_camera(tracking);
5039 float ctime = DEG_get_ctime(depsgraph);
5040 float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
5041
5042 BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
5043
5044 copy_m4_m4(obmat, cob->matrix);
5045
5046 mul_m4_m4m4(cob->matrix, obmat, mat);
5047 }
5048 }
5049
5050 static bConstraintTypeInfo CTI_CAMERASOLVER = {
5051 CONSTRAINT_TYPE_CAMERASOLVER, /* type */
5052 sizeof(bCameraSolverConstraint), /* size */
5053 "Camera Solver", /* name */
5054 "bCameraSolverConstraint", /* struct name */
5055 NULL, /* free data */
5056 camerasolver_id_looper, /* id looper */
5057 NULL, /* copy data */
5058 camerasolver_new_data, /* new data */
5059 NULL, /* get constraint targets */
5060 NULL, /* flush constraint targets */
5061 NULL, /* get target matrix */
5062 camerasolver_evaluate, /* evaluate */
5063 };
5064
5065 /* ----------- Object Solver ------------- */
5066
objectsolver_new_data(void * cdata)5067 static void objectsolver_new_data(void *cdata)
5068 {
5069 bObjectSolverConstraint *data = (bObjectSolverConstraint *)cdata;
5070
5071 data->clip = NULL;
5072 data->flag |= OBJECTSOLVER_ACTIVECLIP;
5073 unit_m4(data->invmat);
5074 }
5075
objectsolver_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)5076 static void objectsolver_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
5077 {
5078 bObjectSolverConstraint *data = con->data;
5079
5080 func(con, (ID **)&data->clip, false, userdata);
5081 func(con, (ID **)&data->camera, false, userdata);
5082 }
5083
objectsolver_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * UNUSED (targets))5084 static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets))
5085 {
5086 Depsgraph *depsgraph = cob->depsgraph;
5087 Scene *scene = cob->scene;
5088 bObjectSolverConstraint *data = con->data;
5089 MovieClip *clip = data->clip;
5090 Object *camob = data->camera ? data->camera : scene->camera;
5091
5092 if (data->flag & OBJECTSOLVER_ACTIVECLIP) {
5093 clip = scene->clip;
5094 }
5095 if (!camob || !clip) {
5096 return;
5097 }
5098
5099 MovieTracking *tracking = &clip->tracking;
5100 MovieTrackingObject *object;
5101
5102 object = BKE_tracking_object_get_named(tracking, data->object);
5103 if (!object) {
5104 return;
5105 }
5106
5107 float mat[4][4], obmat[4][4], imat[4][4], parmat[4][4];
5108 float ctime = DEG_get_ctime(depsgraph);
5109 float framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
5110
5111 BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, framenr, mat);
5112
5113 invert_m4_m4(imat, mat);
5114 mul_m4_m4m4(parmat, camob->obmat, imat);
5115
5116 copy_m4_m4(obmat, cob->matrix);
5117
5118 /* Recalculate the inverse matrix if requested. */
5119 if (data->flag & OBJECTSOLVER_SET_INVERSE) {
5120 invert_m4_m4(data->invmat, parmat);
5121
5122 data->flag &= ~OBJECTSOLVER_SET_INVERSE;
5123
5124 /* Write the computed matrix back to the master copy if in COW evaluation. */
5125 bConstraint *orig_con = constraint_find_original_for_update(cob, con);
5126
5127 if (orig_con != NULL) {
5128 bObjectSolverConstraint *orig_data = orig_con->data;
5129
5130 copy_m4_m4(orig_data->invmat, data->invmat);
5131 orig_data->flag &= ~OBJECTSOLVER_SET_INVERSE;
5132 }
5133 }
5134
5135 mul_m4_series(cob->matrix, parmat, data->invmat, obmat);
5136 }
5137
5138 static bConstraintTypeInfo CTI_OBJECTSOLVER = {
5139 CONSTRAINT_TYPE_OBJECTSOLVER, /* type */
5140 sizeof(bObjectSolverConstraint), /* size */
5141 "Object Solver", /* name */
5142 "bObjectSolverConstraint", /* struct name */
5143 NULL, /* free data */
5144 objectsolver_id_looper, /* id looper */
5145 NULL, /* copy data */
5146 objectsolver_new_data, /* new data */
5147 NULL, /* get constraint targets */
5148 NULL, /* flush constraint targets */
5149 NULL, /* get target matrix */
5150 objectsolver_evaluate, /* evaluate */
5151 };
5152
5153 /* ----------- Transform Cache ------------- */
5154
transformcache_id_looper(bConstraint * con,ConstraintIDFunc func,void * userdata)5155 static void transformcache_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata)
5156 {
5157 bTransformCacheConstraint *data = con->data;
5158 func(con, (ID **)&data->cache_file, true, userdata);
5159 }
5160
transformcache_evaluate(bConstraint * con,bConstraintOb * cob,ListBase * targets)5161 static void transformcache_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targets)
5162 {
5163 #ifdef WITH_ALEMBIC
5164 bTransformCacheConstraint *data = con->data;
5165 Scene *scene = cob->scene;
5166
5167 CacheFile *cache_file = data->cache_file;
5168
5169 if (!cache_file) {
5170 return;
5171 }
5172
5173 const float frame = DEG_get_ctime(cob->depsgraph);
5174 const float time = BKE_cachefile_time_offset(cache_file, frame, FPS);
5175
5176 if (!data->reader || !STREQ(data->reader_object_path, data->object_path)) {
5177 STRNCPY(data->reader_object_path, data->object_path);
5178 BKE_cachefile_reader_open(cache_file, &data->reader, cob->ob, data->object_path);
5179 }
5180
5181 ABC_get_transform(data->reader, cob->matrix, time, cache_file->scale);
5182 #else
5183 UNUSED_VARS(con, cob);
5184 #endif
5185
5186 UNUSED_VARS(targets);
5187 }
5188
transformcache_copy(bConstraint * con,bConstraint * srccon)5189 static void transformcache_copy(bConstraint *con, bConstraint *srccon)
5190 {
5191 bTransformCacheConstraint *src = srccon->data;
5192 bTransformCacheConstraint *dst = con->data;
5193
5194 BLI_strncpy(dst->object_path, src->object_path, sizeof(dst->object_path));
5195 dst->cache_file = src->cache_file;
5196 dst->reader = NULL;
5197 dst->reader_object_path[0] = '\0';
5198 }
5199
transformcache_free(bConstraint * con)5200 static void transformcache_free(bConstraint *con)
5201 {
5202 bTransformCacheConstraint *data = con->data;
5203
5204 if (data->reader) {
5205 BKE_cachefile_reader_free(data->cache_file, &data->reader);
5206 data->reader_object_path[0] = '\0';
5207 }
5208 }
5209
transformcache_new_data(void * cdata)5210 static void transformcache_new_data(void *cdata)
5211 {
5212 bTransformCacheConstraint *data = (bTransformCacheConstraint *)cdata;
5213
5214 data->cache_file = NULL;
5215 }
5216
5217 static bConstraintTypeInfo CTI_TRANSFORM_CACHE = {
5218 CONSTRAINT_TYPE_TRANSFORM_CACHE, /* type */
5219 sizeof(bTransformCacheConstraint), /* size */
5220 "Transform Cache", /* name */
5221 "bTransformCacheConstraint", /* struct name */
5222 transformcache_free, /* free data */
5223 transformcache_id_looper, /* id looper */
5224 transformcache_copy, /* copy data */
5225 transformcache_new_data, /* new data */
5226 NULL, /* get constraint targets */
5227 NULL, /* flush constraint targets */
5228 NULL, /* get target matrix */
5229 transformcache_evaluate, /* evaluate */
5230 };
5231
5232 /* ************************* Constraints Type-Info *************************** */
5233 /* All of the constraints api functions use bConstraintTypeInfo structs to carry out
5234 * and operations that involve constraint specific code.
5235 */
5236
5237 /* These globals only ever get directly accessed in this file */
5238 static bConstraintTypeInfo *constraintsTypeInfo[NUM_CONSTRAINT_TYPES];
5239 static short CTI_INIT = 1; /* when non-zero, the list needs to be updated */
5240
5241 /* This function only gets called when CTI_INIT is non-zero */
constraints_init_typeinfo(void)5242 static void constraints_init_typeinfo(void)
5243 {
5244 constraintsTypeInfo[0] = NULL; /* 'Null' Constraint */
5245 constraintsTypeInfo[1] = &CTI_CHILDOF; /* ChildOf Constraint */
5246 constraintsTypeInfo[2] = &CTI_TRACKTO; /* TrackTo Constraint */
5247 constraintsTypeInfo[3] = &CTI_KINEMATIC; /* IK Constraint */
5248 constraintsTypeInfo[4] = &CTI_FOLLOWPATH; /* Follow-Path Constraint */
5249 constraintsTypeInfo[5] = &CTI_ROTLIMIT; /* Limit Rotation Constraint */
5250 constraintsTypeInfo[6] = &CTI_LOCLIMIT; /* Limit Location Constraint */
5251 constraintsTypeInfo[7] = &CTI_SIZELIMIT; /* Limit Scale Constraint */
5252 constraintsTypeInfo[8] = &CTI_ROTLIKE; /* Copy Rotation Constraint */
5253 constraintsTypeInfo[9] = &CTI_LOCLIKE; /* Copy Location Constraint */
5254 constraintsTypeInfo[10] = &CTI_SIZELIKE; /* Copy Scale Constraint */
5255 constraintsTypeInfo[11] = &CTI_PYTHON; /* Python/Script Constraint */
5256 constraintsTypeInfo[12] = &CTI_ACTION; /* Action Constraint */
5257 constraintsTypeInfo[13] = &CTI_LOCKTRACK; /* Locked-Track Constraint */
5258 constraintsTypeInfo[14] = &CTI_DISTLIMIT; /* Limit Distance Constraint */
5259 constraintsTypeInfo[15] = &CTI_STRETCHTO; /* StretchTo Constaint */
5260 constraintsTypeInfo[16] = &CTI_MINMAX; /* Floor Constraint */
5261 /* constraintsTypeInfo[17] = &CTI_RIGIDBODYJOINT; */ /* RigidBody Constraint - Deprecated */
5262 constraintsTypeInfo[18] = &CTI_CLAMPTO; /* ClampTo Constraint */
5263 constraintsTypeInfo[19] = &CTI_TRANSFORM; /* Transformation Constraint */
5264 constraintsTypeInfo[20] = &CTI_SHRINKWRAP; /* Shrinkwrap Constraint */
5265 constraintsTypeInfo[21] = &CTI_DAMPTRACK; /* Damped TrackTo Constraint */
5266 constraintsTypeInfo[22] = &CTI_SPLINEIK; /* Spline IK Constraint */
5267 constraintsTypeInfo[23] = &CTI_TRANSLIKE; /* Copy Transforms Constraint */
5268 constraintsTypeInfo[24] = &CTI_SAMEVOL; /* Maintain Volume Constraint */
5269 constraintsTypeInfo[25] = &CTI_PIVOT; /* Pivot Constraint */
5270 constraintsTypeInfo[26] = &CTI_FOLLOWTRACK; /* Follow Track Constraint */
5271 constraintsTypeInfo[27] = &CTI_CAMERASOLVER; /* Camera Solver Constraint */
5272 constraintsTypeInfo[28] = &CTI_OBJECTSOLVER; /* Object Solver Constraint */
5273 constraintsTypeInfo[29] = &CTI_TRANSFORM_CACHE; /* Transform Cache Constraint */
5274 constraintsTypeInfo[30] = &CTI_ARMATURE; /* Armature Constraint */
5275 }
5276
5277 /* This function should be used for getting the appropriate type-info when only
5278 * a constraint type is known
5279 */
BKE_constraint_typeinfo_from_type(int type)5280 const bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type)
5281 {
5282 /* initialize the type-info list? */
5283 if (CTI_INIT) {
5284 constraints_init_typeinfo();
5285 CTI_INIT = 0;
5286 }
5287
5288 /* only return for valid types */
5289 if ((type >= CONSTRAINT_TYPE_NULL) && (type < NUM_CONSTRAINT_TYPES)) {
5290 /* there shouldn't be any segfaults here... */
5291 return constraintsTypeInfo[type];
5292 }
5293
5294 CLOG_WARN(&LOG, "No valid constraint type-info data available. Type = %i", type);
5295
5296 return NULL;
5297 }
5298
5299 /* This function should always be used to get the appropriate type-info, as it
5300 * has checks which prevent segfaults in some weird cases.
5301 */
BKE_constraint_typeinfo_get(bConstraint * con)5302 const bConstraintTypeInfo *BKE_constraint_typeinfo_get(bConstraint *con)
5303 {
5304 /* only return typeinfo for valid constraints */
5305 if (con) {
5306 return BKE_constraint_typeinfo_from_type(con->type);
5307 }
5308
5309 return NULL;
5310 }
5311
5312 /* ************************* General Constraints API ************************** */
5313 /* The functions here are called by various parts of Blender. Very few (should be none if possible)
5314 * constraint-specific code should occur here.
5315 */
5316
5317 /* ---------- Data Management ------- */
5318
5319 /**
5320 * Helper function for #BKE_constraint_free_data() - unlinks references.
5321 */
con_unlink_refs_cb(bConstraint * UNUSED (con),ID ** idpoin,bool is_reference,void * UNUSED (userData))5322 static void con_unlink_refs_cb(bConstraint *UNUSED(con),
5323 ID **idpoin,
5324 bool is_reference,
5325 void *UNUSED(userData))
5326 {
5327 if (*idpoin && is_reference) {
5328 id_us_min(*idpoin);
5329 }
5330 }
5331
5332 /**
5333 * Free data of a specific constraint if it has any info.
5334 * be sure to run #BIK_clear_data() when freeing an IK constraint,
5335 * unless DAG_relations_tag_update is called.
5336 */
BKE_constraint_free_data_ex(bConstraint * con,bool do_id_user)5337 void BKE_constraint_free_data_ex(bConstraint *con, bool do_id_user)
5338 {
5339 if (con->data) {
5340 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
5341
5342 if (cti) {
5343 /* perform any special freeing constraint may have */
5344 if (cti->free_data) {
5345 cti->free_data(con);
5346 }
5347
5348 /* unlink the referenced resources it uses */
5349 if (do_id_user && cti->id_looper) {
5350 cti->id_looper(con, con_unlink_refs_cb, NULL);
5351 }
5352 }
5353
5354 /* free constraint data now */
5355 MEM_freeN(con->data);
5356 }
5357 }
5358
BKE_constraint_free_data(bConstraint * con)5359 void BKE_constraint_free_data(bConstraint *con)
5360 {
5361 BKE_constraint_free_data_ex(con, true);
5362 }
5363
5364 /* Free all constraints from a constraint-stack */
BKE_constraints_free_ex(ListBase * list,bool do_id_user)5365 void BKE_constraints_free_ex(ListBase *list, bool do_id_user)
5366 {
5367 bConstraint *con;
5368
5369 /* Free constraint data and also any extra data */
5370 for (con = list->first; con; con = con->next) {
5371 BKE_constraint_free_data_ex(con, do_id_user);
5372 }
5373
5374 /* Free the whole list */
5375 BLI_freelistN(list);
5376 }
5377
BKE_constraints_free(ListBase * list)5378 void BKE_constraints_free(ListBase *list)
5379 {
5380 BKE_constraints_free_ex(list, true);
5381 }
5382
5383 /* Remove the specified constraint from the given constraint stack */
BKE_constraint_remove(ListBase * list,bConstraint * con)5384 bool BKE_constraint_remove(ListBase *list, bConstraint *con)
5385 {
5386 if (con) {
5387 BKE_constraint_free_data(con);
5388 BLI_freelinkN(list, con);
5389 return true;
5390 }
5391
5392 return false;
5393 }
5394
BKE_constraint_remove_ex(ListBase * list,Object * ob,bConstraint * con,bool clear_dep)5395 bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool clear_dep)
5396 {
5397 const short type = con->type;
5398 if (BKE_constraint_remove(list, con)) {
5399 /* ITASC needs to be rebuilt once a constraint is removed T26920. */
5400 if (clear_dep && ELEM(type, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) {
5401 BIK_clear_data(ob->pose);
5402 }
5403 return true;
5404 }
5405
5406 return false;
5407 }
5408
5409 /* ......... */
5410
5411 /* Creates a new constraint, initializes its data, and returns it */
add_new_constraint_internal(const char * name,short type)5412 static bConstraint *add_new_constraint_internal(const char *name, short type)
5413 {
5414 bConstraint *con = MEM_callocN(sizeof(bConstraint), "Constraint");
5415 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_from_type(type);
5416 const char *newName;
5417
5418 /* Set up a generic constraint data-block. */
5419 con->type = type;
5420 con->flag |= CONSTRAINT_OVERRIDE_LIBRARY_LOCAL;
5421 con->enforce = 1.0f;
5422
5423 /* Only open the main panel when constraints are created, not the sub-panels. */
5424 con->ui_expand_flag = (1 << 0);
5425 if (ELEM(type, CONSTRAINT_TYPE_ACTION, CONSTRAINT_TYPE_SPLINEIK)) {
5426 /* Expand the two sub-panels in the cases where the main panel barely has any properties. */
5427 con->ui_expand_flag |= (1 << 1) | (1 << 2);
5428 }
5429
5430 /* Determine a basic name, and info */
5431 if (cti) {
5432 /* initialize constraint data */
5433 con->data = MEM_callocN(cti->size, cti->structName);
5434
5435 /* only constraints that change any settings need this */
5436 if (cti->new_data) {
5437 cti->new_data(con->data);
5438 }
5439
5440 /* if no name is provided, use the type of the constraint as the name */
5441 newName = (name && name[0]) ? name : DATA_(cti->name);
5442 }
5443 else {
5444 /* if no name is provided, use the generic "Const" name */
5445 /* NOTE: any constraint type that gets here really shouldn't get added... */
5446 newName = (name && name[0]) ? name : DATA_("Const");
5447 }
5448
5449 /* copy the name */
5450 BLI_strncpy(con->name, newName, sizeof(con->name));
5451
5452 /* return the new constraint */
5453 return con;
5454 }
5455
5456 /* Add a newly created constraint to the constraint list. */
add_new_constraint_to_list(Object * ob,bPoseChannel * pchan,bConstraint * con)5457 static void add_new_constraint_to_list(Object *ob, bPoseChannel *pchan, bConstraint *con)
5458 {
5459 ListBase *list;
5460
5461 /* find the constraint stack - bone or object? */
5462 list = (pchan) ? (&pchan->constraints) : (&ob->constraints);
5463
5464 if (list) {
5465 /* add new constraint to end of list of constraints before ensuring that it has a unique name
5466 * (otherwise unique-naming code will fail, since it assumes element exists in list)
5467 */
5468 BLI_addtail(list, con);
5469 BKE_constraint_unique_name(con, list);
5470
5471 /* if the target list is a list on some PoseChannel belonging to a proxy-protected
5472 * Armature layer, we must tag newly added constraints with a flag which allows them
5473 * to persist after proxy syncing has been done
5474 */
5475 if (BKE_constraints_proxylocked_owner(ob, pchan)) {
5476 con->flag |= CONSTRAINT_PROXY_LOCAL;
5477 }
5478
5479 /* make this constraint the active one */
5480 BKE_constraints_active_set(list, con);
5481 }
5482 }
5483
5484 /* if pchan is not NULL then assume we're adding a pose constraint */
add_new_constraint(Object * ob,bPoseChannel * pchan,const char * name,short type)5485 static bConstraint *add_new_constraint(Object *ob,
5486 bPoseChannel *pchan,
5487 const char *name,
5488 short type)
5489 {
5490 bConstraint *con;
5491
5492 /* add the constraint */
5493 con = add_new_constraint_internal(name, type);
5494
5495 add_new_constraint_to_list(ob, pchan, con);
5496
5497 /* set type+owner specific immutable settings */
5498 /* TODO: does action constraint need anything here - i.e. spaceonce? */
5499 switch (type) {
5500 case CONSTRAINT_TYPE_CHILDOF: {
5501 /* if this constraint is being added to a posechannel, make sure
5502 * the constraint gets evaluated in pose-space */
5503 if (pchan) {
5504 con->ownspace = CONSTRAINT_SPACE_POSE;
5505 con->flag |= CONSTRAINT_SPACEONCE;
5506 }
5507 break;
5508 }
5509 }
5510
5511 return con;
5512 }
5513
BKE_constraint_target_uses_bbone(struct bConstraint * con,struct bConstraintTarget * UNUSED (ct))5514 bool BKE_constraint_target_uses_bbone(struct bConstraint *con,
5515 struct bConstraintTarget *UNUSED(ct))
5516 {
5517 return (con->flag & CONSTRAINT_BBONE_SHAPE) || (con->type == CONSTRAINT_TYPE_ARMATURE);
5518 }
5519
5520 /* ......... */
5521
5522 /* Add new constraint for the given bone */
BKE_constraint_add_for_pose(Object * ob,bPoseChannel * pchan,const char * name,short type)5523 bConstraint *BKE_constraint_add_for_pose(Object *ob,
5524 bPoseChannel *pchan,
5525 const char *name,
5526 short type)
5527 {
5528 if (pchan == NULL) {
5529 return NULL;
5530 }
5531
5532 return add_new_constraint(ob, pchan, name, type);
5533 }
5534
5535 /* Add new constraint for the given object */
BKE_constraint_add_for_object(Object * ob,const char * name,short type)5536 bConstraint *BKE_constraint_add_for_object(Object *ob, const char *name, short type)
5537 {
5538 return add_new_constraint(ob, NULL, name, type);
5539 }
5540
5541 /* ......... */
5542
5543 /* Run the given callback on all ID-blocks in list of constraints */
BKE_constraints_id_loop(ListBase * conlist,ConstraintIDFunc func,void * userdata)5544 void BKE_constraints_id_loop(ListBase *conlist, ConstraintIDFunc func, void *userdata)
5545 {
5546 bConstraint *con;
5547
5548 for (con = conlist->first; con; con = con->next) {
5549 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
5550
5551 if (cti) {
5552 if (cti->id_looper) {
5553 cti->id_looper(con, func, userdata);
5554 }
5555 }
5556 }
5557 }
5558
5559 /* ......... */
5560
5561 /* helper for BKE_constraints_copy(), to be used for making sure that ID's are valid */
con_extern_cb(bConstraint * UNUSED (con),ID ** idpoin,bool UNUSED (is_reference),void * UNUSED (userData))5562 static void con_extern_cb(bConstraint *UNUSED(con),
5563 ID **idpoin,
5564 bool UNUSED(is_reference),
5565 void *UNUSED(userData))
5566 {
5567 if (*idpoin && ID_IS_LINKED(*idpoin)) {
5568 id_lib_extern(*idpoin);
5569 }
5570 }
5571
5572 /**
5573 * Helper for #BKE_constraints_copy(),
5574 * to be used for making sure that user-counts of copied ID's are fixed up.
5575 */
con_fix_copied_refs_cb(bConstraint * UNUSED (con),ID ** idpoin,bool is_reference,void * UNUSED (userData))5576 static void con_fix_copied_refs_cb(bConstraint *UNUSED(con),
5577 ID **idpoin,
5578 bool is_reference,
5579 void *UNUSED(userData))
5580 {
5581 /* Increment user-count if this is a reference type. */
5582 if ((*idpoin) && (is_reference)) {
5583 id_us_plus(*idpoin);
5584 }
5585 }
5586
5587 /** Copies a single constraint's data (\a dst must already be a shallow copy of \a src). */
constraint_copy_data_ex(bConstraint * dst,bConstraint * src,const int flag,const bool do_extern)5588 static void constraint_copy_data_ex(bConstraint *dst,
5589 bConstraint *src,
5590 const int flag,
5591 const bool do_extern)
5592 {
5593 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(src);
5594
5595 /* make a new copy of the constraint's data */
5596 dst->data = MEM_dupallocN(dst->data);
5597
5598 /* only do specific constraints if required */
5599 if (cti) {
5600 /* perform custom copying operations if needed */
5601 if (cti->copy_data) {
5602 cti->copy_data(dst, src);
5603 }
5604
5605 /* Fix usercounts for all referenced data that need it. */
5606 if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
5607 cti->id_looper(dst, con_fix_copied_refs_cb, NULL);
5608 }
5609
5610 /* for proxies we don't want to make extern */
5611 if (do_extern) {
5612 /* go over used ID-links for this constraint to ensure that they are valid for proxies */
5613 if (cti->id_looper) {
5614 cti->id_looper(dst, con_extern_cb, NULL);
5615 }
5616 }
5617 }
5618 }
5619
5620 /** Allocate and duplicate a single constraint, outside of any object/pose context. */
BKE_constraint_duplicate_ex(bConstraint * src,const int flag,const bool do_extern)5621 bConstraint *BKE_constraint_duplicate_ex(bConstraint *src, const int flag, const bool do_extern)
5622 {
5623 bConstraint *dst = MEM_dupallocN(src);
5624 constraint_copy_data_ex(dst, src, flag, do_extern);
5625 dst->next = dst->prev = NULL;
5626 return dst;
5627 }
5628
5629 /* Add a copy of the given constraint for the given bone */
BKE_constraint_copy_for_pose(Object * ob,bPoseChannel * pchan,bConstraint * src)5630 bConstraint *BKE_constraint_copy_for_pose(Object *ob, bPoseChannel *pchan, bConstraint *src)
5631 {
5632 if (pchan == NULL) {
5633 return NULL;
5634 }
5635
5636 bConstraint *new_con = BKE_constraint_duplicate_ex(src, 0, !ID_IS_LINKED(ob));
5637 add_new_constraint_to_list(ob, pchan, new_con);
5638 return new_con;
5639 }
5640
5641 /* Add a copy of the given constraint for the given object */
BKE_constraint_copy_for_object(Object * ob,bConstraint * src)5642 bConstraint *BKE_constraint_copy_for_object(Object *ob, bConstraint *src)
5643 {
5644 bConstraint *new_con = BKE_constraint_duplicate_ex(src, 0, !ID_IS_LINKED(ob));
5645 add_new_constraint_to_list(ob, NULL, new_con);
5646 return new_con;
5647 }
5648
5649 /* duplicate all of the constraints in a constraint stack */
BKE_constraints_copy_ex(ListBase * dst,const ListBase * src,const int flag,bool do_extern)5650 void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag, bool do_extern)
5651 {
5652 bConstraint *con, *srccon;
5653
5654 BLI_listbase_clear(dst);
5655 BLI_duplicatelist(dst, src);
5656
5657 for (con = dst->first, srccon = src->first; con && srccon;
5658 srccon = srccon->next, con = con->next) {
5659 constraint_copy_data_ex(con, srccon, flag, do_extern);
5660 }
5661 }
5662
BKE_constraints_copy(ListBase * dst,const ListBase * src,bool do_extern)5663 void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
5664 {
5665 BKE_constraints_copy_ex(dst, src, 0, do_extern);
5666 }
5667
5668 /* ......... */
5669
BKE_constraints_find_name(ListBase * list,const char * name)5670 bConstraint *BKE_constraints_find_name(ListBase *list, const char *name)
5671 {
5672 return BLI_findstring(list, name, offsetof(bConstraint, name));
5673 }
5674
5675 /* finds the 'active' constraint in a constraint stack */
BKE_constraints_active_get(ListBase * list)5676 bConstraint *BKE_constraints_active_get(ListBase *list)
5677 {
5678 bConstraint *con;
5679
5680 /* search for the first constraint with the 'active' flag set */
5681 if (list) {
5682 for (con = list->first; con; con = con->next) {
5683 if (con->flag & CONSTRAINT_ACTIVE) {
5684 return con;
5685 }
5686 }
5687 }
5688
5689 /* no active constraint found */
5690 return NULL;
5691 }
5692
5693 /* Set the given constraint as the active one (clearing all the others) */
BKE_constraints_active_set(ListBase * list,bConstraint * con)5694 void BKE_constraints_active_set(ListBase *list, bConstraint *con)
5695 {
5696 bConstraint *c;
5697
5698 if (list) {
5699 for (c = list->first; c; c = c->next) {
5700 if (c == con) {
5701 c->flag |= CONSTRAINT_ACTIVE;
5702 }
5703 else {
5704 c->flag &= ~CONSTRAINT_ACTIVE;
5705 }
5706 }
5707 }
5708 }
5709
constraint_list_find_from_target(ListBase * constraints,bConstraintTarget * tgt)5710 static bConstraint *constraint_list_find_from_target(ListBase *constraints, bConstraintTarget *tgt)
5711 {
5712 LISTBASE_FOREACH (bConstraint *, con, constraints) {
5713 ListBase *targets = NULL;
5714
5715 if (con->type == CONSTRAINT_TYPE_PYTHON) {
5716 targets = &((bPythonConstraint *)con->data)->targets;
5717 }
5718 else if (con->type == CONSTRAINT_TYPE_ARMATURE) {
5719 targets = &((bArmatureConstraint *)con->data)->targets;
5720 }
5721
5722 if (targets && BLI_findindex(targets, tgt) != -1) {
5723 return con;
5724 }
5725 }
5726
5727 return NULL;
5728 }
5729
5730 /* Finds the constraint that owns the given target within the object. */
BKE_constraint_find_from_target(Object * ob,bConstraintTarget * tgt,bPoseChannel ** r_pchan)5731 bConstraint *BKE_constraint_find_from_target(Object *ob,
5732 bConstraintTarget *tgt,
5733 bPoseChannel **r_pchan)
5734 {
5735 if (r_pchan != NULL) {
5736 *r_pchan = NULL;
5737 }
5738
5739 bConstraint *result = constraint_list_find_from_target(&ob->constraints, tgt);
5740
5741 if (result != NULL) {
5742 return result;
5743 }
5744
5745 if (ob->pose != NULL) {
5746 LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
5747 result = constraint_list_find_from_target(&pchan->constraints, tgt);
5748
5749 if (result != NULL) {
5750 if (r_pchan != NULL) {
5751 *r_pchan = pchan;
5752 }
5753
5754 return result;
5755 }
5756 }
5757 }
5758
5759 return NULL;
5760 }
5761
5762 /* Finds the original copy of the constraint based on a COW copy. */
constraint_find_original(Object * ob,bPoseChannel * pchan,bConstraint * con,Object ** r_orig_ob)5763 static bConstraint *constraint_find_original(Object *ob,
5764 bPoseChannel *pchan,
5765 bConstraint *con,
5766 Object **r_orig_ob)
5767 {
5768 Object *orig_ob = (Object *)DEG_get_original_id(&ob->id);
5769
5770 if (ELEM(orig_ob, NULL, ob)) {
5771 return NULL;
5772 }
5773
5774 /* Find which constraint list to use. */
5775 ListBase *constraints, *orig_constraints;
5776
5777 if (pchan != NULL) {
5778 bPoseChannel *orig_pchan = pchan->orig_pchan;
5779
5780 if (orig_pchan == NULL) {
5781 return NULL;
5782 }
5783
5784 constraints = &pchan->constraints;
5785 orig_constraints = &orig_pchan->constraints;
5786 }
5787 else {
5788 constraints = &ob->constraints;
5789 orig_constraints = &orig_ob->constraints;
5790 }
5791
5792 /* Lookup the original constraint by index. */
5793 int index = BLI_findindex(constraints, con);
5794
5795 if (index >= 0) {
5796 bConstraint *orig_con = BLI_findlink(orig_constraints, index);
5797
5798 /* Verify it has correct type and name. */
5799 if (orig_con && orig_con->type == con->type && STREQ(orig_con->name, con->name)) {
5800 if (r_orig_ob != NULL) {
5801 *r_orig_ob = orig_ob;
5802 }
5803
5804 return orig_con;
5805 }
5806 }
5807
5808 return NULL;
5809 }
5810
constraint_find_original_for_update(bConstraintOb * cob,bConstraint * con)5811 static bConstraint *constraint_find_original_for_update(bConstraintOb *cob, bConstraint *con)
5812 {
5813 /* Write the computed distance back to the master copy if in COW evaluation. */
5814 if (!DEG_is_active(cob->depsgraph)) {
5815 return NULL;
5816 }
5817
5818 Object *orig_ob = NULL;
5819 bConstraint *orig_con = constraint_find_original(cob->ob, cob->pchan, con, &orig_ob);
5820
5821 if (orig_con != NULL) {
5822 DEG_id_tag_update(&orig_ob->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_TRANSFORM);
5823 }
5824
5825 return orig_con;
5826 }
5827
5828 /* -------- Constraints and Proxies ------- */
5829
5830 /* Rescue all constraints tagged as being CONSTRAINT_PROXY_LOCAL
5831 * (i.e. added to bone that's proxy-synced in this file) */
BKE_constraints_proxylocal_extract(ListBase * dst,ListBase * src)5832 void BKE_constraints_proxylocal_extract(ListBase *dst, ListBase *src)
5833 {
5834 bConstraint *con, *next;
5835
5836 /* for each tagged constraint, remove from src and move to dst */
5837 for (con = src->first; con; con = next) {
5838 next = con->next;
5839
5840 /* check if tagged */
5841 if (con->flag & CONSTRAINT_PROXY_LOCAL) {
5842 BLI_remlink(src, con);
5843 BLI_addtail(dst, con);
5844 }
5845 }
5846 }
5847
5848 /* Returns if the owner of the constraint is proxy-protected */
BKE_constraints_proxylocked_owner(Object * ob,bPoseChannel * pchan)5849 bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
5850 {
5851 /* Currently, constraints can only be on object or bone level */
5852 if (ob && ob->proxy) {
5853 if (ob->pose && pchan) {
5854 bArmature *arm = ob->data;
5855
5856 /* On bone-level, check if bone is on proxy-protected layer */
5857 if ((pchan->bone) && (pchan->bone->layer & arm->layer_protected)) {
5858 return true;
5859 }
5860 }
5861 else {
5862 /* FIXME: constraints on object-level are not handled well yet */
5863 return true;
5864 }
5865 }
5866
5867 return false;
5868 }
5869
5870 /* -------- Target-Matrix Stuff ------- */
5871
5872 /* This function is a relic from the prior implementations of the constraints system, when all
5873 * constraints either had one or no targets. It used to be called during the main constraint
5874 * solving loop, but is now only used for the remaining cases for a few constraints.
5875 *
5876 * None of the actual calculations of the matrices should be done here! Also, this function is
5877 * not to be used by any new constraints, particularly any that have multiple targets.
5878 */
BKE_constraint_target_matrix_get(struct Depsgraph * depsgraph,Scene * scene,bConstraint * con,int index,short ownertype,void * ownerdata,float mat[4][4],float ctime)5879 void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph,
5880 Scene *scene,
5881 bConstraint *con,
5882 int index,
5883 short ownertype,
5884 void *ownerdata,
5885 float mat[4][4],
5886 float ctime)
5887 {
5888 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
5889 ListBase targets = {NULL, NULL};
5890 bConstraintOb *cob;
5891 bConstraintTarget *ct;
5892
5893 if (cti && cti->get_constraint_targets) {
5894 /* make 'constraint-ob' */
5895 cob = MEM_callocN(sizeof(bConstraintOb), "tempConstraintOb");
5896 cob->type = ownertype;
5897 cob->scene = scene;
5898 cob->depsgraph = depsgraph;
5899 switch (ownertype) {
5900 case CONSTRAINT_OBTYPE_OBJECT: /* it is usually this case */
5901 {
5902 cob->ob = (Object *)ownerdata;
5903 cob->pchan = NULL;
5904 if (cob->ob) {
5905 copy_m4_m4(cob->matrix, cob->ob->obmat);
5906 copy_m4_m4(cob->startmat, cob->matrix);
5907 }
5908 else {
5909 unit_m4(cob->matrix);
5910 unit_m4(cob->startmat);
5911 }
5912 break;
5913 }
5914 case CONSTRAINT_OBTYPE_BONE: /* this may occur in some cases */
5915 {
5916 cob->ob = NULL; /* this might not work at all :/ */
5917 cob->pchan = (bPoseChannel *)ownerdata;
5918 if (cob->pchan) {
5919 copy_m4_m4(cob->matrix, cob->pchan->pose_mat);
5920 copy_m4_m4(cob->startmat, cob->matrix);
5921 }
5922 else {
5923 unit_m4(cob->matrix);
5924 unit_m4(cob->startmat);
5925 }
5926 break;
5927 }
5928 }
5929
5930 /* get targets - we only need the first one though (and there should only be one) */
5931 cti->get_constraint_targets(con, &targets);
5932
5933 /* only calculate the target matrix on the first target */
5934 ct = BLI_findlink(&targets, index);
5935
5936 if (ct) {
5937 if (cti->get_target_matrix) {
5938 cti->get_target_matrix(depsgraph, con, cob, ct, ctime);
5939 }
5940 copy_m4_m4(mat, ct->matrix);
5941 }
5942
5943 /* free targets + 'constraint-ob' */
5944 if (cti->flush_constraint_targets) {
5945 cti->flush_constraint_targets(con, &targets, 1);
5946 }
5947 MEM_freeN(cob);
5948 }
5949 else {
5950 /* invalid constraint - perhaps... */
5951 unit_m4(mat);
5952 }
5953 }
5954
5955 /* Get the list of targets required for solving a constraint */
BKE_constraint_targets_for_solving_get(struct Depsgraph * depsgraph,bConstraint * con,bConstraintOb * cob,ListBase * targets,float ctime)5956 void BKE_constraint_targets_for_solving_get(struct Depsgraph *depsgraph,
5957 bConstraint *con,
5958 bConstraintOb *cob,
5959 ListBase *targets,
5960 float ctime)
5961 {
5962 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
5963
5964 if (cti && cti->get_constraint_targets) {
5965 bConstraintTarget *ct;
5966
5967 /* get targets
5968 * - constraints should use ct->matrix, not directly accessing values
5969 * - ct->matrix members have not yet been calculated here!
5970 */
5971 cti->get_constraint_targets(con, targets);
5972
5973 /* The Armature constraint doesn't need ct->matrix for evaluate at all. */
5974 if (ELEM(cti->type, CONSTRAINT_TYPE_ARMATURE)) {
5975 return;
5976 }
5977
5978 /* set matrices
5979 * - calculate if possible, otherwise just initialize as identity matrix
5980 */
5981 if (cti->get_target_matrix) {
5982 for (ct = targets->first; ct; ct = ct->next) {
5983 cti->get_target_matrix(depsgraph, con, cob, ct, ctime);
5984 }
5985 }
5986 else {
5987 for (ct = targets->first; ct; ct = ct->next) {
5988 unit_m4(ct->matrix);
5989 }
5990 }
5991 }
5992 }
5993
5994 /* ---------- Evaluation ----------- */
5995
5996 /* This function is called whenever constraints need to be evaluated. Currently, all
5997 * constraints that can be evaluated are every time this gets run.
5998 *
5999 * BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
6000 * after running this function, to sort out cob
6001 */
BKE_constraints_solve(struct Depsgraph * depsgraph,ListBase * conlist,bConstraintOb * cob,float ctime)6002 void BKE_constraints_solve(struct Depsgraph *depsgraph,
6003 ListBase *conlist,
6004 bConstraintOb *cob,
6005 float ctime)
6006 {
6007 bConstraint *con;
6008 float oldmat[4][4];
6009 float enf;
6010
6011 /* check that there is a valid constraint object to evaluate */
6012 if (cob == NULL) {
6013 return;
6014 }
6015
6016 /* loop over available constraints, solving and blending them */
6017 for (con = conlist->first; con; con = con->next) {
6018 const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
6019 ListBase targets = {NULL, NULL};
6020
6021 /* these we can skip completely (invalid constraints...) */
6022 if (cti == NULL) {
6023 continue;
6024 }
6025 if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) {
6026 continue;
6027 }
6028 /* these constraints can't be evaluated anyway */
6029 if (cti->evaluate_constraint == NULL) {
6030 continue;
6031 }
6032 /* influence == 0 should be ignored */
6033 if (con->enforce == 0.0f) {
6034 continue;
6035 }
6036
6037 /* influence of constraint
6038 * - value should have been set from animation data already
6039 */
6040 enf = con->enforce;
6041
6042 /* make copy of world-space matrix pre-constraint for use with blending later */
6043 copy_m4_m4(oldmat, cob->matrix);
6044
6045 /* move owner matrix into right space */
6046 BKE_constraint_mat_convertspace(
6047 cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace, false);
6048
6049 /* prepare targets for constraint solving */
6050 BKE_constraint_targets_for_solving_get(depsgraph, con, cob, &targets, ctime);
6051
6052 /* Solve the constraint and put result in cob->matrix */
6053 cti->evaluate_constraint(con, cob, &targets);
6054
6055 /* clear targets after use
6056 * - this should free temp targets but no data should be copied back
6057 * as constraints may have done some nasty things to it...
6058 */
6059 if (cti->flush_constraint_targets) {
6060 cti->flush_constraint_targets(con, &targets, 1);
6061 }
6062
6063 /* move owner back into world-space for next constraint/other business */
6064 if ((con->flag & CONSTRAINT_SPACEONCE) == 0) {
6065 BKE_constraint_mat_convertspace(
6066 cob->ob, cob->pchan, cob->matrix, con->ownspace, CONSTRAINT_SPACE_WORLD, false);
6067 }
6068
6069 /* Interpolate the enforcement, to blend result of constraint into final owner transform
6070 * - all this happens in world-space to prevent any weirdness creeping in
6071 * (T26014 and T25725), since some constraints may not convert the solution back to the input
6072 * space before blending but all are guaranteed to end up in good "world-space" result.
6073 */
6074 /* Note: all kind of stuff here before (caused trouble), much easier to just interpolate,
6075 * or did I miss something? -jahka (r.32105) */
6076 if (enf < 1.0f) {
6077 float solution[4][4];
6078 copy_m4_m4(solution, cob->matrix);
6079 interp_m4_m4m4(cob->matrix, oldmat, solution, enf);
6080 }
6081 }
6082 }
6083