mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-21 04:39:45 +00:00
Hoist MOULOpenSourceClientPlugin/Plasma20/* to top level
to match H'uru layout and make patching/cherry-picking easier.
This commit is contained in:
494
Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp
Normal file
494
Sources/Plasma/FeatureLib/pfCamera/plCameraModifier.cpp
Normal file
@ -0,0 +1,494 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
#include "HeadSpin.h"
|
||||
|
||||
#include "plCameraModifier.h"
|
||||
#include "plCameraBrain.h"
|
||||
#include "plVirtualCamNeu.h"
|
||||
#include "hsTimer.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "../pnSceneObject/plCoordinateInterface.h"
|
||||
#include "../plMessage/plInputEventMsg.h"
|
||||
#include "../plMessage/plAnimCmdMsg.h"
|
||||
#include "../pnMessage/plTimeMsg.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
#include "../pnKeyedObject/plFixedKey.h"
|
||||
#include "../plInputCore/plInputDevice.h"
|
||||
#include "../plInputCore/plInputManager.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "../pnMessage/plCameraMsg.h"
|
||||
#include "../plPhysical/plSimDefs.h"
|
||||
|
||||
#include "plPhysical.h"
|
||||
#include "../pnSceneObject/plSimulationInterface.h"
|
||||
#include "../plAvatar/plAvatarMgr.h"
|
||||
#include "../plAvatar/plArmatureMod.h"
|
||||
#include "../plAvatar/plPhysicalControllerCore.h"
|
||||
|
||||
// new stuff
|
||||
|
||||
plCameraModifier1::plCameraModifier1() :
|
||||
fBrain(nil),
|
||||
fSubObj(nil),
|
||||
fFOVw(45.0f),
|
||||
fFOVh(33.75f),
|
||||
fAnimated(false),
|
||||
fStartAnimOnPush(false),
|
||||
fStopAnimOnPop(false),
|
||||
fResetAnimOnPop(false),
|
||||
fInSubLastUpdate(false),
|
||||
fUpdateBrainTarget(false)
|
||||
{
|
||||
fFrom.Set(0,0,0);
|
||||
fAt.Set(0,1,0);
|
||||
}
|
||||
|
||||
|
||||
plCameraModifier1::~plCameraModifier1()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < GetNumTrans(); i++)
|
||||
delete(GetTrans(i));
|
||||
fTrans.SetCountAndZero(0);
|
||||
|
||||
for (i = 0; i < fMessageQueue.Count(); i++)
|
||||
hsRefCnt_SafeUnRef(fMessageQueue[i]);
|
||||
fMessageQueue.SetCountAndZero(0);
|
||||
|
||||
for (i = 0; i < fFOVInstructions.Count(); i++)
|
||||
hsRefCnt_SafeUnRef(fFOVInstructions[i]);
|
||||
fFOVInstructions.SetCountAndZero(0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void plCameraModifier1::AddTarget(plSceneObject* so)
|
||||
{
|
||||
fTarget = so;
|
||||
if( plVirtualCam1::Instance() )
|
||||
plVirtualCam1::Instance()->AddCameraLoaded(so);
|
||||
fFrom = (so->GetWorldToLocal().GetTranslate());
|
||||
if (GetBrain())
|
||||
{
|
||||
if (fTarget->GetCoordinateInterface())
|
||||
GetBrain()->AddTarget();
|
||||
else
|
||||
fUpdateBrainTarget = true; // update the brain later
|
||||
}
|
||||
if (GetKey())
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plEvalMsg::Index(), GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plCameraModifier1::SetSubject(plSceneObject* pObj)
|
||||
{
|
||||
if (GetBrain())
|
||||
GetBrain()->SetSubject(pObj);
|
||||
else
|
||||
fSubObj = pObj;
|
||||
}
|
||||
|
||||
plSceneObject* plCameraModifier1::GetSubject()
|
||||
{
|
||||
if (GetBrain())
|
||||
return GetBrain()->GetSubject();
|
||||
else
|
||||
return fSubObj;
|
||||
}
|
||||
|
||||
void plCameraModifier1::SetFOVw(hsScalar f, hsBool fUpdateVCam)
|
||||
{
|
||||
fFOVw = f;
|
||||
if (plVirtualCam1::Instance() && fUpdateVCam)
|
||||
plVirtualCam1::SetFOV(fFOVw, fFOVh, this);
|
||||
}
|
||||
|
||||
void plCameraModifier1::SetFOVh(hsScalar f, hsBool fUpdateVCam)
|
||||
{
|
||||
fFOVh = f;
|
||||
if (plVirtualCam1::Instance() && fUpdateVCam)
|
||||
plVirtualCam1::SetFOV(fFOVw, fFOVh, this);
|
||||
}
|
||||
|
||||
hsBool plCameraModifier1::SetFaded(hsBool b)
|
||||
{
|
||||
if (GetBrain())
|
||||
return GetBrain()->SetFaded(b);
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plCameraModifier1::GetFaded()
|
||||
{
|
||||
if (GetBrain())
|
||||
return GetBrain()->GetFaded();
|
||||
return false;
|
||||
}
|
||||
hsBool plCameraModifier1::MsgReceive(plMessage* msg)
|
||||
{
|
||||
if (GetBrain())
|
||||
GetBrain()->MsgReceive(msg);
|
||||
|
||||
plCameraMsg* pCamMsg = plCameraMsg::ConvertNoRef(msg);
|
||||
if (pCamMsg)
|
||||
{
|
||||
if (pCamMsg->Cmd(plCameraMsg::kAddFOVKeyframe))
|
||||
{
|
||||
hsRefCnt_SafeRef(msg);
|
||||
fFOVInstructions.Append(pCamMsg);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
if (pCamMsg->Cmd(plCameraMsg::kSetAnimated))
|
||||
{
|
||||
fAnimated = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
plEventCallbackMsg* pEventMsg = plEventCallbackMsg::ConvertNoRef(msg);
|
||||
if (pEventMsg)
|
||||
{
|
||||
double time = (double)fFOVInstructions[pEventMsg->fIndex]->GetConfig()->fAccel;
|
||||
double time2 = (double)pEventMsg->fEventTime;
|
||||
time = hsABS(time - time2);
|
||||
hsScalar h = fFOVInstructions[pEventMsg->fIndex]->GetConfig()->fFOVh;
|
||||
if (GetBrain())
|
||||
GetBrain()->SetFOVGoal(h, time);
|
||||
}
|
||||
|
||||
plAnimCmdMsg* pAnimMsg = plAnimCmdMsg::ConvertNoRef(msg);
|
||||
if (pAnimMsg)
|
||||
{
|
||||
hsRefCnt_SafeRef(msg);
|
||||
msg->ClearReceivers();
|
||||
msg->AddReceiver(msg->GetSender());
|
||||
fMessageQueue.Append(msg);
|
||||
return true;
|
||||
}
|
||||
plGenRefMsg* pRefMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if (pRefMsg )
|
||||
{
|
||||
if( pRefMsg->GetContext() & (plRefMsg::kOnCreate | plRefMsg::kOnRequest) )
|
||||
{
|
||||
if (pRefMsg->fType == kRefBrain)
|
||||
{
|
||||
plCameraBrain1* pBrain = plCameraBrain1::ConvertNoRef(pRefMsg->GetRef());
|
||||
if (pBrain)
|
||||
{
|
||||
pBrain->SetCamera(this);
|
||||
fBrain = pBrain;
|
||||
if (fSubObj)
|
||||
fBrain->SetSubject(fSubObj);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (pRefMsg->fType == kRefCallbackMsg && fMessageQueue[pRefMsg->fWhich] != nil)
|
||||
{
|
||||
|
||||
plgDispatch::MsgSend(fMessageQueue[pRefMsg->fWhich]);
|
||||
fMessageQueue[pRefMsg->fWhich] = nil;
|
||||
}
|
||||
}
|
||||
else if( pRefMsg->GetContext() & (plRefMsg::kOnDestroy | plRefMsg::kOnRemove) )
|
||||
{
|
||||
plCameraBrain1* pBrain = (plCameraBrain1*)(pRefMsg->GetRef());
|
||||
if (fBrain == pBrain)
|
||||
fBrain = nil;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plSingleModifier::MsgReceive(msg);
|
||||
}
|
||||
|
||||
|
||||
void plCameraModifier1::Update()
|
||||
{
|
||||
// update the brain
|
||||
|
||||
// this freeze thing is a useful debugging tool...
|
||||
if (plVirtualCam1::Instance()->freeze)
|
||||
return;
|
||||
|
||||
if (GetBrain())
|
||||
{
|
||||
if (fUpdateBrainTarget && fTarget->GetCoordinateInterface()) // if we need to update the brain and the target is loaded
|
||||
{
|
||||
fUpdateBrainTarget = false;
|
||||
GetBrain()->AddTarget(); // update the brain's target
|
||||
}
|
||||
|
||||
hsBool moveInSub = !(GetBrain()->HasFlag(plCameraBrain1::kIgnoreSubworldMovement));
|
||||
|
||||
if (moveInSub && GetBrain()->GetSubject())
|
||||
{
|
||||
plKey worldKey = nil;
|
||||
|
||||
// First check if this is a physical. If so, grab the subworld from that
|
||||
if (GetBrain()->GetSubject()->GetSimulationInterface())
|
||||
{
|
||||
plPhysical* phys = GetBrain()->GetSubject()->GetSimulationInterface()->GetPhysical();
|
||||
if (phys)
|
||||
worldKey = phys->GetWorldKey();
|
||||
}
|
||||
// Also, check if this is an avatar. They don't have physicals, you
|
||||
// have to ask the avatar controller for the subworld key.
|
||||
if (!worldKey)
|
||||
{
|
||||
plArmatureMod* armMod = plAvatarMgr::FindAvatar(plKey(GetBrain()->GetSubject()->GetKey()));
|
||||
if (armMod && armMod->GetController() )
|
||||
worldKey = armMod->GetController()->GetSubworld();
|
||||
}
|
||||
|
||||
if (worldKey)
|
||||
{
|
||||
// this picks up and moves the camera to it's previous subworld coordinate (so the subworld isn't moving out from underneath us)
|
||||
hsMatrix44 l2w, w2l;
|
||||
plSceneObject* so = plSceneObject::ConvertNoRef(worldKey->ObjectIsLoaded());
|
||||
if (so)
|
||||
{
|
||||
l2w = so->GetLocalToWorld();
|
||||
w2l = so->GetWorldToLocal();
|
||||
|
||||
if (fInSubLastUpdate)
|
||||
{
|
||||
if (!(fLastSubPos == fFrom && fLastSubPOA == fAt))
|
||||
{
|
||||
SetTargetPos(l2w * fLastSubPos);
|
||||
SetTargetPOA(l2w * fLastSubPOA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fInSubLastUpdate = true;
|
||||
}
|
||||
GetBrain()->Update();
|
||||
fLastSubPos = w2l * GetTargetPos();
|
||||
fLastSubPOA = w2l * GetTargetPOA();
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fInSubLastUpdate = false;
|
||||
}
|
||||
}
|
||||
GetBrain()->Update();
|
||||
fLastSubPos = GetTargetPos();
|
||||
fLastSubPOA = GetTargetPOA();
|
||||
}
|
||||
}
|
||||
|
||||
void plCameraModifier1::Read(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(stream, mgr);
|
||||
fBrain = nil;
|
||||
mgr->ReadKeyNotifyMe(stream, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefBrain), plRefFlags::kActiveRef);
|
||||
int count = stream->ReadSwap32();
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
||||
plKey key = mgr->ReadKey(stream);
|
||||
hsBool cutpos = stream->ReadBool();
|
||||
hsBool cutpoa = stream->ReadBool();
|
||||
hsBool ignore = stream->ReadBool();
|
||||
hsScalar v = stream->ReadSwapScalar();
|
||||
hsScalar a = stream->ReadSwapScalar();
|
||||
hsScalar d = stream->ReadSwapScalar();
|
||||
hsScalar pV = stream->ReadSwapScalar();
|
||||
hsScalar pA = stream->ReadSwapScalar();
|
||||
hsScalar pD = stream->ReadSwapScalar();
|
||||
|
||||
CamTrans* camTrans = TRACKED_NEW CamTrans(key);
|
||||
camTrans->fAccel = a;
|
||||
camTrans->fDecel = d;
|
||||
camTrans->fVelocity = v;
|
||||
camTrans->fPOAAccel = pA;
|
||||
camTrans->fPOADecel = pD;
|
||||
camTrans->fPOAVelocity = pV;
|
||||
camTrans->fCutPos = cutpos;
|
||||
camTrans->fCutPOA = cutpoa;
|
||||
camTrans->fIgnore = ignore;
|
||||
|
||||
fTrans.Append(camTrans);
|
||||
}
|
||||
fFOVw = stream->ReadSwapFloat();
|
||||
fFOVh = stream->ReadSwapFloat();
|
||||
int n = stream->ReadSwap32();
|
||||
fMessageQueue.SetCountAndZero(n);
|
||||
for(i = 0; i < n; i++ )
|
||||
{
|
||||
plMessage* pMsg = plMessage::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
fMessageQueue[i] = pMsg;
|
||||
}
|
||||
for(i = 0; i < n; i++ )
|
||||
{
|
||||
mgr->ReadKeyNotifyMe(stream, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, i, kRefCallbackMsg), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
n = stream->ReadSwap32();
|
||||
fFOVInstructions.SetCountAndZero(n);
|
||||
for(i = 0; i < n; i++ )
|
||||
{
|
||||
plCameraMsg* pMsg = plCameraMsg::ConvertNoRef(mgr->ReadCreatable(stream));
|
||||
fFOVInstructions[i] = pMsg;
|
||||
}
|
||||
fAnimated = stream->ReadBool();
|
||||
fStartAnimOnPush = stream->ReadBool();
|
||||
fStopAnimOnPop = stream->ReadBool();
|
||||
fResetAnimOnPop = stream->ReadBool();
|
||||
|
||||
}
|
||||
|
||||
void plCameraModifier1::Write(hsStream* stream, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(stream, mgr);
|
||||
if (fBrain)
|
||||
mgr->WriteKey(stream, fBrain );
|
||||
|
||||
int i = fTrans.Count();
|
||||
stream->WriteSwap32(i);
|
||||
for (i = 0; i < fTrans.Count(); i++)
|
||||
{
|
||||
mgr->WriteKey(stream, fTrans[i]->fTransTo);
|
||||
stream->WriteBool(fTrans[i]->fCutPos);
|
||||
stream->WriteBool(fTrans[i]->fCutPOA);
|
||||
stream->WriteBool(fTrans[i]->fIgnore);
|
||||
stream->WriteSwapScalar(fTrans[i]->fVelocity);
|
||||
stream->WriteSwapScalar(fTrans[i]->fAccel);
|
||||
stream->WriteSwapScalar(fTrans[i]->fDecel);
|
||||
stream->WriteSwapScalar(fTrans[i]->fPOAVelocity);
|
||||
stream->WriteSwapScalar(fTrans[i]->fPOAAccel);
|
||||
stream->WriteSwapScalar(fTrans[i]->fPOADecel);
|
||||
}
|
||||
stream->WriteSwapFloat(fFOVw);
|
||||
stream->WriteSwapFloat(fFOVh);
|
||||
stream->WriteSwap32(fMessageQueue.Count());
|
||||
for (i = 0; i < fMessageQueue.Count(); i++)
|
||||
{
|
||||
mgr->WriteCreatable(stream, fMessageQueue[i]);
|
||||
}
|
||||
for (i = 0; i < fMessageQueue.Count(); i++)
|
||||
{
|
||||
mgr->WriteKey(stream, fMessageQueue[i]->GetSender());
|
||||
}
|
||||
stream->WriteSwap32(fFOVInstructions.Count());
|
||||
for (i = 0; i < fFOVInstructions.Count(); i++)
|
||||
{
|
||||
mgr->WriteCreatable(stream, fFOVInstructions[i]);
|
||||
}
|
||||
stream->WriteBool(fAnimated);
|
||||
stream->WriteBool(fStartAnimOnPush);
|
||||
stream->WriteBool(fStopAnimOnPop);
|
||||
stream->WriteBool(fResetAnimOnPop);
|
||||
}
|
||||
|
||||
void plCameraModifier1::Push(hsBool recenter)
|
||||
{
|
||||
if (fAnimated)
|
||||
{
|
||||
if (fStartAnimOnPush)
|
||||
{
|
||||
plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
pMsg->SetCmd(plAnimCmdMsg::kRunForward);
|
||||
pMsg->SetBCastFlag(plMessage::kPropagateToModifiers);
|
||||
pMsg->AddReceiver(GetTarget()->GetKey());
|
||||
if (GetBrain() && GetBrain()->GetSubject())
|
||||
pMsg->AddReceiver(GetBrain()->GetSubject()->GetKey());
|
||||
pMsg->Send();
|
||||
}
|
||||
}
|
||||
if (fBrain)
|
||||
fBrain->Push(recenter);
|
||||
|
||||
|
||||
if (GetKey())
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plMouseEventMsg::Index(), GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plCameraModifier1::Pop()
|
||||
{
|
||||
if (fAnimated)
|
||||
{
|
||||
if (fStopAnimOnPop)
|
||||
{
|
||||
plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
pMsg->SetCmd(plAnimCmdMsg::kStop);
|
||||
pMsg->SetBCastFlag(plMessage::kPropagateToModifiers);
|
||||
pMsg->AddReceiver(GetTarget()->GetKey());
|
||||
if (GetBrain() && GetBrain()->GetSubject())
|
||||
pMsg->AddReceiver(GetBrain()->GetSubject()->GetKey());
|
||||
pMsg->Send();
|
||||
}
|
||||
if (fResetAnimOnPop)
|
||||
{
|
||||
plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg;
|
||||
pMsg->SetCmd(plAnimCmdMsg::kGoToBegin);
|
||||
pMsg->SetBCastFlag(plMessage::kPropagateToModifiers);
|
||||
pMsg->AddReceiver(GetTarget()->GetKey());
|
||||
if (GetBrain() && GetBrain()->GetSubject())
|
||||
pMsg->AddReceiver(GetBrain()->GetSubject()->GetKey());
|
||||
pMsg->Send();
|
||||
}
|
||||
}
|
||||
if (fBrain)
|
||||
fBrain->Pop();
|
||||
if (GetKey()) // the reason we might not have a key is a special run-time POA which doesn't need to receive messages...
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plMouseEventMsg::Index(), GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plCameraModifier1::SetTransform(hsPoint3 at)
|
||||
{
|
||||
if (!GetTarget())
|
||||
return;
|
||||
hsMatrix44 l2w;
|
||||
hsMatrix44 w2l;
|
||||
hsVector3 up(0,0,1);
|
||||
l2w.Make(&fFrom, &at, &up);
|
||||
l2w.GetInverse(&w2l);
|
||||
IGetTargetCoordinateInterface(0)->SetTransform( l2w, w2l );
|
||||
}
|
Reference in New Issue
Block a user