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