28 #define USE_NONUNIFORM_SCALE
42 int a,
t, segcount = 0,
size, newsize, *oldparent, parent;
68 pchan_tip = pchan_tip->
parent;
72 for (curchan = pchan_tip; curchan; curchan = curchan->
parent) {
76 chanlist[segcount] = curchan;
79 if (segcount ==
data->rootbone || segcount > 255) {
91 for (target =
tree->targets.first; target; target = target->
next) {
92 curchan =
tree->pchan[target->
tip];
116 tree->iterations =
data->iterations;
117 tree->totchannel = segcount;
122 for (
a = 0;
a < segcount;
a++) {
123 tree->pchan[
a] = chanlist[segcount -
a - 1];
126 target->
tip = segcount - 1;
138 while (
a <
size && t < tree->totchannel) {
140 for (;
t <
tree->totchannel &&
tree->pchan[
t] != chanlist[segcount -
a - 1];
t++) {
143 if (
t >=
tree->totchannel) {
146 for (;
a <
size &&
t <
tree->totchannel &&
tree->pchan[
t] == chanlist[segcount -
a - 1];
152 segcount = segcount -
a;
153 target->
tip =
tree->totchannel + segcount - 1;
156 for (parent =
a - 1; parent <
tree->totchannel; parent++) {
157 if (
tree->pchan[parent] == chanlist[segcount - 1]->parent) {
163 if (parent ==
tree->totchannel) {
168 newsize =
tree->totchannel + segcount;
169 oldchan =
tree->pchan;
170 oldparent =
tree->parent;
174 memcpy(
tree->pchan, oldchan,
sizeof(
void *) *
tree->totchannel);
175 memcpy(
tree->parent, oldparent,
sizeof(
int) *
tree->totchannel);
180 for (
a = 0;
a < segcount;
a++) {
181 tree->pchan[
tree->totchannel +
a] = chanlist[segcount -
a - 1];
184 tree->parent[
tree->totchannel] = parent;
186 tree->totchannel = newsize;
204 float iR_parmat[4][4];
219 float vec[3], ikmat[4][4];
230 #ifdef USE_NONUNIFORM_SCALE
241 #ifdef USE_NONUNIFORM_SCALE
267 float R_parmat[3][3], identity[3][3];
268 float iR_parmat[3][3];
269 float R_bonemat[3][3];
270 float goalrot[3][3], goalpos[3];
271 float rootmat[4][4], imat[4][4];
272 float goal[4][4], goalinv[4][4];
273 float irest_basis[3][3], full_basis[3][3];
274 float end_pose[4][4], world_pose[4][4];
275 float basis[3][3], rest_basis[3][3], start[3], *ikstretch =
NULL;
276 float resultinf = 0.0f;
277 int a, flag, hasstretch = 0, resultblend = 0;
279 IK_Segment *seg, *parent, **iktree, *iktarget;
285 if (
tree->totchannel == 0) {
291 for (
a = 0;
a <
tree->totchannel;
a++) {
293 pchan =
tree->pchan[
a];
320 parent = iktree[
tree->parent[
a]];
338 if (pchan->
parent && (
a > 0)) {
343 start[0] = start[1] = start[2] = 0.0f;
394 pchan =
tree->pchan[0];
412 for (target =
tree->targets.first; target; target = target->
next) {
414 int poleconstrain = 0;
452 poleangledata =
data;
458 if (!resultblend && target->
con->
enforce != 1.0f) {
459 float q1[4], q2[4], q[4];
461 float mfac = 1.0f - fac;
463 pchan =
tree->pchan[target->
tip];
471 goalpos[0] = fac * goalpos[0] + mfac * world_pose[3][0];
472 goalpos[1] = fac * goalpos[1] + mfac * world_pose[3][1];
473 goalpos[2] = fac * goalpos[2] + mfac * world_pose[3][2];
482 iktarget = iktree[target->
tip];
487 solver, iktarget, goalpos, polepos,
data->poleangle, (poleangledata ==
data));
508 tree->basis_change =
MEM_mallocN(
sizeof(
float[3][3]) *
tree->totchannel,
"ik basis change");
510 ikstretch =
MEM_mallocN(
sizeof(
float) *
tree->totchannel,
"ik stretch");
513 for (
a = 0;
a <
tree->totchannel;
a++) {
518 float parentstretch, stretch;
520 pchan =
tree->pchan[
a];
521 parentstretch = (
tree->parent[
a] >= 0) ? ikstretch[
tree->parent[
a]] : 1.0f;
535 stretch = (parentstretch == 0.0f) ? 1.0f : ikstretch[
a] / parentstretch;
542 if (resultblend && resultinf != 1.0f) {
565 if (
tree->basis_change) {
605 for (
a = 0;
a <
tree->totchannel;
a++) {
619 for (
a = 0;
a <
tree->totchannel;
a++) {
623 for (
a = 0;
a <
tree->totchannel;
a++) {
646 while (pchan->iktree.first) {
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct 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(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct 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])
void unit_m4(float m[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void normalize_m3(float R[3][3]) ATTR_NONNULL()
#define mul_m4_series(...)
bool invert_m3_m3(float R[3][3], const float A[3][3])
void copy_m4_m4(float m1[4][4], const float m2[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 interp_qt_qtqt(float q[4], const float a[4], const float b[4], float t)
void mat3_to_quat(float q[4], const float mat[3][3])
void mat4_to_quat(float q[4], const float mat[4][4])
void quat_to_mat3(float mat[3][3], const float q[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 r[3], float unit_scale)
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
struct Depsgraph Depsgraph
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_OBTYPE_OBJECT
Object is a sort of wrapper for general info.
_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 GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
IK_Solver * IK_CreateSolver(IK_Segment *root)
float IK_SolverGetPoleAngle(IK_Solver *solver)
#define IK_STRETCH_STIFF_MAX
IK_Segment * IK_CreateSegment(int flag)
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
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.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
const Depsgraph * depsgraph
void iksolver_execute_tree(struct Depsgraph *depsgraph, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
void iksolver_initialize_tree(struct Depsgraph *UNUSED(depsgraph), struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
static void free_posetree(PoseTree *tree)
static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3])
void iksolver_clear_data(bPose *pose)
static void make_dmats(bPoseChannel *pchan)
static void initialize_posetree(struct Object *UNUSED(ob), bPoseChannel *pchan_tip)
static void execute_posetree(struct Depsgraph *depsgraph, struct Scene *scene, Object *ob, PoseTree *tree)
void iksolver_release_tree(struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
T length(const vec_base< T, Size > &a)
struct bConstraint * next
struct bPoseChannel * parent
struct bPoseChannel * next