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;
841 if (pchan->bone ==
nullptr || pchan->bone->segments <= 1) {
869 if (armature->
edbo !=
nullptr) {
908 if (armature->
edbo !=
nullptr) {
936 if (armature->
edbo !=
nullptr) {
952 if (armature->
edbo !=
nullptr) {
978 if (armature->
edbo !=
nullptr) {
998 if (armature->
edbo !=
nullptr) {
1019 if (armature->
edbo !=
nullptr) {
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.
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.
CCL_NAMESPACE_BEGIN ccl_device_inline float frac(float x, ccl_private int *ix)
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]