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. 474
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp
  4. 71
      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.

474
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)
{
hsRefCnt_SafeRef(fMessages[i]);
if (fIsInside)
fMessages[i]->SetCmd(plCameraMsg::kEntering);
else
fMessages[i]->ClearCmd(plCameraMsg::kEntering);
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND plgDispatch::MsgSend(fMessages[i]);
// 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]);
if (fSavedMsgEnterFlag)
{
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
{
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]);
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() fEntering = (pCollMsg->fEntering != 0);
fNumEvals = 0;
fLastEnterEval=-999;
fLastExitEval=-999;
}
// end of (PHYSX BUG WORKAROUND)
#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();
return;
} }
fSavedActivatorMsg = nil;
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;
} }
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
// get rid of any saved messages... this should happen though plCollisionBookKeepingInfo* collisionInfo = new plCollisionBookKeepingInfo(hitter, entering);
if (fSavedActivatorMsg) fCollisionList.push_back(collisionInfo);
{ #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
delete fSavedActivatorMsg; collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
DetectorLog("%s: Killing saved message... shouldn't happen", GetKeyName()); #endif
} }
// 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
/* fSavedActivatorMsg = TRACKED_NEW plActivatorMsg;
fSavedActivatorMsg->AddReceivers(fReceivers);
if (fProxyKey)
fSavedActivatorMsg->fHiteeObj = fProxyKey;
else
fSavedActivatorMsg->fHiteeObj = GetTarget()->GetKey();
fSavedActivatorMsg->fHitterObj = hitter; void plObjectInVolumeDetector::IRegisterForEval()
fSavedActivatorMsg->SetSender(GetKey()); {
fWaitingForEval = true;
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
}
void plObjectInVolumeDetector::ISendTriggerMsg(plKey hitter, bool entering)
{
plActivatorMsg* activatorMsg = new plActivatorMsg();
activatorMsg->SetSender(GetKey());
activatorMsg->AddReceivers(fReceivers);
activatorMsg->fHiteeObj = fProxyKey ? fProxyKey : GetTarget()->GetKey();
activatorMsg->fHitterObj = hitter;
if (entering) if (entering)
{ activatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
//DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName(),fNumEvals);
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
fLastEnterEval = fNumEvals;
}
else else
{ activatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
//DetectorLog("%s: Saving Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
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
plgDispatch::MsgSend(activatorMsg);
// fSavedActivatorMsg = nil;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
} }
/*
void plObjectInVolumeDetector::ISendSavedTriggerMsgs()
{
if (fSavedActivatorMsg)
{
if (fSavedActivatorMsg->fTriggerType == plActivatorMsg::kVolumeEnter)
DetectorLog("%s: Sending Entering volume - Evals=%d", GetKeyName(),fNumEvals);
else
DetectorLog("%s: Sending Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
// we're saving the message to be dispatched later...
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,35 +380,16 @@ 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)
{ IHandleEval(pEval);
//if (fSavedActivatorMsg)
// DetectorLog("%s: InVolumeEval=%d with saved message", GetKeyName(), fNumEvals);
//else
// DetectorLog("%s: InVolumeEval=%d without saved message", GetKeyName(), fNumEvals);
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++) {
plCollisionBookKeepingInfo* collisionInfo = *it;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (plSimulationMgr::GetInstance()->GetStepCount() - collisionInfo->fLastStep > 1)
{ {
bool alreadyInside; #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
ResidentSet::iterator HitIt; bool wasInside = fCurrentResidents.find(collisionInfo->fHitter) != fCurrentResidents.end();
HitIt = fCurrentResidents.find((*it)->hitter); if (collisionInfo->fEntering != wasInside)
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());
delete actout;
}
}
else
{ {
//fSubStepCurState says we are outside if (collisionInfo->fEntering)
if(alreadyInside) {
{//we are actuall exiting fCurrentResidents.insert(collisionInfo->fHitter);
actout->SetTriggerType(plActivatorMsg::kVolumeExit); DetectorLog("%s: Sending Volume Enter ActivatorMsg", GetKeyName());
fCurrentResidents.erase((*it)->hitter); ISendTriggerMsg(collisionInfo->fHitter, true);
actout->AddReceivers(fReceivers); }
actout->Send(); else
DetectorLog("%s sent an Exit ActivatorMsg. To: %s", GetKeyName(), GetTarget()->GetKeyName()); {
} fCurrentResidents.erase(collisionInfo->fHitter);
else DetectorLog("%s: Sending Volume Exit ActivatorMsg", GetKeyName());
{ ISendTriggerMsg(collisionInfo->fHitter, false);
DetectorLog("%s squelched an Exit ActivatorMsg.", GetKeyName()); }
delete actout;
}
} }
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);
}
DetectorLog("This is the regions inhabitants after the op");
for(ResidentSet::iterator it = fCurrentResidents.begin(); it!= fCurrentResidents.end(); it++)
{ {
DetectorLog("%s", (*it)->GetName()); ++it;
} }
DetectorLog("*********"); #else
++it;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
fCollisionList.clear(); #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (fCollisionList.empty())
{
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false;
}
#else
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);
} }
} }

71
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& key, bool entering)
plCollisionBookKeepingInfo(plKey& hit) : fHitter(key), fEntering(entering) { }
{
hitter=hit; plKey fHitter;
enters=0; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
exits=0; UInt32 fLastStep;
} #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
~plCollisionBookKeepingInfo() 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; }
plObjectInVolumeDetector(Int8 i){fType = i;fWaitingForEval=false;fSavedActivatorMsg=nil;}
virtual ~plObjectInVolumeDetector(){;} 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;
bool fIsInside;
bool fSavingSendMsg; #ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
bool fSavedMsgEnterFlag; UInt32 fLastStep;
int fNumEvals; #endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
int fLastEnterEval; bool fIsInside;
int fLastExitEval; bool fEntering;
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false); virtual void ISendTriggerMsg();
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