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:
968
Sources/Plasma/PubUtilLib/plPipeline/plDynamicEnvMap.cpp
Normal file
968
Sources/Plasma/PubUtilLib/plPipeline/plDynamicEnvMap.cpp
Normal file
@ -0,0 +1,968 @@
|
||||
/*==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 "hsTypes.h"
|
||||
#include "plDynamicEnvMap.h"
|
||||
|
||||
#include "plPipeline.h"
|
||||
#include "plPipeDebugFlags.h"
|
||||
#include "plDrawable.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
#include "hsTimer.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
#include "../plMessage/plDynamicEnvMapMsg.h"
|
||||
#include "../pfCamera/plCameraModifier.h"
|
||||
#include "../pfCamera/plVirtualCamNeu.h"
|
||||
#include "../plMessage/plRenderMsg.h"
|
||||
#include "../plMessage/plAgeLoadedMsg.h"
|
||||
#include "../plMessage/plLayRefMsg.h"
|
||||
#include "../pnMessage/plPipeResMakeMsg.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
|
||||
#include "../plScene/plVisRegion.h"
|
||||
#include "../plScene/plVisMgr.h"
|
||||
#include "../plResMgr/plKeyFinder.h"
|
||||
#include "../plSurface/plLayer.h"
|
||||
|
||||
plDynamicEnvMap::plDynamicEnvMap()
|
||||
: fPos(0,0,0),
|
||||
fHither(0.3f),
|
||||
fYon(1000.f),
|
||||
fFogStart(1000.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fLastRender(0),
|
||||
fOutStanding(0),
|
||||
fIncCharacters(false),
|
||||
fRootNode(nil)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i] = TRACKED_NEW plRenderRequestMsg(nil, &fReqs[i]);;
|
||||
|
||||
SetPosition(fPos);
|
||||
}
|
||||
|
||||
plDynamicEnvMap::plDynamicEnvMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth, UInt8 sDepth)
|
||||
: fPos(0,0,0),
|
||||
fHither(0.3f),
|
||||
fYon(0.f), // yon < hither means ignore and use current settings
|
||||
fFogStart(-1.f), // - fog start means use current settings
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fLastRender(0),
|
||||
fOutStanding(0),
|
||||
fIncCharacters(false),
|
||||
fRootNode(nil),
|
||||
plCubicRenderTarget(plRenderTarget::kIsTexture, width, height, bitDepth, zDepth, sDepth)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i] = TRACKED_NEW plRenderRequestMsg(nil, &fReqs[i]);;
|
||||
|
||||
SetPosition(fPos);
|
||||
}
|
||||
|
||||
plDynamicEnvMap::~plDynamicEnvMap()
|
||||
{
|
||||
SetDeviceRef(nil);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
delete fReqMsgs[i];
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Init()
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
|
||||
ISetupRenderRequests();
|
||||
}
|
||||
|
||||
hsPoint3 plDynamicEnvMap::GetPosition() const
|
||||
{
|
||||
if (fRootNode)
|
||||
{
|
||||
// This is to catch export issues where we've got a root node, but its iface
|
||||
// hasn't fully been set up yet.
|
||||
if (fRootNode->GetCoordinateInterface())
|
||||
return fRootNode->GetLocalToWorld().GetTranslate();
|
||||
}
|
||||
|
||||
return fPos;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetPosition(const hsPoint3& pos)
|
||||
{
|
||||
hsAssert(fRootNode == nil, "Trying to override a cube map's root node.");
|
||||
fPos = pos;
|
||||
SetCameraMatrix(fPos);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::IUpdatePosition()
|
||||
{
|
||||
hsPoint3 pos = GetPosition();
|
||||
if (pos != fPos)
|
||||
SetCameraMatrix(fPos);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetHither(hsScalar f)
|
||||
{
|
||||
fHither = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetYon(hsScalar f)
|
||||
{
|
||||
fYon = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetFogStart(hsScalar f)
|
||||
{
|
||||
fFogStart = f;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetColor(const hsColorRGBA& col)
|
||||
{
|
||||
fColor = col;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetRefreshRate(hsScalar secs)
|
||||
{
|
||||
fRefreshRate = secs / 6.f;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISetupRenderRequests()
|
||||
{
|
||||
UInt32 renderState
|
||||
= plPipeline::kRenderNormal
|
||||
| plPipeline::kRenderClearColor
|
||||
| plPipeline::kRenderClearDepth;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
fReqs[i].SetRenderState(renderState);
|
||||
|
||||
fReqs[i].SetDrawableMask(plDrawable::kNormal);
|
||||
fReqs[i].SetSubDrawableMask(plDrawable::kSubAllTypes);
|
||||
|
||||
fReqs[i].SetHither(fHither);
|
||||
fReqs[i].SetYon(fYon);
|
||||
|
||||
fReqs[i].SetFogStart(fFogStart);
|
||||
|
||||
fReqs[i].SetFovX(90.f);
|
||||
fReqs[i].SetFovY(90.f);
|
||||
|
||||
fReqs[i].SetClearColor(fColor);
|
||||
fReqs[i].SetClearDepth(1.f);
|
||||
|
||||
fReqs[i].SetClearDrawable(nil);
|
||||
fReqs[i].SetRenderTarget(GetFace(i));
|
||||
|
||||
fReqs[i].SetCameraTransform(GetWorldToCamera(i), GetCameraToWorld(i));
|
||||
|
||||
fReqs[i].SetVisForce(fVisSet);
|
||||
|
||||
fReqs[i].RequestAck(GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISubmitRenderRequest(int i)
|
||||
{
|
||||
IUpdatePosition();
|
||||
fReqMsgs[i]->SendAndKeep();
|
||||
fLastRender = i;
|
||||
fOutStanding++;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ISubmitRenderRequests()
|
||||
{
|
||||
IUpdatePosition();
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
fReqMsgs[i]->SendAndKeep();
|
||||
fLastRefresh = hsTimer::GetSysSeconds();
|
||||
fOutStanding += 6;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ICheckForRefresh(double t, plPipeline *pipe)
|
||||
{
|
||||
if( fLastRefresh <= 0 )
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
|
||||
if( fRefreshRate <= 0 )
|
||||
return;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
if (pipe->IsDebugFlagSet(plPipeDbg::kFlagNVPerfHUD) && hsTimer::GetDelSysSeconds() == 0)
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
if( t > fLastRefresh + 6.f * fRefreshRate )
|
||||
{
|
||||
ISubmitRenderRequests();
|
||||
return;
|
||||
}
|
||||
while( t > fLastRefresh + fRefreshRate )
|
||||
{
|
||||
int nextRender = fLastRender+1;
|
||||
if( nextRender > 5 )
|
||||
nextRender = 0;
|
||||
ISubmitRenderRequest(nextRender);
|
||||
fLastRefresh += fRefreshRate;
|
||||
}
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::ReRender()
|
||||
{
|
||||
ISetupRenderRequests();
|
||||
ISubmitRenderRequests();
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::INeedReRender()
|
||||
{
|
||||
fOutStanding = 0;
|
||||
fLastRefresh = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderRequestAck* ack = plRenderRequestAck::ConvertNoRef(msg);
|
||||
if( ack )
|
||||
{
|
||||
fOutStanding--;
|
||||
return true;
|
||||
}
|
||||
plRenderMsg* rendMsg = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rendMsg )
|
||||
{
|
||||
if( fOutStanding )
|
||||
INeedReRender();
|
||||
|
||||
ICheckForRefresh(hsTimer::GetSysSeconds(), rendMsg->Pipeline());
|
||||
return true;
|
||||
}
|
||||
if( plPipeRTMakeMsg::ConvertNoRef(msg) )
|
||||
{
|
||||
INeedReRender();
|
||||
plCubicRenderTarget::MsgReceive(msg);
|
||||
return true;
|
||||
}
|
||||
plAgeLoadedMsg* ageLoaded = plAgeLoadedMsg::ConvertNoRef(msg);
|
||||
if( ageLoaded && ageLoaded->fLoaded )
|
||||
return INeedReRender();
|
||||
|
||||
if( plInitialAgeStateLoadedMsg::ConvertNoRef(msg) )
|
||||
return INeedReRender();
|
||||
|
||||
plDynamicEnvMapMsg* cmd = plDynamicEnvMapMsg::ConvertNoRef(msg);
|
||||
if( cmd )
|
||||
{
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetPosition )
|
||||
SetPosition(cmd->fPos);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetHither )
|
||||
SetHither(cmd->fHither);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetFogStart )
|
||||
SetFogStart(cmd->fFogStart);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetYon )
|
||||
SetYon(cmd->fYon);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetColor )
|
||||
SetColor(cmd->fColor);
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetRefresh )
|
||||
SetRefreshRate(cmd->fRefresh);
|
||||
|
||||
// If we're going to ReRender, make sure we've gotten any
|
||||
// parameter changes first.
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kReRender )
|
||||
{
|
||||
ISetupRenderRequests();
|
||||
INeedReRender();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( IOnRefMsg(refMsg) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return plCubicRenderTarget::MsgReceive(msg);
|
||||
}
|
||||
|
||||
hsBool plDynamicEnvMap::IOnRefMsg(plGenRefMsg* refMsg)
|
||||
{
|
||||
switch( refMsg->fType)
|
||||
{
|
||||
case kRefVisSet:
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( reg && (fVisRegions.kMissingIndex == idx) )
|
||||
{
|
||||
fVisRegions.Append(reg);
|
||||
fVisSet.SetBit(reg->GetIndex());
|
||||
}
|
||||
ISetupRenderRequests();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( reg && (fVisRegions.kMissingIndex != idx) )
|
||||
{
|
||||
fVisRegions.Remove(idx);
|
||||
fVisSet.ClearBit(reg->GetIndex());
|
||||
}
|
||||
ISetupRenderRequests();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case kRefRootNode:
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
fRootNode = so;
|
||||
else
|
||||
fRootNode = nil;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::SetIncludeCharacters(hsBool b)
|
||||
{
|
||||
fIncCharacters = b;
|
||||
if( b )
|
||||
fVisSet.SetBit(plVisMgr::kCharacter);
|
||||
else
|
||||
fVisSet.ClearBit(plVisMgr::kCharacter);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::AddVisRegion(plVisRegion* reg)
|
||||
{
|
||||
plGenRefMsg* msg = TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnRequest, 0, kRefVisSet);
|
||||
hsgResMgr::ResMgr()->AddViaNotify(reg->GetKey(), msg, plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
UInt32 sz = plCubicRenderTarget::Read(s);
|
||||
|
||||
fPos.Read(s);
|
||||
fHither = s->ReadSwapScalar();
|
||||
fYon = s->ReadSwapScalar();
|
||||
fFogStart = s->ReadSwapScalar();
|
||||
fColor.Read(s);
|
||||
|
||||
fRefreshRate = s->ReadSwapScalar();
|
||||
|
||||
SetPosition(fPos);
|
||||
|
||||
sz += sizeof(fPos) + sizeof(fHither) + sizeof(fYon) + sizeof(fFogStart) + sizeof(fColor) + sizeof(fRefreshRate);
|
||||
|
||||
fIncCharacters = s->ReadByte();
|
||||
SetIncludeCharacters(fIncCharacters);
|
||||
int nVis = s->ReadSwap32();
|
||||
int i;
|
||||
for( i = 0; i < nVis; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
|
||||
nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++)
|
||||
{
|
||||
char *name = s->ReadSafeString();
|
||||
plKey key = plKeyFinder::Instance().StupidSearch(nil, nil, plVisRegion::Index(), name);
|
||||
delete[] name;
|
||||
if (key)
|
||||
hsgResMgr::ResMgr()->AddViaNotify(key, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefRootNode), plRefFlags::kActiveRef);
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void plDynamicEnvMap::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
|
||||
UInt32 sz = plCubicRenderTarget::Write(s);
|
||||
|
||||
fPos.Write(s);
|
||||
s->WriteSwapScalar(fHither);
|
||||
s->WriteSwapScalar(fYon);
|
||||
s->WriteSwapScalar(fFogStart);
|
||||
fColor.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fRefreshRate);
|
||||
|
||||
sz += sizeof(fPos) + sizeof(fHither) + sizeof(fYon) + sizeof(fFogStart) + sizeof(fColor) + sizeof(fRefreshRate);
|
||||
|
||||
s->WriteByte(fIncCharacters);
|
||||
s->WriteSwap32(fVisRegions.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fVisRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fVisRegions[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegionNames.Count());
|
||||
for( i = 0; i < fVisRegionNames.Count(); i++)
|
||||
{
|
||||
s->WriteSafeString(fVisRegionNames[i]);
|
||||
}
|
||||
|
||||
mgr->WriteKey(s, fRootNode);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
UInt8 plDynamicCamMap::fFlags = kReflectionEnabled | kReflectionCapable;
|
||||
|
||||
plDynamicCamMap::plDynamicCamMap() :
|
||||
fHither(0.3f),
|
||||
fYon(500.f),
|
||||
fFogStart(1000.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fOutStanding(0),
|
||||
fCamera(nil),
|
||||
fRootNode(nil),
|
||||
fIncCharacters(false),
|
||||
fDisableTexture(nil)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
fReqMsg = TRACKED_NEW plRenderRequestMsg(nil, &fReq);
|
||||
}
|
||||
|
||||
plDynamicCamMap::plDynamicCamMap(UInt16 width, UInt16 height, UInt8 bitDepth, UInt8 zDepth, UInt8 sDepth) :
|
||||
fHither(0.3f),
|
||||
fYon(-1.f),
|
||||
fFogStart(-1.f),
|
||||
fRefreshRate(0.f),
|
||||
fLastRefresh(0.0),
|
||||
fOutStanding(0),
|
||||
fCamera(nil),
|
||||
fRootNode(nil),
|
||||
fIncCharacters(false),
|
||||
fDisableTexture(nil),
|
||||
plRenderTarget(plRenderTarget::kIsTexture, width, height, bitDepth, zDepth, sDepth)
|
||||
{
|
||||
fColor.Set(0,0,0,1.f);
|
||||
fReqMsg = TRACKED_NEW plRenderRequestMsg(nil, &fReq);
|
||||
}
|
||||
|
||||
plDynamicCamMap::~plDynamicCamMap()
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
|
||||
SetDeviceRef(nil);
|
||||
|
||||
delete fReqMsg;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Init()
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plPipeRTMakeMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plInitialAgeStateLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plAgeLoadedMsg::Index(), GetKey());
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetRefreshRate(hsScalar secs)
|
||||
{
|
||||
fRefreshRate = secs;
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ISetupRenderRequest(plPipeline *pipe)
|
||||
{
|
||||
fReq.SetRenderState(plPipeline::kRenderNormal | plPipeline::kRenderClearColor | plPipeline::kRenderClearDepth);
|
||||
fReq.SetDrawableMask(plDrawable::kNormal);
|
||||
fReq.SetSubDrawableMask(plDrawable::kSubAllTypes);
|
||||
fReq.SetHither(fHither);
|
||||
fReq.SetYon(fYon);
|
||||
fReq.SetFogStart(fFogStart);
|
||||
|
||||
// For a reflection map, this must match the camera FOV, or else the camera based
|
||||
// texture coordinates for the reflection texture will be off.
|
||||
//
|
||||
// For a fixed camera, you might want to use the height in both params, so that
|
||||
// you're rendering a square FOV into your square texture. In practice, the artists
|
||||
// don't mind the visual results when just scaling their UVs, so I'll leave it the
|
||||
// same for both cases.
|
||||
fReq.SetFovX(fCamera ? fCamera->GetFOVw() : plVirtualCam1::Instance()->GetFOVw());
|
||||
fReq.SetFovY(fCamera ? fCamera->GetFOVh() : plVirtualCam1::Instance()->GetFOVh());
|
||||
|
||||
fReq.SetClearColor(fColor);
|
||||
fReq.SetClearDepth(1.f);
|
||||
fReq.SetClearDrawable(nil);
|
||||
fReq.SetRenderTarget(this);
|
||||
fReq.SetVisForce(fVisSet);
|
||||
fReq.SetIgnoreOccluders(true);
|
||||
fReq.RequestAck(GetKey());
|
||||
|
||||
hsMatrix44 w2c, c2w;
|
||||
if (fCamera)
|
||||
{
|
||||
w2c.MakeCamera(&fCamera->GetTargetPos(), &fCamera->GetTargetPOA(), &hsVector3(0.f, 0.f, 1.f));
|
||||
w2c.GetInverse(&c2w);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!fRootNode)
|
||||
return;
|
||||
|
||||
// Could be optimized, but the matrix construction work here seems cheap relative to the cost
|
||||
// of rerendering all this stuff to a separate target, so I doubt we'd notice.
|
||||
hsMatrix44 invert;
|
||||
invert.MakeScaleMat(&(hsVector3(1.f, 1.f, -1.f)));
|
||||
w2c = pipe->GetWorldToCamera();
|
||||
c2w = pipe->GetCameraToWorld();
|
||||
|
||||
w2c = w2c * fRootNode->GetLocalToWorld() * invert * fRootNode->GetWorldToLocal();
|
||||
c2w = fRootNode->GetWorldToLocal() * invert * fRootNode->GetLocalToWorld() * c2w;
|
||||
}
|
||||
fReq.SetCameraTransform(w2c, c2w);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ISubmitRenderRequest(plPipeline *pipe)
|
||||
{
|
||||
ISetupRenderRequest(pipe);
|
||||
fReqMsg->SendAndKeep();
|
||||
fOutStanding++;
|
||||
fLastRefresh = hsTimer::GetSysSeconds();
|
||||
}
|
||||
|
||||
void plDynamicCamMap::ICheckForRefresh(double t, plPipeline *pipe)
|
||||
{
|
||||
int i;
|
||||
|
||||
hsBool useRefl = (fFlags & kReflectionMask) == kReflectionMask;
|
||||
if (!fCamera)
|
||||
{
|
||||
if ((useRefl && fMatLayers[0]->GetTexture() != this) || (!useRefl && fMatLayers[0]->GetTexture() != fDisableTexture))
|
||||
IPrepTextureLayers();
|
||||
}
|
||||
|
||||
// So no one's using us, eh? Hitting this condition is likely a bug,
|
||||
// but an assert every frame would be annoying. We'll notice when
|
||||
// the render target never updates.
|
||||
if (fTargetNodes.GetCount() == 0)
|
||||
return;
|
||||
|
||||
// If dynamic planar reflections are disabled and we're using our substitute
|
||||
// texture, don't update. Otherwise, this particular reflection is forced to
|
||||
// always display.
|
||||
if (!useRefl && fDisableTexture)
|
||||
return;
|
||||
|
||||
hsBool inView = false;
|
||||
for (i = 0; i < fTargetNodes.GetCount(); i++)
|
||||
{
|
||||
if (pipe->TestVisibleWorld(fTargetNodes[i]))
|
||||
{
|
||||
inView = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inView)
|
||||
return;
|
||||
|
||||
if( fLastRefresh <= 0 )
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
return;
|
||||
}
|
||||
|
||||
if( fRefreshRate <= 0 )
|
||||
return;
|
||||
|
||||
#ifndef PLASMA_EXTERNAL_RELEASE
|
||||
if (pipe->IsDebugFlagSet(plPipeDbg::kFlagNVPerfHUD) && hsTimer::GetDelSysSeconds() == 0)
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
}
|
||||
#endif // PLASMA_EXTERNAL_RELEASE
|
||||
|
||||
if (t > fLastRefresh + fRefreshRate)
|
||||
{
|
||||
ISubmitRenderRequest(pipe);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::INeedReRender()
|
||||
{
|
||||
fOutStanding = 0;
|
||||
fLastRefresh = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderRequestAck* ack = plRenderRequestAck::ConvertNoRef(msg);
|
||||
if( ack )
|
||||
{
|
||||
fOutStanding--;
|
||||
return true;
|
||||
}
|
||||
plRenderMsg* rendMsg = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rendMsg )
|
||||
{
|
||||
if( fOutStanding )
|
||||
INeedReRender();
|
||||
|
||||
ICheckForRefresh(hsTimer::GetSysSeconds(), rendMsg->Pipeline());
|
||||
return true;
|
||||
}
|
||||
if( plPipeRTMakeMsg::ConvertNoRef(msg) )
|
||||
{
|
||||
INeedReRender();
|
||||
plRenderTarget::MsgReceive(msg);
|
||||
return true;
|
||||
}
|
||||
plAgeLoadedMsg* ageLoaded = plAgeLoadedMsg::ConvertNoRef(msg);
|
||||
if( ageLoaded && ageLoaded->fLoaded )
|
||||
return INeedReRender();
|
||||
|
||||
if( plInitialAgeStateLoadedMsg::ConvertNoRef(msg) )
|
||||
return INeedReRender();
|
||||
|
||||
plDynamicEnvMapMsg* cmd = plDynamicEnvMapMsg::ConvertNoRef(msg);
|
||||
if( cmd )
|
||||
{
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetFogStart )
|
||||
fFogStart = cmd->fFogStart;
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetColor )
|
||||
fColor = cmd->fColor;
|
||||
|
||||
if( cmd->fCmd & plDynamicEnvMapMsg::kSetRefresh )
|
||||
SetRefreshRate(cmd->fRefresh);
|
||||
|
||||
return true;
|
||||
}
|
||||
plRefMsg* refMsg = plRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( IOnRefMsg(refMsg) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return plRenderTarget::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::IPrepTextureLayers()
|
||||
{
|
||||
if (fDisableTexture)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fMatLayers.GetCount(); i++)
|
||||
{
|
||||
if ((fFlags & kReflectionMask) == kReflectionMask)
|
||||
{
|
||||
fMatLayers[i]->SetUVWSrc(plLayerInterface::kUVWPosition);
|
||||
fMatLayers[i]->SetMiscFlags(hsGMatState::kMiscCam2Screen | hsGMatState::kMiscPerspProjection);
|
||||
hsgResMgr::ResMgr()->SendRef(GetKey(), TRACKED_NEW plGenRefMsg(fMatLayers[i]->GetKey(), plRefMsg::kOnRequest, 0, plLayRefMsg::kTexture), plRefFlags::kActiveRef);
|
||||
}
|
||||
else
|
||||
{
|
||||
fMatLayers[i]->SetUVWSrc(0);
|
||||
fMatLayers[i]->SetMiscFlags(0);
|
||||
hsgResMgr::ResMgr()->SendRef(fDisableTexture->GetKey(), TRACKED_NEW plGenRefMsg(fMatLayers[i]->GetKey(), plRefMsg::kOnRequest, 0, plLayRefMsg::kTexture), plRefFlags::kActiveRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plDynamicCamMap::IOnRefMsg(plRefMsg* refMsg)
|
||||
{
|
||||
plGenRefMsg* genRefMsg = plGenRefMsg::ConvertNoRef(refMsg);
|
||||
|
||||
if (genRefMsg)
|
||||
{
|
||||
if (genRefMsg->fType == kRefVisSet)
|
||||
{
|
||||
plVisRegion* reg = plVisRegion::ConvertNoRef(refMsg->GetRef());
|
||||
if (reg)
|
||||
{
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if ((refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace)) && fVisRegions.kMissingIndex == idx)
|
||||
{
|
||||
fVisRegions.Append(reg);
|
||||
fVisSet.SetBit(reg->GetIndex());
|
||||
}
|
||||
else if (!(refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace)) && fVisRegions.kMissingIndex != idx)
|
||||
{
|
||||
fVisRegions.Remove(idx);
|
||||
fVisSet.ClearBit(reg->GetIndex());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefCamera)
|
||||
{
|
||||
plCameraModifier1 *cam = plCameraModifier1::ConvertNoRef(refMsg->GetRef());
|
||||
if (cam)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fCamera = cam;
|
||||
else
|
||||
fCamera = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefRootNode)
|
||||
{
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if (so)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fRootNode = so;
|
||||
else
|
||||
fRootNode = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefTargetNode)
|
||||
{
|
||||
plSceneObject *so = plSceneObject::ConvertNoRef(refMsg->GetRef());
|
||||
if (so)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
{
|
||||
if (fTargetNodes.Find(so) == fTargetNodes.kMissingIndex)
|
||||
fTargetNodes.Append(so);
|
||||
}
|
||||
else
|
||||
{
|
||||
fTargetNodes.RemoveItem(so);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefDisableTexture)
|
||||
{
|
||||
plBitmap *bitmap = plBitmap::ConvertNoRef(refMsg->GetRef());
|
||||
if (bitmap)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
fDisableTexture = bitmap;
|
||||
else
|
||||
fDisableTexture = nil;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (genRefMsg->fType == kRefMatLayer)
|
||||
{
|
||||
plLayer *lay = plLayer::ConvertNoRef(refMsg->GetRef());
|
||||
if (lay)
|
||||
{
|
||||
if (refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace))
|
||||
{
|
||||
if (fMatLayers.Find(lay) == fMatLayers.kMissingIndex)
|
||||
fMatLayers.Append(lay);
|
||||
}
|
||||
else
|
||||
{
|
||||
fMatLayers.RemoveItem(lay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetIncludeCharacters(hsBool b)
|
||||
{
|
||||
fIncCharacters = b;
|
||||
if( b )
|
||||
fVisSet.SetBit(plVisMgr::kCharacter);
|
||||
else
|
||||
fVisSet.ClearBit(plVisMgr::kCharacter);
|
||||
}
|
||||
|
||||
void plDynamicCamMap::AddVisRegion(plVisRegion* reg)
|
||||
{
|
||||
hsgResMgr::ResMgr()->AddViaNotify( reg->GetKey(), TRACKED_NEW plGenRefMsg( GetKey(), plGenRefMsg::kOnReplace, -1, kRefVisSet ), plRefFlags::kActiveRef );
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetEnabled(hsBool enable)
|
||||
{
|
||||
if (enable)
|
||||
fFlags |= kReflectionEnabled;
|
||||
else
|
||||
fFlags &= ~kReflectionEnabled;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::SetCapable(hsBool capable)
|
||||
{
|
||||
if (capable)
|
||||
fFlags |= kReflectionCapable;
|
||||
else
|
||||
fFlags &= ~kReflectionCapable;
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
plRenderTarget::Read(s);
|
||||
|
||||
fHither = s->ReadSwapScalar();
|
||||
fYon = s->ReadSwapScalar();
|
||||
fFogStart = s->ReadSwapScalar();
|
||||
fColor.Read(s);
|
||||
|
||||
fRefreshRate = s->ReadSwapScalar();
|
||||
fIncCharacters = s->ReadBool();
|
||||
SetIncludeCharacters(fIncCharacters);
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefCamera), plRefFlags::kPassiveRef);
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefRootNode), plRefFlags::kActiveRef);
|
||||
|
||||
int numTargs = s->ReadByte();
|
||||
int i;
|
||||
for (i = 0; i < numTargs; i++)
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, i, kRefTargetNode), plRefFlags::kPassiveRef);
|
||||
|
||||
int nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefVisSet), plRefFlags::kActiveRef);
|
||||
|
||||
nVis = s->ReadSwap32();
|
||||
for( i = 0; i < nVis; i++)
|
||||
{
|
||||
char *name = s->ReadSafeString();
|
||||
plKey key = plKeyFinder::Instance().StupidSearch(nil, nil, plVisRegion::Index(), name);
|
||||
delete[] name;
|
||||
if (key)
|
||||
hsgResMgr::ResMgr()->AddViaNotify(key, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kRefVisSet), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefDisableTexture), plRefFlags::kActiveRef);
|
||||
|
||||
UInt8 numLayers = s->ReadByte();
|
||||
for (i = 0; i < numLayers; i++)
|
||||
{
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefMatLayer), plRefFlags::kPassiveRef);
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
void plDynamicCamMap::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
plRenderTarget::Write(s);
|
||||
|
||||
s->WriteSwapScalar(fHither);
|
||||
s->WriteSwapScalar(fYon);
|
||||
s->WriteSwapScalar(fFogStart);
|
||||
fColor.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fRefreshRate);
|
||||
s->WriteByte(fIncCharacters);
|
||||
mgr->WriteKey(s, (fCamera ? fCamera->GetKey() : nil));
|
||||
mgr->WriteKey(s, (fRootNode ? fRootNode->GetKey() : nil));
|
||||
|
||||
s->WriteByte(fTargetNodes.GetCount());
|
||||
int i;
|
||||
for (i = 0; i < fTargetNodes.GetCount(); i++)
|
||||
mgr->WriteKey(s, fTargetNodes[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegions.GetCount());
|
||||
for( i = 0; i < fVisRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fVisRegions[i]);
|
||||
|
||||
s->WriteSwap32(fVisRegionNames.Count());
|
||||
for( i = 0; i < fVisRegionNames.Count(); i++)
|
||||
{
|
||||
s->WriteSafeString(fVisRegionNames[i]);
|
||||
}
|
||||
|
||||
mgr->WriteKey(s, fDisableTexture ? fDisableTexture->GetKey() : nil);
|
||||
|
||||
s->WriteByte(fMatLayers.GetCount());
|
||||
for (i = 0; i < fMatLayers.GetCount(); i++)
|
||||
{
|
||||
mgr->WriteKey(s, fMatLayers[i]->GetKey());
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user