Blender  V3.3
iksolver_plugin.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "BIK_api.h"
11 #include "BLI_blenlib.h"
12 #include "BLI_math.h"
13 #include "BLI_utildefines.h"
14 
15 #include "BKE_armature.h"
16 #include "BKE_constraint.h"
17 
18 #include "DNA_action_types.h"
19 #include "DNA_armature_types.h"
20 #include "DNA_constraint_types.h"
21 #include "DNA_object_types.h"
22 
23 #include "IK_solver.h"
24 #include "iksolver_plugin.h"
25 
26 #include <string.h> /* memcpy */
27 
28 #define USE_NONUNIFORM_SCALE
29 
30 /* ********************** THE IK SOLVER ******************* */
31 
32 /* allocates PoseTree, and links that to root bone/channel */
33 /* NOTE: detecting the IK chain is duplicate code...
34  * in drawarmature.c and in transform_conversions.c */
35 static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_tip)
36 {
37  bPoseChannel *curchan, *pchan_root = NULL, *chanlist[256], **oldchan;
38  PoseTree *tree;
39  PoseTarget *target;
40  bConstraint *con;
42  int a, t, segcount = 0, size, newsize, *oldparent, parent;
43 
44  /* find IK constraint, and validate it */
45  for (con = pchan_tip->constraints.first; con; con = con->next) {
46  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
47  data = (bKinematicConstraint *)con->data;
48  if (data->flag & CONSTRAINT_IK_AUTO) {
49  break;
50  }
51  if (data->tar == NULL) {
52  continue;
53  }
54  if (data->tar->type == OB_ARMATURE && data->subtarget[0] == 0) {
55  continue;
56  }
57  if ((con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) == 0 && (con->enforce != 0.0f)) {
58  break;
59  }
60  }
61  }
62  if (con == NULL) {
63  return;
64  }
65 
66  /* exclude tip from chain? */
67  if (!(data->flag & CONSTRAINT_IK_TIP)) {
68  pchan_tip = pchan_tip->parent;
69  }
70 
71  /* Find the chain's root & count the segments needed */
72  for (curchan = pchan_tip; curchan; curchan = curchan->parent) {
73  pchan_root = curchan;
74 
75  curchan->flag |= POSE_CHAIN; /* don't forget to clear this */
76  chanlist[segcount] = curchan;
77  segcount++;
78 
79  if (segcount == data->rootbone || segcount > 255) {
80  break; /* 255 is weak */
81  }
82  }
83  if (!segcount) {
84  return;
85  }
86 
87  /* setup the chain data */
88 
89  /* we make tree-IK, unless all existing targets are in this chain */
90  for (tree = pchan_root->iktree.first; tree; tree = tree->next) {
91  for (target = tree->targets.first; target; target = target->next) {
92  curchan = tree->pchan[target->tip];
93  if (curchan->flag & POSE_CHAIN) {
94  curchan->flag &= ~POSE_CHAIN;
95  }
96  else {
97  break;
98  }
99  }
100  if (target) {
101  break;
102  }
103  }
104 
105  /* create a target */
106  target = MEM_callocN(sizeof(PoseTarget), "posetarget");
107  target->con = con;
108  pchan_tip->flag &= ~POSE_CHAIN;
109 
110  if (tree == NULL) {
111  /* make new tree */
112  tree = MEM_callocN(sizeof(PoseTree), "posetree");
113 
115 
116  tree->iterations = data->iterations;
117  tree->totchannel = segcount;
118  tree->stretch = (data->flag & CONSTRAINT_IK_STRETCH);
119 
120  tree->pchan = MEM_callocN(segcount * sizeof(void *), "ik tree pchan");
121  tree->parent = MEM_callocN(segcount * sizeof(int), "ik tree parent");
122  for (a = 0; a < segcount; a++) {
123  tree->pchan[a] = chanlist[segcount - a - 1];
124  tree->parent[a] = a - 1;
125  }
126  target->tip = segcount - 1;
127 
128  /* AND! link the tree to the root */
129  BLI_addtail(&pchan_root->iktree, tree);
130  }
131  else {
132  tree->iterations = MAX2(data->iterations, tree->iterations);
133  tree->stretch = tree->stretch && !(data->flag & CONSTRAINT_IK_STRETCH);
134 
135  /* Skip common pose channels and add remaining. */
136  size = MIN2(segcount, tree->totchannel);
137  a = t = 0;
138  while (a < size && t < tree->totchannel) {
139  /* locate first matching channel */
140  for (; t < tree->totchannel && tree->pchan[t] != chanlist[segcount - a - 1]; t++) {
141  /* pass */
142  }
143  if (t >= tree->totchannel) {
144  break;
145  }
146  for (; a < size && t < tree->totchannel && tree->pchan[t] == chanlist[segcount - a - 1];
147  a++, t++) {
148  /* pass */
149  }
150  }
151 
152  segcount = segcount - a;
153  target->tip = tree->totchannel + segcount - 1;
154 
155  if (segcount > 0) {
156  for (parent = a - 1; parent < tree->totchannel; parent++) {
157  if (tree->pchan[parent] == chanlist[segcount - 1]->parent) {
158  break;
159  }
160  }
161 
162  /* shouldn't happen, but could with dependency cycles */
163  if (parent == tree->totchannel) {
164  parent = a - 1;
165  }
166 
167  /* resize array */
168  newsize = tree->totchannel + segcount;
169  oldchan = tree->pchan;
170  oldparent = tree->parent;
171 
172  tree->pchan = MEM_callocN(newsize * sizeof(void *), "ik tree pchan");
173  tree->parent = MEM_callocN(newsize * sizeof(int), "ik tree parent");
174  memcpy(tree->pchan, oldchan, sizeof(void *) * tree->totchannel);
175  memcpy(tree->parent, oldparent, sizeof(int) * tree->totchannel);
176  MEM_freeN(oldchan);
177  MEM_freeN(oldparent);
178 
179  /* add new pose channels at the end, in reverse order */
180  for (a = 0; a < segcount; a++) {
181  tree->pchan[tree->totchannel + a] = chanlist[segcount - a - 1];
182  tree->parent[tree->totchannel + a] = tree->totchannel + a - 1;
183  }
184  tree->parent[tree->totchannel] = parent;
185 
186  tree->totchannel = newsize;
187  }
188 
189  /* move tree to end of list, for correct evaluation order */
190  BLI_remlink(&pchan_root->iktree, tree);
191  BLI_addtail(&pchan_root->iktree, tree);
192  }
193 
194  /* add target to the tree */
195  BLI_addtail(&tree->targets, target);
196  /* mark root channel having an IK tree */
197  pchan_root->flag |= POSE_IKTREE;
198 }
199 
200 /* transform from bone(b) to bone(b+1), store in chan_mat */
201 static void make_dmats(bPoseChannel *pchan)
202 {
203  if (pchan->parent) {
204  float iR_parmat[4][4];
205  invert_m4_m4(iR_parmat, pchan->parent->pose_mat);
206  mul_m4_m4m4(pchan->chan_mat, iR_parmat, pchan->pose_mat); /* delta mat */
207  }
208  else {
209  copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
210  }
211 }
212 
213 /* applies IK matrix to pchan, IK is done separated */
214 /* formula: pose_mat(b) = pose_mat(b-1) * diffmat(b-1, b) * ik_mat(b) */
215 /* to make this work, the diffmats have to be precalculated! Stored in chan_mat */
216 static void where_is_ik_bone(bPoseChannel *pchan,
217  float ik_mat[3][3]) /* nr = to detect if this is first bone */
218 {
219  float vec[3], ikmat[4][4];
220 
221  copy_m4_m3(ikmat, ik_mat);
222 
223  if (pchan->parent) {
224  mul_m4_m4m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat);
225  }
226  else {
227  copy_m4_m4(pchan->pose_mat, pchan->chan_mat);
228  }
229 
230 #ifdef USE_NONUNIFORM_SCALE
231  /* apply IK mat, but as if the bones have uniform scale since the IK solver
232  * is not aware of non-uniform scale */
233  float scale[3];
234  mat4_to_size(scale, pchan->pose_mat);
235  normalize_v3_length(pchan->pose_mat[0], scale[1]);
236  normalize_v3_length(pchan->pose_mat[2], scale[1]);
237 #endif
238 
239  mul_m4_m4m4(pchan->pose_mat, pchan->pose_mat, ikmat);
240 
241 #ifdef USE_NONUNIFORM_SCALE
242  float ik_scale[3];
243  mat3_to_size(ik_scale, ik_mat);
244  normalize_v3_length(pchan->pose_mat[0], scale[0] * ik_scale[0]);
245  normalize_v3_length(pchan->pose_mat[2], scale[2] * ik_scale[2]);
246 #endif
247 
248  /* calculate head */
249  copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
250  /* calculate tail */
251  copy_v3_v3(vec, pchan->pose_mat[1]);
252  mul_v3_fl(vec, pchan->bone->length);
253  add_v3_v3v3(pchan->pose_tail, pchan->pose_head, vec);
254 
255  pchan->flag |= POSE_DONE;
256 }
257 
263  struct Scene *scene,
264  Object *ob,
265  PoseTree *tree)
266 {
267  float R_parmat[3][3], identity[3][3];
268  float iR_parmat[3][3];
269  float R_bonemat[3][3];
270  float goalrot[3][3], goalpos[3];
271  float rootmat[4][4], imat[4][4];
272  float goal[4][4], goalinv[4][4];
273  float irest_basis[3][3], full_basis[3][3];
274  float end_pose[4][4], world_pose[4][4];
275  float basis[3][3], rest_basis[3][3], start[3], *ikstretch = NULL;
276  float resultinf = 0.0f;
277  int a, flag, hasstretch = 0, resultblend = 0;
278  bPoseChannel *pchan;
279  IK_Segment *seg, *parent, **iktree, *iktarget;
280  IK_Solver *solver;
281  PoseTarget *target;
282  bKinematicConstraint *data, *poleangledata = NULL;
283  Bone *bone;
284 
285  if (tree->totchannel == 0) {
286  return;
287  }
288 
289  iktree = MEM_mallocN(sizeof(void *) * tree->totchannel, "ik tree");
290 
291  for (a = 0; a < tree->totchannel; a++) {
292  float length;
293  pchan = tree->pchan[a];
294  bone = pchan->bone;
295 
296  /* set DoF flag */
297  flag = 0;
298  if (!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP)) {
299  flag |= IK_XDOF;
300  }
301  if (!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP)) {
302  flag |= IK_YDOF;
303  }
304  if (!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP)) {
305  flag |= IK_ZDOF;
306  }
307 
308  if (tree->stretch && (pchan->ikstretch > 0.0f)) {
309  flag |= IK_TRANS_YDOF;
310  hasstretch = 1;
311  }
312 
313  seg = iktree[a] = IK_CreateSegment(flag);
314 
315  /* find parent */
316  if (a == 0) {
317  parent = NULL;
318  }
319  else {
320  parent = iktree[tree->parent[a]];
321  }
322 
323  IK_SetParent(seg, parent);
324 
325  /* get the matrix that transforms from prevbone into this bone */
326  copy_m3_m4(R_bonemat, pchan->pose_mat);
327 
328  /* gather transformations for this IK segment */
329 
330  if (pchan->parent) {
331  copy_m3_m4(R_parmat, pchan->parent->pose_mat);
332  }
333  else {
334  unit_m3(R_parmat);
335  }
336 
337  /* bone offset */
338  if (pchan->parent && (a > 0)) {
339  sub_v3_v3v3(start, pchan->pose_head, pchan->parent->pose_tail);
340  }
341  else {
342  /* only root bone (a = 0) has no parent */
343  start[0] = start[1] = start[2] = 0.0f;
344  }
345 
346  /* change length based on bone size */
347  length = bone->length * len_v3(R_bonemat[1]);
348 
349  /* basis must be pure rotation */
350  normalize_m3(R_bonemat);
351  normalize_m3(R_parmat);
352 
353  /* compute rest basis and its inverse */
354  copy_m3_m3(rest_basis, bone->bone_mat);
355  transpose_m3_m3(irest_basis, bone->bone_mat);
356 
357  /* compute basis with rest_basis removed */
358  invert_m3_m3(iR_parmat, R_parmat);
359  mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
360  mul_m3_m3m3(basis, irest_basis, full_basis);
361 
362  /* transform offset into local bone space */
363  mul_m3_v3(iR_parmat, start);
364 
365  IK_SetTransform(seg, start, rest_basis, basis, length);
366 
367  if (pchan->ikflag & BONE_IK_XLIMIT) {
368  IK_SetLimit(seg, IK_X, pchan->limitmin[0], pchan->limitmax[0]);
369  }
370  if (pchan->ikflag & BONE_IK_YLIMIT) {
371  IK_SetLimit(seg, IK_Y, pchan->limitmin[1], pchan->limitmax[1]);
372  }
373  if (pchan->ikflag & BONE_IK_ZLIMIT) {
374  IK_SetLimit(seg, IK_Z, pchan->limitmin[2], pchan->limitmax[2]);
375  }
376 
377  IK_SetStiffness(seg, IK_X, pchan->stiffness[0]);
378  IK_SetStiffness(seg, IK_Y, pchan->stiffness[1]);
379  IK_SetStiffness(seg, IK_Z, pchan->stiffness[2]);
380 
381  if (tree->stretch && (pchan->ikstretch > 0.0f)) {
382  const float ikstretch_sq = square_f(pchan->ikstretch);
383  /* this function does its own clamping */
384  IK_SetStiffness(seg, IK_TRANS_Y, 1.0f - ikstretch_sq);
386  }
387  }
388 
389  solver = IK_CreateSolver(iktree[0]);
390 
391  /* set solver goals */
392 
393  /* first set the goal inverse transform, assuming the root of tree was done ok! */
394  pchan = tree->pchan[0];
395  if (pchan->parent) {
396  /* transform goal by parent mat, so this rotation is not part of the
397  * segment's basis. otherwise rotation limits do not work on the
398  * local transform of the segment itself. */
399  copy_m4_m4(rootmat, pchan->parent->pose_mat);
400  /* However, we do not want to get (i.e. reverse) parent's scale,
401  * as it generates T31008 kind of nasty bugs. */
402  normalize_m4(rootmat);
403  }
404  else {
405  unit_m4(rootmat);
406  }
407  copy_v3_v3(rootmat[3], pchan->pose_head);
408 
409  mul_m4_m4m4(imat, ob->obmat, rootmat);
410  invert_m4_m4(goalinv, imat);
411 
412  for (target = tree->targets.first; target; target = target->next) {
413  float polepos[3];
414  int poleconstrain = 0;
415 
416  data = (bKinematicConstraint *)target->con->data;
417 
418  /* 1.0=ctime, we pass on object for auto-ik (owner-type here is object, even though
419  * strictly speaking, it is a posechannel)
420  */
422  depsgraph, scene, target->con, 0, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
423 
424  /* and set and transform goal */
425  mul_m4_m4m4(goal, goalinv, rootmat);
426 
427  copy_v3_v3(goalpos, goal[3]);
428  copy_m3_m4(goalrot, goal);
429  normalize_m3(goalrot);
430 
431  /* same for pole vector target */
432  if (data->poletar) {
434  depsgraph, scene, target->con, 1, CONSTRAINT_OBTYPE_OBJECT, ob, rootmat, 1.0);
435 
436  if (data->flag & CONSTRAINT_IK_SETANGLE) {
437  /* don't solve IK when we are setting the pole angle */
438  break;
439  }
440 
441  mul_m4_m4m4(goal, goalinv, rootmat);
442  copy_v3_v3(polepos, goal[3]);
443  poleconstrain = 1;
444 
445  /* for pole targets, we blend the result of the ik solver
446  * instead of the target position, otherwise we can't get
447  * a smooth transition */
448  resultblend = 1;
449  resultinf = target->con->enforce;
450 
451  if (data->flag & CONSTRAINT_IK_GETANGLE) {
452  poleangledata = data;
453  data->flag &= ~CONSTRAINT_IK_GETANGLE;
454  }
455  }
456 
457  /* do we need blending? */
458  if (!resultblend && target->con->enforce != 1.0f) {
459  float q1[4], q2[4], q[4];
460  float fac = target->con->enforce;
461  float mfac = 1.0f - fac;
462 
463  pchan = tree->pchan[target->tip];
464 
465  /* end effector in world space */
466  copy_m4_m4(end_pose, pchan->pose_mat);
467  copy_v3_v3(end_pose[3], pchan->pose_tail);
468  mul_m4_series(world_pose, goalinv, ob->obmat, end_pose);
469 
470  /* blend position */
471  goalpos[0] = fac * goalpos[0] + mfac * world_pose[3][0];
472  goalpos[1] = fac * goalpos[1] + mfac * world_pose[3][1];
473  goalpos[2] = fac * goalpos[2] + mfac * world_pose[3][2];
474 
475  /* blend rotation */
476  mat3_to_quat(q1, goalrot);
477  mat4_to_quat(q2, world_pose);
478  interp_qt_qtqt(q, q1, q2, mfac);
479  quat_to_mat3(goalrot, q);
480  }
481 
482  iktarget = iktree[target->tip];
483 
484  if ((data->flag & CONSTRAINT_IK_POS) && data->weight != 0.0f) {
485  if (poleconstrain) {
487  solver, iktarget, goalpos, polepos, data->poleangle, (poleangledata == data));
488  }
489  IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
490  }
491  if ((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0f)) {
492  if ((data->flag & CONSTRAINT_IK_AUTO) == 0) {
493  IK_SolverAddGoalOrientation(solver, iktarget, goalrot, data->orientweight);
494  }
495  }
496  }
497 
498  /* solve */
499  IK_Solve(solver, 0.0f, tree->iterations);
500 
501  if (poleangledata) {
502  poleangledata->poleangle = IK_SolverGetPoleAngle(solver);
503  }
504 
505  IK_FreeSolver(solver);
506 
507  /* gather basis changes */
508  tree->basis_change = MEM_mallocN(sizeof(float[3][3]) * tree->totchannel, "ik basis change");
509  if (hasstretch) {
510  ikstretch = MEM_mallocN(sizeof(float) * tree->totchannel, "ik stretch");
511  }
512 
513  for (a = 0; a < tree->totchannel; a++) {
514  IK_GetBasisChange(iktree[a], tree->basis_change[a]);
515 
516  if (hasstretch) {
517  /* have to compensate for scaling received from parent */
518  float parentstretch, stretch;
519 
520  pchan = tree->pchan[a];
521  parentstretch = (tree->parent[a] >= 0) ? ikstretch[tree->parent[a]] : 1.0f;
522 
523  if (tree->stretch && (pchan->ikstretch > 0.0f)) {
524  float trans[3], length;
525 
526  IK_GetTranslationChange(iktree[a], trans);
527  length = pchan->bone->length * len_v3(pchan->pose_mat[1]);
528 
529  ikstretch[a] = (length == 0.0f) ? 1.0f : (trans[1] + length) / length;
530  }
531  else {
532  ikstretch[a] = 1.0;
533  }
534 
535  stretch = (parentstretch == 0.0f) ? 1.0f : ikstretch[a] / parentstretch;
536 
537  mul_v3_fl(tree->basis_change[a][0], stretch);
538  mul_v3_fl(tree->basis_change[a][1], stretch);
539  mul_v3_fl(tree->basis_change[a][2], stretch);
540  }
541 
542  if (resultblend && resultinf != 1.0f) {
543  unit_m3(identity);
544  blend_m3_m3m3(tree->basis_change[a], identity, tree->basis_change[a], resultinf);
545  }
546 
547  IK_FreeSegment(iktree[a]);
548  }
549 
550  MEM_freeN(iktree);
551  if (ikstretch) {
552  MEM_freeN(ikstretch);
553  }
554 }
555 
557 {
558  BLI_freelistN(&tree->targets);
559  if (tree->pchan) {
560  MEM_freeN(tree->pchan);
561  }
562  if (tree->parent) {
563  MEM_freeN(tree->parent);
564  }
565  if (tree->basis_change) {
566  MEM_freeN(tree->basis_change);
567  }
568  MEM_freeN(tree);
569 }
570 
571 /* ------------------------------
572  * Plugin API for legacy iksolver */
573 
575  struct Scene *UNUSED(scene),
576  struct Object *ob,
577  float UNUSED(ctime))
578 {
579  bPoseChannel *pchan;
580 
581  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
582  if (pchan->constflag & PCHAN_HAS_IK) { /* flag is set on editing constraints */
583  initialize_posetree(ob, pchan); /* will attach it to root! */
584  }
585  }
586  ob->pose->flag &= ~POSE_WAS_REBUILT;
587 }
588 
590  struct Scene *scene,
591  Object *ob,
592  bPoseChannel *pchan_root,
593  float ctime)
594 {
595  while (pchan_root->iktree.first) {
596  PoseTree *tree = pchan_root->iktree.first;
597  int a;
598 
599  /* stop on the first tree that isn't a standard IK chain */
600  if (tree->type != CONSTRAINT_TYPE_KINEMATIC) {
601  return;
602  }
603 
604  /* 4. walk over the tree for regular solving */
605  for (a = 0; a < tree->totchannel; a++) {
606  if (!(tree->pchan[a]->flag & POSE_DONE)) { /* successive trees can set the flag */
607  BKE_pose_where_is_bone(depsgraph, scene, ob, tree->pchan[a], ctime, 1);
608  }
609  /* Tell blender that this channel was controlled by IK,
610  * it's cleared on each BKE_pose_where_is(). */
611  tree->pchan[a]->flag |= POSE_CHAIN;
612  }
613 
614  /* 5. execute the IK solver */
616 
617  /* 6. apply the differences to the channels,
618  * we need to calculate the original differences first */
619  for (a = 0; a < tree->totchannel; a++) {
620  make_dmats(tree->pchan[a]);
621  }
622 
623  for (a = 0; a < tree->totchannel; a++) {
624  /* sets POSE_DONE */
625  where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
626  }
627 
628  /* 7. and free */
629  BLI_remlink(&pchan_root->iktree, tree);
631  }
632 }
633 
634 void iksolver_release_tree(struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
635 {
637 }
638 
640 {
641  LISTBASE_FOREACH (bPoseChannel *, pchan, &pose->chanbase) {
642  if ((pchan->flag & POSE_IKTREE) == 0) {
643  continue;
644  }
645 
646  while (pchan->iktree.first) {
647  PoseTree *tree = pchan->iktree.first;
648 
649  /* stop on the first tree that isn't a standard IK chain */
650  if (tree->type != CONSTRAINT_TYPE_KINEMATIC) {
651  break;
652  }
653 
654  BLI_remlink(&pchan->iktree, tree);
656  }
657  }
658 }
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra)
Definition: armature.c:2474
void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, struct Scene *scene, struct bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
Definition: constraint.c:6214
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
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
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
MINLINE float square_f(float a)
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void copy_m3_m3(float m1[3][3], const float m2[3][3])
Definition: math_matrix.c:71
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 copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:102
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1912
#define mul_m4_series(...)
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 mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2138
void transpose_m3_m3(float R[3][3], const float M[3][3])
Definition: math_matrix.c:1347
void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], float srcweight)
Definition: math_matrix.c:2383
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:388
void mat3_to_size(float size[3], const float M[3][3])
Definition: math_matrix.c:2131
void normalize_m4(float R[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1945
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void mat3_to_quat(float q[4], const float mat[3][3])
void mat4_to_quat(float q[4], const float mat[4][4])
void quat_to_mat3(float mat[3][3], const float q[4])
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 add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_length(float r[3], float unit_scale)
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define UNUSED(x)
#define MAX2(a, b)
#define MIN2(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ BONE_IK_ZLIMIT
@ BONE_IK_NO_YDOF_TEMP
@ BONE_IK_XLIMIT
@ BONE_IK_NO_XDOF_TEMP
@ BONE_IK_NO_ZDOF
@ BONE_IK_NO_ZDOF_TEMP
@ BONE_IK_YLIMIT
@ BONE_IK_NO_YDOF
@ BONE_IK_NO_XDOF
@ PCHAN_HAS_IK
@ POSE_DONE
@ POSE_IKTREE
@ POSE_CHAIN
@ POSE_WAS_REBUILT
@ CONSTRAINT_OFF
@ CONSTRAINT_DISABLE
@ CONSTRAINT_IK_ROT
@ CONSTRAINT_IK_GETANGLE
@ CONSTRAINT_IK_SETANGLE
@ CONSTRAINT_IK_POS
@ CONSTRAINT_IK_AUTO
@ CONSTRAINT_IK_STRETCH
@ CONSTRAINT_IK_TIP
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_OBTYPE_OBJECT
Object is a sort of wrapper for general info.
@ OB_ARMATURE
_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
IK_Solver * IK_CreateSolver(IK_Segment *root)
Definition: IK_Solver.cpp:259
float IK_SolverGetPoleAngle(IK_Solver *solver)
Definition: IK_Solver.cpp:355
#define IK_STRETCH_STIFF_MAX
Definition: IK_solver.h:146
IK_Segment * IK_CreateSegment(int flag)
Definition: IK_Solver.cpp:87
void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle)
Definition: IK_Solver.cpp:332
void IK_Segment
Definition: IK_solver.h:79
void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
Definition: IK_Solver.cpp:121
void IK_FreeSolver(IK_Solver *solver)
Definition: IK_Solver.cpp:270
#define IK_STRETCH_STIFF_MIN
Definition: IK_solver.h:145
void IK_FreeSegment(IK_Segment *seg)
Definition: IK_Solver.cpp:112
@ IK_TRANS_YDOF
Definition: IK_solver.h:86
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight)
Definition: IK_Solver.cpp:304
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
Definition: IK_Solver.cpp:171
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight)
Definition: IK_Solver.cpp:285
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
Definition: IK_Solver.cpp:386
void IK_SetTransform(IK_Segment *seg, float start[3], float rest_basis[][3], float basis[][3], float length)
Definition: IK_Solver.cpp:132
void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
Definition: IK_Solver.cpp:224
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
Definition: IK_Solver.cpp:194
void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
Definition: IK_Solver.cpp:245
void IK_Solver
Definition: IK_solver.h:124
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
const Depsgraph * depsgraph
void * tree
void iksolver_execute_tree(struct Depsgraph *depsgraph, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
void iksolver_initialize_tree(struct Depsgraph *UNUSED(depsgraph), struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
static void free_posetree(PoseTree *tree)
static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3])
void iksolver_clear_data(bPose *pose)
static void make_dmats(bPoseChannel *pchan)
static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_tip)
static void execute_posetree(struct Depsgraph *depsgraph, struct Scene *scene, Object *ob, PoseTree *tree)
void iksolver_release_tree(struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
@ IK_ZDOF
@ IK_XDOF
@ IK_YDOF
@ IK_X
@ IK_Y
@ IK_TRANS_Y
@ IK_Z
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
static unsigned a[3]
Definition: RandGen.cpp:78
T length(const vec_base< T, Size > &a)
float length
float bone_mat[3][3]
void * first
Definition: DNA_listBase.h:31
struct bPose * pose
float obmat[4][4]
struct PoseTarget * next
Definition: BKE_armature.h:113
struct bConstraint * con
Definition: BKE_armature.h:115
struct bConstraint * next
ListBase constraints
struct Bone * bone
struct bPoseChannel * parent
float stiffness[3]
struct ListBase iktree
float pose_head[3]
float chan_mat[4][4]
float pose_tail[3]
struct bPoseChannel * next
float pose_mat[4][4]
ListBase chanbase
short flag