Browse Source

Rework PhysX collision flutter bug workaround

To better handle erroneous trigger events under the new timing method, use the number
of times the simulation has actually advanced instead of the number of evals received.

Cleaned up a bit.
avatar-physics
Skoader 12 years ago
parent
commit
7a47e52ac6
  1. 3
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp
  2. 4
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h
  3. 444
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
  4. 65
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h

3
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.cpp

@ -355,6 +355,7 @@ plSimulationMgr::plSimulationMgr()
, fMaxDelta(kDefaultMaxDelta) , fMaxDelta(kDefaultMaxDelta)
, fStepSize(kDefaultStepSize) , fStepSize(kDefaultStepSize)
, fAccumulator(0.0f) , fAccumulator(0.0f)
, fStepCount(0)
, fLOSDispatch(TRACKED_NEW plLOSDispatch()) , fLOSDispatch(TRACKED_NEW plLOSDispatch())
, fSoundMgr(new plPhysicsSoundMgr) , fSoundMgr(new plPhysicsSoundMgr)
, fLog(nil) , fLog(nil)
@ -609,6 +610,8 @@ void plSimulationMgr::Advance(float delSecs)
fAccumulator = fMaxDelta; fAccumulator = fMaxDelta;
} }
++fStepCount;
// Perform as many whole substeps as possible saving the remainder in our accumulator. // Perform as many whole substeps as possible saving the remainder in our accumulator.
int numSubSteps = (int)(fAccumulator / fStepSize + 0.000001f); int numSubSteps = (int)(fAccumulator / fStepSize + 0.000001f);
float delta = numSubSteps * fStepSize; float delta = numSubSteps * fStepSize;

4
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysX/plSimulationMgr.h

@ -99,6 +99,8 @@ public:
int GetMaterialIdx(NxScene* scene, hsScalar friction, hsScalar restitution); int GetMaterialIdx(NxScene* scene, hsScalar friction, hsScalar restitution);
UInt32 GetStepCount() { return fStepCount; }
// PHYSX FIXME - walk thru all the convex hull detector regions to see if we are in any... we're either coming or going // 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 UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering);
void UpdateAvatarInDetector(plKey world, plPXPhysical* detector); void UpdateAvatarInDetector(plKey world, plPXPhysical* detector);
@ -161,6 +163,8 @@ protected:
float fStepSize; float fStepSize;
float fAccumulator; float fAccumulator;
UInt32 fStepCount;
// A utility class to keep track of a request for a physical synchronization. // A utility class to keep track of a request for a physical synchronization.
// These requests must pass a certain criteria (see the code for the latest) // These requests must pass a certain criteria (see the code for the latest)
// before they are actually either sent over the network or rejected. // before they are actually either sent over the network or rejected.

444
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp

@ -68,8 +68,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "../plModifier/plDetectorLog.h" #include "../plModifier/plDetectorLog.h"
#define USE_PHYSX_MULTIPLE_CAMREGION_ENTER 1 #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
#define USE_PHYSX_COLLISION_FLUTTER_WORKAROUND 1 #include "../plPhysX/plSimulationMgr.h"
#endif
plArmatureMod* plCollisionDetector::IGetAvatarModifier(plKey key) plArmatureMod* plCollisionDetector::IGetAvatarModifier(plKey key)
{ {
@ -245,127 +246,40 @@ plCameraRegionDetector::~plCameraRegionDetector()
fMessages.SetCountAndZero(0); fMessages.SetCountAndZero(0);
} }
void plCameraRegionDetector::ITrigger(plKey hitter, bool entering, bool immediate) void plCameraRegionDetector::ISendTriggerMsg()
{ {
for (int i = 0; i < fMessages.Count(); ++i)
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
if (entering && fNumEvals - fLastExitEval <= 1 && fSavingSendMsg)
{
DetectorLog("%s: Skipping Camera Entering volume", GetKeyName());
fLastEnterEval = fNumEvals;
if (fSavingSendMsg)
{
DetectorLog("%s: Dumping saved Camera Exiting volume", GetKeyName());
}
fSavingSendMsg = false;
return;
}
if (!entering && fNumEvals - fLastEnterEval <= 1 && fSavingSendMsg)
{
DetectorLog("%s: Skipping Exiting volume", GetKeyName());
fLastExitEval = fNumEvals;
if (fSavingSendMsg)
{ {
DetectorLog("%s: Dumping saved Camera Entering volume", GetKeyName());
}
fSavingSendMsg = false;
return;
}
// get rid of any saved messages... this should happen though
if (fSavingSendMsg)
{
DetectorLog("%s: Killing saved camera message... shouldn't happen", GetKeyName());
}
// end PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
fSavingSendMsg = true;
fSavedMsgEnterFlag = entering;
if (entering)
{
//DetectorLog("%s: Saving camera Entering volume - Evals=%d", GetKeyName(),fNumEvals);
fLastEnterEval = fNumEvals;
}
else
{
//DetectorLog("%s: Saving camera Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
fLastExitEval = fNumEvals;
}
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
// we're saving the message to be dispatched later...
if (immediate)
{
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
ISendSavedTriggerMsgs();
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
void plCameraRegionDetector::ISendSavedTriggerMsgs()
{
if (fSavingSendMsg)
{
for (int i = 0; i < fMessages.Count(); i++)
{
char str[256];
hsRefCnt_SafeRef(fMessages[i]); hsRefCnt_SafeRef(fMessages[i]);
if (fSavedMsgEnterFlag) if (fIsInside)
{
fMessages[i]->SetCmd(plCameraMsg::kEntering); fMessages[i]->SetCmd(plCameraMsg::kEntering);
sprintf(str, "Entering cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName(),fNumEvals,i+1,fMessages.Count());
fIsInside = true;
}
else else
{
fMessages[i]->ClearCmd(plCameraMsg::kEntering); fMessages[i]->ClearCmd(plCameraMsg::kEntering);
sprintf(str, "Exiting cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName(),fNumEvals,i+1,fMessages.Count());
fIsInside = false;
}
plgDispatch::MsgSend(fMessages[i]); plgDispatch::MsgSend(fMessages[i]);
DetectorLog("%s", str);
} }
}
fSavingSendMsg = false;
} }
hsBool plCameraRegionDetector::MsgReceive(plMessage* msg) hsBool plCameraRegionDetector::MsgReceive(plMessage* msg)
{ {
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg); plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
if (pCollMsg) if (pCollMsg)
{ {
// camera collisions are only for the local player // camera collisions are only for the local player
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey) if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
return true; return true;
#ifdef USE_PHYSX_MULTIPLE_CAMREGION_ENTER
// first determine if this is a multiple camera region enter (PHYSX BUG WORKAROUND)
if (!fWaitingForEval) if (!fWaitingForEval)
{//plObjectInVolumeCollisionDetector::MsgReceive() will flip fWaitingForEval IRegisterForEval();
// and registers for the Eval, child objects of plObjectInVolumeCollisionDetector
//must decide when they are no longer interested in Evals. I suggest using IHandleEvals()
fNumEvals = 0;
fLastEnterEval=-999;
fLastExitEval=-999;
}
// end of (PHYSX BUG WORKAROUND) fEntering = (pCollMsg->fEntering != 0);
#endif // USE_PHYSX_MULTIPLE_CAMREG_ENTER
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
#endif
return true;
} }
return plObjectInVolumeDetector::MsgReceive(msg); return plObjectInVolumeDetector::MsgReceive(msg);
} }
void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr) void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
@ -388,22 +302,24 @@ void plCameraRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
mgr->WriteCreatable( stream, fMessages[i] ); mgr->WriteCreatable( stream, fMessages[i] );
} }
void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
void plCameraRegionDetector::IHandleEval(plEvalMsg*)
{ {
fNumEvals++; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (fNumEvals - fLastEnterEval > 1 && fNumEvals-fLastExitEval>1) if (plSimulationMgr::GetInstance()->GetStepCount() - fLastStep > 1)
{ {
ISendSavedTriggerMsgs(); #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (fIsInside != fEntering)
{
fIsInside = fEntering;
DetectorLog("%s CameraRegion: %s", fIsInside ? "Entering" : "Exiting", GetKeyName());
ISendTriggerMsg();
}
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey()); plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false; fWaitingForEval = false;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
} }
else #endif
{
if(fSavedActivatorMsg)
DetectorLog("%s didn't send its message. fNumEvals=%d fLastEnterEval=%d, fLastExit=%d",
GetKeyName(),fNumEvals, fLastEnterEval, fLastExitEval);
}
} }
///////////////////////////////// /////////////////////////////////
@ -412,182 +328,49 @@ void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
///////////////////////////////// /////////////////////////////////
// object-in-volume detector // object-in-volume detector
void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering, bool immediate) void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering)
{ {
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame for (bookKeepingList::iterator it = fCollisionList.begin(); it != fCollisionList.end(); ++it)
/* if (entering && fNumEvals - fLastExitEval <= 1 && fSavedActivatorMsg)
{ {
//DetectorLog("%s: Skipping Entering volume", GetKeyName()); plCollisionBookKeepingInfo* collisionInfo = *it;
fLastEnterEval = fNumEvals; if (collisionInfo->fHitter == hitter)
if (fSavedActivatorMsg)
{ {
//DetectorLog("%s: Dumping saved Exiting volume", GetKeyName()); collisionInfo->fEntering = entering;
delete fSavedActivatorMsg; collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
}
fSavedActivatorMsg = nil;
return; return;
} }
if (!entering && fNumEvals - fLastEnterEval <= 1 && fSavedActivatorMsg)
{
//DetectorLog("%s: Skipping Exiting volume", GetKeyName());
fLastExitEval = fNumEvals;
if (fSavedActivatorMsg)
{
//DetectorLog("%s: Dumping saved Entering volume", GetKeyName());
delete fSavedActivatorMsg;
}
fSavedActivatorMsg = nil;
return;
}
// get rid of any saved messages... this should happen though
if (fSavedActivatorMsg)
{
delete fSavedActivatorMsg;
DetectorLog("%s: Killing saved message... shouldn't happen", GetKeyName());
}
// end PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
*/
if(!immediate)
{
bookKeepingList::iterator curit=fCollisionList.begin();
while(curit!=fCollisionList.end())
{
if(hitter==(*curit)->hitter)
{//hey the object is already in my list
//try and figure out what my real state is
if(entering)
{
(*curit)->enters++;
if(!(*curit)->fSubStepCurState)
{//We weren't already in
(*curit)->fSubStepCurState =true;
}
}
else
{
(*curit)->exits++;
if((*curit)->fSubStepCurState)
{//We were already in
(*curit)->fSubStepCurState =false;
}
}
//get out
break;
}
curit++;
}
if(curit==fCollisionList.end())
{
//hitter was not in the list add him in
//hitter was not in the current frame list
//lets find out its state in the begining of the frame
ResidentSet::iterator curres = fCurrentResidents.find(hitter);
bool initialState;
if(curres != fCurrentResidents.end())
initialState =true;
else
initialState =false;
plCollisionBookKeepingInfo* BookKeeper=TRACKED_NEW plCollisionBookKeepingInfo(hitter);
if(entering)
{
BookKeeper->enters++;
BookKeeper->fSubStepCurState =true;
}
else
{
BookKeeper->exits++;
BookKeeper->fSubStepCurState =false;
}
fCollisionList.push_front(BookKeeper);
}
}
else
{
plActivatorMsg* ActivatorMsg = TRACKED_NEW plActivatorMsg;
ActivatorMsg->AddReceivers(fReceivers);
if (fProxyKey)
ActivatorMsg->fHiteeObj = fProxyKey;
else
ActivatorMsg->fHiteeObj = GetTarget()->GetKey();
ActivatorMsg->fHitterObj = hitter;
ActivatorMsg->SetSender(GetKey());
if (entering)
{
ActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
}
else
{
ActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
}
plgDispatch::MsgSend(ActivatorMsg);
} }
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
/* fSavedActivatorMsg = TRACKED_NEW plActivatorMsg; plCollisionBookKeepingInfo* collisionInfo = new plCollisionBookKeepingInfo(hitter, entering);
fCollisionList.push_back(collisionInfo);
fSavedActivatorMsg->AddReceivers(fReceivers);
if (fProxyKey)
fSavedActivatorMsg->fHiteeObj = fProxyKey;
else
fSavedActivatorMsg->fHiteeObj = GetTarget()->GetKey();
fSavedActivatorMsg->fHitterObj = hitter;
fSavedActivatorMsg->SetSender(GetKey());
if (entering)
{
//DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName(),fNumEvals);
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
fLastEnterEval = fNumEvals;
}
else
{
//DetectorLog("%s: Saving Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
fLastExitEval = fNumEvals;
}
*/
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
// we're saving the message to be dispatched later... #endif
if (immediate) }
{
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// fSavedActivatorMsg = nil;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND void plObjectInVolumeDetector::IRegisterForEval()
} {
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND fWaitingForEval = true;
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
} }
/*
void plObjectInVolumeDetector::ISendSavedTriggerMsgs() void plObjectInVolumeDetector::ISendTriggerMsg(plKey hitter, bool entering)
{ {
if (fSavedActivatorMsg) plActivatorMsg* activatorMsg = new plActivatorMsg();
{ activatorMsg->SetSender(GetKey());
if (fSavedActivatorMsg->fTriggerType == plActivatorMsg::kVolumeEnter) activatorMsg->AddReceivers(fReceivers);
DetectorLog("%s: Sending Entering volume - Evals=%d", GetKeyName(),fNumEvals); activatorMsg->fHiteeObj = fProxyKey ? fProxyKey : GetTarget()->GetKey();
activatorMsg->fHitterObj = hitter;
if (entering)
activatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
else else
DetectorLog("%s: Sending Exiting volume - Evals=%d", GetKeyName(),fNumEvals); activatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
// we're saving the message to be dispatched later... plgDispatch::MsgSend(activatorMsg);
plgDispatch::MsgSend(fSavedActivatorMsg);
}
fSavedActivatorMsg = nil;
} }
*/
hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg) hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
{ {
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg); plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
@ -597,36 +380,17 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
if (IIsDisabledAvatar(pCollMsg->fOtherKey)) if (IIsDisabledAvatar(pCollMsg->fOtherKey))
return false; return false;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
if (!fWaitingForEval) if (!fWaitingForEval)
{ IRegisterForEval();
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = true;
}
// end PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
ITrigger(pCollMsg->fOtherKey, (pCollMsg->fEntering != 0));
ITrigger(pCollMsg->fOtherKey, (pCollMsg->fEntering != 0));
return true; return true;
} }
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
plEvalMsg* pEval = plEvalMsg::ConvertNoRef(msg); plEvalMsg* pEval = plEvalMsg::ConvertNoRef(msg);
if (pEval) if (pEval)
{
//if (fSavedActivatorMsg)
// DetectorLog("%s: InVolumeEval=%d with saved message", GetKeyName(), fNumEvals);
//else
// DetectorLog("%s: InVolumeEval=%d without saved message", GetKeyName(), fNumEvals);
IHandleEval(pEval); IHandleEval(pEval);
}
// end PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
plPlayerPageMsg* pageMsg = plPlayerPageMsg::ConvertNoRef(msg); plPlayerPageMsg* pageMsg = plPlayerPageMsg::ConvertNoRef(msg);
if (pageMsg && pageMsg->fUnload) if (pageMsg && pageMsg->fUnload)
{ {
@ -636,73 +400,57 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
return plCollisionDetector::MsgReceive(msg); return plCollisionDetector::MsgReceive(msg);
} }
void plObjectInVolumeDetector::IHandleEval(plEvalMsg* pEval) void plObjectInVolumeDetector::IHandleEval(plEvalMsg*)
{ {
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey()); bookKeepingList::iterator it = fCollisionList.begin();
fWaitingForEval = false; while (it != fCollisionList.end())
for(bookKeepingList::reverse_iterator it= fCollisionList.rbegin();it!=fCollisionList.rend(); it++)
{
bool alreadyInside;
ResidentSet::iterator HitIt;
HitIt = fCurrentResidents.find((*it)->hitter);
if(HitIt != fCurrentResidents.end()) alreadyInside = true;
else alreadyInside=false;
plActivatorMsg* actout=TRACKED_NEW plActivatorMsg;
actout->fHitterObj=((*it)->hitter);
actout->SetSender(GetKey());
if (fProxyKey)
actout->fHiteeObj = fProxyKey;
else
actout->fHiteeObj = GetTarget()->GetKey();
if((*it)->fSubStepCurState)//current substate says we are entered
{//different enters and exits
//figure out what to do
if(!alreadyInside)
{//we are actuall entering
actout->SetTriggerType(plActivatorMsg::kVolumeEnter);
fCurrentResidents.insert((*it)->hitter);
actout->AddReceivers(fReceivers);
actout->Send();
DetectorLog("%s sent an Enter ActivatorMsg. To: %s", GetKeyName(), GetTarget()->GetKeyName() );
}
else
{ {
DetectorLog("%s squelched an Enter ActivatorMsg.", GetKeyName()); plCollisionBookKeepingInfo* collisionInfo = *it;
delete actout; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
} if (plSimulationMgr::GetInstance()->GetStepCount() - collisionInfo->fLastStep > 1)
}
else
{ {
//fSubStepCurState says we are outside #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if(alreadyInside) bool wasInside = fCurrentResidents.find(collisionInfo->fHitter) != fCurrentResidents.end();
{//we are actuall exiting if (collisionInfo->fEntering != wasInside)
actout->SetTriggerType(plActivatorMsg::kVolumeExit); {
fCurrentResidents.erase((*it)->hitter); if (collisionInfo->fEntering)
actout->AddReceivers(fReceivers); {
actout->Send(); fCurrentResidents.insert(collisionInfo->fHitter);
DetectorLog("%s sent an Exit ActivatorMsg. To: %s", GetKeyName(), GetTarget()->GetKeyName()); DetectorLog("%s: Sending Volume Enter ActivatorMsg", GetKeyName());
ISendTriggerMsg(collisionInfo->fHitter, true);
} }
else else
{ {
DetectorLog("%s squelched an Exit ActivatorMsg.", GetKeyName()); fCurrentResidents.erase(collisionInfo->fHitter);
delete actout; DetectorLog("%s: Sending Volume Exit ActivatorMsg", GetKeyName());
ISendTriggerMsg(collisionInfo->fHitter, false);
} }
} }
delete collisionInfo;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
it = fCollisionList.erase(it);
} }
DetectorLog("*********"); else
for(bookKeepingList::iterator it = fCollisionList.begin(); it != fCollisionList.end(); it ++)
{ {
delete (*it); ++it;
} }
DetectorLog("This is the regions inhabitants after the op"); #else
for(ResidentSet::iterator it = fCurrentResidents.begin(); it!= fCurrentResidents.end(); it++) ++it;
{ #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
DetectorLog("%s", (*it)->GetName());
} }
DetectorLog("*********");
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (fCollisionList.empty())
{
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false;
}
#else
fCollisionList.clear(); fCollisionList.clear();
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
} }
void plObjectInVolumeDetector::SetTarget(plSceneObject* so) void plObjectInVolumeDetector::SetTarget(plSceneObject* so)
@ -780,13 +528,13 @@ void plObjectInVolumeAndFacingDetector::ICheckForTrigger()
{ {
DetectorLog("%s: Trigger InVolume&Facing", GetKeyName()); DetectorLog("%s: Trigger InVolume&Facing", GetKeyName());
fTriggered = true; fTriggered = true;
ITrigger(avatar->GetKey(), true, true); ISendTriggerMsg(avatar->GetKey(), true);
} }
else if (!facing && fTriggered) else if (!facing && fTriggered)
{ {
DetectorLog("%s: Untrigger InVolume&Facing", GetKeyName()); DetectorLog("%s: Untrigger InVolume&Facing", GetKeyName());
fTriggered = false; fTriggered = false;
ITrigger(avatar->GetKey(), false, true); ISendTriggerMsg(avatar->GetKey(), false);
} }
} }
} }
@ -820,7 +568,7 @@ hsBool plObjectInVolumeAndFacingDetector::MsgReceive(plMessage* msg)
if (fTriggered) if (fTriggered)
{ {
fTriggered = false; fTriggered = false;
ITrigger(plNetClientApp::GetInstance()->GetLocalPlayerKey(), false, true); ISendTriggerMsg(plNetClientApp::GetInstance()->GetLocalPlayerKey(), false);
} }
} }

65
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h

@ -53,6 +53,8 @@ class plArmatureMod;
class plActivatorMsg; class plActivatorMsg;
class plEvalMsg; class plEvalMsg;
#define USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
class plCollisionDetector : public plDetectorModifier class plCollisionDetector : public plDetectorModifier
{ {
protected: protected:
@ -90,34 +92,26 @@ public:
// sub type for object-in-volume detectors // sub type for object-in-volume detectors
class plObjectInVolumeDetector : public plCollisionDetector class plObjectInVolumeDetector : public plCollisionDetector
{ {
public: protected:
class plCollisionBookKeepingInfo class plCollisionBookKeepingInfo
{ {
friend plObjectInVolumeDetector;
public: public:
plCollisionBookKeepingInfo(plKey& hit) plCollisionBookKeepingInfo(plKey& key, bool entering)
{ : fHitter(key), fEntering(entering) { }
hitter=hit;
enters=0; plKey fHitter;
exits=0; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
} UInt32 fLastStep;
~plCollisionBookKeepingInfo() #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
{ bool fEntering;
hitter=nil;
}
protected:
plKey hitter;
int enters,exits;
bool fSubStepCurState;
}; };
protected:
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false); virtual void ITrigger(plKey hitter, bool entering);
//virtual void ISendSavedTriggerMsgs(); virtual void ISendTriggerMsg(plKey hitter, bool entering);
virtual void IRegisterForEval();
virtual void IHandleEval(plEvalMsg* pEval); virtual void IHandleEval(plEvalMsg* pEval);
bool fWaitingForEval; bool fWaitingForEval;
plActivatorMsg* fSavedActivatorMsg;
typedef std::list<plCollisionBookKeepingInfo*> bookKeepingList; typedef std::list<plCollisionBookKeepingInfo*> bookKeepingList;
bookKeepingList fCollisionList; bookKeepingList fCollisionList;
typedef std::set<plKey> ResidentSet; typedef std::set<plKey> ResidentSet;
@ -126,12 +120,12 @@ protected:
public: public:
plObjectInVolumeDetector() plObjectInVolumeDetector()
{ : plCollisionDetector(), fWaitingForEval(false) { }
fWaitingForEval=false;fSavedActivatorMsg=nil;
plObjectInVolumeDetector(Int8 i)
: plCollisionDetector(), fWaitingForEval(false) { fType = i; }
} virtual ~plObjectInVolumeDetector() { }
plObjectInVolumeDetector(Int8 i){fType = i;fWaitingForEval=false;fSavedActivatorMsg=nil;}
virtual ~plObjectInVolumeDetector(){;}
virtual hsBool MsgReceive(plMessage* msg); virtual hsBool MsgReceive(plMessage* msg);
@ -178,18 +172,19 @@ class plCameraRegionDetector : public plObjectInVolumeDetector
{ {
protected: protected:
hsTArray<plCameraMsg*> fMessages; hsTArray<plCameraMsg*> fMessages;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
UInt32 fLastStep;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
bool fIsInside; bool fIsInside;
bool fSavingSendMsg; bool fEntering;
bool fSavedMsgEnterFlag;
int fNumEvals; virtual void ISendTriggerMsg();
int fLastEnterEval;
int fLastExitEval;
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
virtual void ISendSavedTriggerMsgs();
virtual void IHandleEval(plEvalMsg* pEval); virtual void IHandleEval(plEvalMsg* pEval);
public: public:
plCameraRegionDetector(){ fIsInside = false; fSavingSendMsg = false; } plCameraRegionDetector()
: plObjectInVolumeDetector(), fIsInside(false) { }
~plCameraRegionDetector(); ~plCameraRegionDetector();
virtual hsBool MsgReceive(plMessage* msg); virtual hsBool MsgReceive(plMessage* msg);

Loading…
Cancel
Save