T2D rotateTo extension for fxPhysics2D
by Christian Armeanu · 09/02/2005 (5:14 pm) · 0 comments
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 ...
Part 1:
- add the following two blocks to class fxPhysics2D:
Part 2:
- replace the following methods with the implementations below:
Part 3:
Part 4:
- add the following:
Part 5:
add the following:
Part 6:
- insert the following at line [2596] after the physics update:
And to test it, just try something like this:
- Chris
I hope I didn't miss anything, but I'm sure you'll let me know if I did ...
Ok, here we go ...
Part 1:
//##########################################################################################################################################
//## 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
//##########################################################################################################################################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;
}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
}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
//##########################################################################################################################################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
//##########################################################################################################################################Part 6:
//########################################################################################################################################## //## extensions by CA : 25-08-2005 //########################################################################################################################################## pSceneObject2D->updateRotateTo( elapsedTime ); //########################################################################################################################################## //## end of extensions //##########################################################################################################################################
And to test it, just try something like this:
$player.rotateTo( 123, true ); $player.setAutoRotation( 10 );
- Chris
