RotateTo bug
by Michael Woerister · in Torque Game Builder · 03/27/2006 (1:35 pm) · 5 replies
Hi,
the t2dSceneObject::rotateTo() does not work. I set "autoStop" and "snap" to true but the sprites keeps rotating. It looks like some floating point accuracy problem or the check whether the target rotation is reached misses a certain case because 70% of the time it works. The rotation target is 0.0 (to be accurate it is -0.0 but that should not make a difference, or does it?)
I spent some time looking at the updateRotationTarget() method in t2dPhysics.cc and rewrote it but that didn't help. Maybe I just overlooked something or it is the wrong place to look at.
the t2dSceneObject::rotateTo() does not work. I set "autoStop" and "snap" to true but the sprites keeps rotating. It looks like some floating point accuracy problem or the check whether the target rotation is reached misses a certain case because 70% of the time it works. The rotation target is 0.0 (to be accurate it is -0.0 but that should not make a difference, or does it?)
I spent some time looking at the updateRotationTarget() method in t2dPhysics.cc and rewrote it but that didn't help. Maybe I just overlooked something or it is the wrong place to look at.
#2
03/27/2006 (2:22 pm)
I think tried with default and with 10 and got the same results. But that should not matter anyway or do I understand something wrong here. When a function is called rotateTo() then I suppose it does exactly that: rotate to the specified target.
#3
03/27/2006 (3:56 pm)
The problem is that float will most likely never reach a certain value. So if you don't give it an "error range", it will jump over the targeted value back and forth.
#4
It should be bullet proof now.
03/27/2006 (11:22 pm)
I just took another look at it and discovered a copy and paste error in my modified version of updateRotationTarget(). I corrected it and now it seems to work fine. Here it is:void t2dPhysics::updateRotationTarget( const F32 angularVelocity, const F32 elapsedTime )
{
// Ignore if Rotation Target is inactive or being updated.
if ( !getRotationTargetActive() || mUpdatingRotationTarget ) return;
// Set Updating Rotation Target.
mUpdatingRotationTarget = true;
// Any Sweeping?
if ( mIsZero(elapsedTime) || mIsZero(angularVelocity) )
{
// No, so just do a distance calculation. Within specified distance?
if ( mLessThanOrEqual( mFabs(getRotation()-getRotationTarget()), getRotationTargetMargin() ) )
{
// Yes, so process rotation target.
processRotationTarget();
}
// Reset Updating Rotation Target.
mUpdatingRotationTarget = false;
// No rotation-integration so finish here.
return;
}
// Fetch From/To Rotations.
const F32 rotFrom = getRotation();
const F32 sweep = angularVelocity * elapsedTime;
const F32 rotTo = rotFrom + sweep;
// Fetch Rotation Target.
F32 rotTarget = getRotationTarget();
setRotation(rotTo);
if( mGreaterThanOrEqual( mFabs(sweep + getRotationTargetMargin()),360.0f) )
{
processRotationTarget();
}
else
if( mLessThanZero(rotTo) )
{
if( mLessThanOrEqual(rotTarget, rotFrom + getRotationTargetMargin() ) || mGreaterThanOrEqual(rotTarget, (rotTo - getRotationTargetMargin()) + 360.0f) )
processRotationTarget();
}
else
if( mGreaterThan(rotTo,360.0f) )
{
if( mGreaterThanOrEqual(rotTarget, rotFrom - getRotationTargetMargin() ) || mLessThanOrEqual(rotTarget, rotTo + getRotationTargetMargin() - 360.0f) )
processRotationTarget();
}
else
{
F32 rotMin, rotMax;
mGetMinMax(rotFrom,rotTo,rotMin,rotMax);
if( mGreaterThanOrEqual(rotTarget, rotMin - getRotationTargetMargin()) && mLessThanOrEqual(rotTarget, rotMax + getRotationTargetMargin()))
processRotationTarget();
}
// Reset Updating Rotation Target.
mUpdatingRotationTarget = false;
}It should be bullet proof now.
#5
Thanks a bunch for this fix, I've integrated it into our repository and it will be included in the next release!
Cheers,
-Justin
04/13/2006 (11:39 am)
Michael,Thanks a bunch for this fix, I've integrated it into our repository and it will be included in the next release!
Cheers,
-Justin
Torque Owner Philip Mansfield
Default Studio Name