PhysX 3.4 implementation

This commit is contained in:
rextimmy 2018-01-19 22:34:26 +10:00
parent 463cd50d0a
commit 3bbdd9b155
15 changed files with 527 additions and 418 deletions

View file

@ -33,19 +33,43 @@
#define WIN32
#endif
// macOS _DEBUG & NDEBUG
#if defined(TORQUE_OS_MAC) && defined(TORQUE_DEBUG) && !defined(_DEBUG)
#define _DEBUG
#elif defined(TORQUE_OS_MAC) && defined(TORQUE_RELEASE) && !defined(NDEBUG)
#define NDEBUG
#endif
// Linux _DEBUG & NDEBUG
#if defined(TORQUE_OS_LINUX) && defined(TORQUE_DEBUG) && !defined(_DEBUG)
#define _DEBUG
#elif defined(TORQUE_OS_LINUX) && defined(TORQUE_RELEASE) && !defined(NDEBUG)
#define NDEBUG
#endif
//-------------------------------------------------------------------------
//safe release template
template <class T> void SafeReleasePhysx(T* a)
{
if (a)
{
a->release();
a = NULL;
}
}
#include <PxPhysicsAPI.h>
#include <PxExtensionsAPI.h>
#include <PxDefaultErrorCallback.h>
#include <PxDefaultAllocator.h>
#include <PxDefaultSimulationFilterShader.h>
#include <PxDefaultCpuDispatcher.h>
#include <PxShapeExt.h>
#include <PxSimpleFactory.h>
#include <PxFoundation.h>
#include <PxController.h>
#include <PxIO.h>
#include <extensions/PxExtensionsAPI.h>
#include <extensions/PxDefaultErrorCallback.h>
#include <extensions/PxDefaultAllocator.h>
#include <extensions/PxDefaultSimulationFilterShader.h>
#include <extensions/PxDefaultCpuDispatcher.h>
#include <extensions/PxShapeExt.h>
#include <extensions/PxSimpleFactory.h>
#include <foundation/PxFoundation.h>
#include <characterkinematic/PxController.h>
#include <pvd/PxPvd.h>
extern physx::PxPhysics* gPhysics3SDK;

View file

@ -52,12 +52,9 @@ void Px3Body::_releaseActor()
if ( !mActor )
return;
mWorld->releaseWriteLock();
mActor->userData = NULL;
mActor->release();
mActor = NULL;
SafeReleasePhysx(mActor);
mBodyFlags = 0;
if ( mMaterial )
@ -80,7 +77,7 @@ bool Px3Body::init( PhysicsCollision *shape,
AssertFatal( shape, "Px3Body::init - Got a null collision shape!" );
AssertFatal( dynamic_cast<Px3Collision*>( shape ), "Px3Body::init - The collision shape is the wrong type!" );
AssertFatal( !((Px3Collision*)shape)->getShapes().empty(), "Px3Body::init - Got empty collision shape!" );
// Cleanup any previous actor.
_releaseActor();
@ -96,18 +93,20 @@ bool Px3Body::init( PhysicsCollision *shape,
{
mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
actor->setRigidDynamicFlag(physx::PxRigidDynamicFlag::eKINEMATIC, true);
actor->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, true);
actor->setMass(getMax( mass, 1.0f ));
}
else if ( mass > 0.0f )
{
mActor = gPhysics3SDK->createRigidDynamic(physx::PxTransform(physx::PxIDENTITY()));
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
actor->setMaxAngularVelocity(80.f);
}
else
{
mActor = gPhysics3SDK->createRigidStatic(physx::PxTransform(physx::PxIDENTITY()));
mIsStatic = true;
}
}
mMaterial = gPhysics3SDK->createMaterial(0.6f,0.4f,0.1f);
@ -123,12 +122,13 @@ bool Px3Body::init( PhysicsCollision *shape,
Con::errorf("PhysX3 Dynamic Triangle Mesh is not supported.");
}
}
physx::PxShape * pShape = mActor->createShape(*desc->pGeometry,*mMaterial);
physx::PxShape * pShape = physx::PxRigidActorExt::createExclusiveShape(*mActor, *desc->pGeometry, *mMaterial);
physx::PxFilterData colData;
if(isDebris)
colData.word0 = PX3_DEBRIS;
else if(isTrigger)
colData.word0 = PX3_TRIGGER;
colData.word0 = PX3_TRIGGER;
else
colData.word0 = PX3_DEFAULT;
@ -149,10 +149,6 @@ bool Px3Body::init( PhysicsCollision *shape,
physx::PxRigidBodyExt::setMassAndUpdateInertia(*actor,mass);
}
// This sucks, but it has to happen if we want
// to avoid write lock errors from PhysX right now.
mWorld->releaseWriteLock();
mWorld->getScene()->addActor(*mActor);
mIsEnabled = true;
@ -178,9 +174,9 @@ void Px3Body::setMaterial( F32 restitution,
actor->wakeUp();
}
mMaterial->setRestitution(restitution);
mMaterial->setStaticFriction(staticFriction);
mMaterial->setDynamicFriction(friction);
mMaterial->setRestitution(restitution);
mMaterial->setStaticFriction(staticFriction);
mMaterial->setDynamicFriction(friction);
}
@ -322,15 +318,14 @@ Box3F Px3Body::getWorldBounds()
physx::PxBounds3 bounds;
bounds.setEmpty();
physx::PxBounds3 shapeBounds;
physx::PxBounds3 shapeBounds;
U32 shapeCount = mActor->getNbShapes();
physx::PxShape **shapes = new physx::PxShape*[shapeCount];
mActor->getShapes(shapes, shapeCount);
for ( U32 i = 0; i < shapeCount; i++ )
{
// Get the shape's bounds.
// Get the shape's bounds.
shapeBounds = physx::PxShapeExt::getWorldBounds(*shapes[i],*mActor);
// Combine them into the total bounds.
bounds.include( shapeBounds );
@ -350,10 +345,6 @@ void Px3Body::setSimulationEnabled( bool enabled )
if(mBodyFlags & BF_TRIGGER)
return;
// This sucks, but it has to happen if we want
// to avoid write lock errors from PhysX right now.
mWorld->releaseWriteLock();
U32 shapeCount = mActor->getNbShapes();
physx::PxShape **shapes = new physx::PxShape*[shapeCount];
mActor->getShapes(shapes, shapeCount);
@ -367,12 +358,6 @@ void Px3Body::setSimulationEnabled( bool enabled )
void Px3Body::setTransform( const MatrixF &transform )
{
AssertFatal( mActor, "Px3Body::setTransform - The actor is null!" );
// This sucks, but it has to happen if we want
// to avoid write lock errors from PhysX right now.
mWorld->releaseWriteLock();
mActor->setGlobalPose(px3Cast<physx::PxTransform>(transform),false);
@ -380,7 +365,7 @@ void Px3Body::setTransform( const MatrixF &transform )
return;
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
bool kinematic = actor->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC;
bool kinematic = actor->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC;
// If its dynamic we have more to do.
if ( isDynamic() && !kinematic )
{
@ -395,10 +380,6 @@ void Px3Body::applyCorrection( const MatrixF &transform )
AssertFatal( mActor, "Px3Body::applyCorrection - The actor is null!" );
AssertFatal( isDynamic(), "Px3Body::applyCorrection - This call is only for dynamics!" );
// This sucks, but it has to happen if we want
// to avoid write lock errors from PhysX right now.
mWorld->releaseWriteLock();
mActor->setGlobalPose( px3Cast<physx::PxTransform>(transform) );
}
@ -406,35 +387,27 @@ void Px3Body::applyImpulse( const Point3F &origin, const Point3F &force )
{
AssertFatal( mActor, "Px3Body::applyImpulse - The actor is null!" );
// This sucks, but it has to happen if we want
// to avoid write lock errors from PhysX right now.
mWorld->releaseWriteLock();
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
if ( mIsEnabled && isDynamic() )
physx::PxRigidBodyExt::addForceAtPos(*actor,px3Cast<physx::PxVec3>(force),
px3Cast<physx::PxVec3>(origin),
physx::PxForceMode::eIMPULSE);
physx::PxRigidBodyExt::addForceAtPos( *actor,px3Cast<physx::PxVec3>(force), px3Cast<physx::PxVec3>(origin), physx::PxForceMode::eIMPULSE );
}
void Px3Body::applyTorque( const Point3F &torque )
void Px3Body::applyTorque(const Point3F &torque)
{
AssertFatal(mActor, "Px3Body::applyImpulse - The actor is null!");
mWorld->releaseWriteLock();
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
if (mIsEnabled && isDynamic())
actor->addTorque( px3Cast<physx::PxVec3>(torque), physx::PxForceMode::eFORCE, true);
actor->addTorque(px3Cast<physx::PxVec3>(torque), physx::PxForceMode::eFORCE, true);
}
void Px3Body::applyForce( const Point3F &force )
void Px3Body::applyForce(const Point3F &force)
{
AssertFatal(mActor, "Px3Body::applyTorque - The actor is null!");
mWorld->releaseWriteLock();
physx::PxRigidDynamic *actor = mActor->is<physx::PxRigidDynamic>();
if (mIsEnabled && isDynamic())
actor->addForce( px3Cast<physx::PxVec3>(force), physx::PxForceMode::eFORCE, true);
actor->addForce(px3Cast<physx::PxVec3>(force), physx::PxForceMode::eFORCE, true);
}
void Px3Body::findContact(SceneObject **contactObject,

View file

@ -40,7 +40,8 @@ class Px3World;
class Px3Collision;
struct Px3CollisionDesc;
namespace physx{
namespace physx
{
class PxRigidActor;
class PxMaterial;
class PxShape;

View file

@ -36,136 +36,124 @@ Px3Collision::Px3Collision()
}
Px3Collision::~Px3Collision()
{
for ( U32 i=0; i < mColShapes.size(); i++ )
{
Px3CollisionDesc *desc = mColShapes[i];
delete desc->pGeometry;
// Delete the descriptor.
delete desc;
}
{
for ( U32 i=0; i < mColShapes.size(); i++ )
{
Px3CollisionDesc *desc = mColShapes[i];
delete desc->pGeometry;
// Delete the descriptor.
delete desc;
}
mColShapes.clear();
mColShapes.clear();
}
void Px3Collision::addPlane( const PlaneF &plane )
{
physx::PxVec3 pos = px3Cast<physx::PxVec3>(plane.getPosition());
Px3CollisionDesc *desc = new Px3CollisionDesc;
physx::PxVec3 pos = px3Cast<physx::PxVec3>(plane.getPosition());
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxPlaneGeometry();
desc->pose = physx::PxTransform(pos, physx::PxQuat(physx::PxHalfPi, physx::PxVec3(0.0f, -1.0f, 0.0f)));
mColShapes.push_back(desc);
mColShapes.push_back(desc);
}
void Px3Collision::addBox( const Point3F &halfWidth,const MatrixF &localXfm )
{
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxBoxGeometry(px3Cast<physx::PxVec3>(halfWidth));
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxBoxGeometry(px3Cast<physx::PxVec3>(halfWidth));
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
}
void Px3Collision::addSphere( F32 radius,
const MatrixF &localXfm )
void Px3Collision::addSphere( F32 radius, const MatrixF &localXfm )
{
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxSphereGeometry(radius);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxSphereGeometry(radius);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
}
void Px3Collision::addCapsule( F32 radius,
F32 height,
const MatrixF &localXfm )
void Px3Collision::addCapsule( F32 radius, F32 height, const MatrixF &localXfm )
{
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxCapsuleGeometry(radius,height*0.5);//uses half height
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxCapsuleGeometry(radius,height*0.5);//uses half height
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
}
bool Px3Collision::addConvex( const Point3F *points,
U32 count,
const MatrixF &localXfm )
bool Px3Collision::addConvex( const Point3F *points, U32 count, const MatrixF &localXfm )
{
physx::PxCooking *cooking = Px3World::getCooking();
physx::PxConvexMeshDesc convexDesc;
convexDesc.points.data = points;
convexDesc.points.stride = sizeof(Point3F);
convexDesc.points.count = count;
convexDesc.flags = physx::PxConvexFlag::eFLIPNORMALS|physx::PxConvexFlag::eCOMPUTE_CONVEX | physx::PxConvexFlag::eINFLATE_CONVEX;
physx::PxCooking *cooking = Px3World::getCooking();
physx::PxConvexMeshDesc convexDesc;
convexDesc.points.data = points;
convexDesc.points.stride = sizeof(Point3F);
convexDesc.points.count = count;
convexDesc.flags = physx::PxConvexFlag::eCOMPUTE_CONVEX | physx::PxConvexFlag::eCHECK_ZERO_AREA_TRIANGLES;
if(PhysicsWorld::isGpuEnabled())
convexDesc.flags |= physx::PxConvexFlag::eGPU_COMPATIBLE;
Px3MemOutStream stream;
if(!cooking->cookConvexMesh(convexDesc,stream))
return false;
Px3MemOutStream stream;
if(!cooking->cookConvexMesh(convexDesc,stream))
return false;
physx::PxConvexMesh* convexMesh;
Px3MemInStream in(stream.getData(), stream.getSize());
convexMesh = gPhysics3SDK->createConvexMesh(in);
physx::PxConvexMesh* convexMesh;
Px3MemInStream in(stream.getData(), stream.getSize());
convexMesh = gPhysics3SDK->createConvexMesh(in);
Px3CollisionDesc *desc = new Px3CollisionDesc;
Px3CollisionDesc *desc = new Px3CollisionDesc;
physx::PxVec3 scale = px3Cast<physx::PxVec3>(localXfm.getScale());
physx::PxQuat rotation = px3Cast<physx::PxQuat>(QuatF(localXfm));
physx::PxMeshScale meshScale(scale,rotation);
desc->pGeometry = new physx::PxConvexMeshGeometry(convexMesh,meshScale);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
return true;
desc->pGeometry = new physx::PxConvexMeshGeometry(convexMesh,meshScale);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
return true;
}
bool Px3Collision::addTriangleMesh( const Point3F *vert,
U32 vertCount,
const U32 *index,
U32 triCount,
const MatrixF &localXfm )
bool Px3Collision::addTriangleMesh( const Point3F *vert, U32 vertCount, const U32 *index, U32 triCount, const MatrixF &localXfm )
{
physx::PxCooking *cooking = Px3World::getCooking();
physx::PxTriangleMeshDesc meshDesc;
meshDesc.points.count = vertCount;
meshDesc.points.data = vert;
meshDesc.points.stride = sizeof(Point3F);
physx::PxCooking *cooking = Px3World::getCooking();
physx::PxTriangleMeshDesc meshDesc;
meshDesc.points.count = vertCount;
meshDesc.points.data = vert;
meshDesc.points.stride = sizeof(Point3F);
meshDesc.triangles.count = triCount;
meshDesc.triangles.data = index;
meshDesc.triangles.stride = 3*sizeof(U32);
meshDesc.flags = physx::PxMeshFlag::eFLIPNORMALS;
meshDesc.triangles.count = triCount;
meshDesc.triangles.data = index;
meshDesc.triangles.stride = 3*sizeof(U32);
meshDesc.flags = physx::PxMeshFlag::eFLIPNORMALS;
Px3MemOutStream stream;
if(!cooking->cookTriangleMesh(meshDesc,stream))
return false;
Px3MemOutStream stream;
if(!cooking->cookTriangleMesh(meshDesc,stream))
return false;
physx::PxTriangleMesh *mesh;
Px3MemInStream in(stream.getData(), stream.getSize());
mesh = gPhysics3SDK->createTriangleMesh(in);
physx::PxTriangleMesh *mesh;
Px3MemInStream in(stream.getData(), stream.getSize());
mesh = gPhysics3SDK->createTriangleMesh(in);
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxTriangleMeshGeometry(mesh);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
return true;
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = new physx::PxTriangleMeshGeometry(mesh);
desc->pose = px3Cast<physx::PxTransform>(localXfm);
mColShapes.push_back(desc);
return true;
}
bool Px3Collision::addHeightfield( const U16 *heights,
const bool *holes,
U32 blockSize,
F32 metersPerSample,
const MatrixF &localXfm )
bool Px3Collision::addHeightfield( const U16 *heights, const bool *holes, U32 blockSize, F32 metersPerSample, const MatrixF &localXfm )
{
const F32 heightScale = 0.03125f;
physx::PxHeightFieldSample* samples = (physx::PxHeightFieldSample*) new physx::PxHeightFieldSample[blockSize*blockSize];
memset(samples,0,blockSize*blockSize*sizeof(physx::PxHeightFieldSample));
const F32 heightScale = 0.03125f;
physx::PxHeightFieldSample* samples = (physx::PxHeightFieldSample*) new physx::PxHeightFieldSample[blockSize*blockSize];
memset(samples,0,blockSize*blockSize*sizeof(physx::PxHeightFieldSample));
physx::PxHeightFieldDesc heightFieldDesc;
heightFieldDesc.nbColumns = blockSize;
heightFieldDesc.nbRows = blockSize;
heightFieldDesc.thickness = -10.f;
heightFieldDesc.convexEdgeThreshold = 0;
heightFieldDesc.format = physx::PxHeightFieldFormat::eS16_TM;
heightFieldDesc.samples.data = samples;
heightFieldDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
physx::PxHeightFieldDesc heightFieldDesc;
heightFieldDesc.nbColumns = blockSize;
heightFieldDesc.nbRows = blockSize;
heightFieldDesc.thickness = -10.f;
heightFieldDesc.convexEdgeThreshold = 0;
heightFieldDesc.format = physx::PxHeightFieldFormat::eS16_TM;
heightFieldDesc.samples.data = samples;
heightFieldDesc.samples.stride = sizeof(physx::PxHeightFieldSample);
physx::PxU8 *currentByte = (physx::PxU8*)heightFieldDesc.samples.data;
physx::PxU8 *currentByte = (physx::PxU8*)heightFieldDesc.samples.data;
for ( U32 row = 0; row < blockSize; row++ )
{
const U32 tess = ( row + 1 ) % 2;
@ -177,7 +165,6 @@ bool Px3Collision::addHeightfield( const U16 *heights,
U32 index = ( blockSize - row - 1 ) + ( column * blockSize );
currentSample->height = (physx::PxI16)heights[ index ];
if ( holes && holes[ getMax( (S32)index - 1, 0 ) ] ) // row index for holes adjusted so PhysX collision shape better matches rendered terrain
{
currentSample->materialIndex0 = physx::PxHeightFieldMaterial::eHOLE;
@ -189,29 +176,30 @@ bool Px3Collision::addHeightfield( const U16 *heights,
currentSample->materialIndex1 = 0;
}
int flag = ( column + tess ) % 2;
if(flag)
currentSample->clearTessFlag();
else
currentSample->setTessFlag();
S32 flag = ( column + tess ) % 2;
if(flag)
currentSample->clearTessFlag();
else
currentSample->setTessFlag();
currentByte += heightFieldDesc.samples.stride;
}
}
physx::PxHeightField * hf = gPhysics3SDK->createHeightField(heightFieldDesc);
physx::PxHeightFieldGeometry *geom = new physx::PxHeightFieldGeometry(hf,physx::PxMeshGeometryFlags(),heightScale,metersPerSample,metersPerSample);
physx::PxCooking *cooking = Px3World::getCooking();
physx::PxHeightField * hf = cooking->createHeightField(heightFieldDesc,gPhysics3SDK->getPhysicsInsertionCallback());
physx::PxHeightFieldGeometry *geom = new physx::PxHeightFieldGeometry(hf,physx::PxMeshGeometryFlags(),heightScale,metersPerSample,metersPerSample);
physx::PxTransform pose= physx::PxTransform(physx::PxQuat(Float_HalfPi, physx::PxVec3(1, 0, 0 )));
physx::PxTransform pose1= physx::PxTransform(physx::PxQuat(Float_Pi, physx::PxVec3(0, 0, 1 )));
physx::PxTransform pose2 = pose1 * pose;
pose2.p = physx::PxVec3(( blockSize - 1 ) * metersPerSample, 0, 0 );
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = geom;
desc->pose = pose2;
physx::PxTransform pose= physx::PxTransform(physx::PxQuat(Float_HalfPi, physx::PxVec3(1, 0, 0 )));
physx::PxTransform pose1= physx::PxTransform(physx::PxQuat(Float_Pi, physx::PxVec3(0, 0, 1 )));
physx::PxTransform pose2 = pose1 * pose;
pose2.p = physx::PxVec3(( blockSize - 1 ) * metersPerSample, 0, 0 );
Px3CollisionDesc *desc = new Px3CollisionDesc;
desc->pGeometry = geom;
desc->pose = pose2;
mColShapes.push_back(desc);
mColShapes.push_back(desc);
SAFE_DELETE(samples);
return true;
return true;
}

View file

@ -23,6 +23,9 @@
#ifndef _PX3COLLISION_H_
#define _PX3COLLISION_H_
#ifndef _PHYSX3_H_
#include "T3D/physics/physx3/px3.h"
#endif
#ifndef _T3D_PHYSICS_PHYSICSCOLLISION_H_
#include "T3D/physics/physicsCollision.h"
#endif

View file

@ -53,7 +53,7 @@ void Px3Player::_releaseController()
{
mController->getActor()->userData = NULL;
mWorld->getStaticChangedSignal().remove( this, &Px3Player::_onStaticChanged );
mController->release();
SafeReleasePhysx(mController);
}
}
@ -136,8 +136,6 @@ Point3F Px3Player::move( const VectorF &disp, CollisionList &outCol )
return newPos;
}
mWorld->releaseWriteLock();
mCollisionList = &outCol;
physx::PxVec3 dispNx( disp.x, disp.y, disp.z );
@ -151,8 +149,8 @@ Point3F Px3Player::move( const VectorF &disp, CollisionList &outCol )
physx::PxFilterData data;
data.word0=groups;
filter.mFilterData = &data;
filter.mFilterFlags = physx::PxSceneQueryFilterFlags(physx::PxControllerFlag::eCOLLISION_DOWN|physx::PxControllerFlag::eCOLLISION_SIDES|physx::PxControllerFlag::eCOLLISION_UP);
filter.mFilterFlags = physx::PxQueryFlags(physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::eSTATIC);
mController->move( dispNx,0.0001f,0, filter );
Point3F newPos = px3Cast<Point3F>( mController->getPosition() );
@ -272,7 +270,6 @@ void Px3Player::enableCollision()
{
AssertFatal( mController, "Px3Player::enableCollision - The controller is null!" );
mWorld->releaseWriteLock();
px3GetFirstShape(mController->getActor())->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,true);
}
@ -280,7 +277,6 @@ void Px3Player::disableCollision()
{
AssertFatal( mController, "Px3Player::disableCollision - The controller is null!" );
mWorld->releaseWriteLock();
px3GetFirstShape(mController->getActor())->setFlag(physx::PxShapeFlag::eSIMULATION_SHAPE,false);
}
@ -293,8 +289,6 @@ void Px3Player::setTransform( const MatrixF &transform )
{
AssertFatal( mController, "Px3Player::setTransform - The controller is null!" );
mWorld->releaseWriteLock();
Point3F newPos = transform.getPosition();
newPos.z += mOriginOffset;
@ -355,7 +349,6 @@ void Px3Player::setSpacials(const Point3F &nPos, const Point3F &nSize)
F32 height = nSize.z - (radius * 2.0f);
height -= mSkinWidth * 2.0f;
mWorld->releaseWriteLock();
mController->resize(height);
px3GetFirstShape(mController->getActor())->getCapsuleGeometry(mGeometry);
}

View file

@ -83,10 +83,7 @@ Px3ConsoleStream::~Px3ConsoleStream()
{
}
void Px3ConsoleStream::reportError( physx::PxErrorCode code, const char *message, const char* file, int line )
void Px3ConsoleStream::reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line)
{
UTF8 info[1024];
dSprintf( info, 1024, "File: %s\nLine: %d\n%s", file, line, message );
Platform::AlertOK( "PhysX Error", info );
// Con::printf( "PhysX Error:\n %s(%d) : %s\n", file, line, message );
}
Con::warnf( "PhysX Warning: %s(%d) : %s", file, line, message );
}

View file

@ -62,11 +62,11 @@ protected:
};
class Px3ConsoleStream : public physx::PxDefaultErrorCallback
class Px3ConsoleStream : public physx::PxErrorCallback
{
protected:
virtual void reportError( physx::PxErrorCode code, const char *message, const char* file, int line );
virtual void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line);
public:

View file

@ -41,27 +41,31 @@
#include "gfx/sim/debugDraw.h"
#include "gfx/primBuilder.h"
physx::PxPhysics* gPhysics3SDK = NULL;
physx::PxCooking* Px3World::smCooking = NULL;
physx::PxFoundation* Px3World::smFoundation = NULL;
physx::PxProfileZoneManager* Px3World::smProfileZoneManager = NULL;
physx::PxDefaultCpuDispatcher* Px3World::smCpuDispatcher=NULL;
physx::PxDefaultCpuDispatcher* Px3World::smCpuDispatcher = NULL;
#ifndef TORQUE_OS_MAC
physx::PxCudaContextManager* Px3World::smCudaContextManager = NULL;
#endif
Px3ConsoleStream* Px3World::smErrorCallback = NULL;
physx::PxVisualDebuggerConnection* Px3World::smPvdConnection=NULL;
physx::PxPvd* Px3World::smPvdConnection = NULL;
physx::PxPvdTransport* Px3World::smPvdTransport = NULL;
physx::PxDefaultAllocator Px3World::smMemoryAlloc;
Px3World::Px3World(): mScene( NULL ),
mProcessList( NULL ),
mIsSimulating( false ),
mErrorReport( false ),
mTickCount( 0 ),
Px3World::Px3World() :
mScene( NULL ),
mIsEnabled( false ),
mIsSimulating( false ),
mIsServer( false ),
mIsSceneLocked( false ),
mTickCount( 0 ),
mProcessList( NULL ),
mEditorTimeScale( 1.0f ),
mAccumulator( 0 ),
mErrorReport( false ),
mControllerManager(NULL),
mIsSceneLocked(false),
mRenderBuffer(NULL)
mRenderBuffer(NULL),
mAccumulator( 0 )
{
}
@ -80,33 +84,25 @@ bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *se
// then we cannot reset the SDK.
if ( clientWorld || serverWorld )
return false;
if(smPvdConnection)
smPvdConnection->release();
if(smCooking)
smCooking->release();
if(smCpuDispatcher)
smCpuDispatcher->release();
#ifndef TORQUE_OS_MAC
SafeReleasePhysx(smCudaContextManager);
#endif
SafeReleasePhysx(smCpuDispatcher);
SafeReleasePhysx(smCooking);
smGpuEnabled = false;
// Destroy the existing SDK.
if ( gPhysics3SDK )
{
PxCloseExtensions();
gPhysics3SDK->release();
SafeReleasePhysx(gPhysics3SDK);
}
if(smErrorCallback)
{
SAFE_DELETE(smErrorCallback);
}
SafeReleasePhysx(smPvdConnection);
SafeReleasePhysx(smPvdTransport);
if(smFoundation)
{
smFoundation->release();
SAFE_DELETE(smErrorCallback);
}
SAFE_DELETE(smErrorCallback);
SafeReleasePhysx(smFoundation);
// If we're not supposed to restart... return.
if ( destroyOnly )
@ -114,20 +110,18 @@ bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *se
bool memTrack = false;
#ifdef TORQUE_DEBUG
memTrack = true;
memTrack = false;
#endif
smErrorCallback = new Px3ConsoleStream;
smFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, smMemoryAlloc, *smErrorCallback);
smProfileZoneManager = &physx::PxProfileZoneManager::createProfileZoneManager(smFoundation);
gPhysics3SDK = PxCreatePhysics(PX_PHYSICS_VERSION, *smFoundation, physx::PxTolerancesScale(),memTrack,smProfileZoneManager);
smFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, smMemoryAlloc, *smErrorCallback);
smPvdConnection = PxCreatePvd(*smFoundation);
gPhysics3SDK = PxCreatePhysics(PX_PHYSICS_VERSION, *smFoundation, physx::PxTolerancesScale(),memTrack, smPvdConnection);
if ( !gPhysics3SDK )
{
Con::errorf( "PhysX3 failed to initialize!" );
Platform::messageBox( Con::getVariable( "$appName" ),
avar("PhysX3 could not be started!\r\n"),
MBOk, MIStop );
Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop );
Platform::forceShutdown( -1 );
// We shouldn't get here, but this shuts up
@ -135,33 +129,67 @@ bool Px3World::restartSDK( bool destroyOnly, Px3World *clientWorld, Px3World *se
return false;
}
if(!PxInitExtensions(*gPhysics3SDK))
if(!PxInitExtensions(*gPhysics3SDK, smPvdConnection))
{
Con::errorf( "PhysX3 failed to initialize extensions!" );
Platform::messageBox( Con::getVariable( "$appName" ),
avar("PhysX3 could not be started!\r\n"),
MBOk, MIStop );
Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop );
Platform::forceShutdown( -1 );
return false;
}
//no gpu support on macOS
#ifndef TORQUE_OS_MAC
//check if we are allowed to use gpu acceleration
if (PhysicsPlugin::gpuAccelerationAllowed())
{
// attempt to create a cuda context manager - only works on nvidia gpu (SM 3.0+ i.e kepler or better)
if (!smCpuDispatcher)
{
//check we have capable gpu, -1 means none found
S32 suggestedGpu = PxGetSuggestedCudaDeviceOrdinal(*smErrorCallback);
if (suggestedGpu != -1)
{
physx::PxCudaContextManagerDesc cudaContextManagerDesc;
smCudaContextManager = PxCreateCudaContextManager(*smFoundation, cudaContextManagerDesc);
if (smCudaContextManager)
smGpuEnabled = true;
}
}
}
#endif
smCooking = PxCreateCooking(PX_PHYSICS_VERSION, *smFoundation, physx::PxCookingParams(physx::PxTolerancesScale()));
//cpu dispatcher
if (!smCpuDispatcher)
smCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(PHYSICSMGR->getThreadCount());
physx::PxCookingParams params = physx::PxCookingParams(physx::PxTolerancesScale());
params.meshWeldTolerance = 0.001f;
params.meshPreprocessParams = physx::PxMeshPreprocessingFlags(physx::PxMeshPreprocessingFlag::eWELD_VERTICES);
#ifndef TORQUE_OS_MAC
if(smGpuEnabled)
params.buildGPUData = true;
#endif
smCooking = PxCreateCooking(PX_PHYSICS_VERSION, *smFoundation, params);
if(!smCooking)
{
Con::errorf( "PhysX3 failed to initialize cooking!" );
Platform::messageBox( Con::getVariable( "$appName" ),
avar("PhysX3 could not be started!\r\n"),
MBOk, MIStop );
Platform::messageBox( Con::getVariable( "$appName" ), avar("PhysX3 could not be started!\r\n"), MBOk, MIStop );
Platform::forceShutdown( -1 );
return false;
}
//TODO: enable/disable this from script
#ifdef TORQUE_DEBUG
physx::PxVisualDebuggerConnectionFlags connectionFlags(physx::PxVisualDebuggerExt::getAllConnectionFlags());
smPvdConnection = physx::PxVisualDebuggerExt::createConnection(gPhysics3SDK->getPvdConnectionManager(),
"localhost", 5425, 100, connectionFlags);
if(!smPvdTransport)
smPvdTransport = physx::PxDefaultPvdSocketTransportCreate("localhost", 5425, 100);
smPvdConnection->connect(*smPvdTransport, physx::PxPvdInstrumentationFlag::eALL);
#endif
//use legacy heightfield
//TODO: new method causing crashes on collision in debug build (unified HeightFields)
PxRegisterLegacyHeightFields(*gPhysics3SDK);
return true;
}
@ -169,8 +197,6 @@ void Px3World::destroyWorld()
{
getPhysicsResults();
mRenderBuffer = NULL;
// Release the tick processing signals.
if ( mProcessList )
{
@ -179,19 +205,9 @@ void Px3World::destroyWorld()
mProcessList = NULL;
}
if(mControllerManager)
{
mControllerManager->release();
mControllerManager = NULL;
}
SafeReleasePhysx(mControllerManager);
// Destroy the scene.
if ( mScene )
{
// Release the scene.
mScene->release();
mScene = NULL;
}
SafeReleasePhysx(mScene);
}
bool Px3World::initWorld( bool isServer, ProcessList *processList )
@ -203,27 +219,32 @@ bool Px3World::initWorld( bool isServer, ProcessList *processList )
}
mIsServer = isServer;
physx::PxSceneDesc sceneDesc(gPhysics3SDK->getTolerancesScale());
sceneDesc.gravity = px3Cast<physx::PxVec3>(mGravity);
sceneDesc.userData = this;
if(!sceneDesc.cpuDispatcher)
{
//Create shared cpu dispatcher
if(!smCpuDispatcher)
smCpuDispatcher = physx::PxDefaultCpuDispatcherCreate(PHYSICSMGR->getThreadCount());
sceneDesc.cpuDispatcher = smCpuDispatcher;
Con::printf("PhysX3 using Cpu: %d workers", smCpuDispatcher->getWorkerCount());
sceneDesc.cpuDispatcher = smCpuDispatcher;
Con::printf("PhysX3 using Cpu: %d workers", smCpuDispatcher->getWorkerCount());
#ifndef TORQUE_OS_MAC
if (smGpuEnabled)
{
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_GPU_DYNAMICS;
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_PCM;
sceneDesc.broadPhaseType = physx::PxBroadPhaseType::eGPU;
sceneDesc.gpuDispatcher = smCudaContextManager->getGpuDispatcher();
Con::printf("PhysX3 using Gpu: %s", smCudaContextManager->getDeviceName());
}
#endif
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_CCD;
sceneDesc.flags |= physx::PxSceneFlag::eENABLE_ACTIVETRANSFORMS;
sceneDesc.filterShader = physx::PxDefaultSimulationFilterShader;
mScene = gPhysics3SDK->createScene(sceneDesc);
//cache renderbuffer for use with debug drawing
mScene = gPhysics3SDK->createScene(sceneDesc);
mRenderBuffer = const_cast<physx::PxRenderBuffer*>(&mScene->getRenderBuffer());
physx::PxDominanceGroupPair debrisDominance( 0.0f, 1.0f );
@ -252,15 +273,16 @@ bool Px3World::_simulate(const F32 dt)
if (numSimulationSubSteps)
{
//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
S32 clampedSimulationSteps = (numSimulationSubSteps > smPhysicsMaxSubSteps)? smPhysicsMaxSubSteps : numSimulationSubSteps;
S32 clampedSimulationSteps = (numSimulationSubSteps > smPhysicsMaxSubSteps) ? smPhysicsMaxSubSteps : numSimulationSubSteps;
for (S32 i=0;i<clampedSimulationSteps;i++)
{
mScene->fetchResults(true);
if(i > 0)
mScene->fetchResults(true);
mScene->simulate(smPhysicsStepTime);
}
}
mIsSimulating = true;
return true;
@ -299,36 +321,6 @@ void Px3World::getPhysicsResults()
mScene->fetchResults(true);
mIsSimulating = false;
mTickCount++;
// Con::printf( "%s PhysXWorld::getPhysicsResults!", this == smClientWorld ? "Client" : "Server" );
}
void Px3World::releaseWriteLocks()
{
Px3World *world = dynamic_cast<Px3World*>( PHYSICSMGR->getWorld( "server" ) );
if ( world )
world->releaseWriteLock();
world = dynamic_cast<Px3World*>( PHYSICSMGR->getWorld( "client" ) );
if ( world )
world->releaseWriteLock();
}
void Px3World::releaseWriteLock()
{
if ( !mScene || !mIsSimulating )
return;
PROFILE_SCOPE(PxWorld_ReleaseWriteLock);
// We use checkResults here to release the write lock
// but we do not change the simulation flag or increment
// the tick count... we may have gotten results, but the
// simulation hasn't really ticked!
mScene->checkResults( true );
//AssertFatal( mScene->isWritable(), "PhysX3World::releaseWriteLock() - We should have been writable now!" );
}
void Px3World::lockScenes()
@ -388,8 +380,7 @@ void Px3World::unlockScene()
}
bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo *ri, const Point3F &impulse )
{
{
physx::PxVec3 orig = px3Cast<physx::PxVec3>( startPnt );
physx::PxVec3 dir = px3Cast<physx::PxVec3>( endPnt - startPnt );
physx::PxF32 maxDist = dir.magnitude();
@ -398,15 +389,15 @@ bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo
U32 groups = 0xffffffff;
groups &= ~( PX3_TRIGGER ); // No trigger shapes!
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::eIMPACT | physx::PxHitFlag::eNORMAL);
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL);
physx::PxQueryFilterData filterData(physx::PxQueryFlag::eSTATIC|physx::PxQueryFlag::eDYNAMIC);
filterData.data.word0 = groups;
physx::PxRaycastBuffer buf;
if(!mScene->raycast(orig,dir,maxDist,buf,outFlags,filterData))
return false;
return false;
if(!buf.hasBlock)
return false;
return false;
const physx::PxRaycastHit hit = buf.block;
physx::PxRigidActor *actor = hit.actor;
@ -425,8 +416,8 @@ bool Px3World::castRay( const Point3F &startPnt, const Point3F &endPnt, RayInfo
}
if ( impulse.isZero() ||
!actor->isRigidDynamic() ||
actor->is<physx::PxRigidDynamic>()->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC )
!actor->is<physx::PxRigidDynamic>() ||
actor->is<physx::PxRigidDynamic>()->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC )
return true;
physx::PxRigidBody *body = actor->is<physx::PxRigidBody>();
@ -453,7 +444,7 @@ PhysicsBody* Px3World::castRay( const Point3F &start, const Point3F &end, U32 bo
groups &= ~( PX3_TRIGGER ); // triggers
groups &= ~( PX3_DEBRIS ); // debris
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::eIMPACT | physx::PxHitFlag::eNORMAL);
physx::PxHitFlags outFlags(physx::PxHitFlag::eDISTANCE | physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL);
physx::PxQueryFilterData filterData;
if(bodyTypes & BT_Static)
filterData.flags |= physx::PxQueryFlag::eSTATIC;
@ -491,12 +482,12 @@ void Px3World::explosion( const Point3F &pos, F32 radius, F32 forceMagnitude )
{
physx::PxRigidActor *actor = buffer.touches[i].actor;
bool dynamic = actor->isRigidDynamic();
bool dynamic = actor->is<physx::PxRigidDynamic>();
if ( !dynamic )
continue;
bool kinematic = actor->is<physx::PxRigidDynamic>()->getRigidDynamicFlags() & physx::PxRigidDynamicFlag::eKINEMATIC;
bool kinematic = actor->is<physx::PxRigidDynamic>()->getRigidBodyFlags() & physx::PxRigidBodyFlag::eKINEMATIC;
if ( kinematic )
continue;
@ -523,8 +514,6 @@ physx::PxController* Px3World::createController( physx::PxControllerDesc &desc )
if ( !mScene )
return NULL;
// We need the writelock!
releaseWriteLock();
physx::PxController* pController = mControllerManager->createController(desc);
AssertFatal( pController, "Px3World::createController - Got a null!" );
return pController;
@ -543,7 +532,7 @@ static ColorI getDebugColor( physx::PxU32 packed )
void Px3World::onDebugDraw( const SceneRenderState *state )
{
if ( !mScene || !mRenderBuffer )
if ( !mScene || !mRenderBuffer)
return;
mScene->setVisualizationParameter(physx::PxVisualizationParameter::eSCALE,1.0f);

View file

@ -23,15 +23,15 @@
#ifndef _PX3WORLD_H_
#define _PX3WORLD_H_
#ifndef _PHYSX3_H_
#include "T3D/physics/physx3/px3.h"
#endif
#ifndef _T3D_PHYSICS_PHYSICSWORLD_H_
#include "T3D/physics/physicsWorld.h"
#endif
#ifndef _MMATH_H_
#include "math/mMath.h"
#endif
#ifndef _PHYSX3_H_
#include "T3D/physics/physx3/px3.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
@ -51,26 +51,29 @@ enum Px3CollisionGroup
class Px3World : public PhysicsWorld
{
protected:
physx::PxScene* mScene;
bool mIsEnabled;
bool mIsSimulating;
bool mIsServer;
bool mIsSceneLocked;
bool mIsSceneLocked;
U32 mTickCount;
ProcessList *mProcessList;
F32 mEditorTimeScale;
bool mErrorReport;
physx::PxRenderBuffer *mRenderBuffer;
physx::PxControllerManager* mControllerManager;
physx::PxRenderBuffer *mRenderBuffer;
F32 mAccumulator;
static Px3ConsoleStream *smErrorCallback;
static physx::PxDefaultAllocator smMemoryAlloc;
static physx::PxFoundation* smFoundation;
static physx::PxCooking *smCooking;
static physx::PxProfileZoneManager* smProfileZoneManager;
static physx::PxDefaultCpuDispatcher* smCpuDispatcher;
static physx::PxVisualDebuggerConnection* smPvdConnection;
F32 mAccumulator;
#ifndef TORQUE_OS_MAC
static physx::PxCudaContextManager* smCudaContextManager;
#endif
static physx::PxPvd* smPvdConnection;
static physx::PxPvdTransport* smPvdTransport;
bool _simulate(const F32 dt);
public:
@ -86,21 +89,20 @@ public:
virtual PhysicsBody* castRay( const Point3F &start, const Point3F &end, U32 bodyTypes = BT_All );
virtual void explosion( const Point3F &pos, F32 radius, F32 forceMagnitude );
virtual bool isEnabled() const { return mIsEnabled; }
physx::PxScene* getScene(){ return mScene;}
physx::PxScene* getScene(){ return mScene; }
void setEnabled( bool enabled );
U32 getTick() { return mTickCount; }
void tickPhysics( U32 elapsedMs );
void getPhysicsResults();
void setEditorTimeScale( F32 timeScale ) { mEditorTimeScale = timeScale; }
const F32 getEditorTimeScale() const { return mEditorTimeScale; }
void releaseWriteLock();
bool isServer(){return mIsServer;}
bool isServer() { return mIsServer; }
physx::PxController* createController( physx::PxControllerDesc &desc );
void lockScene();
void unlockScene();
//static
static bool restartSDK( bool destroyOnly = false, Px3World *clientWorld = NULL, Px3World *serverWorld = NULL );
static void releaseWriteLocks();
static physx::PxCooking *getCooking();
static void lockScenes();
static void unlockScenes();