You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.8 KiB

/*==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/>.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plFogEnvironment.cpp - Functions for the fog volume class //
// //
//////////////////////////////////////////////////////////////////////////////
#include "plFogEnvironment.h"
#include "plTweak.h"
//// Constructors & Destructor ///////////////////////////////////////////////
plFogEnvironment::plFogEnvironment()
{
fType = kNoFog;
}
plFogEnvironment::plFogEnvironment( hsScalar start, hsScalar end, hsScalar density, hsColorRGBA &color )
{
Set( start, end, density, &color );
}
plFogEnvironment::plFogEnvironment( FogType type, hsScalar end, hsScalar density, hsColorRGBA &color )
{
SetExp( type, end, density, &color );
}
plFogEnvironment::~plFogEnvironment()
{
}
//// Set /////////////////////////////////////////////////////////////////////
void plFogEnvironment::Set( hsScalar start, hsScalar end, hsScalar density, const hsColorRGBA *color )
{
if( density <= 0.f )
{
fType = kNoFog;
fStart = 0.f;
fEnd = 0.f;
fDensity = 0.f;
}
else
{
fType = kLinearFog;
fStart = start;
fEnd = end;
fDensity = density;
}
if( color != nil )
fColor = *color;
}
void plFogEnvironment::SetExp( FogType type, hsScalar end, hsScalar density, const hsColorRGBA *color )
{
hsAssert( type == kExpFog || type == kExp2Fog, "Invalid fog type passed to plFogEnvironment" );
if( density <= 0.f )
{
fType = kNoFog;
fStart = 0.f;
fEnd = 0.f;
fDensity = 0.f;
}
else
{
fType = type;
fStart = 0.0f;
fEnd = end;
fDensity = density;
}
if( color != nil )
fColor = *color;
}
//// GetParameters ///////////////////////////////////////////////////////////
// Gets the parameters. Sets start to 0 if the type is not linear (can be
// nil).
void plFogEnvironment::GetParameters( hsScalar *start, hsScalar *end, hsScalar *density, hsColorRGBA *color )
{
hsAssert( fType != kLinearFog || start != nil, "Trying to get non-linear paramters on linear fog!" );
hsAssert( end != nil && density != nil && color != nil, "Bad pointer to plFogEnvironment::GetParameters()" );
if( fType == kLinearFog )
*start = fStart;
else if( start != nil )
*start = 0.0f;
*end = fEnd;
*density = fDensity;
*color = fColor;
}
//// GetPipelineParams ///////////////////////////////////////////////////////
// Gets linear pipeline (DX8) specific parameters. Basically massages our
// interface values into values that DX8 can use. In this case, we simply
// scale our end value out by the density. The whole formula is:
// pipelineEnd = ( end - start ) / density + start
void plFogEnvironment::GetPipelineParams( hsScalar *start, hsScalar *end, hsColorRGBA *color )
{
// hsAssert( fType == kLinearFog, "Getting linear pipeline params on non-linear fog!" );
*color = fColor;
switch(fType)
{
case kLinearFog:
*start = fStart;
*end = (fEnd - fStart) / fDensity + fStart;
break;
case kExpFog:
{
plConst(float) kKnee(0.0f);
*start = fEnd * kKnee;
*end = (fEnd - *start) / fDensity + *start;
}
break;
default:
case kExp2Fog:
{
plConst(float) kKnee(0.3f);
*start = fEnd * kKnee;
*end = (fEnd - *start) / fDensity + *start;
}
break;
}
}
//// GetPipelineParams ///////////////////////////////////////////////////////
// Gets exp/exp^2 pipeline (DX8) specific parameters. Basically massages our
// interface values into values that DX8 can use. In this case, we're going
// to modulate the density by the end value so that it actually ends at the
// right spot.
void plFogEnvironment::GetPipelineParams( hsScalar *density, hsColorRGBA *color )
{
const float ln256 = logf( 256.f );
const float sqrtLn256 = sqrtf( ln256 );
hsAssert( fType == kExpFog || fType == kExp2Fog, "Getting non-linear pipeline params on linear fog!" );
*density = ( ( fType == kExpFog ) ? ln256: sqrtLn256 ) * fDensity / fEnd;
*color = fColor;
}
//// Read ////////////////////////////////////////////////////////////////////
void plFogEnvironment::Read( hsStream *s, hsResMgr *mgr )
{
hsKeyedObject::Read( s, mgr );
fType = s->ReadByte();
fStart = s->ReadSwapFloat();
fEnd = s->ReadSwapFloat();
fDensity = s->ReadSwapFloat();
fColor.Read( s );
}
//// Write ///////////////////////////////////////////////////////////////////
void plFogEnvironment::Write( hsStream *s, hsResMgr *mgr )
{
hsKeyedObject::Write( s, mgr );
s->WriteByte( fType );
s->WriteSwapFloat( fStart );
s->WriteSwapFloat( fEnd );
s->WriteSwapFloat( fDensity );
fColor.Write( s );
}