From 0e88bd249b6b0beff63510185d1059a7a54b3889 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 23 Feb 2012 18:12:19 -0500 Subject: [PATCH 1/4] Revert "Pop cameras when we exit a region" This was a fluke and did not really fix the issue --- Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp index c0b03ffd..57a3648d 100644 --- a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp +++ b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp @@ -276,14 +276,12 @@ void plCameraRegionDetector::ISendSavedTriggerMsgs() if (fSavedMsgEnterFlag) { fMessages[i]->SetCmd(plCameraMsg::kEntering); - fMessages[i]->ClearCmd(plCameraMsg::kPop); DetectorLog("Entering cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size()); fIsInside = true; } else { fMessages[i]->ClearCmd(plCameraMsg::kEntering); - fMessages[i]->SetCmd(plCameraMsg::kPop); // for spawnpoints with a camera stack DetectorLog("Exiting cameraRegion: %s - Evals=%d -msg %d of %d\n", GetKeyName().c_str(),fNumEvals,i+1,fMessages.size()); fIsInside = false; } From 8deeb6831ad5cc3f523dbc2fd8b5a3ff0ae9adf4 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 23 Feb 2012 18:13:03 -0500 Subject: [PATCH 2/4] Disallow duplicate camera pushes --- Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp index b132a453..164e24a4 100644 --- a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp +++ b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp @@ -1509,13 +1509,8 @@ void plVirtualCam1::AddCameraToStack(plCameraModifier1* pCam) void plVirtualCam1::PushCamera(plCameraModifier1* pCam, hsBool bDefault) { // pushing the same camera, folks? + // -- disallowed 2/13/2012 -- if (pCam == GetCurrentStackCamera()) - { - AddCameraToStack(pCam); - return; - } - // make sure that we don't keep adding the default camera if we're already in it - if (bDefault && pCam == GetCurrentStackCamera()) return; // look up whatever transition we might have specified From 8c345dac3d1d6c3c0e595c515b525d15fadb3daa Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 24 Feb 2012 22:31:10 -0500 Subject: [PATCH 3/4] Take this opportunity to vector-ize plVirtualCam1 --- .../FeatureLib/pfCamera/plVirtualCamNeu.cpp | 93 +++++++++---------- .../FeatureLib/pfCamera/plVirtualCamNeu.h | 38 ++++---- 2 files changed, 63 insertions(+), 68 deletions(-) diff --git a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp index 164e24a4..e68a01c0 100644 --- a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp +++ b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.cpp @@ -225,21 +225,21 @@ plVirtualCam1::~plVirtualCam1() } // for saving camera stack -plCameraModifier1* plVirtualCam1::GetCameraNumber(int camNumber) +plCameraModifier1* plVirtualCam1::GetCameraNumber(size_t camNumber) { return (fCameraStack[camNumber]); } // for rebuilding camera stack void plVirtualCam1::RebuildStack(const plKey& key) { - if (fCameraStack.Count() == 1) + if (fCameraStack.size() == 1) { plUoid U(kDefaultCameraMod1_KEY); plKey pKey = hsgResMgr::ResMgr()->FindKey(U); if (pKey) { if (fCameraStack[0]->GetKey() == pKey) - fCameraStack.SetCountAndZero(0); + fCameraStack.clear(); } } plSceneObject* pObj = plSceneObject::ConvertNoRef(key->GetObjectPtr()); @@ -398,14 +398,13 @@ void plVirtualCam1::Reset(hsBool bRender) fPythonOverride = nil; if (fFirstPersonOverride) fFirstPersonOverride = nil; - fCamerasLoaded.SetCountAndZero(0); - fCameraStack.SetCountAndZero(0); - fCameraStack.Append(fDriveCamera); + fCamerasLoaded.clear(); + fCameraStack.clear(); + fCameraStack.push_back(fDriveCamera); plUoid U(kDefaultCameraMod1_KEY); plKey pKey = hsgResMgr::ResMgr()->FindKey(U); if (pKey) PushCamera((plCameraModifier1*)pKey->GetObjectPtr()); - //fCameraStack.Append((plCameraModifier1*)pKey->GetObjectPtr()); if (fThirdPersonCam) PushCamera(fThirdPersonCam); @@ -429,7 +428,7 @@ void plVirtualCam1::Reset(hsBool bRender) void plVirtualCam1::ClearStack() { - fCameraStack.SetCountAndZero(0); + fCameraStack.clear(); plUoid U(kDefaultCameraMod1_KEY); plKey pKey = hsgResMgr::ResMgr()->FindKey(U); if (pKey) @@ -451,10 +450,9 @@ plCameraModifier1* plVirtualCam1::GetCurrentCamera() return(fFirstPersonOverride); if (fTransPos == POS_TRANS_FOLLOW) return(fTransitionCamera); - - if (fCameraStack.Count()) - return fCameraStack[fCameraStack.Count() - 1]; - else return nil; + if (fCameraStack.size()) + return fCameraStack.back(); + return nil; } hsBool plVirtualCam1::Is1stPersonCamera() @@ -471,9 +469,10 @@ hsBool plVirtualCam1::Is1stPersonCamera() plCameraModifier1* plVirtualCam1::GetCurrentStackCamera() { - if (fCameraStack.Count()) - return fCameraStack[fCameraStack.Count() - 1]; - else return nil; + if (fCameraStack.size()) + return fCameraStack.back(); + else + return nil; } void plVirtualCam1::ICreatePlate() @@ -535,11 +534,12 @@ void plVirtualCam1::SetRender(hsBool render) // hack, hack, hack hsBool plVirtualCam1::RestoreFromName(const plString& name) { - for(int i = 0; i < fCamerasLoaded.Count(); i++) + for(plSOVec::iterator it = fCamerasLoaded.begin(); it != fCamerasLoaded.end(); ++it) { - if (name.Compare(fCamerasLoaded[i]->GetKeyName()) == 0) + plKey cam = (*it)->GetKey(); + if (name.Compare(cam->GetName(), plString::kCaseInsensitive) == 0) { - RebuildStack(fCamerasLoaded[i]->GetKey()); + RebuildStack(cam); return true; } } @@ -775,33 +775,34 @@ void plVirtualCam1::IUpdate() RunTransition(); - for (int i=0; i < fCameraStack.Count(); i++) + for (plCameraVec::iterator i = fCameraStack.begin(); i != fCameraStack.end(); ++i) { hsBool update = true; - for (int j=i+1; jGetBrain()) + if(alwaysCutForColin && cam->GetBrain()) { - fCameraStack[i]->GetBrain()->SetFlags(plCameraBrain1::kCutPos); - fCameraStack[i]->GetBrain()->SetFlags(plCameraBrain1::kCutPOA); + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPos); + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPOA); } if(fForceCutOnce) { - fCameraStack[i]->GetBrain()->SetFlags(plCameraBrain1::kCutPosOnce); - fCameraStack[i]->GetBrain()->SetFlags(plCameraBrain1::kCutPOAOnce); + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPosOnce); + cam->GetBrain()->SetFlags(plCameraBrain1::kCutPOAOnce); } - fCameraStack[i]->Update(); + cam->Update(); } } if(fForceCutOnce)fForceCutOnce=false; @@ -1397,12 +1398,9 @@ hsBool plVirtualCam1::MsgReceive(plMessage* msg) // array. Since this message indicates it was destroyed anyway, this should be // ok. plCameraModifier1* pMod = (plCameraModifier1*)(pRefMsg->GetRef()); - // we go in reverse so that removes don't mess up our index - for (int i = fCameraStack.Count() - 1; i >= 0; --i) - { - if (fCameraStack[i] == pMod) - fCameraStack.Remove(i); - } + plCameraVec::iterator it = std::find(fCameraStack.begin(), fCameraStack.end(), pMod); + if (it != fCameraStack.end()) + fCameraStack.erase(it); } return true; } @@ -1495,7 +1493,7 @@ void plVirtualCam1::CreateDefaultCamera(plSceneObject* subject) void plVirtualCam1::AddCameraToStack(plCameraModifier1* pCam) { - fCameraStack.Append(pCam); + fCameraStack.push_back(pCam); if (pCam->GetBrain()) { if (HasMovementFlag(B_CONTROL_CAMERA_WALK_PAN)) @@ -1665,9 +1663,9 @@ void plVirtualCam1::PushCamera(plCameraModifier1* pCam, hsBool bDefault) #endif } // make this the default camera if that's what we want... - if (fCameraStack.Count() > 0 && bDefault) + if (fCameraStack.size() > 0 && bDefault) { - fCameraStack.SetCountAndZero(0); + fCameraStack.clear(); AddCameraToStack(pCam); #ifdef STATUS_LOG camLog->AddLineF("Camera %s is now the DEFAULT camera for this age", pCam->GetKeyName().c_str()); @@ -1679,15 +1677,15 @@ void plVirtualCam1::PushCamera(plCameraModifier1* pCam, hsBool bDefault) void plVirtualCam1::PopCamera(plCameraModifier1* pCam) { // sanity / new default camera check - if (fCameraStack.Count() <= 1) + if (fCameraStack.size() <= 1) return; // is it the current camera AND the same camera we would otherwise switch to? - if (pCam==GetCurrentStackCamera() && pCam == fCameraStack[fCameraStack.Count() - 2]) + if (pCam==GetCurrentStackCamera() && pCam == fCameraStack[fCameraStack.size() - 2]) { // pop but don't transition to a new camera // or do anything else: - fCameraStack.Remove(fCameraStack.Count() - 1); + fCameraStack.pop_back(); return; } @@ -1709,7 +1707,7 @@ void plVirtualCam1::PopCamera(plCameraModifier1* pCam) !GetCurrentStackCamera()) { // special camera mode (like drive) just pop it - fCameraStack.Remove(fCameraStack.Count() - 1); + fCameraStack.pop_back(); GetCurrentStackCamera()->Push(!HasFlags(kAvatarWalking)); return; } @@ -1721,7 +1719,7 @@ void plVirtualCam1::PopCamera(plCameraModifier1* pCam) #endif // pop and actually transition to a new camera - fCameraStack.Remove(fCameraStack.Count() - 1); + fCameraStack.pop_back(); if (GetCurrentStackCamera()) { @@ -1804,14 +1802,9 @@ void plVirtualCam1::PopCamera(plCameraModifier1* pCam) IHandleCameraStatusLog(pCam, kBackgroundPop); #endif // just remove this from the stack - for (int i = 0; i < fCameraStack.Count(); i++) - { - if (fCameraStack[i] == pCam) - { - fCameraStack.Remove(i); - break; - } - } + plCameraVec::iterator it = std::find(fCameraStack.begin(), fCameraStack.end(), pCam); + if (it != fCameraStack.end()) + fCameraStack.erase(it); } if (!InTransition()) SetFOV(GetCurrentStackCamera()->GetFOVw(), GetCurrentStackCamera()->GetFOVh(), GetCurrentStackCamera()); diff --git a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h index 015681b2..57727ec2 100644 --- a/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h +++ b/Sources/Plasma/FeatureLib/pfCamera/plVirtualCamNeu.h @@ -73,6 +73,8 @@ struct hsColorRGBA; class plVirtualCam1 : public hsKeyedObject { + typedef std::vector plCameraVec; + typedef std::vector plSOVec; protected: @@ -127,8 +129,8 @@ public: static float GetFOVh() { return fFOVh; } static float GetHither() { return fHither; } static float GetYon() { return fYon; } - static void SetOffset(float x, float y, float z); - static void SetAspectRatio(float aspect) { fAspectRatio = aspect; } + static void SetOffset(float x, float y, float z); + static void SetAspectRatio(float aspect) { fAspectRatio = aspect; } static float GetAspectRatio() { return fAspectRatio; } hsBool InTransition() { return fTransPos != POS_TRANS_OFF; } @@ -148,8 +150,8 @@ public: const hsMatrix44 GetCurrentMatrix() { return fMatrix; } static plVirtualCam1* Instance() { return fInstance; } - int GetNumCameras() { return fCameraStack.Count(); } - plCameraModifier1* GetCameraNumber(int camNumber); + size_t GetNumCameras() { return fCameraStack.size(); } + plCameraModifier1* GetCameraNumber(size_t camNumber); void RebuildStack(const plKey& key); void SetFlags(int flag) { fFlags.SetBit(flag); } @@ -169,7 +171,7 @@ public: static hsBool IsCurrentCamera(const plCameraModifier1* mod); void ClearStack(); - void AddCameraLoaded(plSceneObject* pCam) { fCamerasLoaded.Append(pCam); } + void AddCameraLoaded(plSceneObject* pCam) { fCamerasLoaded.push_back(pCam); } hsBool RestoreFromName(const plString& name); void StartUnPan(); // these are for console access @@ -209,25 +211,25 @@ private: plDebugInputInterface* fCameraDriveInterface; plPlate* fEffectPlate; FILE* foutLog; - hsTArray fCameraStack; + plCameraVec fCameraStack; int fFreezeCounter; int fFadeCounter; hsBitVector fFlags; - hsTArray fCamerasLoaded; + plSOVec fCamerasLoaded; hsBitVector fMoveFlags; - float fX; - float fY; - float fXPanLimit; - float fZPanLimit; - float fXPanLimitGoal; - float fZPanLimitGoal; - float fXUnPanRate; - float fZUnPanRate; - float fXPanInterpRate; - float fZPanInterpRate; + float fX; + float fY; + float fXPanLimit; + float fZPanLimit; + float fXPanLimitGoal; + float fZPanLimitGoal; + float fXUnPanRate; + float fZUnPanRate; + float fXPanInterpRate; + float fZPanInterpRate; double fUnPanEndTime; double fInterpPanLimitTime; - float fRetainedFY; + float fRetainedFY; // built-in cameras plCameraModifier1* fDriveCamera; // for driving around From 24a644107e3cfbc40ccefef0820fdda4bb3c7a24 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Sat, 25 Feb 2012 01:55:55 -0500 Subject: [PATCH 4/4] Fix relto-plunge Looks like the fissure fall camera region got triggered then untriggered during the linking process. In debug builds, this happened in one frame, so only an exit message got sent out. In faster builds, both would be sent, and you would plunge. To fix that, we don't send eval until we're no longer MidLink. --- .../plPhysical/plCollisionDetector.cpp | 23 +++++++++++++++---- .../plPhysical/plCollisionDetector.h | 8 +++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp index 57a3648d..cf03b0b9 100644 --- a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp +++ b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.cpp @@ -73,6 +73,9 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com plArmatureMod* plCollisionDetector::IGetAvatarModifier(plKey key) { + if (!key) + return nil; + plSceneObject* avObj = plSceneObject::ConvertNoRef(key->ObjectIsLoaded()); if (avObj) { @@ -242,8 +245,6 @@ plCameraRegionDetector::~plCameraRegionDetector() void plCameraRegionDetector::ITrigger(plKey hitter, bool entering, bool immediate) { - if (fSavingSendMsg) - DetectorLogRed("%s: Stale messages on ITrigger. This should never happen!", GetKeyName().c_str()); if (fIsInside && entering) DetectorLogRed("%s: Duplicate enter! Did we miss an exit?", GetKeyName().c_str()); else if (!fIsInside && !entering) @@ -384,11 +385,18 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg) plCollideMsg* pCollMsg = plCollideMsg::ConvertNoRef(msg); if (pCollMsg) { + fLastHitter = pCollMsg->fOtherKey; // If the avatar is disabled (flying around), don't trigger - if (IIsDisabledAvatar(pCollMsg->fOtherKey)) + if (IIsDisabledAvatar(fLastHitter)) return false; - ITrigger(pCollMsg->fOtherKey, (pCollMsg->fEntering != 0)); - plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey()); + ITrigger(fLastHitter, (pCollMsg->fEntering != 0)); + + // If we never eval before the exit... + if (fWaitingForEval) + plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey()); + else + plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey()); + fWaitingForEval = !fWaitingForEval; return true; } @@ -396,8 +404,13 @@ hsBool plObjectInVolumeDetector::MsgReceive(plMessage* msg) if (pEvalMsg) { fNumEvals++; + // Don't dispatch if we're not in the age + if (plArmatureMod* av = IGetAvatarModifier(fLastHitter)) + if (av->IsMidLink()) + return true; ISendSavedTriggerMsgs(); plgDispatch::Dispatch()->UnRegisterForExactType(plEvalMsg::Index(), GetKey()); + fWaitingForEval = false; } plPlayerPageMsg* pageMsg = plPlayerPageMsg::ConvertNoRef(msg); diff --git a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h index f2fa65ea..623b716a 100644 --- a/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h +++ b/Sources/Plasma/PubUtilLib/plPhysical/plCollisionDetector.h @@ -99,15 +99,19 @@ protected: uint32_t fNumEvals; uint32_t fLastEnterEval; uint32_t fLastExitEval; + bool fWaitingForEval; + plKey fLastHitter; public: plObjectInVolumeDetector() - : plCollisionDetector(), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), fLastExitEval(0) + : plCollisionDetector(), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), + fWaitingForEval(false), fLastHitter(nil) { } plObjectInVolumeDetector(int8_t type) - : plCollisionDetector(type), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), fLastExitEval(0) + : plCollisionDetector(type), fSavedActivatorMsg(nil), fNumEvals(0), fLastEnterEval(0), + fWaitingForEval(false), fLastHitter(nil) { } virtual ~plObjectInVolumeDetector() { }