33#define USE_NONUNIFORM_SCALE
44 ik_constraints.
append(con);
47 if (
data->tar ==
nullptr) {
56 ik_constraints.
append(con);
74 bPoseChannel *curchan, *pchan_root =
nullptr, *chanlist[256], **oldchan;
81 pchan_tip = pchan_tip->
parent;
85 for (curchan = pchan_tip; curchan; curchan = curchan->
parent) {
89 chanlist[segcount] = curchan;
92 if (segcount ==
data->rootbone || segcount > 255) {
103 for (target =
static_cast<PoseTarget *
>(
tree->targets.first); target; target = target->
next)
105 curchan =
tree->pchan[target->
tip];
120 target->
con = constraint;
123 if (
tree ==
nullptr) {
129 tree->iterations =
data->iterations;
130 tree->totchannel = segcount;
135 for (
int a = 0; a < segcount; a++) {
136 tree->pchan[a] = chanlist[segcount - a - 1];
137 tree->parent[a] = a - 1;
139 target->
tip = segcount - 1;
145 tree->iterations = std::max<int>(
data->iterations,
tree->iterations);
149 const int size = std::min(segcount,
tree->totchannel);
152 while (a <
size && t < tree->totchannel) {
154 for (; t <
tree->totchannel &&
tree->pchan[t] != chanlist[segcount - a - 1]; t++) {
157 if (t >=
tree->totchannel) {
160 for (; a <
size && t <
tree->totchannel &&
tree->pchan[t] == chanlist[segcount - a - 1];
167 segcount = segcount - a;
168 target->
tip =
tree->totchannel + segcount - 1;
172 for (parent = a - 1; parent <
tree->totchannel; parent++) {
173 if (
tree->pchan[parent] == chanlist[segcount - 1]->parent) {
179 if (parent ==
tree->totchannel) {
184 const int newsize =
tree->totchannel + segcount;
185 oldchan =
tree->pchan;
186 int *oldparent =
tree->parent;
190 memcpy(
tree->pchan, oldchan,
sizeof(
void *) *
tree->totchannel);
191 memcpy(
tree->parent, oldparent,
sizeof(
int) *
tree->totchannel);
196 for (a = 0; a < segcount; a++) {
197 tree->pchan[
tree->totchannel + a] = chanlist[segcount - a - 1];
198 tree->parent[
tree->totchannel + a] =
tree->totchannel + a - 1;
200 tree->parent[
tree->totchannel] = parent;
202 tree->totchannel = newsize;
217 if (constraint->enforce != 0.0 && !(constraint->flag &
CONSTRAINT_OFF)) {
227 float iR_parmat[4][4];
242 float vec[3], ikmat[4][4];
253#ifdef USE_NONUNIFORM_SCALE
264#ifdef USE_NONUNIFORM_SCALE
287 float R_parmat[3][3], identity[3][3];
288 float iR_parmat[3][3];
289 float R_bonemat[3][3];
290 float goalrot[3][3], goalpos[3];
291 float rootmat[4][4], imat[4][4];
292 float goal[4][4], goalinv[4][4];
293 float irest_basis[3][3], full_basis[3][3];
294 float end_pose[4][4], world_pose[4][4];
295 float basis[3][3], rest_basis[3][3], start[3], *ikstretch =
nullptr;
296 float resultinf = 0.0f;
297 int a,
flag, hasstretch = 0, resultblend = 0;
299 IK_Segment *seg, *parent, **iktree, *iktarget;
304 if (
tree->totchannel == 0) {
310 for (a = 0; a <
tree->totchannel; a++) {
312 pchan =
tree->pchan[a];
339 parent = iktree[
tree->parent[a]];
357 if (pchan->
parent && (a > 0)) {
362 start[0] = start[1] = start[2] = 0.0f;
413 pchan =
tree->pchan[0];
428 mul_m4_m4m4(imat, ob->object_to_world().ptr(), rootmat);
433 int poleconstrain = 0;
468 resultinf = (target->con->flag &
CONSTRAINT_OFF) ? 0.0f : target->con->enforce;
471 poleangledata =
data;
477 if (!resultblend && ((target->con->flag &
CONSTRAINT_OFF) || target->con->enforce != 1.0f)) {
478 float q1[4], q2[4], q[4];
479 float fac = (target->con->flag &
CONSTRAINT_OFF) ? 0.0f : target->con->enforce;
480 float mfac = 1.0f - fac;
482 pchan =
tree->pchan[target->tip];
487 mul_m4_series(world_pose, goalinv, ob->object_to_world().ptr(), end_pose);
490 goalpos[0] = fac * goalpos[0] + mfac * world_pose[3][0];
491 goalpos[1] = fac * goalpos[1] + mfac * world_pose[3][1];
492 goalpos[2] = fac * goalpos[2] + mfac * world_pose[3][2];
501 iktarget = iktree[target->tip];
506 solver, iktarget, goalpos, polepos,
data->poleangle, (poleangledata ==
data));
532 for (a = 0; a <
tree->totchannel; a++) {
537 float parentstretch, stretch;
539 pchan =
tree->pchan[a];
540 parentstretch = (
tree->parent[a] >= 0) ? ikstretch[
tree->parent[a]] : 1.0f;
554 stretch = (parentstretch == 0.0f) ? 1.0f : ikstretch[a] / parentstretch;
561 if (resultblend && resultinf != 1.0f) {
584 if (
tree->basis_change) {
619 bool has_influence =
false;
621 if (!(target->con->flag &
CONSTRAINT_OFF) && target->con->enforce != 0.0f) {
622 has_influence =
true;
628 for (a = 0; a <
tree->totchannel; a++) {
637 if (!has_influence) {
648 for (a = 0; a <
tree->totchannel; a++) {
652 for (a = 0; a <
tree->totchannel; a++) {
676 while (pchan->iktree.first) {
void BKE_pose_where_is_bone(Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
void BKE_constraint_target_matrix_get(struct Depsgraph *depsgraph, struct Scene *scene, struct bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float square_f(float a)
void mul_m3_v3(const float M[3][3], float r[3])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m3_m3(float m1[3][3], const float m2[3][3])
void unit_m3(float m[3][3])
void copy_m3_m4(float m1[3][3], const float m2[4][4])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void normalize_m3(float R[3][3]) ATTR_NONNULL()
#define mul_m4_series(...)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void mat4_to_size(float size[3], const float M[4][4])
void transpose_m3_m3(float R[3][3], const float M[3][3])
void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], float srcweight)
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
void mat3_to_size(float size[3], const float M[3][3])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
void unit_m4(float m[4][4])
void interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void quat_to_mat3(float m[3][3], const float q[4])
void mat3_to_quat(float q[4], const float mat[3][3])
void mat4_to_quat(float q[4], const float mat[4][4])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_length(float n[3], float unit_length)
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_OBTYPE_OBJECT
Object is a sort of wrapper for general info.
IK_Solver * IK_CreateSolver(IK_Segment *root)
float IK_SolverGetPoleAngle(IK_Solver *solver)
#define IK_STRETCH_STIFF_MAX
void IK_SolverSetPoleVectorConstraint(IK_Solver *solver, IK_Segment *tip, float goal[3], float polegoal[3], float poleangle, int getangle)
void IK_SetParent(IK_Segment *seg, IK_Segment *parent)
void IK_FreeSolver(IK_Solver *solver)
#define IK_STRETCH_STIFF_MIN
IK_Segment * IK_CreateSegment(int flag)
void IK_FreeSegment(IK_Segment *seg)
void IK_SolverAddGoalOrientation(IK_Solver *solver, IK_Segment *tip, float goal[][3], float weight)
void IK_SetLimit(IK_Segment *seg, IK_SegmentAxis axis, float lmin, float lmax)
void IK_SolverAddGoal(IK_Solver *solver, IK_Segment *tip, float goal[3], float weight)
int IK_Solve(IK_Solver *solver, float tolerance, int max_iterations)
void IK_SetTransform(IK_Segment *seg, float start[3], float rest_basis[][3], float basis[][3], float length)
void IK_GetBasisChange(IK_Segment *seg, float basis_change[][3])
void IK_SetStiffness(IK_Segment *seg, IK_SegmentAxis axis, float stiffness)
void IK_GetTranslationChange(IK_Segment *seg, float *translation_change)
Read Guarded memory(de)allocation.
BMesh const char void * data
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint ** constraints
void append(const T &value)
float length(VecOp< float, D >) RET
void iksolver_release_tree(Scene *, Object *ob, float)
static void initialize_posetree(Object *, bPoseChannel *pchan_tip)
static void find_ik_constraints(ListBase *constraints, blender::Vector< bConstraint * > &ik_constraints)
static void free_posetree(PoseTree *tree)
static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3])
void iksolver_execute_tree(Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
void iksolver_clear_data(bPose *pose)
void iksolver_initialize_tree(Depsgraph *, Scene *, Object *ob, float)
static void make_dmats(bPoseChannel *pchan)
static void execute_posetree(Depsgraph *depsgraph, Scene *scene, Object *ob, PoseTree *tree)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
struct bPoseChannel * parent