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. 438
      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)
, fStepSize(kDefaultStepSize)
, fAccumulator(0.0f)
, fStepCount(0)
, fLOSDispatch(TRACKED_NEW plLOSDispatch())
, fSoundMgr(new plPhysicsSoundMgr)
, fLog(nil)
@ -609,6 +610,8 @@ void plSimulationMgr::Advance(float delSecs)
fAccumulator = fMaxDelta;
}
++fStepCount;
// Perform as many whole substeps as possible saving the remainder in our accumulator.
int numSubSteps = (int)(fAccumulator / fStepSize + 0.000001f);
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);
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
void UpdateDetectorsInScene(plKey world, plKey avatar, hsPoint3& pos, bool entering);
void UpdateAvatarInDetector(plKey world, plPXPhysical* detector);
@ -161,6 +163,8 @@ protected:
float fStepSize;
float fAccumulator;
UInt32 fStepCount;
// 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)
// before they are actually either sent over the network or rejected.

438
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"
#define USE_PHYSX_MULTIPLE_CAMREGION_ENTER 1
#define USE_PHYSX_COLLISION_FLUTTER_WORKAROUND 1
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
#include "../plPhysX/plSimulationMgr.h"
#endif
plArmatureMod* plCollisionDetector::IGetAvatarModifier(plKey key)
{
@ -245,127 +246,40 @@ plCameraRegionDetector::~plCameraRegionDetector()
fMessages.SetCountAndZero(0);
}
void plCameraRegionDetector::ITrigger(plKey hitter, bool entering, bool immediate)
{
#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)
void plCameraRegionDetector::ISendTriggerMsg()
{
DetectorLog("%s: Skipping Exiting volume", GetKeyName());
fLastExitEval = fNumEvals;
if (fSavingSendMsg)
for (int i = 0; i < fMessages.Count(); ++i)
{
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)
{
if (fIsInside)
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)
{
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
if (pCollMsg)
{
// camera collisions are only for the local player
if (plNetClientApp::GetInstance()->GetLocalPlayerKey() != pCollMsg->fOtherKey)
return true;
#ifdef USE_PHYSX_MULTIPLE_CAMREGION_ENTER
// first determine if this is a multiple camera region enter (PHYSX BUG WORKAROUND)
if (!fWaitingForEval)
{//plObjectInVolumeCollisionDetector::MsgReceive() will flip fWaitingForEval
// and registers for the Eval, child objects of plObjectInVolumeCollisionDetector
//must decide when they are no longer interested in Evals. I suggest using IHandleEvals()
IRegisterForEval();
fNumEvals = 0;
fLastEnterEval=-999;
fLastExitEval=-999;
}
// end of (PHYSX BUG WORKAROUND)
#endif // USE_PHYSX_MULTIPLE_CAMREG_ENTER
fEntering = (pCollMsg->fEntering != 0);
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
#endif
return true;
}
return plObjectInVolumeDetector::MsgReceive(msg);
}
void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
@ -388,22 +302,24 @@ void plCameraRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
mgr->WriteCreatable( stream, fMessages[i] );
}
void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
void plCameraRegionDetector::IHandleEval(plEvalMsg*)
{
fNumEvals++;
if (fNumEvals - fLastEnterEval > 1 && fNumEvals-fLastExitEval>1)
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (plSimulationMgr::GetInstance()->GetStepCount() - fLastStep > 1)
{
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (fIsInside != fEntering)
{
ISendSavedTriggerMsgs();
fIsInside = fEntering;
DetectorLog("%s CameraRegion: %s", fIsInside ? "Entering" : "Exiting", GetKeyName());
ISendTriggerMsg();
}
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
else
{
if(fSavedActivatorMsg)
DetectorLog("%s didn't send its message. fNumEvals=%d fLastEnterEval=%d, fLastExit=%d",
GetKeyName(),fNumEvals, fLastEnterEval, fLastExitEval);
}
#endif
}
/////////////////////////////////
@ -412,182 +328,49 @@ void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
/////////////////////////////////
// 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
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
/* if (entering && fNumEvals - fLastExitEval <= 1 && fSavedActivatorMsg)
{
//DetectorLog("%s: Skipping Entering volume", GetKeyName());
fLastEnterEval = fNumEvals;
if (fSavedActivatorMsg)
{
//DetectorLog("%s: Dumping saved Exiting volume", GetKeyName());
delete fSavedActivatorMsg;
}
fSavedActivatorMsg = nil;
return;
}
if (!entering && fNumEvals - fLastEnterEval <= 1 && fSavedActivatorMsg)
for (bookKeepingList::iterator it = fCollisionList.begin(); it != fCollisionList.end(); ++it)
{
//DetectorLog("%s: Skipping Exiting volume", GetKeyName());
fLastExitEval = fNumEvals;
if (fSavedActivatorMsg)
plCollisionBookKeepingInfo* collisionInfo = *it;
if (collisionInfo->fHitter == hitter)
{
//DetectorLog("%s: Dumping saved Entering volume", GetKeyName());
delete fSavedActivatorMsg;
}
fSavedActivatorMsg = nil;
collisionInfo->fEntering = entering;
collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
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)
{
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
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++;
plCollisionBookKeepingInfo* collisionInfo = new plCollisionBookKeepingInfo(hitter, entering);
fCollisionList.push_back(collisionInfo);
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
collisionInfo->fLastStep = plSimulationMgr::GetInstance()->GetStepCount();
#endif
}
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)
void plObjectInVolumeDetector::IRegisterForEval()
{
BookKeeper->enters++;
BookKeeper->fSubStepCurState =true;
}
else
{
BookKeeper->exits++;
BookKeeper->fSubStepCurState =false;
}
fCollisionList.push_front(BookKeeper);
}
fWaitingForEval = true;
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
}
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
void plObjectInVolumeDetector::ISendTriggerMsg(plKey hitter, bool entering)
{
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;
fSavedActivatorMsg->SetSender(GetKey());
plActivatorMsg* activatorMsg = new plActivatorMsg();
activatorMsg->SetSender(GetKey());
activatorMsg->AddReceivers(fReceivers);
activatorMsg->fHiteeObj = fProxyKey ? fProxyKey : GetTarget()->GetKey();
activatorMsg->fHitterObj = hitter;
if (entering)
{
//DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName(),fNumEvals);
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
fLastEnterEval = fNumEvals;
}
activatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
else
{
//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
// fSavedActivatorMsg = nil;
activatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
plgDispatch::MsgSend(activatorMsg);
}
/*
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)
{
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
@ -597,36 +380,17 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
if (IIsDisabledAvatar(pCollMsg->fOtherKey))
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)
{
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));
IRegisterForEval();
ITrigger(pCollMsg->fOtherKey, (pCollMsg->fEntering != 0));
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);
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);
}
// 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);
if (pageMsg && pageMsg->fUnload)
{
@ -636,73 +400,57 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
return plCollisionDetector::MsgReceive(msg);
}
void plObjectInVolumeDetector::IHandleEval(plEvalMsg* pEval)
void plObjectInVolumeDetector::IHandleEval(plEvalMsg*)
{
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
fWaitingForEval = false;
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
bookKeepingList::iterator it = fCollisionList.begin();
while (it != fCollisionList.end())
{
DetectorLog("%s squelched an Enter ActivatorMsg.", GetKeyName());
delete actout;
}
}
else
plCollisionBookKeepingInfo* collisionInfo = *it;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
if (plSimulationMgr::GetInstance()->GetStepCount() - collisionInfo->fLastStep > 1)
{
//fSubStepCurState says we are outside
if(alreadyInside)
{//we are actuall exiting
actout->SetTriggerType(plActivatorMsg::kVolumeExit);
fCurrentResidents.erase((*it)->hitter);
actout->AddReceivers(fReceivers);
actout->Send();
DetectorLog("%s sent an Exit ActivatorMsg. To: %s", GetKeyName(), GetTarget()->GetKeyName());
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
bool wasInside = fCurrentResidents.find(collisionInfo->fHitter) != fCurrentResidents.end();
if (collisionInfo->fEntering != wasInside)
{
if (collisionInfo->fEntering)
{
fCurrentResidents.insert(collisionInfo->fHitter);
DetectorLog("%s: Sending Volume Enter ActivatorMsg", GetKeyName());
ISendTriggerMsg(collisionInfo->fHitter, true);
}
else
{
DetectorLog("%s squelched an Exit ActivatorMsg.", GetKeyName());
delete actout;
fCurrentResidents.erase(collisionInfo->fHitter);
DetectorLog("%s: Sending Volume Exit ActivatorMsg", GetKeyName());
ISendTriggerMsg(collisionInfo->fHitter, false);
}
}
delete collisionInfo;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
it = fCollisionList.erase(it);
}
DetectorLog("*********");
for(bookKeepingList::iterator it = fCollisionList.begin(); it != fCollisionList.end(); it ++)
else
{
delete (*it);
++it;
}
DetectorLog("This is the regions inhabitants after the op");
for(ResidentSet::iterator it = fCurrentResidents.begin(); it!= fCurrentResidents.end(); it++)
{
DetectorLog("%s", (*it)->GetName());
#else
++it;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
}
DetectorLog("*********");
#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)
@ -780,13 +528,13 @@ void plObjectInVolumeAndFacingDetector::ICheckForTrigger()
{
DetectorLog("%s: Trigger InVolume&Facing", GetKeyName());
fTriggered = true;
ITrigger(avatar->GetKey(), true, true);
ISendTriggerMsg(avatar->GetKey(), true);
}
else if (!facing && fTriggered)
{
DetectorLog("%s: Untrigger InVolume&Facing", GetKeyName());
fTriggered = false;
ITrigger(avatar->GetKey(), false, true);
ISendTriggerMsg(avatar->GetKey(), false);
}
}
}
@ -820,7 +568,7 @@ hsBool plObjectInVolumeAndFacingDetector::MsgReceive(plMessage* msg)
if (fTriggered)
{
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 plEvalMsg;
#define USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
class plCollisionDetector : public plDetectorModifier
{
protected:
@ -90,34 +92,26 @@ public:
// sub type for object-in-volume detectors
class plObjectInVolumeDetector : public plCollisionDetector
{
public:
protected:
class plCollisionBookKeepingInfo
{
friend plObjectInVolumeDetector;
public:
plCollisionBookKeepingInfo(plKey& hit)
{
hitter=hit;
enters=0;
exits=0;
}
~plCollisionBookKeepingInfo()
{
hitter=nil;
}
protected:
plKey hitter;
int enters,exits;
bool fSubStepCurState;
plCollisionBookKeepingInfo(plKey& key, bool entering)
: fHitter(key), fEntering(entering) { }
plKey fHitter;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
UInt32 fLastStep;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
bool fEntering;
};
protected:
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
//virtual void ISendSavedTriggerMsgs();
virtual void ITrigger(plKey hitter, bool entering);
virtual void ISendTriggerMsg(plKey hitter, bool entering);
virtual void IRegisterForEval();
virtual void IHandleEval(plEvalMsg* pEval);
bool fWaitingForEval;
plActivatorMsg* fSavedActivatorMsg;
typedef std::list<plCollisionBookKeepingInfo*> bookKeepingList;
bookKeepingList fCollisionList;
typedef std::set<plKey> ResidentSet;
@ -126,12 +120,12 @@ protected:
public:
plObjectInVolumeDetector()
{
fWaitingForEval=false;fSavedActivatorMsg=nil;
: plCollisionDetector(), fWaitingForEval(false) { }
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);
@ -178,18 +172,19 @@ class plCameraRegionDetector : public plObjectInVolumeDetector
{
protected:
hsTArray<plCameraMsg*> fMessages;
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
UInt32 fLastStep;
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
bool fIsInside;
bool fSavingSendMsg;
bool fSavedMsgEnterFlag;
int fNumEvals;
int fLastEnterEval;
int fLastExitEval;
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
virtual void ISendSavedTriggerMsgs();
bool fEntering;
virtual void ISendTriggerMsg();
virtual void IHandleEval(plEvalMsg* pEval);
public:
plCameraRegionDetector(){ fIsInside = false; fSavingSendMsg = false; }
plCameraRegionDetector()
: plObjectInVolumeDetector(), fIsInside(false) { }
~plCameraRegionDetector();
virtual hsBool MsgReceive(plMessage* msg);

Loading…
Cancel
Save