From b64123a452d50ba53b9a8db476fed119ffe414d6 Mon Sep 17 00:00:00 2001 From: Areloch Date: Fri, 13 May 2016 23:57:48 -0500 Subject: [PATCH] Adds findContact to regular physics bodies so that they can find contacting objects and surfaces in a way similar to players. --- Engine/source/T3D/physics/bullet/btBody.cpp | 64 ++++++++++++++++++++ Engine/source/T3D/physics/bullet/btBody.h | 2 + Engine/source/T3D/physics/physicsBody.h | 4 ++ Engine/source/T3D/physics/physx3/px3Body.cpp | 52 ++++++++++++++++ Engine/source/T3D/physics/physx3/px3Body.h | 3 + 5 files changed, 125 insertions(+) diff --git a/Engine/source/T3D/physics/bullet/btBody.cpp b/Engine/source/T3D/physics/bullet/btBody.cpp index 77c3b8115..eb722fd17 100644 --- a/Engine/source/T3D/physics/bullet/btBody.cpp +++ b/Engine/source/T3D/physics/bullet/btBody.cpp @@ -378,3 +378,67 @@ void BtBody::setSimulationEnabled( bool enabled ) mIsEnabled = enabled; } + +void BtBody::findContact(SceneObject **contactObject, + VectorF *contactNormal, + Vector *outOverlapObjects) const +{ + AssertFatal(mActor, "BtPlayer::findContact - The controller is null!"); + + VectorF normal; + F32 maxDot = -1.0f; + + // Go thru the contact points... get the first contact. + //mWorld->getDynamicsWorld()->computeOverlappingPairs(); + btOverlappingPairCache *pairCache = mWorld->getDynamicsWorld()->getBroadphase()->getOverlappingPairCache(); + + btBroadphasePairArray& pairArray = pairCache->getOverlappingPairArray(); + U32 numPairs = pairArray.size(); + btManifoldArray manifoldArray; + + for (U32 i = 0; i < numPairs; i++) + { + const btBroadphasePair &pair = pairArray[i]; + + btBroadphasePair *collisionPair = pairCache->findPair(pair.m_pProxy0, pair.m_pProxy1); + if (!collisionPair || !collisionPair->m_algorithm) + continue; + + btCollisionObject *other = (btCollisionObject*)pair.m_pProxy0->m_clientObject; + if (other == mActor) + other = (btCollisionObject*)pair.m_pProxy1->m_clientObject; + + // AssertFatal(!outOverlapObjects->contains(PhysicsUserData::getObject(other->getUserPointer())), + // "Got multiple pairs of the same object!"); + outOverlapObjects->push_back(PhysicsUserData::getObject(other->getUserPointer())); + + if (other->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE) + continue; + + manifoldArray.clear(); + collisionPair->m_algorithm->getAllContactManifolds(manifoldArray); + + for (U32 j = 0; j < manifoldArray.size(); j++) + { + btPersistentManifold *manifold = manifoldArray[j]; + btScalar directionSign = manifold->getBody0() == mActor ? 1.0f : -1.0f; + + for (U32 p = 0; p < manifold->getNumContacts(); p++) + { + const btManifoldPoint &pt = manifold->getContactPoint(p); + + // Test the normal... is it the most vertical one we got? + normal = btCast(pt.m_normalWorldOnB * directionSign); + F32 dot = mDot(normal, VectorF(0, 0, 1)); + if (dot > maxDot) + { + maxDot = dot; + + btCollisionObject *colObject = (btCollisionObject*)collisionPair->m_pProxy0->m_clientObject; + *contactObject = PhysicsUserData::getObject(colObject->getUserPointer()); + *contactNormal = normal; + } + } + } + } +} diff --git a/Engine/source/T3D/physics/bullet/btBody.h b/Engine/source/T3D/physics/bullet/btBody.h index 0f1ab669c..2de1215d2 100644 --- a/Engine/source/T3D/physics/bullet/btBody.h +++ b/Engine/source/T3D/physics/bullet/btBody.h @@ -111,6 +111,8 @@ public: F32 staticFriction ); virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); + + virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, Vector *outOverlapObjects) const; }; #endif // _T3D_PHYSICS_BTBODY_H_ diff --git a/Engine/source/T3D/physics/physicsBody.h b/Engine/source/T3D/physics/physicsBody.h index 15e94bcbd..fd8cca089 100644 --- a/Engine/source/T3D/physics/physicsBody.h +++ b/Engine/source/T3D/physics/physicsBody.h @@ -113,6 +113,10 @@ public: /// virtual void applyImpulse( const Point3F &origin, const Point3F &force ) = 0; + + virtual void findContact(SceneObject **contactObject, + VectorF *contactNormal, + Vector *outOverlapObjects) const = 0; }; diff --git a/Engine/source/T3D/physics/physx3/px3Body.cpp b/Engine/source/T3D/physics/physx3/px3Body.cpp index 026309f08..e36e76d8d 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.cpp +++ b/Engine/source/T3D/physics/physx3/px3Body.cpp @@ -417,3 +417,55 @@ void Px3Body::applyImpulse( const Point3F &origin, const Point3F &force ) } +void Px3Body::findContact(SceneObject **contactObject, + VectorF *contactNormal, + Vector *outOverlapObjects) const +{ + // Calculate the sweep motion... + F32 halfCapSize = mOriginOffset; + F32 halfSmallCapSize = halfCapSize * 0.8f; + F32 diff = halfCapSize - halfSmallCapSize; + + F32 distance = diff + mSkinWidth + 0.01f; + physx::PxVec3 dir(0, 0, -1); + + physx::PxScene *scene = mWorld->getScene(); + physx::PxHitFlags hitFlags(physx::PxHitFlag::eDEFAULT); + physx::PxQueryFilterData filterData(physx::PxQueryFlag::eDYNAMIC | physx::PxQueryFlag::eSTATIC); + filterData.data.word0 = PX3_DEFAULT; + physx::PxSweepHit sweepHit; + physx::PxRigidDynamic *actor = mController->getActor(); + physx::PxU32 shapeIndex; + + bool hit = physx::PxRigidBodyExt::linearSweepSingle(*actor, *scene, dir, distance, hitFlags, sweepHit, shapeIndex, filterData); + if (hit) + { + PhysicsUserData *data = PhysicsUserData::cast(sweepHit.actor->userData); + if (data) + { + *contactObject = data->getObject(); + *contactNormal = px3Cast(sweepHit.normal); + } + } + + // Check for overlapped objects ( triggers ) + + if (!outOverlapObjects) + return; + + filterData.data.word0 = PX3_TRIGGER; + + const physx::PxU32 bufferSize = 10; + physx::PxOverlapBufferN hitBuffer; + hit = scene->overlap(mGeometry, actor->getGlobalPose(), hitBuffer, filterData); + if (hit) + { + for (U32 i = 0; i < hitBuffer.nbTouches; i++) + { + PhysicsUserData *data = PhysicsUserData::cast(hitBuffer.touches[i].actor->userData); + if (data) + outOverlapObjects->push_back(data->getObject()); + } + } + +} \ No newline at end of file diff --git a/Engine/source/T3D/physics/physx3/px3Body.h b/Engine/source/T3D/physics/physx3/px3Body.h index 79096f57b..831d54cde 100644 --- a/Engine/source/T3D/physics/physx3/px3Body.h +++ b/Engine/source/T3D/physics/physx3/px3Body.h @@ -117,6 +117,9 @@ public: F32 staticFriction ); virtual void applyCorrection( const MatrixF &xfm ); virtual void applyImpulse( const Point3F &origin, const Point3F &force ); + + virtual void findContact(SceneObject **contactObject, VectorF *contactNormal, + Vector *outOverlapObjects) const; }; #endif // _PX3BODY_H_