Blender  V2.93
armature_update.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2015 Blender Foundation.
17  * All rights reserved.
18  *
19  * Defines and code for core node types
20  */
21 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_listbase.h"
29 #include "BLI_math.h"
30 #include "BLI_utildefines.h"
31 
32 #include "DNA_armature_types.h"
33 #include "DNA_constraint_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36 
37 #include "BKE_action.h"
38 #include "BKE_anim_path.h"
39 #include "BKE_armature.h"
40 #include "BKE_curve.h"
41 #include "BKE_displist.h"
42 #include "BKE_fcurve.h"
43 #include "BKE_object.h"
44 #include "BKE_scene.h"
45 
46 #include "BIK_api.h"
47 
48 #include "DEG_depsgraph.h"
49 
50 /* ********************** SPLINE IK SOLVER ******************* */
51 
52 /* Temporary evaluation tree data used for Spline IK */
53 typedef struct tSplineIK_Tree {
55 
56  int type; /* type of IK that this serves (CONSTRAINT_TYPE_KINEMATIC or ..._SPLINEIK) */
57 
58  short chainlen; /* number of bones in the chain */
59  float totlength; /* total length of bones in the chain */
60 
61  const float *points; /* parametric positions for the joints along the curve */
62  bPoseChannel **chain; /* chain of bones to affect using Spline IK (ordered from the tip) */
63 
64  bPoseChannel *root; /* bone that is the root node of the chain */
65 
66  bConstraint *con; /* constraint for this chain */
67  bSplineIKConstraint *ik_data; /* constraint settings for this chain */
69 
70 /* ----------- */
71 
72 /* Tag the bones in the chain formed by the given bone for IK. */
74  Object *UNUSED(ob),
75  bPoseChannel *pchan_tip)
76 {
77  bPoseChannel *pchan, *pchan_root = NULL;
78  bPoseChannel *pchan_chain[255];
79  bConstraint *con = NULL;
81  float bone_lengths[255];
82  float totlength = 0.0f;
83  int segcount = 0;
84 
85  /* Find the SplineIK constraint. */
86  for (con = pchan_tip->constraints.first; con; con = con->next) {
88  ik_data = con->data;
89 
90  /* Target can only be a curve. */
91  if ((ik_data->tar == NULL) || (ik_data->tar->type != OB_CURVE)) {
92  continue;
93  }
94  /* Skip if disabled. */
95  if ((con->enforce == 0.0f) || (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF))) {
96  continue;
97  }
98 
99  /* Otherwise, constraint is ok... */
100  break;
101  }
102  }
103  if (con == NULL) {
104  return;
105  }
106 
107  /* Find the root bone and the chain of bones from the root to the tip.
108  * NOTE: this assumes that the bones are connected, but that may not be true... */
109  for (pchan = pchan_tip; pchan && (segcount < ik_data->chainlen);
110  pchan = pchan->parent, segcount++) {
111  /* Store this segment in the chain. */
112  pchan_chain[segcount] = pchan;
113 
114  /* If performing rebinding, calculate the length of the bone. */
115  bone_lengths[segcount] = pchan->bone->length;
116  totlength += bone_lengths[segcount];
117  }
118 
119  if (segcount == 0) {
120  return;
121  }
122 
123  pchan_root = pchan_chain[segcount - 1];
124 
125  /* Perform binding step if required. */
126  if ((ik_data->flag & CONSTRAINT_SPLINEIK_BOUND) == 0) {
127  float segmentLen = (1.0f / (float)segcount);
128 
129  /* Setup new empty array for the points list. */
130  if (ik_data->points) {
132  }
134  ik_data->points = MEM_mallocN(sizeof(float) * ik_data->numpoints, "Spline IK Binding");
135 
136  /* Bind 'tip' of chain (i.e. first joint = tip of bone with the Spline IK Constraint). */
137  ik_data->points[0] = 1.0f;
138 
139  /* Perform binding of the joints to parametric positions along the curve based
140  * proportion of the total length that each bone occupies.
141  */
142  for (int i = 0; i < segcount; i++) {
143  /* 'head' joints, traveling towards the root of the chain.
144  * - 2 methods; the one chosen depends on whether we've got usable lengths.
145  */
146  if ((ik_data->flag & CONSTRAINT_SPLINEIK_EVENSPLITS) || (totlength == 0.0f)) {
147  /* 1) Equi-spaced joints. */
148  ik_data->points[i + 1] = ik_data->points[i] - segmentLen;
149  }
150  else {
151  /* 2) To find this point on the curve, we take a step from the previous joint
152  * a distance given by the proportion that this bone takes.
153  */
154  ik_data->points[i + 1] = ik_data->points[i] - (bone_lengths[i] / totlength);
155  }
156  }
157 
158  /* Spline has now been bound. */
160  }
161 
162  /* Disallow negative values (happens with float precision). */
163  CLAMP_MIN(ik_data->points[segcount], 0.0f);
164 
165  /* Make a new Spline-IK chain, and store it in the IK chains. */
166  /* TODO: we should check if there is already an IK chain on this,
167  * since that would take precedence... */
168  {
169  /* Make a new tree. */
170  tSplineIK_Tree *tree = MEM_callocN(sizeof(tSplineIK_Tree), "SplineIK Tree");
172 
173  tree->chainlen = segcount;
174  tree->totlength = totlength;
175 
176  /* Copy over the array of links to bones in the chain (from tip to root). */
177  tree->chain = MEM_mallocN(sizeof(bPoseChannel *) * segcount, "SplineIK Chain");
178  memcpy(tree->chain, pchan_chain, sizeof(bPoseChannel *) * segcount);
179 
180  /* Store reference to joint position array. */
181  tree->points = ik_data->points;
182 
183  /* Store references to different parts of the chain. */
184  tree->root = pchan_root;
185  tree->con = con;
186  tree->ik_data = ik_data;
187 
188  /* AND! Link the tree to the root. */
189  BLI_addtail(&pchan_root->siktree, tree);
190  }
191 
192  /* Mark root channel having an IK tree. */
193  pchan_root->flag |= POSE_IKSPLINE;
194 }
195 
196 /* Tag which bones are members of Spline IK chains. */
197 static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime))
198 {
199  bPoseChannel *pchan;
200 
201  /* Find the tips of Spline IK chains,
202  * which are simply the bones which have been tagged as such. */
203  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
204  if (pchan->constflag & PCHAN_HAS_SPLINEIK) {
206  }
207  }
208 }
209 
210 /* ----------- */
211 
212 typedef struct tSplineIk_EvalState {
213  float curve_position; /* Current position along the curve. */
214  float curve_scale; /* Global scale to apply to curve positions. */
215  float locrot_offset[4][4]; /* Bone rotation and location offset inherited from parent. */
216  float prev_tail_loc[3]; /* Tail location of the previous bone. */
217  float prev_tail_radius; /* Tail curve radius of the previous bone. */
218  int prev_tail_seg_idx; /* Curve segment the previous tail bone belongs to. */
220 
221 /* Prepare data to evaluate spline IK. */
223 {
224  bSplineIKConstraint *ik_data = tree->ik_data;
225 
226  /* Make sure that the constraint targets are ok, to avoid crashes
227  * in case of a depsgraph bug or dependency cycle.
228  */
229  if (ik_data->tar == NULL) {
230  return false;
231  }
232 
233  CurveCache *cache = ik_data->tar->runtime.curve_cache;
234 
235  if (ELEM(NULL, cache, cache->anim_path_accum_length)) {
236  return false;
237  }
238 
239  /* Initialize the evaluation state. */
240  state->curve_position = 0.0f;
241  state->curve_scale = 1.0f;
242  unit_m4(state->locrot_offset);
243  zero_v3(state->prev_tail_loc);
244  state->prev_tail_radius = 1.0f;
245  state->prev_tail_seg_idx = 0;
246 
247  /* Apply corrections for sensitivity to scaling. */
248  if ((ik_data->yScaleMode != CONSTRAINT_SPLINEIK_YS_FIT_CURVE) && (tree->totlength != 0.0f)) {
249  /* Get the current length of the curve. */
250  /* NOTE: This is assumed to be correct even after the curve was resized. */
251  const float spline_len = BKE_anim_path_get_length(cache);
252 
253  /* Calculate the scale factor to multiply all the path values by so that the
254  * bone chain retains its current length, such that:
255  * maxScale * splineLen = totLength
256  */
257  state->curve_scale = tree->totlength / spline_len;
258  }
259 
260  return true;
261 }
262 
264  bSplineIKConstraint *ik_data, Object *ob, float radius, float r_vec[3], float *r_radius)
265 {
266  /* Apply the curve's object-mode transforms to the position
267  * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root).
268  */
269  if ((ik_data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) == 0) {
270  mul_m4_v3(ik_data->tar->obmat, r_vec);
271  }
272 
273  /* Convert the position to pose-space. */
274  mul_m4_v3(ob->imat, r_vec);
275 
276  /* Set the new radius (it should be the average value). */
277  *r_radius = (radius + *r_radius) / 2;
278 }
279 
280 static float dist_to_sphere_shell(const float sphere_origin[3],
281  const float sphere_radius,
282  const float point[3])
283 {
284  float vec[3];
285  sub_v3_v3v3(vec, sphere_origin, point);
286  return sphere_radius - len_v3(vec);
287 }
288 
289 /* This function positions the tail of the bone so that it preserves the length of it.
290  * The length of the bone can be seen as a sphere radius.
291  */
293  const float head_pos[3],
294  const float sphere_radius,
295  int prev_seg_idx,
296  float r_tail_pos[3],
297  float *r_new_curve_pos,
298  float *r_radius)
299 {
300  /* This is using the tessellated curve data.
301  * So we are working with piece-wise linear curve segments.
302  * The same method is used in #BKE_where_on_path to get curve location data. */
303  const CurveCache *cache = ik_data->tar->runtime.curve_cache;
304  const float *seg_accum_len = cache->anim_path_accum_length;
305 
306  int max_seg_idx = BKE_anim_path_get_array_size(cache) - 1;
307 
308  /* Make an initial guess of where our intersection point will be.
309  * If the curve was a straight line, then the faction passed in r_new_curve_pos
310  * would be the correct location.
311  * So make it our first initial guess.
312  */
313  const float spline_len = BKE_anim_path_get_length(cache);
314  const float guessed_len = *r_new_curve_pos * spline_len;
315 
316  BLI_assert(prev_seg_idx >= 0);
317  int cur_seg_idx = prev_seg_idx;
318  while (cur_seg_idx < max_seg_idx && guessed_len > seg_accum_len[cur_seg_idx]) {
319  cur_seg_idx++;
320  }
321 
322  /* Convert the segment to bev points.
323  * For example, the segment with index 0 will have bev points 0 and 1.
324  */
325  int bp_idx = cur_seg_idx + 1;
326 
327  const BevList *bl = cache->bev.first;
328  bool is_cyclic = bl->poly >= 0;
329  BevPoint *bp = bl->bevpoints;
330  BevPoint *prev_bp;
331  bp = bp + bp_idx;
332  prev_bp = bp - 1;
333 
334  /* Go to the next tessellated curve point until we cross to outside of the sphere. */
335  while (len_v3v3(head_pos, bp->vec) < sphere_radius) {
336  if (bp_idx > max_seg_idx) {
337  /* We are outside the defined curve. We will now extrapolate the intersection point. */
338  break;
339  }
340  prev_bp = bp;
341  if (is_cyclic && bp_idx == max_seg_idx) {
342  /* Wrap around to the start point.
343  * Don't set the bp_idx to zero here as we use it to get the segment index later.
344  */
345  bp = bl->bevpoints;
346  }
347  else {
348  bp++;
349  }
350  bp_idx++;
351  }
352 
353  /* Calculate the intersection point using the secant root finding method */
354  float x0 = 0.0f, x1 = 1.0f, x2 = 0.5f;
355  float x0_point[3], x1_point[3], start_p[3];
356  float epsilon = max_fff(1.0f, len_v3(head_pos), len_v3(bp->vec)) * FLT_EPSILON;
357 
358  if (prev_seg_idx == bp_idx - 1) {
359  /* The intersection lies inside the same segment as the last point.
360  * Set the last point to be the start search point so we minimize the risks of going backwards
361  * on the curve.
362  */
363  copy_v3_v3(start_p, head_pos);
364  }
365  else {
366  copy_v3_v3(start_p, prev_bp->vec);
367  }
368 
369  for (int i = 0; i < 10; i++) {
370  interp_v3_v3v3(x0_point, start_p, bp->vec, x0);
371  interp_v3_v3v3(x1_point, start_p, bp->vec, x1);
372 
373  float f_x0 = dist_to_sphere_shell(head_pos, sphere_radius, x0_point);
374  float f_x1 = dist_to_sphere_shell(head_pos, sphere_radius, x1_point);
375 
376  if (fabsf(f_x1) <= epsilon || f_x0 == f_x1) {
377  break;
378  }
379 
380  x2 = x1 - f_x1 * (x1 - x0) / (f_x1 - f_x0);
381  x0 = x1;
382  x1 = x2;
383  }
384  /* Found the bone tail position! */
385  copy_v3_v3(r_tail_pos, x1_point);
386 
387  /* Because our intersection point lies inside the current segment,
388  * Convert our bevpoint index back to the previous segment index (-2 instead of -1).
389  * This is because our actual location is prev_seg_len + isect_seg_len.
390  */
391  prev_seg_idx = bp_idx - 2;
392  float prev_seg_len = 0;
393 
394  if (prev_seg_idx < 0) {
395  prev_seg_idx = 0;
396  prev_seg_len = 0;
397  }
398  else {
399  prev_seg_len = seg_accum_len[prev_seg_idx];
400  }
401 
402  /* Convert the point back into the 0-1 interpolation range. */
403  const float isect_seg_len = len_v3v3(prev_bp->vec, r_tail_pos);
404  const float frac = isect_seg_len / len_v3v3(prev_bp->vec, bp->vec);
405  *r_new_curve_pos = (prev_seg_len + isect_seg_len) / spline_len;
406 
407  if (*r_new_curve_pos > 1.0f) {
408  *r_radius = bp->radius;
409  }
410  else {
411  *r_radius = (1.0f - frac) * prev_bp->radius + frac * bp->radius;
412  }
413 
414  /* Return the current segment. */
415  return bp_idx - 1;
416 }
417 
418 /* Evaluate spline IK for a given bone. */
420  tSplineIK_Tree *tree, Object *ob, bPoseChannel *pchan, int index, tSplineIk_EvalState *state)
421 {
422  bSplineIKConstraint *ik_data = tree->ik_data;
423 
424  if (pchan->bone->length < FLT_EPSILON) {
425  /* Only move the bone position with zero length bones. */
426  float bone_pos[4], dir[3], rad;
427  BKE_where_on_path(ik_data->tar, state->curve_position, bone_pos, dir, NULL, &rad, NULL);
428 
429  apply_curve_transform(ik_data, ob, rad, bone_pos, &rad);
430 
431  copy_v3_v3(pchan->pose_mat[3], bone_pos);
432  copy_v3_v3(pchan->pose_head, bone_pos);
433  copy_v3_v3(pchan->pose_tail, bone_pos);
434  pchan->flag |= POSE_DONE;
435  return;
436  }
437 
438  float orig_head[3], orig_tail[3], pose_head[3], pose_tail[3];
439  float base_pose_mat[3][3], pose_mat[3][3];
440  float spline_vec[3], scale_fac, radius = 1.0f;
441  float tail_blend_fac = 0.0f;
442 
443  mul_v3_m4v3(pose_head, state->locrot_offset, pchan->pose_head);
444  mul_v3_m4v3(pose_tail, state->locrot_offset, pchan->pose_tail);
445 
446  copy_v3_v3(orig_head, pose_head);
447 
448  /* First, adjust the point positions on the curve. */
449  float curveLen = tree->points[index] - tree->points[index + 1];
450  float bone_len = len_v3v3(pose_head, pose_tail);
451  float point_start = state->curve_position;
452  float pose_scale = bone_len / pchan->bone->length;
453  float base_scale = 1.0f;
454 
456  /* Carry over the bone Y scale to the curve range. */
457  base_scale = pose_scale;
458  }
459 
460  float point_end = point_start + curveLen * base_scale * state->curve_scale;
461 
462  state->curve_position = point_end;
463 
464  /* Step 1: determine the positions for the endpoints of the bone. */
465  if (point_start < 1.0f) {
466  float vec[4], dir[3], rad;
467  radius = 0.0f;
468 
469  /* Calculate head position. */
470  if (point_start == 0.0f) {
471  /* Start of the path. We have no previous tail position to copy. */
472  BKE_where_on_path(ik_data->tar, point_start, vec, dir, NULL, &rad, NULL);
473  }
474  else {
475  copy_v3_v3(vec, state->prev_tail_loc);
476  rad = state->prev_tail_radius;
477  }
478 
479  radius = rad;
480  copy_v3_v3(pose_head, vec);
481  apply_curve_transform(ik_data, ob, rad, pose_head, &radius);
482 
483  /* Calculate tail position. */
485  float sphere_radius;
486 
488  sphere_radius = bone_len;
489  }
490  else {
491  /* Don't take bone scale into account. */
492  sphere_radius = pchan->bone->length;
493  }
494 
495  /* Calculate the tail position with sphere curve intersection. */
496  state->prev_tail_seg_idx = position_tail_on_spline(
497  ik_data, vec, sphere_radius, state->prev_tail_seg_idx, pose_tail, &point_end, &rad);
498 
499  state->prev_tail_radius = rad;
500  copy_v3_v3(state->prev_tail_loc, pose_tail);
501 
502  apply_curve_transform(ik_data, ob, rad, pose_tail, &radius);
503  state->curve_position = point_end;
504  }
505  else {
506  /* Scale to fit curve end position. */
507  if (BKE_where_on_path(ik_data->tar, point_end, vec, dir, NULL, &rad, NULL)) {
508  state->prev_tail_radius = rad;
509  copy_v3_v3(state->prev_tail_loc, vec);
510  copy_v3_v3(pose_tail, vec);
511  apply_curve_transform(ik_data, ob, rad, pose_tail, &radius);
512  }
513  }
514 
515  /* Determine if the bone should still be affected by SplineIK.
516  * This makes it so that the bone slowly becomes poseable again the further it rolls off the
517  * curve. When the whole bone has rolled off the curve, the IK constraint will not influence it
518  * anymore.
519  */
520  if (point_end >= 1.0f) {
521  /* Blending factor depends on the amount of the bone still left on the chain. */
522  tail_blend_fac = (1.0f - point_start) / (point_end - point_start);
523  }
524  else {
525  tail_blend_fac = 1.0f;
526  }
527  }
528 
529  /* Step 2: determine the implied transform from these endpoints.
530  * - splineVec: the vector direction that the spline applies on the bone.
531  * - scaleFac: the factor that the bone length is scaled by to get the desired amount.
532  */
533  sub_v3_v3v3(spline_vec, pose_tail, pose_head);
534  scale_fac = len_v3(spline_vec) / pchan->bone->length;
535 
536  /* Step 3: compute the shortest rotation needed
537  * to map from the bone rotation to the current axis.
538  * - this uses the same method as is used for the Damped Track Constraint
539  * (see the code there for details).
540  */
541  {
542  float dmat[3][3], rmat[3][3];
543  float raxis[3], rangle;
544 
545  /* Compute the raw rotation matrix from the bone's current matrix by extracting only the
546  * orientation-relevant axes, and normalizing them.
547  */
548  mul_m3_m4m4(base_pose_mat, state->locrot_offset, pchan->pose_mat);
549  normalize_m3_m3(rmat, base_pose_mat);
550 
551  /* Also, normalize the orientation imposed by the bone,
552  * now that we've extracted the scale factor. */
553  normalize_v3(spline_vec);
554 
555  /* Calculate smallest axis-angle rotation necessary for getting from the
556  * current orientation of the bone, to the spline-imposed direction.
557  */
558  cross_v3_v3v3(raxis, rmat[1], spline_vec);
559 
560  /* Check if the old and new bone direction is parallel to each other.
561  * If they are, then 'raxis' should be near zero and we will have to get the rotation axis in
562  * some other way.
563  */
564  float norm = normalize_v3(raxis);
565 
566  if (norm < FLT_EPSILON) {
567  /* Can't use cross product! */
568  int order[3] = {0, 1, 2};
569  float tmp_axis[3];
570  zero_v3(tmp_axis);
571 
572  axis_sort_v3(spline_vec, order);
573 
574  /* Use the second largest axis as the basis for the rotation axis. */
575  tmp_axis[order[1]] = 1.0f;
576  cross_v3_v3v3(raxis, tmp_axis, spline_vec);
577  }
578 
579  rangle = dot_v3v3(rmat[1], spline_vec);
580  CLAMP(rangle, -1.0f, 1.0f);
581  rangle = acosf(rangle);
582 
583  /* Multiply the magnitude of the angle by the influence of the constraint to
584  * control the influence of the SplineIK effect.
585  */
586  rangle *= tree->con->enforce * tail_blend_fac;
587 
588  /* Construct rotation matrix from the axis-angle rotation found above.
589  * - This call takes care to make sure that the axis provided is a unit vector first.
590  */
591  axis_angle_to_mat3(dmat, raxis, rangle);
592 
593  /* Combine these rotations so that the y-axis of the bone is now aligned as the
594  * spline dictates, while still maintaining roll control from the existing bone animation. */
595  mul_m3_m3m3(pose_mat, dmat, rmat);
596 
597  /* Attempt to reduce shearing, though I doubt this'll really help too much now... */
598  normalize_m3(pose_mat);
599 
600  mul_m3_m3m3(base_pose_mat, dmat, base_pose_mat);
601 
602  /* Apply rotation to the accumulated parent transform. */
603  mul_m4_m3m4(state->locrot_offset, dmat, state->locrot_offset);
604  }
605 
606  /* Step 4: Set the scaling factors for the axes. */
607 
608  /* Always multiply the y-axis by the scaling factor to get the correct length. */
609  mul_v3_fl(pose_mat[1], scale_fac);
610 
611  /* After that, apply x/z scaling modes. */
612  if (ik_data->xzScaleMode != CONSTRAINT_SPLINEIK_XZS_NONE) {
613  /* First, apply the original scale if enabled. */
615  (ik_data->flag & CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE) != 0) {
616  float scale;
617 
618  /* X-axis scale. */
619  scale = len_v3(pchan->pose_mat[0]);
620  mul_v3_fl(pose_mat[0], scale);
621  /* Z-axis scale. */
622  scale = len_v3(pchan->pose_mat[2]);
623  mul_v3_fl(pose_mat[2], scale);
624 
625  /* Adjust the scale factor used for volume preservation
626  * to consider the pre-IK scaling as the initial volume. */
627  scale_fac /= pose_scale;
628  }
629 
630  /* Apply volume preservation. */
631  switch (ik_data->xzScaleMode) {
633  /* Old 'volume preservation' method using the inverse scale. */
634  float scale;
635 
636  /* Calculate volume preservation factor which is
637  * basically the inverse of the y-scaling factor.
638  */
639  if (fabsf(scale_fac) != 0.0f) {
640  scale = 1.0f / fabsf(scale_fac);
641 
642  /* We need to clamp this within sensible values. */
643  /* NOTE: these should be fine for now, but should get sanitized in future. */
644  CLAMP(scale, 0.0001f, 100000.0f);
645  }
646  else {
647  scale = 1.0f;
648  }
649 
650  /* Apply the scaling. */
651  mul_v3_fl(pose_mat[0], scale);
652  mul_v3_fl(pose_mat[2], scale);
653  break;
654  }
656  /* Improved volume preservation based on the Stretch To constraint. */
657  float final_scale;
658 
659  /* As the basis for volume preservation, we use the inverse scale factor... */
660  if (fabsf(scale_fac) != 0.0f) {
661  /* NOTE: The method here is taken wholesale from the Stretch To constraint. */
662  float bulge = powf(1.0f / fabsf(scale_fac), ik_data->bulge);
663 
664  if (bulge > 1.0f) {
665  if (ik_data->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MAX) {
666  float bulge_max = max_ff(ik_data->bulge_max, 1.0f);
667  float hard = min_ff(bulge, bulge_max);
668 
669  float range = bulge_max - 1.0f;
670  float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
671  float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (float)M_PI_2;
672 
673  bulge = interpf(soft, hard, ik_data->bulge_smooth);
674  }
675  }
676  if (bulge < 1.0f) {
677  if (ik_data->flag & CONSTRAINT_SPLINEIK_USE_BULGE_MIN) {
678  float bulge_min = CLAMPIS(ik_data->bulge_min, 0.0f, 1.0f);
679  float hard = max_ff(bulge, bulge_min);
680 
681  float range = 1.0f - bulge_min;
682  float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
683  float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (float)M_PI_2;
684 
685  bulge = interpf(soft, hard, ik_data->bulge_smooth);
686  }
687  }
688 
689  /* Compute scale factor for xz axes from this value. */
690  final_scale = sqrtf(bulge);
691  }
692  else {
693  /* No scaling, so scale factor is simple. */
694  final_scale = 1.0f;
695  }
696 
697  /* Apply the scaling (assuming normalized scale). */
698  mul_v3_fl(pose_mat[0], final_scale);
699  mul_v3_fl(pose_mat[2], final_scale);
700  break;
701  }
702  }
703  }
704 
705  /* Finally, multiply the x and z scaling by the radius of the curve too,
706  * to allow automatic scales to get tweaked still.
707  */
708  if ((ik_data->flag & CONSTRAINT_SPLINEIK_NO_CURVERAD) == 0) {
709  mul_v3_fl(pose_mat[0], radius);
710  mul_v3_fl(pose_mat[2], radius);
711  }
712 
713  /* Blend the scaling of the matrix according to the influence. */
714  sub_m3_m3m3(pose_mat, pose_mat, base_pose_mat);
715  madd_m3_m3m3fl(pose_mat, base_pose_mat, pose_mat, tree->con->enforce * tail_blend_fac);
716 
717  /* Step 5: Set the location of the bone in the matrix. */
718  if (ik_data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) {
719  /* When the 'no-root' option is affected, the chain can retain
720  * the shape but be moved elsewhere.
721  */
722  copy_v3_v3(pose_head, orig_head);
723  }
724  else if (tree->con->enforce < 1.0f) {
725  /* When the influence is too low:
726  * - Blend the positions for the 'root' bone.
727  * - Stick to the parent for any other.
728  */
729  if (index < tree->chainlen - 1) {
730  copy_v3_v3(pose_head, orig_head);
731  }
732  else {
733  interp_v3_v3v3(pose_head, orig_head, pose_head, tree->con->enforce);
734  }
735  }
736 
737  /* Finally, store the new transform. */
738  copy_m4_m3(pchan->pose_mat, pose_mat);
739  copy_v3_v3(pchan->pose_mat[3], pose_head);
740  copy_v3_v3(pchan->pose_head, pose_head);
741 
742  mul_v3_mat3_m4v3(orig_tail, state->locrot_offset, pchan->pose_tail);
743 
744  /* Recalculate tail, as it's now outdated after the head gets adjusted above! */
746 
747  /* Update the offset in the accumulated parent transform. */
748  sub_v3_v3v3(state->locrot_offset[3], pchan->pose_tail, orig_tail);
749 
750  /* Done! */
751  pchan->flag |= POSE_DONE;
752 }
753 
754 /* Evaluate the chain starting from the nominated bone */
756  struct Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
757 {
759 
760  /* for each pose-tree, execute it if it is spline, otherwise just free it */
761  while ((tree = pchan_root->siktree.first) != NULL) {
762  /* Firstly, calculate the bone matrix the standard way,
763  * since this is needed for roll control. */
764  for (int i = tree->chainlen - 1; i >= 0; i--) {
765  BKE_pose_where_is_bone(depsgraph, scene, ob, tree->chain[i], ctime, 1);
766  }
767 
768  /* After that, evaluate the actual Spline IK, unless there are missing dependencies. */
770 
772  /* Walk over each bone in the chain, calculating the effects of spline IK
773  * - the chain is traversed in the opposite order to storage order
774  * (i.e. parent to children) so that dependencies are correct
775  */
776  for (int i = tree->chainlen - 1; i >= 0; i--) {
777  bPoseChannel *pchan = tree->chain[i];
778  splineik_evaluate_bone(tree, ob, pchan, i, &state);
779  }
780  }
781 
782  /* free the tree info specific to SplineIK trees now */
783  if (tree->chain) {
784  MEM_freeN(tree->chain);
785  }
786 
787  /* free this tree */
788  BLI_freelinkN(&pchan_root->siktree, tree);
789  }
790 }
791 
793 {
794  splineik_init_tree(scene, ob, ctime);
795 }
796 
798  struct Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
799 {
800  splineik_execute_tree(depsgraph, scene, ob, pchan_root, ctime);
801 }
802 
803 /* *************** Depsgraph evaluation callbacks ************ */
804 
806 {
807  MEM_SAFE_FREE(pose->chan_array);
808  const int num_channels = BLI_listbase_count(&pose->chanbase);
809  pose->chan_array = MEM_malloc_arrayN(num_channels, sizeof(bPoseChannel *), "pose->chan_array");
810  int pchan_index = 0;
811  for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
812  pose->chan_array[pchan_index++] = pchan;
813  }
814 }
815 
817 {
818  bPose *pose = ob->pose;
819  BLI_assert(pose != NULL);
820  BLI_assert(pose->chan_array != NULL);
821  BLI_assert(pchan_index >= 0);
822  BLI_assert(pchan_index < MEM_allocN_len(pose->chan_array) / sizeof(bPoseChannel *));
823  return pose->chan_array[pchan_index];
824 }
825 
827 {
828  bPose *pose = object->pose;
829  BLI_assert(pose != NULL);
830 
831  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
832 
833  BLI_assert(object->type == OB_ARMATURE);
834 
835  /* We demand having proper pose. */
836  BLI_assert(object->pose != NULL);
837  BLI_assert((object->pose->flag & POSE_RECALC) == 0);
838 
839  /* imat is needed for solvers. */
840  invert_m4_m4(object->imat, object->obmat);
841 
842  /* clear flags */
843  for (bPoseChannel *pchan = pose->chanbase.first; pchan != NULL; pchan = pchan->next) {
844  pchan->flag &= ~(POSE_DONE | POSE_CHAIN | POSE_IKTREE | POSE_IKSPLINE);
845 
846  /* Free B-Bone shape data cache if it's not a B-Bone. */
847  if (pchan->bone == NULL || pchan->bone->segments <= 1) {
848  BKE_pose_channel_free_bbone_cache(&pchan->runtime);
849  }
850  }
851 
853 
854  if (object->proxy != NULL) {
855  object->proxy->proxy_from = object;
856  }
857 }
858 
860 {
861  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
862  BLI_assert(object->type == OB_ARMATURE);
863  const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
864  bArmature *armature = (bArmature *)object->data;
865  if (armature->flag & ARM_RESTPOS) {
866  return;
867  }
868  /* construct the IK tree (standard IK) */
869  BIK_init_tree(depsgraph, scene, object, ctime);
870  /* construct the Spline IK trees
871  * - this is not integrated as an IK plugin, since it should be able
872  * to function in conjunction with standard IK. */
873  BKE_pose_splineik_init_tree(scene, object, ctime);
874 }
875 
876 void BKE_pose_eval_bone(struct Depsgraph *depsgraph, Scene *scene, Object *object, int pchan_index)
877 {
878  const bArmature *armature = (bArmature *)object->data;
879  if (armature->edbo != NULL) {
880  return;
881  }
882  bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
884  depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
885  BLI_assert(object->type == OB_ARMATURE);
886  if (armature->flag & ARM_RESTPOS) {
887  Bone *bone = pchan->bone;
888  if (bone) {
889  copy_m4_m4(pchan->pose_mat, bone->arm_mat);
890  copy_v3_v3(pchan->pose_head, bone->arm_head);
891  copy_v3_v3(pchan->pose_tail, bone->arm_tail);
892  }
893  }
894  else {
895  /* TODO(sergey): Currently if there are constraints full transform is
896  * being evaluated in BKE_pose_constraints_evaluate. */
897  if (pchan->constraints.first == NULL) {
898  if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
899  /* pass */
900  }
901  else {
902  if ((pchan->flag & POSE_DONE) == 0) {
903  /* TODO(sergey): Use time source node for time. */
904  float ctime = BKE_scene_frame_get(scene); /* not accurate... */
905  BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1);
906  }
907  }
908  }
909  }
910 }
911 
913  Scene *scene,
914  Object *object,
915  int pchan_index)
916 {
917  const bArmature *armature = (bArmature *)object->data;
918  if (armature->edbo != NULL) {
919  return;
920  }
921  bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
923  depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
924  if (armature->flag & ARM_RESTPOS) {
925  return;
926  }
927  if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) {
928  /* IK are being solved separately/ */
929  }
930  else {
931  if ((pchan->flag & POSE_DONE) == 0) {
932  float ctime = BKE_scene_frame_get(scene); /* not accurate... */
933  BKE_pose_where_is_bone(depsgraph, scene, object, pchan, ctime, 1);
934  }
935  }
936 }
937 
939  struct Object *object,
940  bPoseChannel *pchan)
941 {
942  if (!DEG_is_active(depsgraph)) {
943  return;
944  }
945  const bArmature *armature = (bArmature *)object->data;
946  if (armature->edbo != NULL) {
947  return;
948  }
949  bPoseChannel *pchan_orig = pchan->orig_pchan;
950  /* TODO(sergey): Using BKE_pose_copy_pchan_result() introduces T70901, but why? */
951  copy_m4_m4(pchan_orig->pose_mat, pchan->pose_mat);
952  copy_m4_m4(pchan_orig->chan_mat, pchan->chan_mat);
953  copy_v3_v3(pchan_orig->pose_head, pchan->pose_mat[3]);
954  copy_m4_m4(pchan_orig->constinv, pchan->constinv);
955  copy_v3_v3(pchan_orig->pose_tail, pchan->pose_tail);
956 }
957 
958 void BKE_pose_bone_done(struct Depsgraph *depsgraph, struct Object *object, int pchan_index)
959 {
960  const bArmature *armature = (bArmature *)object->data;
961  if (armature->edbo != NULL) {
962  return;
963  }
964  bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
965  float imat[4][4];
967  depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
968  if (pchan->bone) {
969  invert_m4_m4(imat, pchan->bone->arm_mat);
970  mul_m4_m4m4(pchan->chan_mat, pchan->pose_mat, imat);
971  if (!(pchan->bone->flag & BONE_NO_DEFORM)) {
972  mat4_to_dquat(&pchan->runtime.deform_dual_quat, pchan->bone->arm_mat, pchan->chan_mat);
973  }
974  }
976  if (DEG_is_active(depsgraph)) {
977  bPoseChannel *pchan_orig = pchan->orig_pchan;
978  if (pchan->bone == NULL || pchan->bone->segments <= 1) {
980  }
981  }
982 }
983 
985  struct Object *object,
986  int pchan_index)
987 {
988  const bArmature *armature = (bArmature *)object->data;
989  if (armature->edbo != NULL) {
990  return;
991  }
992  bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
994  depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
995  if (pchan->bone != NULL && pchan->bone->segments > 1) {
997  if (DEG_is_active(depsgraph)) {
999  }
1000  }
1001 }
1002 
1004  Scene *scene,
1005  Object *object,
1006  int rootchan_index)
1007 {
1008  const bArmature *armature = (bArmature *)object->data;
1009  if (armature->edbo != NULL) {
1010  return;
1011  }
1012  bPoseChannel *rootchan = pose_pchan_get_indexed(object, rootchan_index);
1014  depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan);
1015  BLI_assert(object->type == OB_ARMATURE);
1016  const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
1017  if (armature->flag & ARM_RESTPOS) {
1018  return;
1019  }
1020  BIK_execute_tree(depsgraph, scene, object, rootchan, ctime);
1021 }
1022 
1024  Scene *scene,
1025  Object *object,
1026  int rootchan_index)
1027 
1028 {
1029  const bArmature *armature = (bArmature *)object->data;
1030  if (armature->edbo != NULL) {
1031  return;
1032  }
1033  bPoseChannel *rootchan = pose_pchan_get_indexed(object, rootchan_index);
1035  depsgraph, __func__, object->id.name, object, "rootchan", rootchan->name, rootchan);
1036  BLI_assert(object->type == OB_ARMATURE);
1037  const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
1038  if (armature->flag & ARM_RESTPOS) {
1039  return;
1040  }
1041  BKE_splineik_execute_tree(depsgraph, scene, object, rootchan, ctime);
1042 }
1043 
1044 static void pose_eval_cleanup_common(Object *object)
1045 {
1046  bPose *pose = object->pose;
1047  BLI_assert(pose != NULL);
1049  UNUSED_VARS_NDEBUG(pose);
1050 }
1051 
1053 {
1054  bPose *pose = object->pose;
1055  BLI_assert(pose != NULL);
1056  UNUSED_VARS_NDEBUG(pose);
1057  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
1058  BLI_assert(object->type == OB_ARMATURE);
1059 }
1060 
1062 {
1063  bPose *pose = object->pose;
1064  BLI_assert(pose != NULL);
1065  UNUSED_VARS_NDEBUG(pose);
1066  const float ctime = BKE_scene_frame_get(scene); /* not accurate... */
1067  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
1068  BLI_assert(object->type == OB_ARMATURE);
1069  /* Release the IK tree. */
1070  BIK_release_tree(scene, object, ctime);
1071  pose_eval_cleanup_common(object);
1072 }
1073 
1075 {
1076  BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
1077  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
1078 
1079  BLI_assert(object->pose->chan_array != NULL || BLI_listbase_is_empty(&object->pose->chanbase));
1080 }
1081 
1083 {
1084  BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
1085  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
1086 }
1087 
1089 {
1090  BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
1091  DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
1092  pose_eval_cleanup_common(object);
1093 }
1094 
1095 void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object, int pchan_index)
1096 {
1097  const bArmature *armature = (bArmature *)object->data;
1098  if (armature->edbo != NULL) {
1099  return;
1100  }
1101  BLI_assert(ID_IS_LINKED(object) && object->proxy_from != NULL);
1102  bPoseChannel *pchan = pose_pchan_get_indexed(object, pchan_index);
1103  BLI_assert(pchan != NULL);
1105  depsgraph, __func__, object->id.name, object, "pchan", pchan->name, pchan);
1106  /* TODO(sergey): Use indexed lookup, once it's guaranteed to be kept
1107  * around for the time while proxies are evaluating.
1108  */
1109 #if 0
1110  bPoseChannel *pchan_from = pose_pchan_get_indexed(object->proxy_from, pchan_index);
1111 #else
1112  bPoseChannel *pchan_from = BKE_pose_channel_find_name(object->proxy_from->pose, pchan->name);
1113 #endif
1114  if (pchan_from == NULL) {
1115  printf(
1116  "WARNING: Could not find bone %s in linked ID anymore... "
1117  "You should delete and re-generate your proxy.\n",
1118  pchan->name);
1119  return;
1120  }
1121  BKE_pose_copy_pchan_result(pchan, pchan_from);
1123  BKE_pchan_bbone_segments_cache_copy(pchan, pchan_from);
1124 
1126 }
typedef float(TangentPoint)[2]
void BIK_init_tree(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, float ctime)
Definition: ikplugin_api.c:83
void BIK_release_tree(struct Scene *scene, struct Object *ob, float ctime)
Definition: ikplugin_api.c:102
void BIK_execute_tree(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime)
Definition: ikplugin_api.c:92
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_pose_copy_pchan_result(struct bPoseChannel *pchanto, const struct bPoseChannel *pchanfrom)
void BKE_pose_channel_free_bbone_cache(struct bPoseChannel_Runtime *runtime)
Definition: action.c:1108
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)
int BKE_anim_path_get_array_size(const struct CurveCache *curve_cache)
float BKE_anim_path_get_length(const struct CurveCache *curve_cache)
void BKE_pchan_bbone_segments_cache_compute(struct bPoseChannel *pchan)
Definition: armature.c:1425
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan)
Definition: armature.c:2660
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:2673
void BKE_pchan_bbone_segments_cache_copy(struct bPoseChannel *pchan, struct bPoseChannel *pchan_from)
Definition: armature.c:1477
display list (or rather multi purpose list) stuff.
General operations, lookup, etc. for blender objects.
float BKE_scene_frame_get(const struct Scene *scene)
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_INLINE
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
#define M_PI_2
Definition: BLI_math_base.h:41
MINLINE float interpf(float a, float b, float t)
void sub_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:1080
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void normalize_m3_m3(float R[3][3], const float M[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1934
void unit_m4(float m[4][4])
Definition: rct.c:1140
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void normalize_m3(float R[3][3]) ATTR_NONNULL()
Definition: math_matrix.c:1919
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
Definition: math_matrix.c:391
void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4])
Definition: math_matrix.c:505
void madd_m3_m3m3fl(float R[3][3], const float A[3][3], const float B[3][3], const float f)
Definition: math_matrix.c:1058
void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:525
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:804
void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4])
void copy_dq_dq(DualQuat *r, const DualQuat *dq)
void axis_angle_to_mat3(float R[3][3], const float axis[3], const float angle)
void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
Definition: math_vector.c:1090
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[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 float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define CLAMPIS(a, b, c)
#define UNUSED_VARS_NDEBUG(...)
#define UNUSED(x)
#define ELEM(...)
#define CLAMP_MIN(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:331
void DEG_debug_print_eval(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
void DEG_debug_print_eval_subdata(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address, const char *subdata_comment, const char *subdata_name, const void *subdata_address)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
@ PCHAN_HAS_SPLINEIK
@ POSE_DONE
@ POSE_IKTREE
@ POSE_IKSPLINE
@ POSE_CHAIN
@ POSE_RECALC
@ BONE_NO_DEFORM
@ ARM_RESTPOS
@ CONSTRAINT_OFF
@ CONSTRAINT_DISABLE
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_SPLINEIK_YS_FIT_CURVE
@ CONSTRAINT_SPLINEIK_YS_ORIGINAL
@ CONSTRAINT_SPLINEIK_EVENSPLITS
@ CONSTRAINT_SPLINEIK_USE_BULGE_MAX
@ CONSTRAINT_SPLINEIK_USE_ORIGINAL_SCALE
@ CONSTRAINT_SPLINEIK_USE_BULGE_MIN
@ CONSTRAINT_SPLINEIK_BOUND
@ CONSTRAINT_SPLINEIK_NO_CURVERAD
@ CONSTRAINT_SPLINEIK_NO_ROOT
@ CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC
@ CONSTRAINT_SPLINEIK_XZS_ORIGINAL
@ CONSTRAINT_SPLINEIK_XZS_NONE
@ CONSTRAINT_SPLINEIK_XZS_INVERSE
Object is a sort of wrapper for general info.
@ OB_ARMATURE
@ OB_CURVE
_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 x2
_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 order
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
static bool splineik_evaluate_init(tSplineIK_Tree *tree, tSplineIk_EvalState *state)
void BKE_splineik_execute_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
void BKE_pose_pchan_index_rebuild(bPose *pose)
static void pose_channel_flush_to_orig_if_needed(struct Depsgraph *depsgraph, struct Object *object, bPoseChannel *pchan)
void BKE_pose_eval_init(struct Depsgraph *depsgraph, Scene *UNUSED(scene), Object *object)
static void apply_curve_transform(bSplineIKConstraint *ik_data, Object *ob, float radius, float r_vec[3], float *r_radius)
void BKE_pose_eval_proxy_cleanup(struct Depsgraph *depsgraph, Object *object)
static void splineik_execute_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
void BKE_pose_splineik_init_tree(Scene *scene, Object *ob, float ctime)
static void splineik_evaluate_bone(tSplineIK_Tree *tree, Object *ob, bPoseChannel *pchan, int index, tSplineIk_EvalState *state)
static int position_tail_on_spline(bSplineIKConstraint *ik_data, const float head_pos[3], const float sphere_radius, int prev_seg_idx, float r_tail_pos[3], float *r_new_curve_pos, float *r_radius)
void BKE_pose_eval_done(struct Depsgraph *depsgraph, Object *object)
void BKE_pose_eval_bbone_segments(struct Depsgraph *depsgraph, struct Object *object, int pchan_index)
static void splineik_init_tree_from_pchan(Scene *UNUSED(scene), Object *UNUSED(ob), bPoseChannel *pchan_tip)
void BKE_pose_bone_done(struct Depsgraph *depsgraph, struct Object *object, int pchan_index)
void BKE_pose_eval_proxy_done(struct Depsgraph *depsgraph, Object *object)
static float dist_to_sphere_shell(const float sphere_origin[3], const float sphere_radius, const float point[3])
void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *object)
void BKE_pose_eval_bone(struct Depsgraph *depsgraph, Scene *scene, Object *object, int pchan_index)
void BKE_pose_eval_cleanup(struct Depsgraph *depsgraph, Scene *scene, Object *object)
static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime))
void BKE_pose_constraints_evaluate(struct Depsgraph *depsgraph, Scene *scene, Object *object, int pchan_index)
void BKE_pose_iktree_evaluate(struct Depsgraph *depsgraph, Scene *scene, Object *object, int rootchan_index)
void BKE_pose_eval_proxy_init(struct Depsgraph *depsgraph, Object *object)
void BKE_pose_splineik_evaluate(struct Depsgraph *depsgraph, Scene *scene, Object *object, int rootchan_index)
static void pose_eval_cleanup_common(Object *object)
void BKE_pose_eval_proxy_copy_bone(struct Depsgraph *depsgraph, Object *object, int pchan_index)
BLI_INLINE bPoseChannel * pose_pchan_get_indexed(Object *ob, int pchan_index)
struct tSplineIK_Tree tSplineIK_Tree
struct tSplineIk_EvalState tSplineIk_EvalState
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition: btVector3.h:263
Scene scene
const Depsgraph * depsgraph
void * tree
#define powf(x, y)
#define atanf(x)
#define acosf(x)
#define fabsf(x)
#define sqrtf(x)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static ulong state[N]
ccl_device_inline float frac(float x, int *ix)
static double epsilon
BevPoint * bevpoints
float radius
float vec[3]
float arm_head[3]
float arm_tail[3]
short segments
float length
float arm_mat[4][4]
ListBase bev
Definition: BKE_curve.h:50
const float * anim_path_accum_length
Definition: BKE_curve.h:58
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
struct CurveCache * curve_cache
struct bPose * pose
struct Object * proxy_from
struct Object * proxy
float imat[4][4]
Object_Runtime runtime
float obmat[4][4]
void * data
ListBase * edbo
struct bConstraint * next
struct DualQuat deform_dual_quat
ListBase constraints
struct Bone * bone
struct bPoseChannel * parent
float pose_head[3]
float chan_mat[4][4]
float pose_tail[3]
struct bPoseChannel * next
float constinv[4][4]
struct bPoseChannel_Runtime runtime
struct bPoseChannel * orig_pchan
float pose_mat[4][4]
struct ListBase siktree
ListBase chanbase
short flag
bPoseChannel ** chan_array
struct tSplineIK_Tree * next
bPoseChannel ** chain
bPoseChannel * root
bSplineIKConstraint * ik_data
const float * points
bConstraint * con
struct tSplineIK_Tree * prev
float locrot_offset[4][4]