53#define ANIM_FEEDBACK 0.8
218 bPoseChannel *curchan, *pchan_root =
nullptr, *chanlist[256], **oldchan;
222 int a, t, segcount = 0,
size, newsize, *oldparent, parent, rootbone, treecount;
228 pchan_tip = pchan_tip->
parent;
231 rootbone = data->rootbone;
233 for (curchan = pchan_tip; curchan; curchan = curchan->
parent) {
234 pchan_root = curchan;
236 if (++segcount > 255) {
240 if (segcount == rootbone) {
266 for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone;
267 segcount++, curchan = curchan->
parent)
269 chanlist[segcount] = curchan;
275 target = MEM_cnew<PoseTarget>(
"posetarget");
281 if (
tree ==
nullptr) {
283 tree = MEM_cnew<PoseTree>(
"posetree");
285 tree->iterations = data->iterations;
286 tree->totchannel = segcount;
290 tree->parent = (
int *)
MEM_callocN(segcount *
sizeof(
int),
"ik tree parent");
291 for (a = 0; a < segcount; a++) {
292 tree->pchan[a] = chanlist[segcount - a - 1];
293 tree->parent[a] = a - 1;
295 target->tip = segcount - 1;
303 tree->iterations = std::max<int>(data->iterations,
tree->iterations);
307 size = std::min(segcount,
tree->totchannel);
309 while (a < size && t < tree->totchannel) {
311 for (; t <
tree->totchannel &&
tree->pchan[t] != chanlist[segcount - a - 1]; t++) {
314 if (t >=
tree->totchannel) {
317 for (; a < size && t <
tree->totchannel &&
tree->pchan[t] == chanlist[segcount - a - 1];
324 segcount = segcount - a;
325 target->tip =
tree->totchannel + segcount - 1;
328 for (parent = a - 1; parent <
tree->totchannel; parent++) {
329 if (
tree->pchan[parent] == chanlist[segcount - 1]->parent) {
335 if (parent ==
tree->totchannel) {
340 newsize =
tree->totchannel + segcount;
341 oldchan =
tree->pchan;
342 oldparent =
tree->parent;
345 tree->parent = (
int *)
MEM_callocN(newsize *
sizeof(
int),
"ik tree parent");
346 memcpy(
tree->pchan, oldchan,
sizeof(
void *) *
tree->totchannel);
347 memcpy(
tree->parent, oldparent,
sizeof(
int) *
tree->totchannel);
352 for (a = 0; a < segcount; a++) {
353 tree->pchan[
tree->totchannel + a] = chanlist[segcount - a - 1];
354 tree->parent[
tree->totchannel + a] =
tree->totchannel + a - 1;
356 tree->parent[
tree->totchannel] = parent;
358 tree->totchannel = newsize;
390 if (data->tar ==
nullptr) {
393 if (data->tar->type ==
OB_ARMATURE && data->subtarget[0] == 0) {
456 double qy =
R(0, 2) -
R(2, 0);
457 double qw =
R(0, 0) +
R(1, 1) +
R(2, 2) + 1;
486static void GetEulerXZY(
const KDL::Rotation &
R,
double &
X,
double &Z,
double &
Y)
500static void GetEulerXYZ(
const KDL::Rotation &
R,
double &
X,
double &
Y,
double &Z)
582 if (constraint->
enforce != 1.0f && target->eeBlend) {
592 mul_m4_series(restmat, target->owner->object_to_world().ptr(), chanmat, target->eeRest);
595 mul_m4_m4m4(restmat, target->owner->object_to_world().ptr(), target->eeRest);
600 next.setValue(&tarmat[0][0]);
674 double q_rest[3], q[3],
length;
698 polerot.
UnitZ(-poledir);
738 values->alpha = condata->
weight;
764 for (i = 0,
error = 0.0, value = values->values; i < values->number; i++, value++) {
772 for (i = 0,
error = 0.0, value = values->values; i < values->number; i++, value++) {
799 switch (condata->
mode) {
801 values->alpha = (values->values[0].y > condata->
dist) ? condata->
weight : 0.0;
804 values->alpha = (values->values[0].y < condata->
dist) ? condata->
weight : 0.0;
807 values->alpha = condata->
weight;
812 switch (condata->
mode) {
814 values->values[0].yd = condata->
dist * 0.95;
817 values->values[0].yd = condata->
dist * 1.05;
820 values->values[0].yd = condata->
dist;
915 for (
uint i = 0; i < _nvalues; i++, dof++) {
932 for (a = 0, ikchan = ikscene->
channels; a < ikscene->
numchan; a++, ikchan++) {
933 pchan =
tree->pchan[a];
934 ikchan->
pchan = pchan;
935 ikchan->
parent = (a > 0) ?
tree->parent[a] : -1;
1049 njoint += ikchan->
ndof;
1073 for (joint = a = 0, ikchan = ikscene->
channels;
1077 pchan = ikchan->
pchan;
1097 joint += ikchan->
ndof;
1117 for (joint = a = 0, ikchan = ikscene->
channels;
1121 pchan = ikchan->
pchan;
1128 joint += ikchan->
ndof;
1153 if (
tree->totchannel == 0) {
1178 switch (ikparam->
solver) {
1195 std::string root(
"root");
1197 std::vector<double> weights;
1205 for (a = 0, ikchan = ikscene->
channels; a <
tree->totchannel; a++, ikchan++) {
1206 pchan = ikchan->
pchan;
1213 fl[0][0], fl[1][0], fl[2][0], fl[0][1], fl[1][1], fl[2][1], fl[0][2], fl[1][2], fl[2][2]);
1218 float R_parmat[3][3];
1219 float iR_parmat[3][3];
1230 start[0] = start[1] = start[2] = 0.0f;
1258 weight[0] = (1.0 - pchan->
stiffness[0]);
1259 weight[1] = (1.0 - pchan->
stiffness[1]);
1260 weight[2] = (1.0 - pchan->
stiffness[2]);
1271 weights.push_back(weight[0]);
1277 weights.push_back(weight[1]);
1283 weights.push_back(weight[2]);
1288 weights.push_back(weight[0]);
1294 weights.push_back(weight[1]);
1300 weights.push_back(weight[0]);
1301 weights.push_back(weight[2]);
1307 weights.push_back(weight[2]);
1313 weights.push_back(weight[1]);
1320 weights.push_back(weight[0]);
1321 weights.push_back(weight[2]);
1327 weights.push_back(weight[1]);
1333 weights.push_back(weight[0]);
1334 weights.push_back(weight[1]);
1335 weights.push_back(weight[2]);
1345 weight[1] = (1.0 -
min_ff(1.0 - ikstretch, 1.0f - 0.001f));
1346 weights.push_back(weight[1]);
1353 ikchan->
tail = joint;
1354 ikchan->
head = parent;
1436 for (numtarget = 0, polarcon =
nullptr,
ret =
true, target = (
PoseTarget *)
tree->targets.first;
1441 pchan =
tree->pchan[target->tip];
1446 ikscene->
targets.push_back(iktarget);
1448 if (iktarget->
ee == -1) {
1454 iktarget->
channel = target->tip;
1457 iktarget->
owner = ob;
1467 polarcon = target->con;
1472 if (numtarget == 1 && polarcon) {
1481 std::string armname;
1484 ret = scene->addObject(armname, ikscene->
base);
1496 assert(Wq.cols() ==
int(weights.size()));
1497 for (
int q = 0; q < Wq.cols(); q++) {
1498 Wq(q, q) = weights[q];
1504 float invBaseFrame[4][4];
1508 float baseFrame[4][4];
1519 for (t = 0; t < ikscene->
targets.size(); t++) {
1525 uint controltype, bone_count;
1531 for (bone_count = 0, bone_length = 0.0f, a = iktarget->
channel; a >= 0;
1532 a =
tree->parent[a], bone_count++)
1534 bone_length += ikscene->
blScale *
tree->pchan[a]->bone->length;
1536 bone_length /= bone_count;
1555 switch (condata->
type) {
1632 if (!
ret || !scene->addCache(ikscene->
cache) || !scene->addSolver(ikscene->
solver) ||
1633 !scene->initialize())
1653 ikdata->
first = ikscene;
1665 if (
tree->basis_change) {
1679 float scale =
len_v3(ob->object_to_world().ptr()[1]);
1683 for (scene = ((
IK_Data *)ob->
pose->
ikdata)->first; scene !=
nullptr; scene = scene->next) {
1703 for (i = 0, ikchan = ikscene->
channels; i < ikscene->
numchan; i++, ikchan++) {
1713 for (i = 0, ikchan = ikscene->
channels; i < ikscene->
numchan; i++, ikchan++) {
1725 for (i = ikscene->
targets.size(); i > 0; i--) {
1737 double timestamp = ctime * frtime + 2147483.648;
1738 double timestep = frtime;
1741 bool simulation =
true;
1760 if (ikscene->
cache && !reiterate && simulation) {
1772 timestep = sts / 1000.0;
1776 ikscene->
scene->
update(timestamp, timestep, numstep,
false, !reiterate, simulation);
1779 for (i = 0; i < ikparam->
numiter; i++) {
1785 ikscene->
scene->
update(timestamp, timestep, numstep,
true,
false, simulation);
1789 ikscene->
scene->
update(timestamp, 0.0, 1,
true,
true,
true);
1793 for (i = ikscene->
targets.size(); i > 0; i--) {
1810 double q_rest[3], q[3];
1817 for (i = 0, ikchan = ikscene->
channels; i < ikscene->
numchan; i++, ikchan++) {
1834 if (!arm->
getSegment(ikchan->
tail, 3, joint, q_rest[0], q[0], tip)) {
1839 scale =
float(q[0] / q_rest[0]);
1841 length =
float(q[0]);
1849 pchan = ikchan->
pchan;
1867 if (i < ikscene->numchan) {
1901 ob->
pose->
flag &= ~POSE_WAS_REBUILT;
1915 for (
IK_Scene *ikscene = ikdata->
first; ikscene; ikscene = ikscene->next) {
1916 if (ikscene->channels[0].pchan == pchan_root) {
1917 float timestep = scene->r.frs_sec_base / scene->r.frs_sec;
1950 scene->cache->clearCacheFrom(
nullptr, 1);
1961 for (
IK_Scene *ikscene = ikdata->
first; ikscene; ikscene = ikscene->next) {
1962 double armlength = ikscene->armature->getArmLength();
1966 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, ikparam->
minstep);
1967 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, ikparam->
maxstep);
1969 ikscene->armature->setControlParameter(
1975 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, 1.0);
1976 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, 1.0);
1978 ikscene->armature->setControlParameter(
1994 switch (data->type) {
Blender kernel action and pose functionality.
void BKE_pose_itasc_init(bItasc *itasc)
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)
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#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 min_ff(float a, float b)
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 unit_m3(float m[3][3])
void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], float srcweight)
void copy_m3_m4(float m1[3][3], const float m2[4][4])
void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3])
bool invert_m3_m3(float inverse[3][3], const float mat[3][3])
void unit_m4(float m[4][4])
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 normalize_m4(float R[4][4]) ATTR_NONNULL()
void quat_to_mat3(float m[3][3], const float q[4])
float normalize_qt(float q[4])
void eulO_to_mat3(float M[3][3], const float e[3], short order)
void axis_angle_to_mat3(float R[3][3], const float axis[3], float angle)
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 len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
#define CONSTRAINT_ID_ALL
@ ITASC_TRANSLATE_ROOT_BONES
@ ITASC_INITIAL_REITERATION
@ CONSTRAINT_IK_TARGETAXIS
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_OBTYPE_OBJECT
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
represents a frame transformation in 3D space (rotation + translation)
Rotation M
Orientation of the Frame.
void setValue(float *oglmat)
void getValue(float *oglmat) const
Vector p
origine of the Frame
void resize(unsigned int newSize)
This class encapsulates a simple joint, that is with one parameterized degree of freedom and with sca...
const JointType & getType() const
represents rotations in 3 dimensional space.
Rotation Inverse() const
Gives back the inverse rotation matrix of *this.
Vector UnitY() const
Access to the underlying unitvectors of the rotation matrix.
Vector UnitZ() const
Access to the underlying unitvectors of the rotation matrix.
Vector UnitX() const
Access to the underlying unitvectors of the rotation matrix.
static Rotation RotX(double angle)
The Rot... static functions give the value of the appropriate rotation matrix back.
void setValue(float *oglmat)
static Rotation RotY(double angle)
The Rot... static functions give the value of the appropriate rotation matrix back.
static Rotation RotZ(double angle)
The Rot... static functions give the value of the appropriate rotation matrix back.
void GetValue(double *xy) const
store vector components in array
A concrete implementation of a 3 dimensional vector class.
void GetValue(double *xyz) const
store vector components in array
bool addSegment(const std::string &segment_name, const std::string &hook_name, const Joint &joint, const double &q_rest, const Frame &f_tip=F_identity, const Inertia &M=Inertia::Zero())
int addLimitConstraint(const std::string &segment_name, unsigned int dof, double _min, double _max)
bool getRelativeFrame(Frame &result, const std::string &segment_name, const std::string &base_name=m_root)
virtual const Frame & getPose(const unsigned int end_effector)
int addConstraint(const std::string &segment_name, ConstraintCallback _function, void *_param=NULL, bool _freeParam=false, bool _substep=false)
virtual int addEndEffector(const std::string &name)
bool getSegment(const std::string &segment_name, const unsigned int q_size, const Joint *&p_joint, double &q_rest, double &q, const Frame *&p_tip)
double getMaxEndEffectorChange()
virtual bool setJointArray(const KDL::JntArray &joints)
double getMaxJointChange()
const void * getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp)
bool setControlParameter(int id, ConstraintAction action, double value, double timestep=0.0)
void substep(bool _substep)
virtual EIGEN_MAKE_ALIGNED_OPERATOR_NEW bool registerCallback(ConstraintCallback _function, void *_param)
virtual const ConstraintValues * getControlParameters(unsigned int *_nvalues)=0
virtual const unsigned int getNrOfConstraints()
virtual e_matrix & getWq()
bool setCallback(MovingFrameCallback _function, void *_param)
virtual const KDL::Frame & getPose(const unsigned int end_effector=0)
bool update(double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false, bool cache=true, bool interpolate=true)
virtual void setParam(SolverParam param, double value)=0
const Depsgraph * depsgraph
draw_view in_light_buf[] float
IMETHOD void SetToZero(Vector &v)
void itasc_clear_data(bPose *pose)
static void RemoveEulerAngleFromMatrix(KDL::Rotation &R, double angle, int axis)
static void copypose_error(const iTaSC::ConstraintValues *values, uint, IK_Target *iktarget)
static int init_scene(Object *ob)
static bool copypose_callback(const iTaSC::Timestamp &, iTaSC::ConstraintValues *const _values, uint, void *_param)
void itasc_update_param(bPose *pose)
static void distance_error(const iTaSC::ConstraintValues *values, uint, IK_Target *iktarget)
static void BKE_pose_rest(IK_Scene *ikscene)
static int initialize_chain(Object *, bPoseChannel *pchan_tip, bConstraint *con)
void itasc_initialize_tree(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
static void convert_pose(IK_Scene *ikscene)
static bool distance_callback(const iTaSC::Timestamp ×tamp, iTaSC::ConstraintValues *const _values, uint, void *_param)
static bool joint_callback(const iTaSC::Timestamp &, iTaSC::ConstraintValues *const _values, uint _nvalues, void *_param)
static bool is_cartesian_constraint(bConstraint *)
static int initialize_scene(Object *ob, bPoseChannel *pchan_tip)
static IK_Data * get_ikdata(bPose *pose)
void itasc_clear_cache(bPose *pose)
void itasc_execute_tree(Depsgraph *depsgraph, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
static bool constraint_valid(bConstraint *con)
void(*)(const iTaSC::ConstraintValues *values, uint nvalues, IK_Target *iktarget) ErrorCallback
static void execute_scene(Depsgraph *depsgraph, Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, float ctime, float frtime)
static bool base_callback(const iTaSC::Timestamp ×tamp, const iTaSC::Frame &, iTaSC::Frame &next, void *param)
static IK_Scene * convert_tree(Depsgraph *depsgraph, Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime)
static void GetJointRotation(KDL::Rotation &boneRot, int type, double *rot)
static double ComputeTwist(const KDL::Rotation &R)
void itasc_test_constraint(Object *, bConstraint *cons)
static void create_scene(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
static bool target_callback(const iTaSC::Timestamp &, const iTaSC::Frame &, iTaSC::Frame &next, void *param)
void itasc_release_tree(Scene *, Object *, float)
static double EulerAngleFromMatrix(const KDL::Rotation &R, int axis)
static int convert_channels(Depsgraph *depsgraph, IK_Scene *ikscene, PoseTree *tree, float ctime)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float2 fabs(const float2 a)
static void error(const char *str)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
INLINE Rall1d< T, V, S > sqr(const Rall1d< T, V, S > &arg)
const double PI
the value of pi
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
Vector Normalize(const Vector &, double eps=epsilon)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
iTaSC::MovingFrame * base
iTaSC::Armature * armature
std::vector< IK_Target * > targets
bConstraint * polarConstraint
bConstraint * blenderConstraint
std::string constraintName
iTaSC::ConstraintSet * constraint
bPoseChannel * rootChannel
ErrorCallback errorCallback
iTaSC::MovingFrame * target
struct bConstraint * next
struct bPoseChannel * parent
struct ConstraintSingleValue * values