/*==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 . 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 ); }