mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
@ -133,8 +133,10 @@ void plWalkingController::RecalcVelocity(double timeNow, double timePrev, hsBool
|
|||||||
|
|
||||||
if (fController && !fWalkingStrategy->IsOnGround())
|
if (fController && !fWalkingStrategy->IsOnGround())
|
||||||
{
|
{
|
||||||
|
// PhysX Hack: AchievedLinearVelocity is a Cyanic fix for superjumps. LinearVelocity is
|
||||||
|
// always (0,0,0) outside of the controller update proc
|
||||||
fImpactTime = fWalkingStrategy->GetAirTime();
|
fImpactTime = fWalkingStrategy->GetAirTime();
|
||||||
fImpactVelocity = fController->GetLinearVelocity();
|
fImpactVelocity = fController->GetAchievedLinearVelocity();
|
||||||
fClearImpact = false;
|
fClearImpact = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -323,48 +323,7 @@ void plWalkingStrategy::Apply(float delSecs)
|
|||||||
LinearVelocity.fX = AchievedLinearVelocity.fX;
|
LinearVelocity.fX = AchievedLinearVelocity.fX;
|
||||||
LinearVelocity.fY = AchievedLinearVelocity.fY;
|
LinearVelocity.fY = AchievedLinearVelocity.fY;
|
||||||
}
|
}
|
||||||
if (!IsOnGround() || IsOnFalseGround())
|
|
||||||
{
|
|
||||||
// We're not on solid ground, so we should be sliding against whatever
|
|
||||||
// we're hitting (like a rock cliff). Each vector in fSlidingNormals is
|
|
||||||
// the surface normal of a collision that's too steep to be ground, so
|
|
||||||
// we project our current velocity onto that plane and slide along the
|
|
||||||
// wall.
|
|
||||||
//
|
|
||||||
// Also, sometimes PhysX reports a bunch of collisions from the wall,
|
|
||||||
// but nothing from underneath (when there should be). So if we're not
|
|
||||||
// touching ground, we offset the avatar in the direction of the
|
|
||||||
// surface normal(s). This doesn't fix the issue 100%, but it's a hell
|
|
||||||
// of a lot better than nothing, and suitable duct tape until a future
|
|
||||||
// PhysX revision fixes the issue.
|
|
||||||
//
|
|
||||||
// Yes, there's room for optimization here if we care.
|
|
||||||
hsVector3 offset(0.f, 0.f, 0.f);
|
|
||||||
for (int i = 0; i < fContactNormals.GetCount(); i++)
|
|
||||||
{
|
|
||||||
offset += fContactNormals[i];
|
|
||||||
hsVector3 velNorm = LinearVelocity;
|
|
||||||
|
|
||||||
if (velNorm.MagnitudeSquared() > 0)
|
|
||||||
velNorm.Normalize();
|
|
||||||
|
|
||||||
if (velNorm * fContactNormals[i] < 0)
|
|
||||||
{
|
|
||||||
hsVector3 proj = (velNorm % fContactNormals[i]) % fContactNormals[i];
|
|
||||||
if (velNorm * proj < 0)
|
|
||||||
proj *= -1.f;
|
|
||||||
LinearVelocity = LinearVelocity.Magnitude() * proj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (offset.MagnitudeSquared() > 0)
|
|
||||||
{
|
|
||||||
// 5 ft/sec is roughly the speed we walk backwards.
|
|
||||||
// The higher the value, the less likely you'll trip
|
|
||||||
// the bug, and this seems reasonable.
|
|
||||||
offset.Normalize();
|
|
||||||
LinearVelocity += offset * 5.0f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//make terminal velocity equal to k. it is wrong but has been this way and
|
//make terminal velocity equal to k. it is wrong but has been this way and
|
||||||
//don't want to break any puzzles. on top of that it will reduce tunneling behavior
|
//don't want to break any puzzles. on top of that it will reduce tunneling behavior
|
||||||
if(LinearVelocity.fZ<kGravity)LinearVelocity.fZ=kGravity;
|
if(LinearVelocity.fZ<kGravity)LinearVelocity.fZ=kGravity;
|
||||||
|
@ -50,7 +50,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
|
|
||||||
#include "hsQuat.h"
|
#include "hsQuat.h"
|
||||||
#define PHYSX_ONLY_TRIGGER_FROM_KINEMATIC 1
|
#define PHYSX_ONLY_TRIGGER_FROM_KINEMATIC 1
|
||||||
#define kSLOPELIMIT (cosf(hsDegreesToRadians(55.f)))
|
#define kSLOPELIMIT (cosf(hsDegreesToRadians(45.f)))
|
||||||
|
|
||||||
class plCoordinateInterface;
|
class plCoordinateInterface;
|
||||||
class plPhysical;
|
class plPhysical;
|
||||||
|
@ -71,13 +71,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|||||||
|
|
||||||
#define kPhysxSkinWidth 0.1f
|
#define kPhysxSkinWidth 0.1f
|
||||||
#define kPhysZOffset ((fRadius + (fHeight / 2)) + kPhysxSkinWidth)
|
#define kPhysZOffset ((fRadius + (fHeight / 2)) + kPhysxSkinWidth)
|
||||||
//#define kSLOPELIMIT (cosf(NxMath::degToRad(55.f)))
|
|
||||||
//#define kPhysicalHeightFudge 0.4f // this fudge was used for PhysX 2.4
|
|
||||||
#define kPhysicalHeightFudge 0.0f
|
#define kPhysicalHeightFudge 0.0f
|
||||||
|
#define STEP_OFFSET 1.f
|
||||||
//#define STEP_OFFSET 1.0f
|
#define kAvatarMass 160.f
|
||||||
#define STEP_OFFSET 0.5f
|
|
||||||
//#define STEP_OFFSET 0.15f
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
@ -89,8 +85,6 @@ static ControllerManager gControllerMgr;
|
|||||||
static std::vector<plPXPhysicalControllerCore*> gControllers;
|
static std::vector<plPXPhysicalControllerCore*> gControllers;
|
||||||
static bool gRebuildCache=false;
|
static bool gRebuildCache=false;
|
||||||
|
|
||||||
#define AvatarMass 200.f
|
|
||||||
|
|
||||||
class PXControllerHitReportWalk : public NxUserControllerHitReport
|
class PXControllerHitReportWalk : public NxUserControllerHitReport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -99,9 +93,9 @@ public:
|
|||||||
plPXPhysicalControllerCore* ac = plPXPhysicalControllerCore::FindController(hit.controller);
|
plPXPhysicalControllerCore* ac = plPXPhysicalControllerCore::FindController(hit.controller);
|
||||||
NxActor& actor = hit.shape->getActor();
|
NxActor& actor = hit.shape->getActor();
|
||||||
plPXPhysical* phys = (plPXPhysical*)actor.userData;
|
plPXPhysical* phys = (plPXPhysical*)actor.userData;
|
||||||
static float SlopeLimit = kSLOPELIMIT;
|
|
||||||
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
||||||
ac->fMovementInterface->IAddContactNormals(normal);
|
ac->fMovementInterface->IAddContactNormals(normal);
|
||||||
|
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
plDbgCollisionInfo info;
|
plDbgCollisionInfo info;
|
||||||
info.fNormal = normal;
|
info.fNormal = normal;
|
||||||
@ -124,6 +118,7 @@ public:
|
|||||||
}
|
}
|
||||||
ac->fDbgCollisionInfo.Append(info);
|
ac->fDbgCollisionInfo.Append(info);
|
||||||
#endif PLASMA_EXTERNAL_RELEASE
|
#endif PLASMA_EXTERNAL_RELEASE
|
||||||
|
|
||||||
// If the avatar hit a movable physical, apply some force to it.
|
// If the avatar hit a movable physical, apply some force to it.
|
||||||
hsVector3 dir = plPXConvert::Vector(hit.dir);
|
hsVector3 dir = plPXConvert::Vector(hit.dir);
|
||||||
float dirdotup=dir.fZ;
|
float dirdotup=dir.fZ;
|
||||||
@ -131,15 +126,16 @@ public:
|
|||||||
NxExtendedVec3 controllerPos=hit.controller->getPosition();
|
NxExtendedVec3 controllerPos=hit.controller->getPosition();
|
||||||
hsVector3 bottomOfTheCapsule((float)controllerPos.x,(float)controllerPos.y,(float)controllerPos.z);
|
hsVector3 bottomOfTheCapsule((float)controllerPos.x,(float)controllerPos.y,(float)controllerPos.z);
|
||||||
bottomOfTheCapsule.fZ=bottomOfTheCapsule.fZ-(ac->fHeight/2.0f + ac->fRadius);
|
bottomOfTheCapsule.fZ=bottomOfTheCapsule.fZ-(ac->fHeight/2.0f + ac->fRadius);
|
||||||
if (actor.isDynamic() )
|
if (actor.isDynamic() && phys )
|
||||||
{
|
{
|
||||||
if((hit.worldPos.z- bottomOfTheCapsule.fZ)<=ac->fRadius)//bottom hemisphere
|
if((hit.worldPos.z- bottomOfTheCapsule.fZ)<=ac->fRadius)//bottom hemisphere
|
||||||
{
|
{
|
||||||
//onTopOfSlopeLimit
|
// If this is an animated physical, we can stand on it
|
||||||
if (phys && phys->GetProperty(plSimulationInterface::kPhysAnim))
|
if (phys->GetProperty(plSimulationInterface::kPhysAnim))
|
||||||
{
|
{
|
||||||
if(normal.fZ>=0)
|
if(normal.fZ>=0)
|
||||||
{//we consider this ground
|
{
|
||||||
|
//we consider this ground
|
||||||
ac->fMovementInterface->AddOnTopOfObject(phys);
|
ac->fMovementInterface->AddOnTopOfObject(phys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,52 +157,22 @@ public:
|
|||||||
setNetGroupID->Send(obj->GetKey());
|
setNetGroupID->Send(obj->GetKey());
|
||||||
}
|
}
|
||||||
plSimulationMgr::GetInstance()->ConsiderSynch(phys, nil);
|
plSimulationMgr::GetInstance()->ConsiderSynch(phys, nil);
|
||||||
// We only allow horizontal pushes. Vertical pushes when we stand on
|
|
||||||
// dynamic objects creates useless stress on the solver.
|
// Now, let's impart some force, fool.
|
||||||
|
// Note: This is a VERY simple implementation. The old one was too hacky and caused weird stuff to happen.
|
||||||
hsVector3 vel=ac->GetLinearVelocity()- plPXConvert::Vector( actor.getLinearVelocity());
|
hsVector3 acceleration = (ac->GetLinearVelocity() - plPXConvert::Vector(actor.getLinearVelocity()));
|
||||||
if(dirdotup>=0)vel.fZ=0.001f;
|
hsVector3 force2impart = acceleration * kAvatarMass;
|
||||||
else vel.fZ=0.0f;
|
// Bad things happen if we impart force directly on top of the actor, so let's allow the avatar to run
|
||||||
static float kAvieMass = 140.f/32.f;
|
// over those physicals and not break them. This is mostly an issue with stuff smaller than step size.
|
||||||
if (!vel.IsEmpty())
|
if (!force2impart.IsEmpty() && normal.fZ < .90f)
|
||||||
{
|
phys->SetHitForce(force2impart, pos);
|
||||||
static float kForceScale = 140.0f;
|
|
||||||
NxF32 coeff;
|
|
||||||
NxExtendedVec3 norm2=hit.controller->getPosition();
|
|
||||||
norm2.x=hit.worldPos.x-bottomOfTheCapsule.fX;
|
|
||||||
norm2.y=hit.worldPos.y-bottomOfTheCapsule.fY;
|
|
||||||
if((hit.worldPos.z- bottomOfTheCapsule.fZ)<ac->fRadius)//bottom hemisphere
|
|
||||||
{
|
|
||||||
norm2.normalize();
|
|
||||||
norm2.z=0.01f;
|
|
||||||
}
|
|
||||||
else if((hit.worldPos.z- bottomOfTheCapsule.fZ)<(ac->fRadius+ac->fHeight))
|
|
||||||
{
|
|
||||||
norm2.z=0.0f;
|
|
||||||
norm2.normalize();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//must be the top so the normal is displacement from the pos - center
|
|
||||||
//of top hemisphere
|
|
||||||
norm2.z=hit.worldPos.z - ((ac->fRadius+ac->fHeight + bottomOfTheCapsule.fZ));
|
|
||||||
norm2.normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float proj=(float)(norm2.x*dir.fX+dir.fY*norm2.y+dir.fZ*norm2.z);
|
|
||||||
coeff =abs(proj*kForceScale*vel.Magnitude());
|
|
||||||
vel.fZ=(float)norm2.z;
|
|
||||||
vel.fY=(float)norm2.y;
|
|
||||||
vel.fX=(float)norm2.x;
|
|
||||||
phys->SetHitForce(vel*coeff, pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // else if the avatar hit a static
|
else // else if the avatar hit a static
|
||||||
{
|
{
|
||||||
return NX_ACTION_NONE;
|
return NX_ACTION_NONE;
|
||||||
}
|
}
|
||||||
if (phys && phys->GetProperty(plSimulationInterface::kAvAnimPushable))
|
if (phys->GetProperty(plSimulationInterface::kAvAnimPushable))
|
||||||
{
|
{
|
||||||
hsQuat inverseRotation = ac->fLocalRotation.Inverse();
|
hsQuat inverseRotation = ac->fLocalRotation.Inverse();
|
||||||
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
hsVector3 normal = plPXConvert::Vector(hit.worldNormal);
|
||||||
@ -546,7 +512,7 @@ NxScene* scene = plSimulationMgr::GetInstance()->GetScene(fWorldKey);
|
|||||||
capDesc.materialIndex= plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0,0.0);
|
capDesc.materialIndex= plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0,0.0);
|
||||||
actorDesc.shapes.pushBack(&capDesc);
|
actorDesc.shapes.pushBack(&capDesc);
|
||||||
NxBodyDesc bodyDesc;
|
NxBodyDesc bodyDesc;
|
||||||
bodyDesc.mass = AvatarMass;//1.f;
|
bodyDesc.mass = kAvatarMass;
|
||||||
actorDesc.body = &bodyDesc;
|
actorDesc.body = &bodyDesc;
|
||||||
bodyDesc.flags = NX_BF_KINEMATIC;
|
bodyDesc.flags = NX_BF_KINEMATIC;
|
||||||
bodyDesc.flags |=NX_BF_DISABLE_GRAVITY ;
|
bodyDesc.flags |=NX_BF_DISABLE_GRAVITY ;
|
||||||
@ -619,7 +585,7 @@ void plPXPhysicalControllerCore::ICreateController(const hsPoint3& pos)
|
|||||||
capDesc.materialIndex= plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0,0.0);
|
capDesc.materialIndex= plSimulationMgr::GetInstance()->GetMaterialIdx(scene, 0.0,0.0);
|
||||||
actorDesc.globalPose=actor->getGlobalPose();
|
actorDesc.globalPose=actor->getGlobalPose();
|
||||||
NxBodyDesc bodyDesc;
|
NxBodyDesc bodyDesc;
|
||||||
bodyDesc.mass = AvatarMass;
|
bodyDesc.mass = kAvatarMass;
|
||||||
actorDesc.body = &bodyDesc;
|
actorDesc.body = &bodyDesc;
|
||||||
bodyDesc.flags = NX_BF_KINEMATIC;
|
bodyDesc.flags = NX_BF_KINEMATIC;
|
||||||
bodyDesc.flags |=NX_BF_DISABLE_GRAVITY ;
|
bodyDesc.flags |=NX_BF_DISABLE_GRAVITY ;
|
||||||
|
@ -156,7 +156,7 @@ class SensorReport : public NxUserTriggerReport
|
|||||||
{
|
{
|
||||||
if (plSimulationMgr::fExtraProfile)
|
if (plSimulationMgr::fExtraProfile)
|
||||||
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
||||||
SendCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
|
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
|
||||||
}
|
}
|
||||||
else if (status & NX_TRIGGER_ON_ENTER)
|
else if (status & NX_TRIGGER_ON_ENTER)
|
||||||
{
|
{
|
||||||
@ -167,7 +167,7 @@ class SensorReport : public NxUserTriggerReport
|
|||||||
{
|
{
|
||||||
if (plSimulationMgr::fExtraProfile)
|
if (plSimulationMgr::fExtraProfile)
|
||||||
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
DetectorLogRed("-->Send Collision (CH) %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
||||||
SendCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
|
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
|
||||||
}
|
}
|
||||||
else if (status & NX_TRIGGER_ON_LEAVE)
|
else if (status & NX_TRIGGER_ON_LEAVE)
|
||||||
{
|
{
|
||||||
@ -187,13 +187,13 @@ class SensorReport : public NxUserTriggerReport
|
|||||||
{
|
{
|
||||||
if (plSimulationMgr::fExtraProfile)
|
if (plSimulationMgr::fExtraProfile)
|
||||||
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
||||||
SendCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
|
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, true);
|
||||||
}
|
}
|
||||||
if (status & NX_TRIGGER_ON_LEAVE)
|
if (status & NX_TRIGGER_ON_LEAVE)
|
||||||
{
|
{
|
||||||
if (plSimulationMgr::fExtraProfile)
|
if (plSimulationMgr::fExtraProfile)
|
||||||
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
DetectorLogRed("-->Send Collision %s %s",triggerPhys->GetObjectKey()->GetName().c_str(),status & NX_TRIGGER_ON_ENTER ? "enter" : "exit");
|
||||||
SendCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
|
plSimulationMgr::GetInstance()->AddCollisionMsg(triggerPhys->GetObjectKey(), otherKey, false);
|
||||||
}
|
}
|
||||||
if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
|
if (!(status & NX_TRIGGER_ON_ENTER) && !(status & NX_TRIGGER_ON_LEAVE) )
|
||||||
{
|
{
|
||||||
@ -205,18 +205,6 @@ class SensorReport : public NxUserTriggerReport
|
|||||||
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
|
#endif // USE_PHYSX_CONVEXHULL_WORKAROUND
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendCollisionMsg(plKey receiver, plKey hitter, hsBool entering)
|
|
||||||
{
|
|
||||||
DetectorLogYellow("Collision: %s was triggered by %s. Sending an %s msg", receiver->GetName().c_str(),
|
|
||||||
hitter ? hitter->GetName().c_str() : "(nil)" , entering ? "'enter'" : "'exit'");
|
|
||||||
plCollideMsg* msg = new plCollideMsg;
|
|
||||||
msg->fOtherKey = hitter;
|
|
||||||
msg->fEntering = entering;
|
|
||||||
msg->AddReceiver(receiver);
|
|
||||||
plgDispatch::Dispatch()->MsgQueue(msg); // Sends the msg on the next client update
|
|
||||||
}
|
|
||||||
|
|
||||||
} gSensorReport;
|
} gSensorReport;
|
||||||
|
|
||||||
// This gets called by PhysX whenever two actor groups that are set to report
|
// This gets called by PhysX whenever two actor groups that are set to report
|
||||||
@ -599,6 +587,34 @@ void plSimulationMgr::UpdateAvatarInDetector(plKey world, plPXPhysical* detector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void plSimulationMgr::AddCollisionMsg(plKey hitee, plKey hitter, bool enter)
|
||||||
|
{
|
||||||
|
// First, make sure we have no dupes
|
||||||
|
for (CollisionVec::iterator it = fCollideMsgs.begin(); it != fCollideMsgs.end(); ++it)
|
||||||
|
{
|
||||||
|
plCollideMsg* pMsg = *it;
|
||||||
|
|
||||||
|
// Should only ever be one receiver.
|
||||||
|
// Oh, it seems we should update the hit status. The latest might be different than the older...
|
||||||
|
// Even in the same frame >.<
|
||||||
|
if (pMsg->fOtherKey == hitter && pMsg->GetReceiver(0) == hitee)
|
||||||
|
{
|
||||||
|
pMsg->fEntering = enter;
|
||||||
|
DetectorLogRed("DUPLICATE COLLISION: %s hit %s",
|
||||||
|
(hitter ? hitter->GetName().c_str() : "(nil)"),
|
||||||
|
(hitee ? hitee->GetName().c_str() : "(nil)"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Still here? Then this must be a unique hit!
|
||||||
|
plCollideMsg* pMsg = new plCollideMsg;
|
||||||
|
pMsg->AddReceiver(hitee);
|
||||||
|
pMsg->fOtherKey = hitter;
|
||||||
|
pMsg->fEntering = enter;
|
||||||
|
fCollideMsgs.push_back(pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
void plSimulationMgr::Advance(float delSecs)
|
void plSimulationMgr::Advance(float delSecs)
|
||||||
{
|
{
|
||||||
if (fSuspended)
|
if (fSuspended)
|
||||||
@ -693,6 +709,15 @@ void plSimulationMgr::Advance(float delSecs)
|
|||||||
|
|
||||||
void plSimulationMgr::ISendUpdates()
|
void plSimulationMgr::ISendUpdates()
|
||||||
{
|
{
|
||||||
|
for (CollisionVec::iterator it = fCollideMsgs.begin(); it != fCollideMsgs.end(); ++it)
|
||||||
|
{
|
||||||
|
plCollideMsg* pMsg = *it;
|
||||||
|
DetectorLogYellow("Collision: %s was triggered by %s. Sending an %s msg", pMsg->GetReceiver(0)->GetName().c_str(),
|
||||||
|
pMsg->fOtherKey ? pMsg->fOtherKey->GetName().c_str() : "(nil)" , pMsg->fEntering ? "'enter'" : "'exit'");
|
||||||
|
plgDispatch::Dispatch()->MsgSend(pMsg);
|
||||||
|
}
|
||||||
|
fCollideMsgs.clear();
|
||||||
|
|
||||||
SceneMap::iterator it = fScenes.begin();
|
SceneMap::iterator it = fScenes.begin();
|
||||||
for (; it != fScenes.end(); it++)
|
for (; it != fScenes.end(); it++)
|
||||||
{
|
{
|
||||||
|
@ -102,11 +102,14 @@ public:
|
|||||||
// 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);
|
||||||
|
|
||||||
//Fix to Move collision messages and their handling out of the simulation step
|
//Fix to Move collision messages and their handling out of the simulation step
|
||||||
void AddCollisionMsg(plCollideMsg* msg);
|
void AddCollisionMsg(plKey hitee, plKey hitter, bool entering);
|
||||||
|
|
||||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||||
static bool fDisplayAwakeActors;
|
static bool fDisplayAwakeActors;
|
||||||
#endif //PLASMA_EXTERNAL_RELEASE
|
#endif //PLASMA_EXTERNAL_RELEASE
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class ContactReport;
|
friend class ContactReport;
|
||||||
|
|
||||||
@ -125,6 +128,10 @@ protected:
|
|||||||
|
|
||||||
plPhysicsSoundMgr* fSoundMgr;
|
plPhysicsSoundMgr* fSoundMgr;
|
||||||
|
|
||||||
|
// Pending collision messages
|
||||||
|
typedef std::vector<plCollideMsg*> CollisionVec;
|
||||||
|
CollisionVec fCollideMsgs;
|
||||||
|
|
||||||
// A mapping from a key to a PhysX scene. The key is either the
|
// A mapping from a key to a PhysX scene. The key is either the
|
||||||
// SimulationMgr key, for the main world, or a SceneObject key if it's a
|
// SimulationMgr key, for the main world, or a SceneObject key if it's a
|
||||||
// subworld.
|
// subworld.
|
||||||
|
@ -236,103 +236,56 @@ void plCollisionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
|||||||
|
|
||||||
plCameraRegionDetector::~plCameraRegionDetector()
|
plCameraRegionDetector::~plCameraRegionDetector()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < fMessages.Count(); i++)
|
for (plCameraMsgVec::iterator it = fMessages.begin(); it != fMessages.end(); ++it)
|
||||||
{
|
hsRefCnt_SafeUnRef(*it);
|
||||||
plMessage* pMsg = fMessages[i];
|
|
||||||
fMessages.Remove(i);
|
|
||||||
delete(pMsg);
|
|
||||||
}
|
|
||||||
fMessages.SetCountAndZero(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void plCameraRegionDetector::ITrigger(plKey hitter, bool entering, bool immediate)
|
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().c_str());
|
|
||||||
fLastEnterEval = fNumEvals;
|
|
||||||
if (fSavingSendMsg)
|
|
||||||
{
|
|
||||||
DetectorLog("%s: Dumping saved Camera Exiting volume", GetKeyName().c_str());
|
|
||||||
}
|
|
||||||
fSavingSendMsg = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!entering && fNumEvals - fLastEnterEval <= 1 && fSavingSendMsg)
|
|
||||||
{
|
|
||||||
DetectorLog("%s: Skipping Exiting volume", GetKeyName().c_str());
|
|
||||||
fLastExitEval = fNumEvals;
|
|
||||||
if (fSavingSendMsg)
|
|
||||||
{
|
|
||||||
DetectorLog("%s: Dumping saved Camera Entering volume", GetKeyName().c_str());
|
|
||||||
}
|
|
||||||
fSavingSendMsg = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get rid of any saved messages... this should happen though
|
|
||||||
if (fSavingSendMsg)
|
if (fSavingSendMsg)
|
||||||
{
|
DetectorLogRed("%s: Stale messages on ITrigger. This should never happen!", GetKeyName().c_str());
|
||||||
DetectorLog("%s: Killing saved camera message... shouldn't happen", GetKeyName().c_str());
|
if (fIsInside && entering)
|
||||||
}
|
DetectorLogRed("%s: Duplicate enter! Did we miss an exit?", GetKeyName().c_str());
|
||||||
// end PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
|
else if (!fIsInside && !entering)
|
||||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
DetectorLogRed("%s: Duplicate exit! Did we miss an enter?", GetKeyName().c_str());
|
||||||
|
|
||||||
fSavingSendMsg = true;
|
fSavingSendMsg = true;
|
||||||
fSavedMsgEnterFlag = entering;
|
fSavedMsgEnterFlag = entering;
|
||||||
if (entering)
|
if (entering)
|
||||||
{
|
{
|
||||||
//DetectorLog("%s: Saving camera Entering volume - Evals=%d", GetKeyName().c_str(),fNumEvals);
|
DetectorLog("%s: Saving camera Entering volume - Evals=%d", GetKeyName().c_str(),fNumEvals);
|
||||||
fLastEnterEval = fNumEvals;
|
fLastEnterEval = fNumEvals;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//DetectorLog("%s: Saving camera Exiting volume - Evals=%d", GetKeyName().c_str(),fNumEvals);
|
DetectorLog("%s: Saving camera Exiting volume - Evals=%d", GetKeyName().c_str(),fNumEvals);
|
||||||
fLastExitEval = 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)
|
if (immediate)
|
||||||
{
|
|
||||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
|
|
||||||
ISendSavedTriggerMsgs();
|
ISendSavedTriggerMsgs();
|
||||||
|
|
||||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
}
|
|
||||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void plCameraRegionDetector::ISendSavedTriggerMsgs()
|
void plCameraRegionDetector::ISendSavedTriggerMsgs()
|
||||||
{
|
{
|
||||||
if (fSavingSendMsg)
|
if (fSavingSendMsg)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fMessages.Count(); i++)
|
for (size_t i = 0; i < fMessages.size(); ++i)
|
||||||
{
|
{
|
||||||
char str[256];
|
|
||||||
|
|
||||||
hsRefCnt_SafeRef(fMessages[i]);
|
hsRefCnt_SafeRef(fMessages[i]);
|
||||||
if (fSavedMsgEnterFlag)
|
if (fSavedMsgEnterFlag)
|
||||||
{
|
{
|
||||||
fMessages[i]->SetCmd(plCameraMsg::kEntering);
|
fMessages[i]->SetCmd(plCameraMsg::kEntering);
|
||||||
sprintf(str, "Entering cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.Count());
|
DetectorLog("Entering cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size());
|
||||||
fIsInside = true;
|
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().c_str(),fNumEvals,i+1,fMessages.Count());
|
DetectorLog("Exiting cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size());
|
||||||
fIsInside = false;
|
fIsInside = false;
|
||||||
}
|
}
|
||||||
plgDispatch::MsgSend(fMessages[i]);
|
plgDispatch::MsgSend(fMessages[i]);
|
||||||
DetectorLog("%s", str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fSavingSendMsg = false;
|
fSavingSendMsg = false;
|
||||||
@ -342,38 +295,23 @@ void plCameraRegionDetector::ISendSavedTriggerMsgs()
|
|||||||
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;
|
||||||
|
// Fall through to plObjectInVolumeDetector, which will register us for plEvalMsg
|
||||||
|
// and handle it for us. (Hint: See ISendSavedTriggerMsgs)
|
||||||
#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()
|
|
||||||
|
|
||||||
fNumEvals = 0;
|
|
||||||
fLastEnterEval=-999;
|
|
||||||
fLastExitEval=-999;
|
|
||||||
}
|
|
||||||
|
|
||||||
// end of (PHYSX BUG WORKAROUND)
|
|
||||||
#endif // USE_PHYSX_MULTIPLE_CAMREG_ENTER
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return plObjectInVolumeDetector::MsgReceive(msg);
|
return plObjectInVolumeDetector::MsgReceive(msg);
|
||||||
}
|
}
|
||||||
void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
||||||
{
|
{
|
||||||
plDetectorModifier::Read(stream, mgr);
|
plDetectorModifier::Read(stream, mgr);
|
||||||
int n = stream->ReadLE32();
|
int n = stream->ReadLE32();
|
||||||
fMessages.SetCountAndZero(n);
|
fMessages.resize(n);
|
||||||
for(int i = 0; i < n; i++ )
|
for(size_t i = 0; i < n; i++ )
|
||||||
{
|
{
|
||||||
plCameraMsg* pMsg = plCameraMsg::ConvertNoRef(mgr->ReadCreatable(stream));
|
plCameraMsg* pMsg = plCameraMsg::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||||
fMessages[i] = pMsg;
|
fMessages[i] = pMsg;
|
||||||
@ -383,28 +321,11 @@ void plCameraRegionDetector::Read(hsStream* stream, hsResMgr* mgr)
|
|||||||
void plCameraRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
void plCameraRegionDetector::Write(hsStream* stream, hsResMgr* mgr)
|
||||||
{
|
{
|
||||||
plDetectorModifier::Write(stream, mgr);
|
plDetectorModifier::Write(stream, mgr);
|
||||||
stream->WriteLE32(fMessages.GetCount());
|
stream->WriteLE32(fMessages.size());
|
||||||
for(int i = 0; i < fMessages.GetCount(); i++ )
|
for(plCameraMsgVec::iterator it = fMessages.begin(); it != fMessages.end(); ++it)
|
||||||
mgr->WriteCreatable( stream, fMessages[i] );
|
mgr->WriteCreatable( stream, *it );
|
||||||
|
|
||||||
}
|
}
|
||||||
void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
|
|
||||||
{
|
|
||||||
fNumEvals++;
|
|
||||||
if (fNumEvals - fLastEnterEval > 1 && fNumEvals-fLastExitEval>1)
|
|
||||||
{
|
|
||||||
ISendSavedTriggerMsgs();
|
|
||||||
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
|
||||||
fWaitingForEval = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(fSavedActivatorMsg)
|
|
||||||
DetectorLog("%s didn't send its message. fNumEvals=%d fLastEnterEval=%d, fLastExit=%d",
|
|
||||||
GetKeyName().c_str(),fNumEvals, fLastEnterEval, fLastExitEval);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
@ -414,127 +335,8 @@ void plCameraRegionDetector::IHandleEval(plEvalMsg *pEval)
|
|||||||
|
|
||||||
void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering, bool immediate)
|
void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering, bool immediate)
|
||||||
{
|
{
|
||||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
hsRefCnt_SafeUnRef(fSavedActivatorMsg);
|
||||||
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
|
fSavedActivatorMsg = new plActivatorMsg;
|
||||||
/* 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)
|
|
||||||
{
|
|
||||||
//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=new plCollisionBookKeepingInfo(hitter);
|
|
||||||
if(entering)
|
|
||||||
{
|
|
||||||
BookKeeper->enters++;
|
|
||||||
BookKeeper->fSubStepCurState =true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BookKeeper->exits++;
|
|
||||||
BookKeeper->fSubStepCurState =false;
|
|
||||||
}
|
|
||||||
fCollisionList.push_front(BookKeeper);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plActivatorMsg* ActivatorMsg = 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 = new plActivatorMsg;
|
|
||||||
|
|
||||||
fSavedActivatorMsg->AddReceivers(fReceivers);
|
fSavedActivatorMsg->AddReceivers(fReceivers);
|
||||||
|
|
||||||
if (fProxyKey)
|
if (fProxyKey)
|
||||||
@ -547,47 +349,36 @@ void plObjectInVolumeDetector::ITrigger(plKey hitter, bool entering, bool immedi
|
|||||||
|
|
||||||
if (entering)
|
if (entering)
|
||||||
{
|
{
|
||||||
//DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName(),fNumEvals);
|
DetectorLog("%s: Saving Entering volume - Evals=%d", GetKeyName().c_str(), fNumEvals);
|
||||||
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
|
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeEnter);
|
||||||
fLastEnterEval = fNumEvals;
|
fLastEnterEval = fNumEvals;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//DetectorLog("%s: Saving Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
|
DetectorLog("%s: Saving Exiting volume - Evals=%d", GetKeyName().c_str(), fNumEvals);
|
||||||
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
|
fSavedActivatorMsg->SetTriggerType(plActivatorMsg::kVolumeExit);
|
||||||
fLastExitEval = 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)
|
if (immediate)
|
||||||
{
|
ISendSavedTriggerMsgs();
|
||||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
|
|
||||||
|
|
||||||
// fSavedActivatorMsg = nil;
|
|
||||||
|
|
||||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
}
|
|
||||||
#endif // USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void plObjectInVolumeDetector::ISendSavedTriggerMsgs()
|
void plObjectInVolumeDetector::ISendSavedTriggerMsgs()
|
||||||
{
|
{
|
||||||
if (fSavedActivatorMsg)
|
if (fSavedActivatorMsg)
|
||||||
{
|
{
|
||||||
if (fSavedActivatorMsg->fTriggerType == plActivatorMsg::kVolumeEnter)
|
if (fSavedActivatorMsg->fTriggerType == plActivatorMsg::kVolumeEnter)
|
||||||
DetectorLog("%s: Sending Entering volume - Evals=%d", GetKeyName(),fNumEvals);
|
DetectorLog("%s: Sending Entering volume - Evals=%d", GetKeyName().c_str(), fNumEvals);
|
||||||
else
|
else
|
||||||
DetectorLog("%s: Sending Exiting volume - Evals=%d", GetKeyName(),fNumEvals);
|
DetectorLog("%s: Sending Exiting volume - Evals=%d", GetKeyName().c_str(), fNumEvals);
|
||||||
|
|
||||||
// we're saving the message to be dispatched later...
|
// we're saving the message to be dispatched later...
|
||||||
plgDispatch::MsgSend(fSavedActivatorMsg);
|
plgDispatch::MsgSend(fSavedActivatorMsg);
|
||||||
}
|
}
|
||||||
fSavedActivatorMsg = nil;
|
fSavedActivatorMsg = nil;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
|
hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
|
||||||
{
|
{
|
||||||
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg);
|
||||||
@ -596,36 +387,18 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
|
|||||||
// If the avatar is disabled (flying around), don't trigger
|
// If the avatar is disabled (flying around), don't trigger
|
||||||
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)
|
|
||||||
{
|
|
||||||
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));
|
||||||
|
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_PHYSX_COLLISION_FLUTTER_WORKAROUND
|
plEvalMsg* pEvalMsg = plEvalMsg::ConvertNoRef(msg);
|
||||||
// PHYSX_FIXME hack for PhysX turd that sends bunches of enter/exits over one frame
|
if (pEvalMsg)
|
||||||
plEvalMsg* pEval = plEvalMsg::ConvertNoRef(msg);
|
|
||||||
if (pEval)
|
|
||||||
{
|
{
|
||||||
|
fNumEvals++;
|
||||||
//if (fSavedActivatorMsg)
|
ISendSavedTriggerMsgs();
|
||||||
// DetectorLog("%s: InVolumeEval=%d with saved message", GetKeyName(), fNumEvals);
|
plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||||
//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,75 +409,6 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg)
|
|||||||
return plCollisionDetector::MsgReceive(msg);
|
return plCollisionDetector::MsgReceive(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void plObjectInVolumeDetector::IHandleEval(plEvalMsg* pEval)
|
|
||||||
{
|
|
||||||
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=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().c_str(), GetTarget()->GetKeyName().c_str() );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DetectorLog("%s squelched an Enter ActivatorMsg.", GetKeyName().c_str());
|
|
||||||
delete actout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//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().c_str(), GetTarget()->GetKeyName().c_str());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DetectorLog("%s squelched an Exit ActivatorMsg.", GetKeyName().c_str());
|
|
||||||
delete actout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DetectorLog("*********");
|
|
||||||
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().c_str());
|
|
||||||
}
|
|
||||||
DetectorLog("*********");
|
|
||||||
|
|
||||||
fCollisionList.clear();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void plObjectInVolumeDetector::SetTarget(plSceneObject* so)
|
void plObjectInVolumeDetector::SetTarget(plSceneObject* so)
|
||||||
{
|
{
|
||||||
plCollisionDetector::SetTarget(so);
|
plCollisionDetector::SetTarget(so);
|
||||||
@ -730,6 +434,7 @@ void plObjectInVolumeDetector::Write(hsStream* stream, hsResMgr* mgr)
|
|||||||
|
|
||||||
|
|
||||||
plObjectInVolumeAndFacingDetector::plObjectInVolumeAndFacingDetector() :
|
plObjectInVolumeAndFacingDetector::plObjectInVolumeAndFacingDetector() :
|
||||||
|
plObjectInVolumeDetector(),
|
||||||
fFacingTolerance(0),
|
fFacingTolerance(0),
|
||||||
fNeedWalkingForward(false),
|
fNeedWalkingForward(false),
|
||||||
fAvatarInVolume(false),
|
fAvatarInVolume(false),
|
||||||
|
@ -73,7 +73,8 @@ public:
|
|||||||
kTypeBump = 0x20,
|
kTypeBump = 0x20,
|
||||||
};
|
};
|
||||||
|
|
||||||
plCollisionDetector() : fType(0), fTriggered(false), fBumped(false){;}
|
plCollisionDetector() : fType(0), fTriggered(false), fBumped(false){ }
|
||||||
|
plCollisionDetector(int8_t type) : fType(type), fTriggered(false), fBumped(false) { }
|
||||||
virtual ~plCollisionDetector(){;}
|
virtual ~plCollisionDetector(){;}
|
||||||
|
|
||||||
virtual hsBool MsgReceive(plMessage* msg);
|
virtual hsBool MsgReceive(plMessage* msg);
|
||||||
@ -90,48 +91,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:
|
|
||||||
class plCollisionBookKeepingInfo
|
|
||||||
{
|
|
||||||
friend class plObjectInVolumeDetector;
|
|
||||||
public:
|
|
||||||
plCollisionBookKeepingInfo(plKey& hit)
|
|
||||||
{
|
|
||||||
hitter=hit;
|
|
||||||
enters=0;
|
|
||||||
exits=0;
|
|
||||||
}
|
|
||||||
~plCollisionBookKeepingInfo()
|
|
||||||
{
|
|
||||||
hitter=nil;
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
plKey hitter;
|
|
||||||
int enters,exits;
|
|
||||||
bool fSubStepCurState;
|
|
||||||
};
|
|
||||||
protected:
|
protected:
|
||||||
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
|
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
|
||||||
//virtual void ISendSavedTriggerMsgs();
|
virtual void ISendSavedTriggerMsgs();
|
||||||
virtual void IHandleEval(plEvalMsg* pEval);
|
|
||||||
bool fWaitingForEval;
|
|
||||||
|
|
||||||
plActivatorMsg* fSavedActivatorMsg;
|
plActivatorMsg* fSavedActivatorMsg;
|
||||||
|
uint32_t fNumEvals;
|
||||||
typedef std::list<plCollisionBookKeepingInfo*> bookKeepingList;
|
uint32_t fLastEnterEval;
|
||||||
bookKeepingList fCollisionList;
|
uint32_t fLastExitEval;
|
||||||
typedef std::set<plKey> ResidentSet;
|
|
||||||
ResidentSet fCurrentResidents;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
plObjectInVolumeDetector()
|
plObjectInVolumeDetector()
|
||||||
{
|
: plCollisionDetector(), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), fLastExitEval(0)
|
||||||
fWaitingForEval=false;fSavedActivatorMsg=nil;
|
{ }
|
||||||
|
|
||||||
}
|
plObjectInVolumeDetector(int8_t type)
|
||||||
plObjectInVolumeDetector(int8_t i){fType = i;fWaitingForEval=false;fSavedActivatorMsg=nil;}
|
: plCollisionDetector(type), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), fLastExitEval(0)
|
||||||
virtual ~plObjectInVolumeDetector(){;}
|
{ }
|
||||||
|
|
||||||
|
virtual ~plObjectInVolumeDetector() { }
|
||||||
|
|
||||||
virtual hsBool MsgReceive(plMessage* msg);
|
virtual hsBool MsgReceive(plMessage* msg);
|
||||||
|
|
||||||
@ -177,23 +156,23 @@ public:
|
|||||||
class plCameraRegionDetector : public plObjectInVolumeDetector
|
class plCameraRegionDetector : public plObjectInVolumeDetector
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
hsTArray<plCameraMsg*> fMessages;
|
typedef std::vector<plCameraMsg*> plCameraMsgVec;
|
||||||
|
|
||||||
|
plCameraMsgVec fMessages;
|
||||||
bool fIsInside;
|
bool fIsInside;
|
||||||
bool fSavingSendMsg;
|
bool fSavingSendMsg;
|
||||||
bool fSavedMsgEnterFlag;
|
bool fSavedMsgEnterFlag;
|
||||||
int fNumEvals;
|
|
||||||
int fLastEnterEval;
|
|
||||||
int fLastExitEval;
|
|
||||||
|
|
||||||
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
|
virtual void ITrigger(plKey hitter, bool entering, bool immediate=false);
|
||||||
virtual void ISendSavedTriggerMsgs();
|
virtual void ISendSavedTriggerMsgs();
|
||||||
virtual void IHandleEval(plEvalMsg* pEval);
|
|
||||||
public:
|
public:
|
||||||
plCameraRegionDetector(){ fIsInside = false; fSavingSendMsg = false; }
|
plCameraRegionDetector()
|
||||||
|
: plObjectInVolumeDetector(), fIsInside(false), fSavingSendMsg(false)
|
||||||
|
{ }
|
||||||
~plCameraRegionDetector();
|
~plCameraRegionDetector();
|
||||||
|
|
||||||
virtual hsBool MsgReceive(plMessage* msg);
|
virtual hsBool MsgReceive(plMessage* msg);
|
||||||
void AddMessage(plCameraMsg* pMsg) { fMessages.Append(pMsg); }
|
void AddMessage(plCameraMsg* pMsg) { fMessages.push_back(pMsg); }
|
||||||
|
|
||||||
CLASSNAME_REGISTER( plCameraRegionDetector );
|
CLASSNAME_REGISTER( plCameraRegionDetector );
|
||||||
GETINTERFACE_ANY( plCameraRegionDetector, plCollisionDetector );
|
GETINTERFACE_ANY( plCameraRegionDetector, plCollisionDetector );
|
||||||
|
Reference in New Issue
Block a user