51#define ANIM_FEEDBACK 0.8
216 bPoseChannel *curchan, *pchan_root =
nullptr, *chanlist[256], **oldchan;
220 int a, t, segcount = 0,
size, newsize, *oldparent, parent, rootbone, treecount;
226 pchan_tip = pchan_tip->
parent;
229 rootbone =
data->rootbone;
231 for (curchan = pchan_tip; curchan; curchan = curchan->
parent) {
232 pchan_root = curchan;
234 if (++segcount > 255) {
238 if (segcount == rootbone) {
264 for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone;
265 segcount++, curchan = curchan->
parent)
267 chanlist[segcount] = curchan;
279 if (
tree ==
nullptr) {
283 tree->iterations =
data->iterations;
284 tree->totchannel = segcount;
289 for (a = 0; a < segcount; a++) {
290 tree->pchan[a] = chanlist[segcount - a - 1];
291 tree->parent[a] = a - 1;
293 target->
tip = segcount - 1;
301 tree->iterations = std::max<int>(
data->iterations,
tree->iterations);
305 size = std::min(segcount,
tree->totchannel);
307 while (a <
size && t < tree->totchannel) {
309 for (; t <
tree->totchannel &&
tree->pchan[t] != chanlist[segcount - a - 1]; t++) {
312 if (t >=
tree->totchannel) {
315 for (; a <
size && t <
tree->totchannel &&
tree->pchan[t] == chanlist[segcount - a - 1];
322 segcount = segcount - a;
323 target->
tip =
tree->totchannel + segcount - 1;
326 for (parent = a - 1; parent <
tree->totchannel; parent++) {
327 if (
tree->pchan[parent] == chanlist[segcount - 1]->parent) {
333 if (parent ==
tree->totchannel) {
338 newsize =
tree->totchannel + segcount;
339 oldchan =
tree->pchan;
340 oldparent =
tree->parent;
344 memcpy(
tree->pchan, oldchan,
sizeof(
void *) *
tree->totchannel);
345 memcpy(
tree->parent, oldparent,
sizeof(
int) *
tree->totchannel);
350 for (a = 0; a < segcount; a++) {
351 tree->pchan[
tree->totchannel + a] = chanlist[segcount - a - 1];
352 tree->parent[
tree->totchannel + a] =
tree->totchannel + a - 1;
354 tree->parent[
tree->totchannel] = parent;
356 tree->totchannel = newsize;
388 if (
data->tar ==
nullptr) {
454 double qy =
R(0, 2) -
R(2, 0);
455 double qw =
R(0, 0) +
R(1, 1) +
R(2, 2) + 1;
598 next.setValue(&tarmat[0][0]);
630 next.setValue(&rootmat[0][0]);
672 double q_rest[3], q[3],
length;
696 polerot.
UnitZ(-poledir);
797 switch (condata->
mode) {
810 switch (condata->
mode) {
913 for (
uint i = 0;
i < _nvalues;
i++, dof++) {
930 for (a = 0, ikchan = ikscene->
channels; a < ikscene->numchan; a++, ikchan++) {
931 pchan =
tree->pchan[a];
932 ikchan->
pchan = pchan;
933 ikchan->
parent = (a > 0) ?
tree->parent[a] : -1;
1047 njoint += ikchan->
ndof;
1071 for (joint = a = 0, ikchan = ikscene->
channels;
1072 a < ikscene->numchan && joint < ikscene->numjoint;
1075 pchan = ikchan->
pchan;
1095 joint += ikchan->
ndof;
1115 for (joint = a = 0, ikchan = ikscene->
channels;
1116 a < ikscene->numchan && joint < ikscene->numjoint;
1119 pchan = ikchan->
pchan;
1126 joint += ikchan->
ndof;
1151 if (
tree->totchannel == 0) {
1163 ikscene->
scene = scene;
1176 switch (ikparam->
solver) {
1193 std::string root(
"root");
1195 std::vector<double> weights;
1203 for (a = 0, ikchan = ikscene->
channels; a < tree->totchannel; a++, ikchan++) {
1204 pchan = ikchan->
pchan;
1211 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]);
1216 float R_parmat[3][3];
1217 float iR_parmat[3][3];
1228 start[0] = start[1] = start[2] = 0.0f;
1256 weight[0] = (1.0 - pchan->
stiffness[0]);
1257 weight[1] = (1.0 - pchan->
stiffness[1]);
1258 weight[2] = (1.0 - pchan->
stiffness[2]);
1269 weights.push_back(weight[0]);
1275 weights.push_back(weight[1]);
1281 weights.push_back(weight[2]);
1286 weights.push_back(weight[0]);
1292 weights.push_back(weight[1]);
1298 weights.push_back(weight[0]);
1299 weights.push_back(weight[2]);
1305 weights.push_back(weight[2]);
1311 weights.push_back(weight[1]);
1318 weights.push_back(weight[0]);
1319 weights.push_back(weight[2]);
1325 weights.push_back(weight[1]);
1331 weights.push_back(weight[0]);
1332 weights.push_back(weight[1]);
1333 weights.push_back(weight[2]);
1343 weight[1] = (1.0 -
min_ff(1.0 - ikstretch, 1.0f - 0.001f));
1344 weights.push_back(weight[1]);
1351 ikchan->
tail = joint;
1352 ikchan->
head = parent;
1434 for (numtarget = 0, polarcon =
nullptr,
ret =
true, target = (
PoseTarget *)
tree->targets.first;
1436 target = target->
next)
1439 pchan =
tree->pchan[target->
tip];
1444 ikscene->
targets.push_back(iktarget);
1446 if (iktarget->
ee == -1) {
1455 iktarget->
owner = ob;
1465 polarcon = target->
con;
1470 if (numtarget == 1 && polarcon) {
1479 std::string armname;
1494 assert(Wq.cols() ==
int(weights.size()));
1495 for (
int q = 0; q < Wq.cols(); q++) {
1496 Wq(q, q) = weights[q];
1502 float invBaseFrame[4][4];
1506 float baseFrame[4][4];
1517 for (t = 0; t < ikscene->
targets.size(); t++) {
1523 uint controltype, bone_count;
1529 for (bone_count = 0, bone_length = 0.0f, a = iktarget->
channel; a >= 0;
1530 a =
tree->parent[a], bone_count++)
1532 bone_length += ikscene->
blScale *
tree->pchan[a]->bone->length;
1534 bone_length /= bone_count;
1553 switch (condata->
type) {
1651 ikdata->
first = ikscene;
1663 if (
tree->basis_change) {
1677 float scale =
len_v3(ob->object_to_world().ptr()[1]);
1723 for (
i = ikscene->
targets.size();
i > 0;
i--) {
1735 double timestamp = ctime * frtime + 2147483.648;
1736 double timestep = frtime;
1739 bool simulation =
true;
1758 if (ikscene->
cache && !reiterate && simulation) {
1770 timestep = sts / 1000.0;
1774 ikscene->
scene->
update(timestamp, timestep, numstep,
false, !reiterate, simulation);
1783 ikscene->
scene->
update(timestamp, timestep, numstep,
true,
false, simulation);
1787 ikscene->
scene->
update(timestamp, 0.0, 1,
true,
true,
true);
1791 for (
i = ikscene->
targets.size();
i > 0;
i--) {
1808 double q_rest[3], q[3];
1832 if (!arm->
getSegment(ikchan->
tail, 3, joint, q_rest[0], q[0], tip)) {
1837 scale = float(q[0] / q_rest[0]);
1847 pchan = ikchan->
pchan;
1914 if (ikscene->channels[0].pchan == pchan_root) {
1948 scene->cache->clearCacheFrom(
nullptr, 1);
1960 double armlength = ikscene->armature->getArmLength();
1964 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, ikparam->
minstep);
1965 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, ikparam->
maxstep);
1967 ikscene->armature->setControlParameter(
1973 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, 1.0);
1974 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, 1.0);
1976 ikscene->armature->setControlParameter(
1992 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)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
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 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 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 unit_m4(float m[4][4])
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.
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Read Guarded memory(de)allocation.
BMesh const char void * data
BPy_StructRNA * depsgraph
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
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.
Vector GetRot() const
Returns a vector with the direction of the equiv. axis and its norm is angle.
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.
Vector2 GetXZRot() const
Returns a 2D vector representing the equivalent rotation in the XZ plane that brings the Y axis onto ...
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 addSolver(Solver *_solver)
bool addConstraintSet(const std::string &name, ConstraintSet *task, const std::string &object1, const std::string &object2, const std::string &ee1="", const std::string &ee2="")
bool update(double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false, bool cache=true, bool interpolate=true)
bool addCache(Cache *_cache)
bool addObject(const std::string &name, Object *object, UncontrolledObject *base=&Object::world, const std::string &baseFrame="")
virtual void setParam(SolverParam param, double value)=0
IMETHOD void SetToZero(Vector &v)
#define assert(assertion)
float length(VecOp< float, D >) RET
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 *)
void(*)(const iTaSC::ConstraintValues *values, uint nvalues, IK_Target *iktarget) ErrorCallback
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)
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_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
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)
double epsilon
default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
Vector Normalize(const Vector &, double eps=epsilon)
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 bPoseChannel * parent
struct ConstraintSingleValue * values