[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21997] branches/itasc: iTaSC: use a much simpler and more stable formula for joint limit.
Benoit Bolsee
benoit.bolsee at online.be
Tue Jul 28 23:07:39 CEST 2009
Revision: 21997
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21997
Author: ben2610
Date: 2009-07-28 23:07:39 +0200 (Tue, 28 Jul 2009)
Log Message:
-----------
iTaSC: use a much simpler and more stable formula for joint limit. Simply use constant weight when the joint enters the limit: it preserves the linearity of the system on each side of the limit. Consistency of the weight is ensured by splitting the timestep so that the weight is changed exactly when the joint crosses the limit.
Modified Paths:
--------------
branches/itasc/intern/itasc/Armature.cpp
branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp
Modified: branches/itasc/intern/itasc/Armature.cpp
===================================================================
--- branches/itasc/intern/itasc/Armature.cpp 2009-07-28 21:06:23 UTC (rev 21996)
+++ branches/itasc/intern/itasc/Armature.cpp 2009-07-28 21:07:39 UTC (rev 21997)
@@ -260,6 +260,21 @@
// update the parameters
LimitConstraintParam_struct* pLimit = (LimitConstraintParam_struct*)_param;
double y = _values->values->y;
+#if 1
+ if (y > pLimit->maxThreshold-0.001) {
+ _values->alpha = pLimit->maxWeight;
+ // change the limit to the threshold value so that there is no oscillation
+ _values->values->yd = pLimit->maxThreshold;
+ } else if (y < pLimit->minThreshold-0.001) {
+ _values->alpha = pLimit->maxWeight;
+ // change the limit to the threshold value so that there is no oscillation
+ _values->values->yd = pLimit->minThreshold;
+ } else {
+ _values->alpha = 0.0;
+ }
+#else
+ // more complex formula to avoid discontinuity of velocity
+ // not needed in animation, disable for now as it creates instability
double x;
if (y > pLimit->maxThreshold) {
if (y < pLimit->max) {
@@ -282,6 +297,7 @@
} else {
_values->alpha = 0.0;
}
+#endif
return true;
}
@@ -526,6 +542,27 @@
double q = m_qKdl(cs->segment->second.q_nr);
double dq = qdot*timestep;
double newq = q+dq;
+#if 1
+ if (((q > pLimit->maxThreshold) ^ (newq > pLimit->maxThreshold)) ||
+ ((q < pLimit->minThreshold) ^ (newq < pLimit->minThreshold))) {
+ if (q > pLimit->maxThreshold) {
+ newq = pLimit->maxThreshold-0.0011;
+ } else if (q < pLimit->minThreshold) {
+ newq = pLimit->minThreshold+0.0011;
+ } else if (newq > pLimit->maxThreshold && cs->values.alpha == 0.0) {
+ newq = pLimit->maxThreshold+0.0011;
+ } else if (cs->values.alpha == 0.0){
+ newq = pLimit->minThreshold-0.0011;
+ }
+ double newdq = fabs(newq-q);
+ dq = fabs(dq);
+ if (newdq < dq) {
+ timestep *= newdq/dq;
+ }
+ }
+#else
+ // more complex formula to avoid discontinuity of velocity
+ // not needed in animation, disable for now as it creates instability
double alpha = cs->values.alpha;
double newalpha;
if (q > pLimit->maxThreshold || q < pLimit->minThreshold ||
@@ -555,6 +592,7 @@
timestep *= newdq/dq;
}
}
+#endif
}
}
}
Modified: branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp
===================================================================
--- branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp 2009-07-28 21:06:23 UTC (rev 21996)
+++ branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp 2009-07-28 21:07:39 UTC (rev 21997)
@@ -785,19 +785,19 @@
if ((flag & IK_XDOF) && (pchan->ikflag & BONE_IK_XLIMIT)) {
joint = bone->name;
joint += ":RX";
- if (arm->addLimitConstraint(joint, pchan->limitmin[0], pchan->limitmax[0], 5.0, 50.0, 5.0) < 0)
+ if (arm->addLimitConstraint(joint, pchan->limitmin[0], pchan->limitmax[0], 0.5, 50.0, 5.0) < 0)
break;
}
if ((flag & IK_YDOF) && (pchan->ikflag & BONE_IK_YLIMIT)) {
joint = bone->name;
joint += ":RY";
- if (arm->addLimitConstraint(joint, pchan->limitmin[1], pchan->limitmax[1], 5.0, 50.0, 5.0) < 0)
+ if (arm->addLimitConstraint(joint, pchan->limitmin[1], pchan->limitmax[1], 0.5, 50.0, 5.0) < 0)
break;
}
if ((flag & IK_ZDOF) && (pchan->ikflag & BONE_IK_ZLIMIT)) {
joint = bone->name;
joint += ":RZ";
- if (arm->addLimitConstraint(joint, pchan->limitmin[2], pchan->limitmax[2], 5.0, 50.0, 5.0) < 0)
+ if (arm->addLimitConstraint(joint, pchan->limitmin[2], pchan->limitmax[2], 0.5, 50.0, 5.0) < 0)
break;
}
// no error, so restore
More information about the Bf-blender-cvs
mailing list