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