|
|
|
/*==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 "hsGEnviron.h"
|
|
|
|
#include "../plSurface/hsGLayer.h"
|
|
|
|
#include "../plSurface/hsGMaterial.h"
|
|
|
|
//#include "hsG3DDevice.h"
|
|
|
|
//#include "plCamera.h"
|
|
|
|
#include "hsFogControl.h"
|
|
|
|
#include "../plGRenderProcs/hsGRenderProcs.h"
|
|
|
|
#if 0 // SCENENODE_DEFER
|
|
|
|
#include "hsScene.h"
|
|
|
|
#endif // SCENENODE_DEFER
|
|
|
|
#include "../plResMgr/hsResMgr.h"
|
|
|
|
#include "hsGStatGather3.h"
|
|
|
|
#include "../plResMgr/plKey.h"
|
|
|
|
#include "hsTimer.h"
|
|
|
|
#include "../plResMgr/plRefMsg.h"
|
|
|
|
|
|
|
|
const UInt16 hsGEnvironment::kSaveMagicNumber = 0x1f7a;
|
|
|
|
const UInt16 hsGEnvironment::kSaveVersion = 2;
|
|
|
|
|
|
|
|
hsScalar hsGEnvironment::fYonScale = 1.f;
|
|
|
|
|
|
|
|
hsGEnvironment::hsGEnvironment()
|
|
|
|
: fFlags(0),
|
|
|
|
fValidScale(1.f),
|
|
|
|
fMap(nil),
|
|
|
|
fPos(0,0,0),
|
|
|
|
fRadius(0),
|
|
|
|
fFogDistance(0),
|
|
|
|
fFogDepth(0),
|
|
|
|
fCurrentDepth(0),
|
|
|
|
fFogDensity(0),
|
|
|
|
fDevCache(nil),
|
|
|
|
fYon(0),
|
|
|
|
fFogControl(nil)
|
|
|
|
{
|
|
|
|
fFogColor.SetValue(hsColorRGBA().Set(0, 0, 0, hsScalar1));
|
|
|
|
SetFogColor(fFogColor.GetValue());
|
|
|
|
*fMapName = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsGEnvironment::~hsGEnvironment()
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeUnRef(fMap);
|
|
|
|
hsRefCnt_SafeUnRef(fDevCache);
|
|
|
|
|
|
|
|
hsRefCnt_SafeUnRef(fFogControl);
|
|
|
|
|
|
|
|
Int32 i;
|
|
|
|
for (i=0; i<fFogStateStack.GetCount(); i++)
|
|
|
|
delete fFogStateStack[i];
|
|
|
|
|
|
|
|
for( i = 0; i < GetNumRenderProcs(); i++ )
|
|
|
|
hsRefCnt_SafeUnRef(GetRenderProc(i));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if 0 // SCENENODE_DEFER
|
|
|
|
hsBool32 hsGEnvironment::AddNode(hsSceneNode *node)
|
|
|
|
{
|
|
|
|
return AddNodeKey(node->GetKey());
|
|
|
|
}
|
|
|
|
#endif // SCENENODE_DEFER
|
|
|
|
|
|
|
|
hsBool32 hsGEnvironment::AddNodeKey(plKey *key)
|
|
|
|
{
|
|
|
|
Int32 i;
|
|
|
|
for (i = 0; i < GetNumNodes(); i++)
|
|
|
|
{
|
|
|
|
if (GetNodeKey(i) == key) // nothing to do
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fNodeKeys.Append(key);
|
|
|
|
|
|
|
|
hsSceneNode *node = (hsSceneNode *)(key->GetObjectPtr());
|
|
|
|
#if 0 // SCENENODE_DEFER
|
|
|
|
if (node)
|
|
|
|
{
|
|
|
|
if (!(GetFlags() & hsGEnvironment::kFarOut))
|
|
|
|
{
|
|
|
|
node->SetEnvironment(this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
node->SetFarEnvironment(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // SCENENODE_DEFER
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsSceneNode* hsGEnvironment::GetNode(Int32 i)
|
|
|
|
{
|
|
|
|
return (hsSceneNode*)(fNodeKeys[i]->GetObjectPtr());
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::FogState::ValidateEnv(hsGEnvironment* env)
|
|
|
|
{
|
|
|
|
char* msg = "hsGEnvironment not in reset state.";
|
|
|
|
if( fFlags & kYonSet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kYonSet, msg);
|
|
|
|
hsAssert(fYon == env->YonState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kDistanceSet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kFogDistanceSet, msg);
|
|
|
|
hsAssert(fDistance == env->FogDistanceState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kDepthSet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kFogDepthSet, msg);
|
|
|
|
hsAssert(fDepth == env->FogDepthState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kDensitySet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kFogDensitySet, msg);
|
|
|
|
hsAssert(fDensity == env->FogDensityState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kColorSet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kFogColorSet, msg);
|
|
|
|
hsAssert(fColor == env->FogColorState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kClearSet )
|
|
|
|
{
|
|
|
|
hsAssert(env->GetFlags() & hsGEnvironment::kClearColorSet, msg);
|
|
|
|
hsAssert(fClear == env->ClearColorState(), msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt32 envFogType = env->GetFlags() & hsGEnvironment::kFogTypeMask;
|
|
|
|
switch( fFlags & kTypeMask )
|
|
|
|
{
|
|
|
|
case kLinear:
|
|
|
|
hsAssert(envFogType == hsGEnvironment::kFogLinear, msg);
|
|
|
|
break;
|
|
|
|
case kExp:
|
|
|
|
hsAssert(envFogType == hsGEnvironment::kFogExp, msg);
|
|
|
|
break;
|
|
|
|
case kExp2:
|
|
|
|
hsAssert(envFogType == hsGEnvironment::kFogExp2, msg);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
hsAssert(false, msg);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::FogState::SetFromEnv(hsGEnvironment* env)
|
|
|
|
{
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kYonSet )
|
|
|
|
{
|
|
|
|
fYon = env->YonState();
|
|
|
|
fFlags |= kYonSet;
|
|
|
|
}
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kFogDistanceSet )
|
|
|
|
{
|
|
|
|
fDistance = env->FogDistanceState();
|
|
|
|
fFlags |= kDistanceSet;
|
|
|
|
}
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kFogDepthSet )
|
|
|
|
{
|
|
|
|
fDepth = env->FogDepthState();
|
|
|
|
fFlags |= kDepthSet;
|
|
|
|
}
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kFogDensitySet )
|
|
|
|
{
|
|
|
|
fDensity = env->FogDensityState();
|
|
|
|
fFlags |= kDensitySet;
|
|
|
|
}
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kFogColorSet )
|
|
|
|
{
|
|
|
|
fColor = env->FogColorState();
|
|
|
|
fFlags |= kColorSet;
|
|
|
|
}
|
|
|
|
if( env->GetFlags() & hsGEnvironment::kClearColorSet )
|
|
|
|
{
|
|
|
|
fClear = env->ClearColorState();
|
|
|
|
fFlags |= kClearSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
fFlags &= ~kTypeMask;
|
|
|
|
switch( env->GetFlags() & hsGEnvironment::kFogTypeMask )
|
|
|
|
{
|
|
|
|
case hsGEnvironment::kFogLinear:
|
|
|
|
fFlags |= kLinear;
|
|
|
|
break;
|
|
|
|
case hsGEnvironment::kFogExp:
|
|
|
|
fFlags |= kExp;
|
|
|
|
break;
|
|
|
|
case hsGEnvironment::kFogExp2:
|
|
|
|
fFlags |= kExp2;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
hsAssert(false, "Fog type should at least default at load");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::FogState::SetToEnv(hsGEnvironment* env)
|
|
|
|
{
|
|
|
|
if( fFlags & kYonSet )
|
|
|
|
env->SetYon(fYon);
|
|
|
|
else
|
|
|
|
env->UnSetYon();
|
|
|
|
|
|
|
|
if( fFlags & kDistanceSet )
|
|
|
|
env->SetFogDistance(fDistance);
|
|
|
|
else
|
|
|
|
env->UnSetFogDistance();
|
|
|
|
|
|
|
|
if( fFlags & kDepthSet )
|
|
|
|
{
|
|
|
|
env->SetFogDepth(fDepth);
|
|
|
|
env->SetCurrentDepth(fDepth.GetValue());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
env->UnSetFogDepth();
|
|
|
|
|
|
|
|
if( fFlags & kDensitySet )
|
|
|
|
env->SetFogDensity(fDensity);
|
|
|
|
else
|
|
|
|
env->UnSetFogDensity();
|
|
|
|
|
|
|
|
if( fFlags & kColorSet )
|
|
|
|
env->SetFogColor(fColor);
|
|
|
|
else
|
|
|
|
env->UnSetFogColor();
|
|
|
|
|
|
|
|
if( fFlags & kClearSet )
|
|
|
|
env->SetClearColor(fClear);
|
|
|
|
else
|
|
|
|
env->UnSetClearColor();
|
|
|
|
|
|
|
|
switch( fFlags & kTypeMask )
|
|
|
|
{
|
|
|
|
case kLinear:
|
|
|
|
env->SetFogType(hsGEnvironment::kFogLinear);
|
|
|
|
break;
|
|
|
|
case kExp:
|
|
|
|
env->SetFogType(hsGEnvironment::kFogExp);
|
|
|
|
break;
|
|
|
|
case kExp2:
|
|
|
|
env->SetFogType(hsGEnvironment::kFogExp2);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
hsAssert(false, "Setting lack of fog type");
|
|
|
|
env->SetFogType(0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const UInt16 hsGEnvironment::FogState::kSaveMagicNumber = 0x7385;
|
|
|
|
const UInt16 hsGEnvironment::FogState::kSaveVersion = 1;
|
|
|
|
|
|
|
|
void hsGEnvironment::FogState::Save(hsStream *stream, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
stream->WriteSwap16(kSaveMagicNumber);
|
|
|
|
stream->WriteSwap16(kSaveVersion);
|
|
|
|
|
|
|
|
hsScalar currSecs = hsTimer::GetSysSeconds();
|
|
|
|
stream->WriteSwap32(fFlags);
|
|
|
|
fColor.Write(stream, currSecs);
|
|
|
|
fClear.Write(stream, currSecs);
|
|
|
|
fDistance.WriteScalar(stream, currSecs);
|
|
|
|
fDensity.WriteScalar(stream, currSecs);
|
|
|
|
fDepth.WriteScalar(stream, currSecs);
|
|
|
|
fYon.WriteScalar(stream, currSecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::FogState::Load(hsStream *stream, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
UInt16 magic = stream->ReadSwap16();
|
|
|
|
hsAssert(magic == kSaveMagicNumber, "Bad magic number in hsGEnvironment::FogState on load.");
|
|
|
|
|
|
|
|
UInt16 version = stream->ReadSwap16();
|
|
|
|
hsAssert(version == kSaveVersion, "Bad version in hsGEnvironment::FogState on load.");
|
|
|
|
|
|
|
|
hsScalar currSecs = hsTimer::GetSysSeconds();
|
|
|
|
fFlags = stream->ReadSwap32();
|
|
|
|
fColor.Read(stream, currSecs);
|
|
|
|
fClear.Read(stream, currSecs);
|
|
|
|
fDistance.ReadScalar(stream, currSecs);
|
|
|
|
fDensity.ReadScalar(stream, currSecs);
|
|
|
|
fDepth.ReadScalar(stream, currSecs);
|
|
|
|
fYon.ReadScalar(stream, currSecs);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void hsGEnvironment::SetResetState()
|
|
|
|
{
|
|
|
|
fResetState.SetFromEnv(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Reset()
|
|
|
|
{
|
|
|
|
fResetState.SetToEnv(this);
|
|
|
|
|
|
|
|
Int32 i;
|
|
|
|
for (i=0; i<fFogStateStack.GetCount(); i++)
|
|
|
|
delete fFogStateStack[i];
|
|
|
|
fFogStateStack.Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::ValidateInResetState()
|
|
|
|
{
|
|
|
|
fResetState.ValidateEnv(this);
|
|
|
|
|
|
|
|
hsAssert(fFogStateStack.GetCount() == 0, "Bad fog state stack.");
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Save(hsStream *stream, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
hsKeyedObject::Save(stream, mgr);
|
|
|
|
|
|
|
|
stream->WriteSwap16(kSaveMagicNumber);
|
|
|
|
stream->WriteSwap16(kSaveVersion);
|
|
|
|
|
|
|
|
stream->WriteSwap32(fFlags);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kCenterSet )
|
|
|
|
fPos.Write(stream);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kRadiusSet )
|
|
|
|
stream->WriteSwapScalar(fRadius);
|
|
|
|
|
|
|
|
FogState tempState;
|
|
|
|
tempState.SetFromEnv(this);
|
|
|
|
|
|
|
|
tempState.Save(stream, mgr);
|
|
|
|
fResetState.Save(stream, mgr);
|
|
|
|
|
|
|
|
UInt32 numFogStates = fFogStateStack.GetCount();
|
|
|
|
stream->WriteSwap32(numFogStates);
|
|
|
|
for (UInt32 i = 0; i < numFogStates; i++)
|
|
|
|
{
|
|
|
|
fFogStateStack[i]->Save(stream, mgr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Load(hsStream *stream, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
// Clear old data
|
|
|
|
UInt32 i;
|
|
|
|
for (i=0; i<fFogStateStack.GetCount(); i++)
|
|
|
|
delete fFogStateStack[i];
|
|
|
|
fFogStateStack.Reset();
|
|
|
|
|
|
|
|
// Load
|
|
|
|
hsKeyedObject::Load(stream, mgr);
|
|
|
|
|
|
|
|
UInt16 magic = stream->ReadSwap16();
|
|
|
|
hsAssert(magic == kSaveMagicNumber, "Bad magic number in hsGEnvironment on load.");
|
|
|
|
|
|
|
|
UInt16 version = stream->ReadSwap16();
|
|
|
|
hsAssert(version == kSaveVersion, "Bad version in hsGEnvironment on load.");
|
|
|
|
|
|
|
|
fFlags = stream->ReadSwap32();
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kCenterSet )
|
|
|
|
fPos.Read(stream);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kRadiusSet )
|
|
|
|
fRadius = stream->ReadSwapScalar();
|
|
|
|
|
|
|
|
FogState tempState;
|
|
|
|
tempState.Load(stream, mgr);
|
|
|
|
tempState.SetToEnv(this);
|
|
|
|
fResetState.Load(stream, mgr);
|
|
|
|
|
|
|
|
UInt32 numFogStates = stream->ReadSwap32();
|
|
|
|
for (i = 0; i < numFogStates; i++)
|
|
|
|
{
|
|
|
|
FogState *newFogState = new FogState;
|
|
|
|
newFogState->Load(stream, mgr);
|
|
|
|
fFogStateStack.Append(newFogState);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Update(hsScalar s, const hsPoint3& vPos)
|
|
|
|
{
|
|
|
|
if( fFlags & kFogDepthSet )
|
|
|
|
fFogDepth.Update(s);
|
|
|
|
if( fFlags & kFogDensitySet )
|
|
|
|
fFogDensity.Update(s);
|
|
|
|
if( fFlags & kFogColorSet )
|
|
|
|
fFogColor.Update(s);
|
|
|
|
if( fFlags & kClearColorSet )
|
|
|
|
fClearColor.Update(s);
|
|
|
|
if( fFlags & kYonSet )
|
|
|
|
fYon.Update(s);
|
|
|
|
if( fFlags & kMapSet )
|
|
|
|
{
|
|
|
|
hsGStatGather3::UpdateMaterialBegin();
|
|
|
|
fMap->Update(s);
|
|
|
|
hsGStatGather3::UpdateMaterialEnd();
|
|
|
|
|
|
|
|
if( fFlags & kClearColorAmbient )
|
|
|
|
SetClearColor(fMap->GetLayer(0)->GetAmbientColor());
|
|
|
|
|
|
|
|
if( fFlags & kFogColorAmbient )
|
|
|
|
SetFogColor(fMap->GetLayer(0)->GetAmbientColor());
|
|
|
|
else
|
|
|
|
if( fFlags & kFogColorDiffuse )
|
|
|
|
SetFogColor(fMap->GetLayer(0)->GetColor());
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & kFogDistanceSet )
|
|
|
|
{
|
|
|
|
fFogDistance.Update(s);
|
|
|
|
|
|
|
|
|
|
|
|
hsVector3 del(&vPos, &fPos);
|
|
|
|
hsScalar dist = del.Magnitude();
|
|
|
|
|
|
|
|
hsScalar yon = hsMaximum(dist, fFogDistance.GetValue());
|
|
|
|
|
|
|
|
SetYon(yon);
|
|
|
|
|
|
|
|
hsScalar depth = fFogDistance.GetValue();
|
|
|
|
if( fFlags & kFogDepthSet )
|
|
|
|
depth *= fFogDepth.GetValue();
|
|
|
|
|
|
|
|
depth += yon - dist;
|
|
|
|
depth /= yon;
|
|
|
|
|
|
|
|
if( depth > hsScalar1 )
|
|
|
|
depth = hsScalar1;
|
|
|
|
|
|
|
|
fCurrentDepth = depth;
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
}
|
|
|
|
else if( fFlags & kFogDepthSet )
|
|
|
|
{
|
|
|
|
fCurrentDepth = fFogDepth.GetValue();
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fFlags &= ~kCurrentDepthSet;
|
|
|
|
|
|
|
|
if( fValidScale != fYonScale )
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fValidScale = fYonScale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedFogDistance(const hsScalar g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kFogDistanceSet )
|
|
|
|
{
|
|
|
|
fFogDistance.Update(hsTimer::GetSysSeconds());
|
|
|
|
fFogDistance.SetGoal(g);
|
|
|
|
fFogDistance.SetDuration(s);
|
|
|
|
fFogDistance.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetFogDistance(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedFogDepth(const hsScalar g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kFogDepthSet )
|
|
|
|
{
|
|
|
|
fFogDepth.Update(hsTimer::GetSysSeconds());
|
|
|
|
fFogDepth.SetGoal(g);
|
|
|
|
fFogDepth.SetDuration(s);
|
|
|
|
fFogDepth.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetFogDepth(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedFogDensity(const hsScalar g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kFogDensitySet )
|
|
|
|
{
|
|
|
|
fFogDensity.Update(hsTimer::GetSysSeconds());
|
|
|
|
fFogDensity.SetGoal(g);
|
|
|
|
fFogDensity.SetDuration(s);
|
|
|
|
fFogDensity.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetFogDensity(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedFogColor(const hsColorRGBA& g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kFogColorSet )
|
|
|
|
{
|
|
|
|
fFogColor.Update(hsTimer::GetSysSeconds());
|
|
|
|
fFogColor.SetGoal(g);
|
|
|
|
fFogColor.SetDuration(s);
|
|
|
|
fFogColor.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetFogColor(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedClearColor(const hsColorRGBA& g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kClearColorSet )
|
|
|
|
{
|
|
|
|
fClearColor.Update(hsTimer::GetSysSeconds());
|
|
|
|
fClearColor.SetGoal(g);
|
|
|
|
fClearColor.SetDuration(s);
|
|
|
|
fClearColor.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetClearColor(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetTimedYon(const hsScalar g, const hsScalar s)
|
|
|
|
{
|
|
|
|
if( fFlags & kYonSet )
|
|
|
|
{
|
|
|
|
fYon.Update(hsTimer::GetSysSeconds());
|
|
|
|
fYon.SetGoal(g);
|
|
|
|
fYon.SetDuration(s);
|
|
|
|
fYon.StartClock(hsTimer::GetSysSeconds());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
SetYon(g);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetMapName(const char *n)
|
|
|
|
{
|
|
|
|
if( n )
|
|
|
|
{
|
|
|
|
hsAssert(strlen(n) < 255, "Environment name overflow");
|
|
|
|
fFlags |= kMapSet;
|
|
|
|
strcpy(fMapName, n);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fFlags &= ~kMapSet;
|
|
|
|
*fMapName = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetMap(hsGMaterial *m)
|
|
|
|
{
|
|
|
|
fFlags |= kMapSet;
|
|
|
|
hsRefCnt_SafeAssign(fMap, m);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetCenter(const hsPoint3 &p)
|
|
|
|
{
|
|
|
|
fFlags |= kCenterSet; fPos = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetRadius(hsScalar r)
|
|
|
|
{
|
|
|
|
fFlags |= kRadiusSet;
|
|
|
|
fRadius = r;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDistance(hsScalar f)
|
|
|
|
{
|
|
|
|
if( fDevCache &&( f != fFogDistance.GetValue()) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDistanceSet;
|
|
|
|
fFogDistance.SetValue(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetCurrentDepth(hsScalar f)
|
|
|
|
{
|
|
|
|
if( fDevCache && (f != fCurrentDepth) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
fCurrentDepth = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDepth(hsScalar f)
|
|
|
|
{
|
|
|
|
if( fDevCache && (f != fFogDepth.GetValue()) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDepthSet;
|
|
|
|
fFogDepth.SetValue(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDensity(hsScalar f)
|
|
|
|
{
|
|
|
|
if( fDevCache && (f != fFogDensity.GetValue()) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDensitySet;
|
|
|
|
fFogDensity.SetValue(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogColor(const hsColorRGBA &c)
|
|
|
|
{
|
|
|
|
if( fDevCache
|
|
|
|
&& (
|
|
|
|
(c.r != fFogColor.GetValue().r)
|
|
|
|
|| (c.g != fFogColor.GetValue().g)
|
|
|
|
|| (c.b != fFogColor.GetValue().b)
|
|
|
|
) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogColorSet;
|
|
|
|
fFogColor.SetValue(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetClearColor(const hsColorRGBA &c)
|
|
|
|
{
|
|
|
|
fFlags |= kClearColorSet;
|
|
|
|
fClearColor.SetValue(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetYon(hsScalar f)
|
|
|
|
{
|
|
|
|
if( fDevCache && (f != fYon.GetValue()) )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kYonSet;
|
|
|
|
fYon.SetValue(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDistance(const hsTimedValue<hsScalar>& f)
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDistanceSet;
|
|
|
|
fFogDistance = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDepth(const hsTimedValue<hsScalar>& f)
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDepthSet;
|
|
|
|
fFogDepth = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogDensity(const hsTimedValue<hsScalar>& f)
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogDensitySet;
|
|
|
|
fFogDensity = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogColor(const hsTimedValue<hsColorRGBA>& c)
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kFogColorSet;
|
|
|
|
fFogColor = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetClearColor(const hsTimedValue<hsColorRGBA>& c)
|
|
|
|
{
|
|
|
|
fFlags |= kClearColorSet;
|
|
|
|
fClearColor = c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetYon(const hsTimedValue<hsScalar>& f)
|
|
|
|
{
|
|
|
|
if( fDevCache )
|
|
|
|
fDevCache->Validate(false);
|
|
|
|
fFlags |= kYonSet;
|
|
|
|
fYon = f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogType(UInt32 t)
|
|
|
|
{
|
|
|
|
fFlags &= ~kFogTypeMask;
|
|
|
|
fFlags |= (t & kFogTypeMask);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogColorAmbient(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
{
|
|
|
|
fFlags &= ~kFogColorDiffuse;
|
|
|
|
fFlags |= kFogColorAmbient;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogColorAmbient;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogColorDiffuse(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
{
|
|
|
|
fFlags &= ~kFogColorAmbient;
|
|
|
|
fFlags |= kFogColorDiffuse;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogColorDiffuse;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetClearColorAmbient(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
fFlags |= kClearColorAmbient;
|
|
|
|
else
|
|
|
|
fFlags &= ~kClearColorAmbient;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetOverride(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
fFlags |= kOverride;
|
|
|
|
else
|
|
|
|
fFlags &= ~kOverride;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetIsFar(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
fFlags |= kFarOut;
|
|
|
|
else
|
|
|
|
fFlags &= ~kFarOut;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetSortObjects(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
fFlags |= kSortObjects;
|
|
|
|
else
|
|
|
|
fFlags &= ~kSortObjects;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetHasFogControl(hsBool32 on)
|
|
|
|
{
|
|
|
|
if( on )
|
|
|
|
fFlags |= kFogControl;
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogControl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetFogControl(hsFogControl* fc)
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeAssign(fFogControl, fc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SetDeviceCache(hsGDevEnvCache *p)
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeAssign(fDevCache, p);
|
|
|
|
}
|
|
|
|
|
|
|
|
hsGEnvironment *hsGEnvironment::Copy(hsGEnvironment *env)
|
|
|
|
{
|
|
|
|
if( env->GetFlags() & kMapSet )
|
|
|
|
SetMap(env->GetMap());
|
|
|
|
else
|
|
|
|
fFlags &= ~kMapSet;
|
|
|
|
if( env->GetFlags() & kCenterSet )
|
|
|
|
SetCenter(env->GetCenter());
|
|
|
|
else
|
|
|
|
fFlags &= ~kCenterSet;
|
|
|
|
if( env->GetFlags() & kRadiusSet )
|
|
|
|
SetRadius(env->GetRadius());
|
|
|
|
else
|
|
|
|
fFlags &= ~kRadiusSet;
|
|
|
|
if( env->GetFlags() & kFogDepthSet )
|
|
|
|
SetFogDepth(env->GetFogDepth());
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogDepthSet;
|
|
|
|
if( env->GetFlags() & kFogDensitySet )
|
|
|
|
SetFogDensity(env->GetFogDensity());
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogDensitySet;
|
|
|
|
if( env->GetFlags() & kFogColorSet )
|
|
|
|
SetFogColor(env->GetFogColor());
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogColorSet;
|
|
|
|
if( env->GetFlags() & kClearColorSet )
|
|
|
|
SetClearColor(env->GetClearColor());
|
|
|
|
else
|
|
|
|
fFlags &= ~kClearColorSet;
|
|
|
|
if( env->GetFlags() & kYonSet )
|
|
|
|
SetYon(env->GetUnscaledYon());
|
|
|
|
else
|
|
|
|
fFlags &= ~kYonSet;
|
|
|
|
|
|
|
|
if( env->GetFlags() & kCurrentDepthSet )
|
|
|
|
{
|
|
|
|
fCurrentDepth = env->GetCurrentDepth();
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
fFlags &= ~hsGEnvironment::kFogTypeMask;
|
|
|
|
fFlags |= env->GetFlags() & hsGEnvironment::kFogTypeMask;
|
|
|
|
|
|
|
|
SetOverride(env->GetOverride());
|
|
|
|
|
|
|
|
SetDeviceCache(env->GetDeviceCache());
|
|
|
|
|
|
|
|
if( env->GetFlags() & kCacheInvalid )
|
|
|
|
fFlags |= kCacheInvalid;
|
|
|
|
else
|
|
|
|
fFlags &= ~kCacheInvalid;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < env->GetNumRenderProcs(); i++ )
|
|
|
|
AddRenderProc(env->GetRenderProc(i));
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::MixEnvirons(hsGEnvironment *env, hsGEnvironment *def)
|
|
|
|
{
|
|
|
|
if( env && (env->GetFlags() & kMapSet) )
|
|
|
|
{
|
|
|
|
SetMap(env->GetMap());
|
|
|
|
}
|
|
|
|
else if( def && (def->GetFlags() & kMapSet) )
|
|
|
|
{
|
|
|
|
hsGMaterial *map = def->GetMap();
|
|
|
|
if( map )
|
|
|
|
{
|
|
|
|
SetMap(def->GetMap());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
def->SetMapName(nil);
|
|
|
|
hsRefCnt_SafeUnRef(fMap);
|
|
|
|
fMap = nil;
|
|
|
|
fFlags &= ~kMapSet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeUnRef(fMap);
|
|
|
|
fMap = nil;
|
|
|
|
fFlags &= ~kMapSet;
|
|
|
|
}
|
|
|
|
if( env && (env->GetFlags() & kCenterSet) )
|
|
|
|
SetCenter(env->GetCenter());
|
|
|
|
else if( def &&(def->GetFlags() & kCenterSet) )
|
|
|
|
SetCenter(def->GetCenter());
|
|
|
|
else
|
|
|
|
fFlags &= ~kCenterSet;
|
|
|
|
if( env && (env->GetFlags() & kRadiusSet) )
|
|
|
|
SetRadius(env->GetRadius());
|
|
|
|
else if( def &&(def->GetFlags() & kRadiusSet) )
|
|
|
|
SetRadius(def->GetRadius());
|
|
|
|
else
|
|
|
|
fFlags &= ~kRadiusSet;
|
|
|
|
|
|
|
|
if( env && (env->GetFlags() & kFogDepthSet) )
|
|
|
|
SetFogDepth(env->GetFogDepth());
|
|
|
|
else if( def &&(def->GetFlags() & kFogDepthSet) )
|
|
|
|
SetFogDepth(def->GetFogDepth());
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogDepthSet;
|
|
|
|
|
|
|
|
if( env &&(env->GetFlags() & kCurrentDepthSet) )
|
|
|
|
{
|
|
|
|
fCurrentDepth = env->GetCurrentDepth();
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if( def &&(def->GetFlags() & kCurrentDepthSet) )
|
|
|
|
{
|
|
|
|
fCurrentDepth = def->GetCurrentDepth();
|
|
|
|
fFlags |= kCurrentDepthSet;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
fFlags &= ~kCurrentDepthSet;
|
|
|
|
|
|
|
|
fFlags &= ~kFogTypeMask;
|
|
|
|
if( env && (env->GetFlags() & kFogTypeMask) )
|
|
|
|
fFlags |= env->GetFlags() & kFogTypeMask;
|
|
|
|
else if( def && (def->GetFlags() & kFogTypeMask) )
|
|
|
|
fFlags |= def->GetFlags() & kFogTypeMask;
|
|
|
|
else
|
|
|
|
fFlags &= ~kFogTypeMask;
|
|
|
|
|
|
|
|
if( env && (env->GetFlags() & kFogDensitySet) )
|
|
|
|
SetFogDensity(env->GetFogDensity());
|
|
|
|
else if( def &&(def->GetFlags() & kFogDensitySet) )
|
|
|
|
SetFogDensity(def->GetFogDensity());
|
|
|
|
else
|
|
|
|
SetFogDensity(hsScalar1);
|
|
|
|
|
|
|
|
if( env &&(env->GetFlags() & kFogColorSet) )
|
|
|
|
SetFogColor(env->GetFogColor());
|
|
|
|
else if( def &&(def->GetFlags() & kFogColorSet) )
|
|
|
|
SetFogColor(def->GetFogColor());
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hsColorRGBA col;
|
|
|
|
col.r = col.g = col.b = col.a = 0;
|
|
|
|
SetFogColor(col);
|
|
|
|
}
|
|
|
|
if( env &&(env->GetFlags() & kClearColorSet) )
|
|
|
|
SetClearColor(env->GetClearColor());
|
|
|
|
else if( def &&(def->GetFlags() & kClearColorSet) )
|
|
|
|
SetClearColor(def->GetClearColor());
|
|
|
|
else
|
|
|
|
fFlags &= ~kClearColorSet;
|
|
|
|
|
|
|
|
if( env && (env->GetFlags() & kYonSet) )
|
|
|
|
SetYon(env->GetUnscaledYon());
|
|
|
|
else if( def &&(def->GetFlags() & kYonSet) )
|
|
|
|
SetYon(def->GetUnscaledYon());
|
|
|
|
else
|
|
|
|
fFlags &= ~kYonSet;
|
|
|
|
|
|
|
|
if( env && (env->GetOverride()) )
|
|
|
|
SetOverride(true);
|
|
|
|
else if( def &&(def->GetOverride()) )
|
|
|
|
SetOverride(true);
|
|
|
|
else
|
|
|
|
SetOverride(false);
|
|
|
|
|
|
|
|
if( env && env->GetDeviceCache() )
|
|
|
|
SetDeviceCache(env->GetDeviceCache());
|
|
|
|
else if( def && def->GetDeviceCache() )
|
|
|
|
SetDeviceCache(def->GetDeviceCache());
|
|
|
|
else
|
|
|
|
SetDeviceCache(nil);
|
|
|
|
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < GetNumRenderProcs(); i++ )
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeUnRef(GetRenderProc(i));
|
|
|
|
}
|
|
|
|
fRenderProcs.Reset();
|
|
|
|
if( env )
|
|
|
|
{
|
|
|
|
for( i = 0; i < env->GetNumRenderProcs(); i++ )
|
|
|
|
AddRenderProc(env->GetRenderProc(i));
|
|
|
|
}
|
|
|
|
if( def )
|
|
|
|
{
|
|
|
|
for( i = 0; i < def->GetNumRenderProcs(); i++ )
|
|
|
|
AddRenderProc(def->GetRenderProc(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Blend()
|
|
|
|
{
|
|
|
|
if( fFogControl )
|
|
|
|
fFogControl->Blend();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Restore()
|
|
|
|
{
|
|
|
|
if( fFogControl )
|
|
|
|
fFogControl->Restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Init(hsSceneNode* node)
|
|
|
|
{
|
|
|
|
if (!node)
|
|
|
|
{
|
|
|
|
char str[256];
|
|
|
|
sprintf(str, "hsGEnvironment %s initted with nil room. Weirdness may result.",
|
|
|
|
GetKeyName());
|
|
|
|
HSDebugProc(str);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( fFogControl )
|
|
|
|
fFogControl->Init(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
SetResetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::SaveFogState()
|
|
|
|
{
|
|
|
|
FogState* curFogState = new FogState;
|
|
|
|
curFogState->SetFromEnv(this);
|
|
|
|
fFogStateStack.Push(curFogState);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::RestoreFogState()
|
|
|
|
{
|
|
|
|
FogState* curFogState = fFogStateStack.GetCount() ? fFogStateStack.Pop() : nil;
|
|
|
|
if (curFogState)
|
|
|
|
{
|
|
|
|
curFogState->SetToEnv(this);
|
|
|
|
}
|
|
|
|
delete curFogState;
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Read(hsStream *stream)
|
|
|
|
{
|
|
|
|
fFlags = stream->ReadSwap32();
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kFogDistanceSet )
|
|
|
|
{
|
|
|
|
hsScalar d = stream->ReadSwapScalar();
|
|
|
|
SetFogDistance(d);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kFogDepthSet )
|
|
|
|
{
|
|
|
|
hsScalar d = stream->ReadSwapScalar();
|
|
|
|
SetFogDepth(d);
|
|
|
|
SetCurrentDepth(d);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kFogDensitySet )
|
|
|
|
{
|
|
|
|
hsScalar d = stream->ReadSwapScalar();
|
|
|
|
SetFogDensity(d);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kFogColorSet )
|
|
|
|
{
|
|
|
|
hsColorRGBA c;
|
|
|
|
c.r = stream->ReadSwapScalar();
|
|
|
|
c.g = stream->ReadSwapScalar();
|
|
|
|
c.b = stream->ReadSwapScalar();
|
|
|
|
c.a = stream->ReadSwapScalar();
|
|
|
|
SetFogColor(c);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kClearColorSet )
|
|
|
|
{
|
|
|
|
hsColorRGBA c;
|
|
|
|
c.r = stream->ReadSwapScalar();
|
|
|
|
c.g = stream->ReadSwapScalar();
|
|
|
|
c.b = stream->ReadSwapScalar();
|
|
|
|
c.a = stream->ReadSwapScalar();
|
|
|
|
SetClearColor(c);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kYonSet )
|
|
|
|
{
|
|
|
|
hsScalar d = stream->ReadSwapScalar();
|
|
|
|
SetYon(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kCenterSet )
|
|
|
|
fPos.Read(stream);
|
|
|
|
if( fFlags & hsGEnvironment::kRadiusSet )
|
|
|
|
fRadius = stream->ReadSwapScalar();
|
|
|
|
// still don't write the map out
|
|
|
|
|
|
|
|
if( !(fFlags & kFogTypeMask) )
|
|
|
|
{
|
|
|
|
if( GetFogDepth() <= 0.5f )
|
|
|
|
fFlags |= kFogLinear;
|
|
|
|
else
|
|
|
|
fFlags |= kFogExp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Write(hsStream *stream)
|
|
|
|
{
|
|
|
|
stream->WriteSwap32(fFlags);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kFogDistanceSet )
|
|
|
|
stream->WriteSwapScalar(GetFogDistance());
|
|
|
|
if( fFlags & hsGEnvironment::kFogDepthSet )
|
|
|
|
stream->WriteSwapScalar(GetFogDepth());
|
|
|
|
if( fFlags & hsGEnvironment::kFogDensitySet )
|
|
|
|
stream->WriteSwapScalar(GetFogDensity());
|
|
|
|
if( fFlags & hsGEnvironment::kFogColorSet )
|
|
|
|
{
|
|
|
|
hsColorRGBA c = GetFogColor();
|
|
|
|
stream->WriteSwapScalar(c.r);
|
|
|
|
stream->WriteSwapScalar(c.g);
|
|
|
|
stream->WriteSwapScalar(c.b);
|
|
|
|
stream->WriteSwapScalar(c.a);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kClearColorSet )
|
|
|
|
{
|
|
|
|
hsColorRGBA c = GetClearColor();
|
|
|
|
stream->WriteSwapScalar(c.r);
|
|
|
|
stream->WriteSwapScalar(c.g);
|
|
|
|
stream->WriteSwapScalar(c.b);
|
|
|
|
stream->WriteSwapScalar(c.a);
|
|
|
|
}
|
|
|
|
if( fFlags & hsGEnvironment::kYonSet )
|
|
|
|
stream->WriteSwapScalar(GetUnscaledYon());
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kCenterSet )
|
|
|
|
fPos.Write(stream);
|
|
|
|
if( fFlags & hsGEnvironment::kRadiusSet )
|
|
|
|
stream->WriteSwapScalar(fRadius);
|
|
|
|
// still don't write the map out
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Write(hsStream* stream, hsResMgr* group)
|
|
|
|
{
|
|
|
|
Write(stream);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kHasRenderProcs )
|
|
|
|
{
|
|
|
|
int n = GetNumRenderProcs();
|
|
|
|
stream->WriteSwap32(n);
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < n; i++ )
|
|
|
|
{
|
|
|
|
hsAssert(0,"Its Pauls fault");
|
|
|
|
// plFactory::LabelAndWrite(stream, group, GetRenderProc(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((GetFlags() & hsGEnvironment::kEnvironMapSet) == hsGEnvironment::kEnvironMapSet)
|
|
|
|
{
|
|
|
|
group->WriteKey(stream, GetMap());
|
|
|
|
}
|
|
|
|
|
|
|
|
stream->WriteSwap32(fNodeKeys.GetCount());
|
|
|
|
Int32 i;
|
|
|
|
for (i = 0; i < fNodeKeys.GetCount(); i++)
|
|
|
|
{
|
|
|
|
group->WriteKey(stream, fNodeKeys[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kFogControl )
|
|
|
|
IWriteFogControl(stream, group);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Read(hsStream* stream, hsResMgr* group)
|
|
|
|
{
|
|
|
|
Read(stream);
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kHasRenderProcs )
|
|
|
|
{
|
|
|
|
int n = stream->ReadSwap32();
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < n; i++ )
|
|
|
|
{
|
|
|
|
hsAssert(0,"Its Pauls fault");
|
|
|
|
// hsGRenderProcs* rp = hsGRenderProcs::ConvertNoRef(plFactory::CreateAndRead(stream, group));
|
|
|
|
// AddRenderProc(rp);
|
|
|
|
// hsRefCnt_SafeUnRef(rp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((GetFlags() & hsGEnvironment::kEnvironMapSet) == hsGEnvironment::kEnvironMapSet)
|
|
|
|
{
|
|
|
|
plRefMsg* refMsg = new plRefMsg(GetKey(), plRefMsg::kOnCreate);
|
|
|
|
group->ReadKeyNotifyMe(stream,refMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
hsAssert(fNodeKeys.GetCount() == 0, "fNodeKeys not empty in hsGEnvironment::Read.");
|
|
|
|
Int32 nodeCount = stream->ReadSwap32();
|
|
|
|
hsAssert(nodeCount > 0, "Environment node not in any rooms in hsGEnvironment::Read.");
|
|
|
|
Int32 i;
|
|
|
|
for (i = 0; i < nodeCount; i++)
|
|
|
|
{
|
|
|
|
plKey *key = group->ReadKey(stream);
|
|
|
|
AddNodeKey(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( fFlags & hsGEnvironment::kFogControl )
|
|
|
|
IReadFogControl(stream, group);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::IReadFogControl(hsStream* s, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
hsAssert(0,"Its Pauls fault");
|
|
|
|
// hsFogControl* fc = hsFogControl::ConvertNoRef(plFactory::CreateAndRead(s, mgr));
|
|
|
|
// SetFogControl(fc);
|
|
|
|
// hsRefCnt_SafeUnRef(fc);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::IWriteFogControl(hsStream* s, hsResMgr* mgr)
|
|
|
|
{
|
|
|
|
hsAssert(0,"Its Pauls fault");
|
|
|
|
// plFactory::LabelAndWrite(s, mgr, fFogControl);
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Push(hsG3DDevice* d)
|
|
|
|
{
|
|
|
|
#if 0 // Nuking old device - mf
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for( i = 0; i < GetNumRenderProcs(); i++ )
|
|
|
|
d->AddRenderProc(GetRenderProc(i));
|
|
|
|
#endif // Nuking old device - mf
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::Pop(hsG3DDevice* d)
|
|
|
|
{
|
|
|
|
#if 0 // Nuking old device - mf
|
|
|
|
int i;
|
|
|
|
for( i = 0; i < GetNumRenderProcs(); i++ )
|
|
|
|
d->RemoveRenderProc(GetRenderProc(i));
|
|
|
|
#endif // Nuking old device - mf
|
|
|
|
}
|
|
|
|
|
|
|
|
void hsGEnvironment::AddRenderProc(hsGRenderProcs* rp)
|
|
|
|
{
|
|
|
|
hsRefCnt_SafeRef(rp);
|
|
|
|
fRenderProcs.Append(rp);
|
|
|
|
fFlags |= hsGEnvironment::kHasRenderProcs;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsGRenderProcs* hsGEnvironment::GetRenderProc(int i)
|
|
|
|
{
|
|
|
|
return fRenderProcs[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt32 hsGEnvironment::GetNumRenderProcs()
|
|
|
|
{
|
|
|
|
return fRenderProcs.GetCount();
|
|
|
|
}
|
|
|
|
|
|
|
|
hsScalar hsGEnvironment::SetYonScale(hsScalar s)
|
|
|
|
{
|
|
|
|
const hsScalar kMinYonScale = 0.05f;
|
|
|
|
const hsScalar kMaxYonScale = 100.f;
|
|
|
|
|
|
|
|
if( s < kMinYonScale )
|
|
|
|
s = kMinYonScale;
|
|
|
|
else if( s > kMaxYonScale )
|
|
|
|
s = kMaxYonScale;
|
|
|
|
return fYonScale = s;
|
|
|
|
}
|
|
|
|
|
|
|
|
hsBool hsGEnvironment::MsgReceive(plMessage* msg)
|
|
|
|
{
|
|
|
|
plRefMsg* refMsg = plRefMsg::ConvertNoRef(msg);
|
|
|
|
|
|
|
|
if( refMsg )
|
|
|
|
{
|
|
|
|
|
|
|
|
hsGMaterial *mat = hsGMaterial::ConvertNoRef(refMsg->GetRef());
|
|
|
|
SetMap(mat);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|