16#if defined(__GNUC__) && !defined(__clang__)
17# pragma GCC diagnostic push
18# pragma GCC diagnostic ignored "-Wdeprecated-copy"
33#if defined(__GNUC__) && !defined(__clang__)
34# pragma GCC diagnostic pop
61#define ANIM_FEEDBACK 0.8
226 bPoseChannel *curchan, *pchan_root =
nullptr, *chanlist[256], **oldchan;
230 int a, t, segcount = 0,
size, newsize, *oldparent, parent, rootbone, treecount;
236 pchan_tip = pchan_tip->
parent;
239 rootbone =
data->rootbone;
241 for (curchan = pchan_tip; curchan; curchan = curchan->
parent) {
242 pchan_root = curchan;
244 if (++segcount > 255) {
248 if (segcount == rootbone) {
274 for (rootbone = segcount, segcount = 0, curchan = pchan_tip; segcount < rootbone;
275 segcount++, curchan = curchan->
parent)
277 chanlist[segcount] = curchan;
289 if (
tree ==
nullptr) {
293 tree->iterations =
data->iterations;
294 tree->totchannel = segcount;
299 for (a = 0; a < segcount; a++) {
300 tree->pchan[a] = chanlist[segcount - a - 1];
301 tree->parent[a] = a - 1;
303 target->
tip = segcount - 1;
311 tree->iterations = std::max<int>(
data->iterations,
tree->iterations);
315 size = std::min(segcount,
tree->totchannel);
317 while (a <
size && t < tree->totchannel) {
319 for (; t <
tree->totchannel &&
tree->pchan[t] != chanlist[segcount - a - 1]; t++) {
322 if (t >=
tree->totchannel) {
325 for (; a <
size && t <
tree->totchannel &&
tree->pchan[t] == chanlist[segcount - a - 1];
332 segcount = segcount - a;
333 target->
tip =
tree->totchannel + segcount - 1;
336 for (parent = a - 1; parent <
tree->totchannel; parent++) {
337 if (
tree->pchan[parent] == chanlist[segcount - 1]->parent) {
343 if (parent ==
tree->totchannel) {
348 newsize =
tree->totchannel + segcount;
349 oldchan =
tree->pchan;
350 oldparent =
tree->parent;
354 memcpy(
tree->pchan, oldchan,
sizeof(
void *) *
tree->totchannel);
355 memcpy(
tree->parent, oldparent,
sizeof(
int) *
tree->totchannel);
360 for (a = 0; a < segcount; a++) {
361 tree->pchan[
tree->totchannel + a] = chanlist[segcount - a - 1];
362 tree->parent[
tree->totchannel + a] =
tree->totchannel + a - 1;
364 tree->parent[
tree->totchannel] = parent;
366 tree->totchannel = newsize;
398 if (
data->tar ==
nullptr) {
464 double qy =
R(0, 2) -
R(2, 0);
465 double qw =
R(0, 0) +
R(1, 1) +
R(2, 2) + 1;
608 next.setValue(&tarmat[0][0]);
640 next.setValue(&rootmat[0][0]);
682 double q_rest[3], q[3],
length;
706 polerot.
UnitZ(-poledir);
807 switch (condata->
mode) {
820 switch (condata->
mode) {
923 for (
uint i = 0;
i < _nvalues;
i++, dof++) {
940 for (a = 0, ikchan = ikscene->
channels; a < ikscene->numchan; a++, ikchan++) {
941 pchan =
tree->pchan[a];
942 ikchan->
pchan = pchan;
943 ikchan->
parent = (a > 0) ?
tree->parent[a] : -1;
1057 njoint += ikchan->
ndof;
1081 for (joint = a = 0, ikchan = ikscene->
channels;
1082 a < ikscene->numchan && joint < ikscene->numjoint;
1085 pchan = ikchan->
pchan;
1105 joint += ikchan->
ndof;
1125 for (joint = a = 0, ikchan = ikscene->
channels;
1126 a < ikscene->numchan && joint < ikscene->numjoint;
1129 pchan = ikchan->
pchan;
1136 joint += ikchan->
ndof;
1161 if (
tree->totchannel == 0) {
1173 ikscene->
scene = scene;
1186 switch (ikparam->
solver) {
1203 std::string root(
"root");
1205 std::vector<double> weights;
1213 for (a = 0, ikchan = ikscene->
channels; a < tree->totchannel; a++, ikchan++) {
1214 pchan = ikchan->
pchan;
1221 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]);
1226 float R_parmat[3][3];
1227 float iR_parmat[3][3];
1238 start[0] = start[1] = start[2] = 0.0f;
1266 weight[0] = (1.0 - pchan->
stiffness[0]);
1267 weight[1] = (1.0 - pchan->
stiffness[1]);
1268 weight[2] = (1.0 - pchan->
stiffness[2]);
1279 weights.push_back(weight[0]);
1285 weights.push_back(weight[1]);
1291 weights.push_back(weight[2]);
1296 weights.push_back(weight[0]);
1302 weights.push_back(weight[1]);
1308 weights.push_back(weight[0]);
1309 weights.push_back(weight[2]);
1315 weights.push_back(weight[2]);
1321 weights.push_back(weight[1]);
1328 weights.push_back(weight[0]);
1329 weights.push_back(weight[2]);
1335 weights.push_back(weight[1]);
1341 weights.push_back(weight[0]);
1342 weights.push_back(weight[1]);
1343 weights.push_back(weight[2]);
1353 weight[1] = (1.0 -
min_ff(1.0 - ikstretch, 1.0f - 0.001f));
1354 weights.push_back(weight[1]);
1361 ikchan->
tail = joint;
1362 ikchan->
head = parent;
1444 for (numtarget = 0, polarcon =
nullptr,
ret =
true, target = (
PoseTarget *)
tree->targets.first;
1446 target = target->
next)
1449 pchan =
tree->pchan[target->
tip];
1454 ikscene->
targets.push_back(iktarget);
1456 if (iktarget->
ee == -1) {
1465 iktarget->
owner = ob;
1475 polarcon = target->
con;
1480 if (numtarget == 1 && polarcon) {
1489 std::string armname;
1504 assert(Wq.cols() ==
int(weights.size()));
1505 for (
int q = 0; q < Wq.cols(); q++) {
1506 Wq(q, q) = weights[q];
1512 float invBaseFrame[4][4];
1516 float baseFrame[4][4];
1527 for (t = 0; t < ikscene->
targets.size(); t++) {
1533 uint controltype, bone_count;
1539 for (bone_count = 0, bone_length = 0.0f, a = iktarget->
channel; a >= 0;
1540 a =
tree->parent[a], bone_count++)
1542 bone_length += ikscene->
blScale *
tree->pchan[a]->bone->length;
1544 bone_length /= bone_count;
1563 switch (condata->
type) {
1661 ikdata->
first = ikscene;
1673 if (
tree->basis_change) {
1687 float scale =
len_v3(ob->object_to_world().ptr()[1]);
1733 for (
i = ikscene->
targets.size();
i > 0;
i--) {
1745 double timestamp = ctime * frtime + 2147483.648;
1746 double timestep = frtime;
1749 bool simulation =
true;
1768 if (ikscene->
cache && !reiterate && simulation) {
1780 timestep = sts / 1000.0;
1784 ikscene->
scene->
update(timestamp, timestep, numstep,
false, !reiterate, simulation);
1793 ikscene->
scene->
update(timestamp, timestep, numstep,
true,
false, simulation);
1797 ikscene->
scene->
update(timestamp, 0.0, 1,
true,
true,
true);
1801 for (
i = ikscene->
targets.size();
i > 0;
i--) {
1818 double q_rest[3], q[3];
1842 if (!arm->
getSegment(ikchan->
tail, 3, joint, q_rest[0], q[0], tip)) {
1847 scale =
float(q[0] / q_rest[0]);
1857 pchan = ikchan->
pchan;
1924 if (ikscene->channels[0].pchan == pchan_root) {
1958 scene->cache->clearCacheFrom(
nullptr, 1);
1970 double armlength = ikscene->armature->getArmLength();
1974 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, ikparam->
minstep);
1975 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, ikparam->
maxstep);
1977 ikscene->armature->setControlParameter(
1983 ikscene->scene->setParam(iTaSC::Scene::MIN_TIMESTEP, 1.0);
1984 ikscene->scene->setParam(iTaSC::Scene::MAX_TIMESTEP, 1.0);
1986 ikscene->armature->setControlParameter(
2002 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 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