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