Browse Source

Remove some PhysX workarounds that are no longer required.

Skoader 13 years ago committed by Adam Johnson
parent
commit
d4e9be28ec
  1. 184
      Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp
  2. 33
      Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.h
  3. 137
      Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp
  4. 7
      Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h

184
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.cpp

@ -138,14 +138,10 @@ plPXPhysical::plPXPhysical()
, fSceneNode(nil)
, fWorldKey(nil)
, fSndGroup(nil)
, fWorldHull(nil)
, fSaveTriangles(nil)
, fHullNumberPlanes(0)
, fMass(0.f)
, fWeWereHit(false)
, fHitForce(0,0,0)
, fHitPos(0,0,0)
, fInsideConvexHull(false)
{
}
@ -190,11 +186,6 @@ plPXPhysical::~plPXPhysical()
plSimulationMgr::GetInstance()->ReleaseScene(fWorldKey);
}
if (fWorldHull)
delete [] fWorldHull;
if (fSaveTriangles)
delete [] fSaveTriangles;
delete fProxyGen;
// remove sdl modifier
@ -206,155 +197,6 @@ plPXPhysical::~plPXPhysical()
delete fSDLMod;
}
static void MakeBoxFromHull(NxConvexMesh* convexMesh, NxBoxShapeDesc& box)
{
NxConvexMeshDesc desc;
convexMesh->saveToDesc(desc);
float minX, minY, minZ, maxX, maxY, maxZ;
minX = minY = minZ = FLT_MAX;
maxX = maxY = maxZ = -FLT_MAX;
for (int i = 0; i < desc.numVertices; i++)
{
float* point = (float*)(((char*)desc.points) + desc.pointStrideBytes*i);
float x = point[0];
float y = point[1];
float z = point[2];
minX = hsMinimum(minX, x);
minY = hsMinimum(minY, y);
minZ = hsMinimum(minZ, z);
maxX = hsMaximum(maxX, x);
maxY = hsMaximum(maxY, y);
maxZ = hsMaximum(maxZ, z);
}
float xWidth = maxX - minX;
float yWidth = maxY - minY;
float zWidth = maxZ - minZ;
box.dimensions.x = xWidth / 2;
box.dimensions.y = yWidth / 2;
box.dimensions.z = zWidth / 2;
//hsMatrix44 mat;
//box.localPose.getRowMajor44(&mat.fMap[0][0]);
hsPoint3 trans(minX + (xWidth / 2), minY + (yWidth / 2), minZ + (zWidth / 2));
//mat.SetTranslate(&trans);
//box.localPose.setRowMajor44(&mat.fMap[0][0]);
hsMatrix44 boxL2W;
boxL2W.Reset();
boxL2W.SetTranslate(&trans);
plPXConvert::Matrix(boxL2W, box.localPose);
}
void plPXPhysical::IMakeHull(NxConvexMesh* convexMesh, hsMatrix44 l2w)
{
NxConvexMeshDesc desc;
convexMesh->saveToDesc(desc);
// make sure there are some triangles to work with
if (desc.numTriangles == 0)
return;
// get rid of any we may have already had
if (fSaveTriangles)
delete [] fSaveTriangles;
fHullNumberPlanes = desc.numTriangles;
fSaveTriangles = new hsPoint3[fHullNumberPlanes*3];
for (int i = 0; i < desc.numTriangles; i++)
{
uint32_t* triangle = (uint32_t*)(((char*)desc.triangles) + desc.triangleStrideBytes*i);
float* vertex1 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[0]);
float* vertex2 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[1]);
float* vertex3 = (float*)(((char*)desc.points) + desc.pointStrideBytes*triangle[2]);
hsPoint3 pt1(vertex1[0],vertex1[1],vertex1[2]);
hsPoint3 pt2(vertex2[0],vertex2[1],vertex2[2]);
hsPoint3 pt3(vertex3[0],vertex3[1],vertex3[2]);
fSaveTriangles[(i*3)+0] = pt1;
fSaveTriangles[(i*3)+1] = pt2;
fSaveTriangles[(i*3)+2] = pt3;
}
}
void plPXPhysical::ISetHullToWorldWTriangles()
{
// if we have a detector hull and the world hasn't been updated
if (fWorldHull == nil)
{
fWorldHull = new hsPlane3[fHullNumberPlanes];
// use the local2world from the physics engine so that it matches the transform of the positions from the triggerees
hsMatrix44 l2w;
plPXConvert::Matrix(fActor->getGlobalPose(), l2w);
int i;
for( i = 0; i < fHullNumberPlanes; i++ )
{
hsPoint3 pt1 = fSaveTriangles[i*3];
hsPoint3 pt2 = fSaveTriangles[(i*3)+1];
hsPoint3 pt3 = fSaveTriangles[(i*3)+2];
// local to world translation
pt1 = l2w * pt1;
pt2 = l2w * pt2;
pt3 = l2w * pt3;
hsPlane3 plane(&pt1, &pt2, &pt3);
fWorldHull[i] = plane;
}
}
}
bool plPXPhysical::IsObjectInsideHull(const hsPoint3& pos)
{
if (fSaveTriangles)
{
ISetHullToWorldWTriangles();
int i;
for( i = 0; i < fHullNumberPlanes; i++ )
{
if (!ITestPlane(pos, fWorldHull[i]))
return false;
}
return true;
}
return false;
}
bool plPXPhysical::Should_I_Trigger(bool enter, hsPoint3& pos)
{
// see if we are inside the detector hull, if so, then don't trigger
bool trigger = false;
bool inside = IsObjectInsideHull(pos);
if ( !inside)
{
trigger = true;
fInsideConvexHull = enter;
}
else
{
// catch those rare cases on slow machines that miss the collision before avatar penetrated the face
if (enter && !fInsideConvexHull)
{
#ifdef PHYSX_SAVE_TRIGGERS_WORKAROUND
trigger = true;
fInsideConvexHull = enter;
DetectorLogSpecial("**>Saved a missing enter collision: %s",GetObjectKey()->GetName().c_str());
#else
DetectorLogSpecial("**>Could have saved a missing enter collision: %s",GetObjectKey()->GetName().c_str());
#endif PHYSX_SAVE_TRIGGERS_WORKAROUND
}
}
return trigger;
}
bool plPXPhysical::Init(PhysRecipe& recipe)
{
bool startAsleep = false;
@ -388,29 +230,6 @@ bool plPXPhysical::Init(PhysRecipe& recipe)
}
break;
case plSimDefs::kHullBounds:
// FIXME PHYSX - Remove when hull detection is fixed
// If this is read time (ie, meshStream is nil), turn the convex hull
// into a box. That way the data won't have to change when convex hulls
// actually work right.
if (fGroup == plSimDefs::kGroupDetector && recipe.meshStream == nil)
{
#ifdef USE_BOXES_FOR_DETECTOR_HULLS
MakeBoxFromHull(recipe.convexMesh, boxDesc);
plSimulationMgr::GetInstance()->GetSDK()->releaseConvexMesh(*recipe.convexMesh);
boxDesc.group = fGroup;
actorDesc.shapes.push_back(&boxDesc);
#else
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
// make a hull of planes for testing IsInside
IMakeHull(recipe.convexMesh,recipe.l2s);
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
convexShapeDesc.meshData = recipe.convexMesh;
convexShapeDesc.userData = recipe.meshStream;
convexShapeDesc.group = fGroup;
actorDesc.shapes.pushBack(&convexShapeDesc);
#endif // USE_BOXES_FOR_DETECTOR_HULLS
}
else
{
convexShapeDesc.meshData = recipe.convexMesh;
convexShapeDesc.userData = recipe.meshStream;
@ -669,9 +488,6 @@ void plPXPhysical::IEnable(bool enable)
{
fActor->clearActorFlag(NX_AF_DISABLE_COLLISION);
// PHYSX FIXME - after re-enabling a possible detector, we need to check to see if any avatar is already in the PhysX turdy hull detector region
plSimulationMgr::GetInstance()->UpdateAvatarInDetector(fWorldKey, this);
if (fActor->isDynamic())
fActor->clearBodyFlag(NX_BF_FROZEN);
else

33
Sources/Plasma/PubUtilLib/plPhysX/plPXPhysical.h

@ -156,11 +156,6 @@ public:
virtual uint16_t GetAllLOSDBs() { return fLOSDBs; }
virtual bool IsInLOSDB(uint16_t flag) { return hsCheckBits(fLOSDBs, flag); }
virtual bool DoDetectorHullWorkaround() { return fSaveTriangles ? true : false; }
virtual bool Should_I_Trigger(bool enter, hsPoint3& pos);
virtual bool IsObjectInsideHull(const hsPoint3& pos);
virtual void SetInsideConvexHull(bool inside) { fInsideConvexHull = inside; }
virtual plKey GetWorldKey() const { return fWorldKey; }
virtual plPhysicalSndGroup* GetSoundGroup() const { return fSndGroup; }
@ -201,14 +196,6 @@ protected:
/** Handle messages about our references. */
bool HandleRefMsg(plGenRefMsg * refM);
/////////////////////////////////////////////////////////////
//
// WORLDS, SUBWORLDS && CONTEXTS
//
/////////////////////////////////////////////////////////////
void IConvertGroups(uint32_t memberOf, uint32_t reportsOn, uint32_t collideWith);
/** See if the object is in a valid, non-overlapping position.
A valid overlap is one which is approved by the collision
masking code, i.e. my memberOf has no intersection with your
@ -236,8 +223,6 @@ protected:
// Enable/disable collisions and dynamic movement
void IEnable(bool enable);
void IMakeHull(NxConvexMesh* convexMesh, hsMatrix44 l2w);
NxActor* fActor;
plKey fWorldKey; // either a subworld or nil
@ -251,24 +236,6 @@ protected:
plKey fObjectKey; // the key to our scene object
plKey fSceneNode; // the room we're in
// PHYSX FIXME - need to create a plasma hull so that we can determine if inside
hsPlane3* fWorldHull;
uint32_t fHullNumberPlanes;
hsPoint3* fSaveTriangles;
bool fInsideConvexHull;
void ISetHullToWorldWTriangles();
inline bool ITestPlane(const hsPoint3 &pos, const hsPlane3 &plane)
{
float dis = plane.fN.InnerProduct(pos);
dis += plane.fD;
if (dis == 0.f)
return false;
if( dis >= 0.f )
return false;
return true;
}
// we need to remember the last matrices we sent to the coordinate interface
// so that we can recognize them when we send them back and not reapply them,
// which would reactivate our body. inelegant but effective

137
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp

@ -95,60 +95,18 @@ class SensorReport : public NxUserTriggerReport
if (doReport)
{
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
if ( triggerPhys->DoDetectorHullWorkaround() )
if (status & NX_TRIGGER_ON_ENTER)
{
if (status & NX_TRIGGER_ON_ENTER && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
}
else if (status & NX_TRIGGER_ON_ENTER)
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
}
if (status & NX_TRIGGER_ON_LEAVE && triggerPhys->Should_I_Trigger(status & NX_TRIGGER_ON_ENTER, otherPos) )
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
}
else if (status & NX_TRIGGER_ON_LEAVE)
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("<--Kill collision %s :failed Should I trigger",triggerPhys->GetObjectKey()->GetName().c_str());
}
if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("<--Kill collision %s :failed event(CH)",triggerPhys->GetObjectKey()->GetName().c_str());
}
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision %s enter",triggerPhys->GetObjectKey()->GetName().c_str());
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
}
else
else if (status & NX_TRIGGER_ON_LEAVE)
{
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
if (status & NX_TRIGGER_ON_ENTER)
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
}
if (status & NX_TRIGGER_ON_LEAVE)
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
}
if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
{
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("<--Kill collision %s :failed event",triggerPhys->GetObjectKey()->GetName().c_str());
}
#ifdef USE_PHYSX_CONVEXHULL_WORKAROUND
if (plSimulationMgr::fExtraProfile)
DetectorLogRed("-->Send Collision %s exit",triggerPhys->GetObjectKey()->GetName().c_str());
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
}
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
}
}
} gSensorReport;
@ -459,85 +417,6 @@ void plSimulationMgr::ReleaseScene(plKey world)
}
}
void plSimulationMgr::ISendCollisionMsg(plKey receiver, plKey hitter, bool entering)
{
DetectorLogYellow("Collision: %s is inside %s. Sending an %s msg", hitter ? hitter->GetName().c_str() : "(nil)",
receiver->GetName().c_str(), entering ? "'enter'" : "'exit'");
plCollideMsg* msg = new plCollideMsg;
msg->fOtherKey = hitter;
msg->fEntering = entering;
msg->AddReceiver(receiver);
msg->Send();
}
void plSimulationMgr::UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering)
{
// search thru the actors in a scene looking for convex hull detectors and see if the avatar is inside it
// ... and then send appropiate collision message if needed
NxScene* scene = GetScene(world);
plSceneObject* avObj = plSceneObject::ConvertNoRef(avatar->ObjectIsLoaded());
const plCoordinateInterface* ci = avObj->GetCoordinateInterface();
hsPoint3 soPos = ci->GetWorldPos();
if (scene)
{
uint32_t numActors = scene->getNbActors();
NxActor** actors = scene->getActors();
for (int i = 0; i < numActors; i++)
{
plPXPhysical* physical = (plPXPhysical*)actors[i]->userData;
if (physical && physical->DoDetectorHullWorkaround())
{
if ( physical->IsObjectInsideHull(pos) )
{
physical->SetInsideConvexHull(entering);
// we are entering this world... say we entered this detector
ISendCollisionMsg(physical->GetObjectKey(), avatar, entering);
}
}
}
}
}
void plSimulationMgr::UpdateAvatarInDetector(plKey world, plPXPhysical* detector)
{
// search thru the actors in a scene looking for avatars that might be in the newly enabled detector region
// ... and then send appropiate collision message if needed
if ( detector->DoDetectorHullWorkaround() )
{
NxScene* scene = GetScene(world);
if (scene)
{
uint32_t numActors = scene->getNbActors();
NxActor** actors = scene->getActors();
for (int i = 0; i < numActors; i++)
{
if ( actors[i]->userData == nil )
{
// we go a controller
plPXPhysicalControllerCore* controller = plPXPhysicalControllerCore::GetController(*actors[i]);
if (controller && controller->IsEnabled())
{
plKey avatar = controller->GetOwner();
plSceneObject* avObj = plSceneObject::ConvertNoRef(avatar->ObjectIsLoaded());
const plCoordinateInterface* ci;
if ( avObj && ( ci = avObj->GetCoordinateInterface() ) )
{
if ( detector->IsObjectInsideHull(ci->GetWorldPos()) )
{
detector->SetInsideConvexHull(true);
// we are entering this world... say we entered this detector
ISendCollisionMsg(detector->GetObjectKey(), avatar, true);
}
}
}
}
}
}
}
}
void plSimulationMgr::AddCollisionMsg(plKey hitee, plKey hitter, bool enter)
{
// First, make sure we have no dupes

7
Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h

@ -99,10 +99,6 @@ public:
int GetMaterialIdx(NxScene* scene, float friction, float restitution);
// PHYSX FIXME - walk thru all the convex hull detector regions to see if we are in any... we're either coming or going
void UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering);
void UpdateAvatarInDetector(plKey world, plPXPhysical* detector);
//Fix to Move collision messages and their handling out of the simulation step
void AddCollisionMsg(plKey hitee, plKey hitter, bool entering);
void AddCollisionMsg(plCollideMsg* msg);
@ -122,9 +118,6 @@ protected:
// Walk through the synchronization requests and send them as appropriate.
void IProcessSynchs();
// PHYSX FIXME send a collision message - should only be used with UpdateDetectorsInScene
void ISendCollisionMsg(plKey receiver, plKey hitter, bool entering);
NxPhysicsSDK* fSDK;
plPhysicsSoundMgr* fSoundMgr;

Loading…
Cancel
Save