66 float bone_lengths[255];
67 float totlength = 0.0f;
94 for (pchan = pchan_tip; pchan && (segcount < ik_data->
chainlen);
95 pchan = pchan->
parent, segcount++)
98 pchan_chain[segcount] = pchan;
102 totlength += bone_lengths[segcount];
109 pchan_root = pchan_chain[segcount - 1];
113 float segmentLen = (1.0f /
float(segcount));
120 ik_data->
points =
static_cast<float *
>(
124 ik_data->
points[0] = 1.0f;
129 for (
int i = 0; i < segcount; i++) {
135 ik_data->
points[i + 1] = ik_data->
points[i] - segmentLen;
141 ik_data->
points[i + 1] = ik_data->
points[i] - (bone_lengths[i] / totlength);
161 tree->chainlen = segcount;
162 tree->totlength = totlength;
173 tree->root = pchan_root;
175 tree->ik_data = ik_data;
216 if (ik_data->
tar ==
nullptr) {
227 state->curve_position = 0.0f;
228 state->curve_scale = 1.0f;
231 state->prev_tail_radius = 1.0f;
232 state->prev_tail_seg_idx = 0;
244 state->curve_scale =
tree->totlength / spline_len;
257 mul_m4_v3(ik_data->
tar->object_to_world().ptr(), r_vec);
261 mul_m4_v3(ob->world_to_object().ptr(), r_vec);
264 *r_radius = (radius + *r_radius) / 2;
268 const float sphere_radius,
269 const float point[3])
273 return sphere_radius -
len_v3(vec);
280 const float head_pos[3],
281 const float sphere_radius,
284 float *r_new_curve_pos,
301 const float guessed_len = *r_new_curve_pos * spline_len;
304 int cur_seg_idx = prev_seg_idx;
305 while (cur_seg_idx < max_seg_idx && guessed_len > seg_accum_len[cur_seg_idx]) {
312 int bp_idx = cur_seg_idx + 1;
322 while (
len_v3v3(head_pos, bp->
vec) < sphere_radius) {
323 if (bp_idx > max_seg_idx) {
328 if (
is_cyclic && bp_idx == max_seg_idx) {
341 float x0 = 0.0f, x1 = 1.0f;
342 float x0_point[3], x1_point[3], start_p[3];
345 if (prev_seg_idx == bp_idx - 1) {
356 for (
int i = 0; i < 10; i++) {
363 if (
fabsf(f_x1) <= epsilon || f_x0 == f_x1) {
367 const float x2 = x1 - f_x1 * (x1 - x0) / (f_x1 - f_x0);
378 prev_seg_idx = bp_idx - 2;
379 float prev_seg_len = 0;
381 if (prev_seg_idx < 0) {
386 prev_seg_len = seg_accum_len[prev_seg_idx];
390 const float isect_seg_len =
len_v3v3(prev_bp->
vec, r_tail_pos);
392 *r_new_curve_pos = (prev_seg_len + isect_seg_len) / spline_len;
394 if (*r_new_curve_pos > 1.0f) {
413 float bone_pos[4], rad;
415 ik_data->
tar,
state->curve_position, bone_pos,
nullptr,
nullptr, &rad,
nullptr);
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;
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;
445 base_scale = pose_scale;
448 float point_end = point_start + curveLen * base_scale *
state->curve_scale;
450 state->curve_position = point_end;
453 if (point_start < 1.0f) {
458 if (point_start == 0.0f) {
464 rad =
state->prev_tail_radius;
476 sphere_radius = bone_len;
485 ik_data, vec, sphere_radius,
state->prev_tail_seg_idx, pose_tail, &point_end, &rad);
487 state->prev_tail_radius = rad;
491 state->curve_position = point_end;
496 state->prev_tail_radius = rad;
508 if (point_end >= 1.0f) {
510 tail_blend_fac = (1.0f - point_start) / (point_end - point_start);
513 tail_blend_fac = 1.0f;
530 float dmat[3][3], rmat[3][3];
531 float raxis[3], rangle;
554 if (
norm < FLT_EPSILON) {
556 int order[3] = {0, 1, 2};
563 tmp_axis[order[1]] = 1.0f;
567 rangle =
dot_v3v3(rmat[1], spline_vec);
568 CLAMP(rangle, -1.0f, 1.0f);
569 rangle =
acosf(rangle);
574 rangle *=
tree->con->enforce * tail_blend_fac;
616 scale_fac /= pose_scale;
628 if (
fabsf(scale_fac) != 0.0f) {
629 scale = 1.0f /
fabsf(scale_fac);
633 CLAMP(scale, 0.0001f, 100000.0f);
649 if (
fabsf(scale_fac) != 0.0f) {
656 float hard =
min_ff(bulge, bulge_max);
658 float range = bulge_max - 1.0f;
659 float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
667 float bulge_min = std::clamp(ik_data->
bulge_min, 0.0f, 1.0f);
668 float hard =
max_ff(bulge, bulge_min);
670 float range = 1.0f - bulge_min;
671 float scale = (range > 0.0f) ? 1.0f / range : 0.0f;
679 final_scale =
sqrtf(bulge);
704 madd_m3_m3m3fl(pose_mat, base_pose_mat, pose_mat,
tree->con->enforce * tail_blend_fac);
713 else if (
tree->con->enforce < 1.0f) {
718 if (index < tree->chainlen - 1) {
753 for (
int i =
tree->chainlen - 1; i >= 0; i--) {
765 for (
int i =
tree->chainlen - 1; i >= 0; i--) {
820 bPose *pose =
object->pose;
832 invert_m4_m4(object->runtime->world_to_object.ptr(), object->object_to_world().ptr());
841 if (pchan->bone ==
nullptr || pchan->bone->segments <= 1) {
869 if (armature->
edbo !=
nullptr) {
874 depsgraph, __func__, object->id.name,
object,
"pchan", pchan->
name, pchan);
908 if (armature->
edbo !=
nullptr) {
913 depsgraph, __func__, object->id.name,
object,
"pchan", pchan->
name, pchan);
936 if (armature->
edbo !=
nullptr) {
952 if (armature->
edbo !=
nullptr) {
958 depsgraph, __func__, object->id.name,
object,
"pchan", pchan->
name, pchan);
978 if (armature->
edbo !=
nullptr) {
983 depsgraph, __func__, object->id.name,
object,
"pchan", pchan->
name, pchan);
998 if (armature->
edbo !=
nullptr) {
1003 depsgraph, __func__, object->id.name,
object,
"rootchan", rootchan->
name, rootchan);
1019 if (armature->
edbo !=
nullptr) {
1024 depsgraph, __func__, object->id.name,
object,
"rootchan", rootchan->
name, rootchan);
1035 bPose *pose =
object->pose;
1043 bPose *pose =
object->pose;
1052 bPose *pose =
object->pose;
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)
void BKE_pose_where_is_bone_tail(bPoseChannel *pchan)
void BKE_pchan_bbone_segments_cache_copy(bPoseChannel *pchan, bPoseChannel *pchan_from)
void BKE_pchan_bbone_segments_cache_compute(bPoseChannel *pchan)
float BKE_scene_ctime_get(const Scene *scene)
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)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
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)
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])
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)
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 UNUSED_VARS_NDEBUG(...)
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)
void DEG_debug_print_eval(Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
@ 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.
Read Guarded memory(de)allocation.
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)
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(float x, ccl_private int *ix)
const Depsgraph * depsgraph
static bool is_cyclic(const Nurb *nu)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
const float * anim_path_accum_length
ObjectRuntimeHandle * runtime
struct bConstraint * next
struct DualQuat deform_dual_quat
struct bPoseChannel * parent
struct bPoseChannel * next
struct bPoseChannel_Runtime runtime
struct bPoseChannel * orig_pchan
bPoseChannel ** chan_array
bSplineIKConstraint * ik_data
float locrot_offset[4][4]