RotateTo extension
by Christian Armeanu · in Torque Game Builder · 08/24/2005 (10:05 am) · 14 replies
Hi,
I extended the engine (fxPhysics2D) with a rotateTo implementation and would like to know if anybody would be interested in:
void fxPhysics2D::rotateTo( const F32 angle, const bool left ) ...
"angle" is the destination angle and the boolean "left" indicates if the rotation should be CC.
Setting autorotation will perform the rotation with the given speed.
Cheers,
Chris
I extended the engine (fxPhysics2D) with a rotateTo implementation and would like to know if anybody would be interested in:
void fxPhysics2D::rotateTo( const F32 angle, const bool left ) ...
"angle" is the destination angle and the boolean "left" indicates if the rotation should be CC.
Setting autorotation will perform the rotation with the given speed.
Cheers,
Chris
About the author
#2
08/24/2005 (4:36 pm)
Sounds interesting are you going to post it as a Resource?
#3
08/24/2005 (8:20 pm)
Cool... please submit it if you want to... would help alot.. :)
#4
Just need to finish my path implementation (today or tomorrow) so I can give it a test drive and will post it latest this weekend (sorry, am a bit short on time).
@LoTekK: It's not a new class as it would require to many extensions to the engine, so I just extended the engine physics (where it seems to belong with the given T2D design anyway).
08/25/2005 (7:53 am)
Eh, I didn't have a lot of time to check the features of the GG site, so I'll just ask: Where should I put it? I was going to just post it here, but I assume as a resource would probably make more sense. Just need to finish my path implementation (today or tomorrow) so I can give it a test drive and will post it latest this weekend (sorry, am a bit short on time).
@LoTekK: It's not a new class as it would require to many extensions to the engine, so I just extended the engine physics (where it seems to belong with the given T2D design anyway).
#5
-Peter
08/25/2005 (8:02 am)
I think this has been suggested several times. Is Melv planning on adding something like this to the next release? I know I could use it a lot!-Peter
#6
08/25/2005 (8:09 am)
@Melv: If you're happy with my implementation it, please feel free to include it.
#7
There are several files that need to be touched for this to work, but nothing to be scared of ;-)
I hope I didn't miss anything, but I'm sure you'll let me know if I did ...
Ok, here we go ...
- add the following two blocks to class fxPhysics2D:
08/27/2005 (11:53 am)
For some reason adding a resource didn't work for me (trying to access the resource after adding reports an invalid / deleted reference ...), so I post it here for now ...There are several files that need to be touched for this to work, but nothing to be scared of ;-)
I hope I didn't miss anything, but I'm sure you'll let me know if I did ...
Ok, here we go ...
//##########################################################################################################################################
//## extensions by CA : 23-08-2005
//##########################################################################################################################################
inline bool isRotateTo(void)
{ return mRotateTo; };
inline F32& getRotateToAngle(void)
{ return mRotateToAngle; };
inline bool isRotateToLeft(void)
{ return mRotateToLeft && mRotateTo; };
inline bool isRotateToRight(void)
{ return (!mRotateToLeft) && mRotateTo; };
inline void disableRotateTo(void)
{ mRotateTo = false; setAutoRotation(0); };
void rotateTo( const F32 angle, const bool left = false );
//##########################################################################################################################################
//## end of extensions
//##########################################################################################################################################
[b]And somewhere down with the member variables:[/b]
//##########################################################################################################################################
//## extensions by CA : 23-08-2005
//##########################################################################################################################################
bool mRotateTo; // if set, object will rotate in (mRotateToLeft) direction to mRotateToAngle
bool mRotateToLeft; // rotate to left if true
F32 mRotateToAngle; // rotate to destination angle
bool mRotateToOnReachCallback; // if true, callback should be executed and flag reset to false
//##########################################################################################################################################
//## end of extensions
//##########################################################################################################################################
#8
- replace the following methods with the implementations below:
08/27/2005 (11:57 am)
Part 2://-----------------------------------------------------------------------------
// Constructor.
//-----------------------------------------------------------------------------
fxPhysics2D::fxPhysics2D() : T2D_Stream_HeaderID(makeFourCCTag('2','D','P','M')),
T2D_Stream_Version(0X00000002),
mLocalSerialiseID(1),
mInitialised(false),
mRefObjectId(0),
mRefMetaString(StringTable->insert("")),
mSize(10.0f, 10.0f),
mHalfSize(5.0f, 5.0f),
mDensity(defaultDensity),
mCollisionScale(1.0f, 1.0f),
mRotateTo(false),
mRotateToOnReachCallback(false)
{
// Set Vector Associations.
VECTOR_SET_ASSOCIATION( mCollisionPolyList );
VECTOR_SET_ASSOCIATION( mCollisionPolyBasisList );
}
//-----------------------------------------------------------------------------
// Initialise.
//-----------------------------------------------------------------------------
void fxPhysics2D::initialise( SimObjectId objectId, const char* pRefMetaString )
{
// Set Reference Object-ID.
mRefObjectId = objectId;
// Set Reference Meta-String.
if ( pRefMetaString )
mRefMetaString = StringTable->insert( pRefMetaString );
else
mRefMetaString = StringTable->insert("");
// Reset Net Velocities.
mNetLinearVelocity.zero();
mNetAngularVelocity = 0.0f;
// Physics Suppression Off.
setPhysicsSuppress(false);
// Set Minimum/Maximum Linear/Angular Velocities.
// NOTE:- We do it without using the appropriate functions as they
// do specific checking which we don't want here.
mMinLinearVelocity = 0.0f;
mMinAngularVelocity = 0.0f;
mMaxLinearVelocity = 2500.0f;
mMaxAngularVelocity = 2500.0f;
//##########################################################################################################################################
//## extensions by CA : 23-08-2005
//##########################################################################################################################################
mRotateTo = false;
mRotateToOnReachCallback = false;
// Disable rotate to angle
disableRotateTo();
//##########################################################################################################################################
//## end of extensions
//##########################################################################################################################################
// Set Velocities.
setLinearVelocity( fxVector2D::getZero() );
setAngularVelocity( 0.0f );
// Set Other Material Properties.
setDynamicFriction( defaultDynamicFriction );
setRestitution( defaultRestitution );
setRelaxation( defaultRelaxation );
setForceScale( defaultForceScale );
setDamping( defaultDamping );
// Set Default Physical Metrics.
setPosition( fxVector2D::getZero() );
setAutoRotation( 0.0f );
setRotation( 0.0f );
// Reset Constant Force.
setConstantForce( fxVector2D::getZero(), false );
// Setup Initial Polygon.
setCollisionPolyPrimitive( 4 );
// Flag as Initialised.
mInitialised = true;
}
#9
08/27/2005 (12:04 pm)
Part 3://-----------------------------------------------------------------------------
// Update Physics Model.
//-----------------------------------------------------------------------------
void fxPhysics2D::update( F32 elapsedTime )
{
// Cannot proceed without parent initialisation.
if ( !isInitialised() )
{
// Warn.
Con::warnf("fxPhysics2D::update() - Cannot proceed without initialisation!");
return;
}
// T2D Debug Profiling.
#ifdef T2D_DEBUG_PROFILING
PROFILE_START(T2D_fxPhysics2D_update);
#endif
// Nothing to do on immovable objects!
if ( isImmovable() )
{
// Reset Linear/Angular Velocities.
mLinearVelocity.zero();
mAngularVelocity = 0.0f;
}
F32 fstep, fnow = mRotation, fdest;
fxVector2D svc;
// Update Physics if not suppressed.
if ( !getPhysicsSuppress() )
{
// Get Velocities.
fxVector2D linearVelocity = getLinearVelocity();
F32 angularVelocity = mRadToDeg(getAngularVelocity());
// Damping?
if ( mNotZero( mDamping ) )
{
// Calculate integrated damping.
F32 dampIntegral = mDamping * elapsedTime;
// Yes, so any Linear Velocity?
if ( mNotZero(linearVelocity.len()) )
{
// Yes, so damp Linear Velocity ...
// Fetch Velocity Magnitude.
F32 linVelMag = linearVelocity.len();
// Calculate Renormalised Damped-Velocity.
linearVelocity.normalise( getMax(linVelMag - (linVelMag * dampIntegral), 0.0f) );
}
// Any Angular Velocity?
if ( mNotZero(angularVelocity) )
{
// Yes, so damp Angular Velocity ...
// Calculate damped-angular velocity delta.
F32 deltaAngVel = angularVelocity * dampIntegral;
// Ensure we don't get angular reversal!
if ( angularVelocity < 0.0f )
angularVelocity = getMin(angularVelocity-deltaAngVel, 0.0f);
else
angularVelocity = getMax(angularVelocity-deltaAngVel, 0.0f);
}
}
// Integrate and clamp Velocities.
setLinearVelocity( linearVelocity + (mNetLinearVelocity * mInverseMass * elapsedTime) );
setAngularVelocity( angularVelocity + (mNetAngularVelocity * mInverseInertialMoment * elapsedTime) );
// Integrate Position/Rotation.
setPosition( mPosition + (linearVelocity * elapsedTime) );
// Use maximum angular velocity of either inherent spin or auto-rotation.
// NOTE:- We need to determine which angular velocity causes the biggest
// change in current rotation.
angularVelocity = mRadToDeg(getAngularVelocity());
//########################
//## extensions by CA : 23-08-2005
//## implemented rotateTo processing
//########################
if ( mFabs(mFmod(mAutoRotation,360.0f)) > mFabs(mFmod(angularVelocity,360.0f)) ) {
// Auto-rotation.
fstep = -(mAutoRotation * elapsedTime);
} else {
// Inherent Spin.
fstep = (angularVelocity * elapsedTime);
}
if( mRotateTo && mAutoRotation > 0 ) {
if( !mRotateToLeft ) {
// turn left
fnow -= mFabs(fstep);
if( fnow < 0.0f ) fnow += 360.0f;
if( ((mRotation >= mRotateToAngle) && (fnow < mRotateToAngle)) || ((mRotation <= mRotateToAngle) && (fnow < mRotateToAngle) && (fnow > mRotation)) ) {
fnow = mRotateToAngle;
mRotateToOnReachCallback = true;
disableRotateTo();
}
} else {
// turn right
fnow += mFabs(fstep);
if( fnow >= 360.0f ) fnow -= 360.0f;
if( ((mRotation <= mRotateToAngle) && (fnow > mRotateToAngle)) || ((mRotation >= mRotateToAngle) && (fnow > mRotateToAngle) && (fnow < mRotation)) ) {
fnow = mRotateToAngle;
mRotateToOnReachCallback = true;
disableRotateTo();
}
}
} else {
fnow = mRotation + fstep;
}
fnow = mFmod( fnow, 360.0f );
setRotation( fnow );
//##################
}
// Reset Net Velocities.
mNetLinearVelocity.zero();
mNetAngularVelocity = 0.0f;
// T2D Debug Profiling.
#ifdef T2D_DEBUG_PROFILING
PROFILE_END();
#endif
}
#10
- add the following:
08/27/2005 (12:06 pm)
Part 4://##########################################################################################################################################
//## extensions by CA : 23-08-2005
//##########################################################################################################################################
void fxPhysics2D::rotateTo( const F32 angle, const bool left )
{
mRotateToAngle = mFmod( angle, 360.0f );
mRotateToLeft = left;
mRotateTo = true;
}
//##########################################################################################################################################
//## end of extensions
//##########################################################################################################################################
#11
add the following:
08/27/2005 (12:09 pm)
Part 5://##########################################################################################################################################
//## extensions by CA : 23-08-2005
//##########################################################################################################################################
ConsoleMethod(fxSceneObject2D, rotateTo, void, 4, 4, "(destAngle, mode) - Set autoRotation destination angle and rotation mode (0=shortest distance, 1=Left, >1=Right).")
{
F32 fto, fmode, fact = object->getParentPhysicsModel().getRotation();
dSscanf(argv[2],"%f", &fto);
dSscanf(argv[3],"%f", &fmode);
if( (isZero(fmode) && (distTurnRight(fact, fto) > distTurnLeft(fact, fto))) || fmode == 1 )
object->getParentPhysicsModel().rotateTo(fto, true);
else
object->getParentPhysicsModel().rotateTo(fto, false);
}
ConsoleMethod(fxSceneObject2D, isRotateTo, bool, 2, 2, "() - Returns true if this object is auto rotating to a destination angle.")
{
return object->getParentPhysicsModel().isRotateTo();
}
ConsoleMethod(fxSceneObject2D, isRotateToLeft, bool, 2, 2, "() - Returns true if this object is auto rotating to a destination angle counter clock wise.")
{
return object->getParentPhysicsModel().isRotateToLeft();
}
ConsoleMethod(fxSceneObject2D, isRotateToRight, bool, 2, 2, "() - Returns true if this object is auto rotating to a destination angle clock wise.")
{
return object->getParentPhysicsModel().isRotateToRight();
}
ConsoleMethod(fxSceneObject2D, onReachRotateTo, void, 3, 3, "(elapsedTime) - Default callback function when rotateTo destination angle is reached.")
{
return;
}
void fxSceneObject2D::updateRotateTo(F32 elapsedTime)
{
if( getParentPhysicsModel().mRotateToOnReachCallback ) {
getParentPhysicsModel().mRotateToOnReachCallback = false;
Con::executef( this, 2, "onReachRotateTo", Con::getFloatArg( elapsedTime ) );
}
}
//##########################################################################################################################################
//## end of extensions
//##########################################################################################################################################
#12
- insert the following at line [2596] after the physics update:
08/27/2005 (12:09 pm)
Part 6://########################################################################################################################################## //## extensions by CA : 25-08-2005 //########################################################################################################################################## pSceneObject2D->updateRotateTo( elapsedTime ); //########################################################################################################################################## //## end of extensions //##########################################################################################################################################
#13
$player.rotateTo( 123, true );
$player.setAutoRotation( 10 );
Have fun!
- Chris
08/27/2005 (12:11 pm)
And to test it, just try something like this:$player.rotateTo( 123, true );
$player.setAutoRotation( 10 );
Have fun!
- Chris
Torque Owner Teck Lee Tan