mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-14 08:04:40 +00:00
Makes vehicles work with the physics plugins.
Makes vehicles create a basic physics body when using one of the physics plugins so that they can collide with other physics-enabled objects. Based on @rextimmy 's work.
This commit is contained in:
parent
5122360552
commit
37e030f8f4
9 changed files with 161 additions and 2 deletions
|
|
@ -378,3 +378,25 @@ void BtBody::setSimulationEnabled( bool enabled )
|
||||||
|
|
||||||
mIsEnabled = enabled;
|
mIsEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BtBody::moveKinematicTo(const MatrixF &transform)
|
||||||
|
{
|
||||||
|
AssertFatal(mActor, "BtBody::moveKinematicTo - The actor is null!");
|
||||||
|
|
||||||
|
U32 bodyflags = mActor->getCollisionFlags();
|
||||||
|
const bool isKinematic = bodyflags & BF_KINEMATIC;
|
||||||
|
if (!isKinematic)
|
||||||
|
{
|
||||||
|
Con::errorf("BtBody::moveKinematicTo is only for kinematic bodies.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCenterOfMass)
|
||||||
|
{
|
||||||
|
MatrixF xfm;
|
||||||
|
xfm.mul(transform, *mCenterOfMass);
|
||||||
|
mActor->setCenterOfMassTransform(btCast<btTransform>(xfm));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mActor->setCenterOfMassTransform(btCast<btTransform>(transform));
|
||||||
|
}
|
||||||
|
|
@ -111,6 +111,8 @@ public:
|
||||||
F32 staticFriction );
|
F32 staticFriction );
|
||||||
virtual void applyCorrection( const MatrixF &xfm );
|
virtual void applyCorrection( const MatrixF &xfm );
|
||||||
virtual void applyImpulse( const Point3F &origin, const Point3F &force );
|
virtual void applyImpulse( const Point3F &origin, const Point3F &force );
|
||||||
|
virtual void moveKinematicTo(const MatrixF &xfm);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _T3D_PHYSICS_BTBODY_H_
|
#endif // _T3D_PHYSICS_BTBODY_H_
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,10 @@ public:
|
||||||
|
|
||||||
///
|
///
|
||||||
virtual void applyImpulse( const Point3F &origin, const Point3F &force ) = 0;
|
virtual void applyImpulse( const Point3F &origin, const Point3F &force ) = 0;
|
||||||
|
|
||||||
|
///
|
||||||
|
virtual void moveKinematicTo(const MatrixF &xfm) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -417,3 +417,22 @@ void Px3Body::applyImpulse( const Point3F &origin, const Point3F &force )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Px3Body::moveKinematicTo(const MatrixF &transform)
|
||||||
|
{
|
||||||
|
AssertFatal(mActor, "Px3Body::moveKinematicTo - The actor is null!");
|
||||||
|
|
||||||
|
const bool isKinematic = mBodyFlags & BF_KINEMATIC;
|
||||||
|
if (!isKinematic)
|
||||||
|
{
|
||||||
|
Con::errorf("Px3Body::moveKinematicTo is only for kinematic bodies.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mWorld->lockScene();
|
||||||
|
|
||||||
|
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
|
||||||
|
actor->setKinematicTarget(px3Cast<physx::PxTransform>(transform));
|
||||||
|
|
||||||
|
mWorld->unlockScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,8 @@ public:
|
||||||
F32 staticFriction );
|
F32 staticFriction );
|
||||||
virtual void applyCorrection( const MatrixF &xfm );
|
virtual void applyCorrection( const MatrixF &xfm );
|
||||||
virtual void applyImpulse( const Point3F &origin, const Point3F &force );
|
virtual void applyImpulse( const Point3F &origin, const Point3F &force );
|
||||||
|
virtual void moveKinematicTo(const MatrixF &xfm);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _PX3BODY_H_
|
#endif // _PX3BODY_H_
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,8 @@ Px3World::Px3World(): mScene( NULL ),
|
||||||
mIsEnabled( false ),
|
mIsEnabled( false ),
|
||||||
mEditorTimeScale( 1.0f ),
|
mEditorTimeScale( 1.0f ),
|
||||||
mAccumulator( 0 ),
|
mAccumulator( 0 ),
|
||||||
mControllerManager( NULL )
|
mControllerManager(NULL),
|
||||||
|
mIsSceneLocked(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,6 +336,62 @@ void Px3World::releaseWriteLock()
|
||||||
//AssertFatal( mScene->isWritable(), "PhysX3World::releaseWriteLock() - We should have been writable now!" );
|
//AssertFatal( mScene->isWritable(), "PhysX3World::releaseWriteLock() - We should have been writable now!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Px3World::lockScenes()
|
||||||
|
{
|
||||||
|
Px3World *world = dynamic_cast<Px3World*>(PHYSICSMGR->getWorld("server"));
|
||||||
|
|
||||||
|
if (world)
|
||||||
|
world->lockScene();
|
||||||
|
|
||||||
|
world = dynamic_cast<Px3World*>(PHYSICSMGR->getWorld("client"));
|
||||||
|
|
||||||
|
if (world)
|
||||||
|
world->lockScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Px3World::unlockScenes()
|
||||||
|
{
|
||||||
|
Px3World *world = dynamic_cast<Px3World*>(PHYSICSMGR->getWorld("server"));
|
||||||
|
|
||||||
|
if (world)
|
||||||
|
world->unlockScene();
|
||||||
|
|
||||||
|
world = dynamic_cast<Px3World*>(PHYSICSMGR->getWorld("client"));
|
||||||
|
|
||||||
|
if (world)
|
||||||
|
world->unlockScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Px3World::lockScene()
|
||||||
|
{
|
||||||
|
if (!mScene)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mIsSceneLocked)
|
||||||
|
{
|
||||||
|
Con::printf("Px3World: Attempting to lock a scene that is already locked.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mScene->lockWrite();
|
||||||
|
mIsSceneLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Px3World::unlockScene()
|
||||||
|
{
|
||||||
|
if (!mScene)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!mIsSceneLocked)
|
||||||
|
{
|
||||||
|
Con::printf("Px3World: Attempting to unlock a scene that is not locked.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mScene->unlockWrite();
|
||||||
|
mIsSceneLocked = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse )
|
bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ protected:
|
||||||
bool mIsEnabled;
|
bool mIsEnabled;
|
||||||
bool mIsSimulating;
|
bool mIsSimulating;
|
||||||
bool mIsServer;
|
bool mIsServer;
|
||||||
|
bool mIsSceneLocked;
|
||||||
U32 mTickCount;
|
U32 mTickCount;
|
||||||
ProcessList *mProcessList;
|
ProcessList *mProcessList;
|
||||||
F32 mEditorTimeScale;
|
F32 mEditorTimeScale;
|
||||||
|
|
@ -96,11 +97,15 @@ public:
|
||||||
void releaseWriteLock();
|
void releaseWriteLock();
|
||||||
bool isServer(){return mIsServer;}
|
bool isServer(){return mIsServer;}
|
||||||
physx::PxController* createController( physx::PxControllerDesc &desc );
|
physx::PxController* createController( physx::PxControllerDesc &desc );
|
||||||
|
void lockScene();
|
||||||
|
void unlockScene();
|
||||||
//static
|
//static
|
||||||
static bool restartSDK( bool destroyOnly = false, Px3World *clientWorld = NULL, Px3World *serverWorld = NULL );
|
static bool restartSDK( bool destroyOnly = false, Px3World *clientWorld = NULL, Px3World *serverWorld = NULL );
|
||||||
static void releaseWriteLocks();
|
static void releaseWriteLocks();
|
||||||
static physx::PxCooking *getCooking();
|
static physx::PxCooking *getCooking();
|
||||||
static void setTiming(F32 stepTime,U32 maxIterations);
|
static void setTiming(F32 stepTime,U32 maxIterations);
|
||||||
|
static void lockScenes();
|
||||||
|
static void unlockScenes();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _PX3WORLD_H_
|
#endif // _PX3WORLD_H_
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,9 @@
|
||||||
#include "gfx/primBuilder.h"
|
#include "gfx/primBuilder.h"
|
||||||
#include "gfx/gfxDrawUtil.h"
|
#include "gfx/gfxDrawUtil.h"
|
||||||
#include "materials/materialDefinition.h"
|
#include "materials/materialDefinition.h"
|
||||||
|
#include "T3D/physics/physicsPlugin.h"
|
||||||
|
#include "T3D/physics/physicsBody.h"
|
||||||
|
#include "T3D/physics/physicsCollision.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
@ -203,7 +206,8 @@ VehicleData::VehicleData()
|
||||||
dMemset(waterSound, 0, sizeof(waterSound));
|
dMemset(waterSound, 0, sizeof(waterSound));
|
||||||
|
|
||||||
collDamageThresholdVel = 20;
|
collDamageThresholdVel = 20;
|
||||||
collDamageMultiplier = 0.05f;
|
collDamageMultiplier = 0.05f;
|
||||||
|
enablePhysicsRep = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -315,6 +319,7 @@ void VehicleData::packData(BitStream* stream)
|
||||||
stream->write(softSplashSoundVel);
|
stream->write(softSplashSoundVel);
|
||||||
stream->write(medSplashSoundVel);
|
stream->write(medSplashSoundVel);
|
||||||
stream->write(hardSplashSoundVel);
|
stream->write(hardSplashSoundVel);
|
||||||
|
stream->write(enablePhysicsRep);
|
||||||
|
|
||||||
// write the water sound profiles
|
// write the water sound profiles
|
||||||
for(i = 0; i < MaxSounds; i++)
|
for(i = 0; i < MaxSounds; i++)
|
||||||
|
|
@ -411,6 +416,7 @@ void VehicleData::unpackData(BitStream* stream)
|
||||||
stream->read(&softSplashSoundVel);
|
stream->read(&softSplashSoundVel);
|
||||||
stream->read(&medSplashSoundVel);
|
stream->read(&medSplashSoundVel);
|
||||||
stream->read(&hardSplashSoundVel);
|
stream->read(&hardSplashSoundVel);
|
||||||
|
stream->read(&enablePhysicsRep);
|
||||||
|
|
||||||
// write the water sound profiles
|
// write the water sound profiles
|
||||||
for(i = 0; i < MaxSounds; i++)
|
for(i = 0; i < MaxSounds; i++)
|
||||||
|
|
@ -465,6 +471,11 @@ void VehicleData::unpackData(BitStream* stream)
|
||||||
|
|
||||||
void VehicleData::initPersistFields()
|
void VehicleData::initPersistFields()
|
||||||
{
|
{
|
||||||
|
addGroup("Physics");
|
||||||
|
addField("enablePhysicsRep", TypeBool, Offset(enablePhysicsRep, VehicleData),
|
||||||
|
"@brief Creates a representation of the object in the physics plugin.\n");
|
||||||
|
endGroup("Physics");
|
||||||
|
|
||||||
addField( "jetForce", TypeF32, Offset(jetForce, VehicleData),
|
addField( "jetForce", TypeF32, Offset(jetForce, VehicleData),
|
||||||
"@brief Additional force applied to the vehicle when it is jetting.\n\n"
|
"@brief Additional force applied to the vehicle when it is jetting.\n\n"
|
||||||
"For WheeledVehicles, the force is applied in the forward direction. For "
|
"For WheeledVehicles, the force is applied in the forward direction. For "
|
||||||
|
|
@ -682,6 +693,8 @@ Vehicle::Vehicle()
|
||||||
mWorkingQueryBox.minExtents.set(-1e9f, -1e9f, -1e9f);
|
mWorkingQueryBox.minExtents.set(-1e9f, -1e9f, -1e9f);
|
||||||
mWorkingQueryBox.maxExtents.set(-1e9f, -1e9f, -1e9f);
|
mWorkingQueryBox.maxExtents.set(-1e9f, -1e9f, -1e9f);
|
||||||
mWorkingQueryBoxCountDown = sWorkingQueryBoxStaleThreshold;
|
mWorkingQueryBoxCountDown = sWorkingQueryBoxStaleThreshold;
|
||||||
|
|
||||||
|
mPhysicsRep = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 Vehicle::getCollisionMask()
|
U32 Vehicle::getCollisionMask()
|
||||||
|
|
@ -695,6 +708,25 @@ Point3F Vehicle::getVelocity() const
|
||||||
return mRigid.linVelocity;
|
return mRigid.linVelocity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Vehicle::_createPhysics()
|
||||||
|
{
|
||||||
|
SAFE_DELETE(mPhysicsRep);
|
||||||
|
|
||||||
|
if (!PHYSICSMGR || !mDataBlock->enablePhysicsRep)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TSShape *shape = mShapeInstance->getShape();
|
||||||
|
PhysicsCollision *colShape = NULL;
|
||||||
|
colShape = shape->buildColShape(false, getScale());
|
||||||
|
|
||||||
|
if (colShape)
|
||||||
|
{
|
||||||
|
PhysicsWorld *world = PHYSICSMGR->getWorld(isServerObject() ? "server" : "client");
|
||||||
|
mPhysicsRep = PHYSICSMGR->createBody();
|
||||||
|
mPhysicsRep->init(colShape, 0, PhysicsBody::BF_KINEMATIC, this, world);
|
||||||
|
mPhysicsRep->setTransform(getTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool Vehicle::onAdd()
|
bool Vehicle::onAdd()
|
||||||
|
|
@ -776,11 +808,15 @@ bool Vehicle::onAdd()
|
||||||
mConvex.box.maxExtents.convolve(mObjScale);
|
mConvex.box.maxExtents.convolve(mObjScale);
|
||||||
mConvex.findNodeTransform();
|
mConvex.findNodeTransform();
|
||||||
|
|
||||||
|
_createPhysics();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vehicle::onRemove()
|
void Vehicle::onRemove()
|
||||||
{
|
{
|
||||||
|
SAFE_DELETE(mPhysicsRep);
|
||||||
|
|
||||||
U32 i=0;
|
U32 i=0;
|
||||||
for( i=0; i<VehicleData::VC_NUM_DUST_EMITTERS; i++ )
|
for( i=0; i<VehicleData::VC_NUM_DUST_EMITTERS; i++ )
|
||||||
{
|
{
|
||||||
|
|
@ -880,6 +916,11 @@ void Vehicle::processTick(const Move* move)
|
||||||
setPosition(mRigid.linPosition, mRigid.angPosition);
|
setPosition(mRigid.linPosition, mRigid.angPosition);
|
||||||
setMaskBits(PositionMask);
|
setMaskBits(PositionMask);
|
||||||
updateContainer();
|
updateContainer();
|
||||||
|
|
||||||
|
//TODO: Only update when position has actually changed
|
||||||
|
//no need to check if mDataBlock->enablePhysicsRep is false as mPhysicsRep will be NULL if it is
|
||||||
|
if (mPhysicsRep)
|
||||||
|
mPhysicsRep->moveKinematicTo(getTransform());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,8 @@ struct VehicleData: public ShapeBaseData
|
||||||
F32 splashFreqMod;
|
F32 splashFreqMod;
|
||||||
F32 splashVelEpsilon;
|
F32 splashVelEpsilon;
|
||||||
|
|
||||||
|
bool enablePhysicsRep;
|
||||||
|
|
||||||
//
|
//
|
||||||
VehicleData();
|
VehicleData();
|
||||||
bool preload(bool server, String &errorStr);
|
bool preload(bool server, String &errorStr);
|
||||||
|
|
@ -142,6 +144,7 @@ struct VehicleData: public ShapeBaseData
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
class PhysicsBody;
|
||||||
|
|
||||||
class Vehicle: public ShapeBase
|
class Vehicle: public ShapeBase
|
||||||
{
|
{
|
||||||
|
|
@ -177,6 +180,8 @@ class Vehicle: public ShapeBase
|
||||||
Point3F cameraRotVec;
|
Point3F cameraRotVec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PhysicsBody *mPhysicsRep;
|
||||||
|
|
||||||
StateDelta mDelta;
|
StateDelta mDelta;
|
||||||
S32 mPredictionCount; ///< Number of ticks to predict
|
S32 mPredictionCount; ///< Number of ticks to predict
|
||||||
VehicleData* mDataBlock;
|
VehicleData* mDataBlock;
|
||||||
|
|
@ -262,6 +267,8 @@ public:
|
||||||
bool onAdd();
|
bool onAdd();
|
||||||
void onRemove();
|
void onRemove();
|
||||||
|
|
||||||
|
void _createPhysics();
|
||||||
|
|
||||||
/// Interpolates between move ticks @see processTick
|
/// Interpolates between move ticks @see processTick
|
||||||
/// @param dt Change in time between the last call and this call to the function
|
/// @param dt Change in time between the last call and this call to the function
|
||||||
void interpolateTick(F32 dt);
|
void interpolateTick(F32 dt);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue