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.
 
 
 
 
 

658 lines
23 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/>.
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==*/
#ifndef plWaveSet7_inc
#define plWaveSet7_inc
#include "hsGeometry3.h"
#include "hsTemplates.h"
#include "../plMath/plRandom.h"
#include "hsBounds.h"
#include "plFixedWaterState7.h"
#include "plWaveSetBase.h"
class hsStream;
class hsResMgr;
class plAccessVtxSpan;
class plMessage;
class hsGMaterial;
class plDrawableSpans;
class plRenderMsg;
class plArmatureUpdateMsg;
class plGenRefMsg;
class plAuxSpan;
class plDynaDecalMgr;
class plGBufferGroup;
class plBitmap;
class plMipmap;
class plLayer;
class plRenderRequest;
class plRenderRequestMsg;
class plRenderTarget;
class plShader;
class plPipeline;
class plRipVSConsts;
class plStatusLog;
class plGraphPlate;
class plWorldWaveData7
{
public:
hsPoint3 fDir;
hsScalar fLength;
hsScalar fFreq;
hsScalar fPhase;
hsScalar fAmplitude;
};
class plWorldWave7 : public plWorldWaveData7
{
public:
inline void Accumulate(hsPoint3& accumPos, hsVector3& accumNorm) const;
};
class plWaveSet7 : public plWaveSetBase
{
public:
// Props inc by 1 (bit shift in bitvector).
enum plDrawProperties {
kDisable = 0,
kNumProps // last in the list
};
// Flags, also in a bitvector, so far unused in the multimodifier
enum {
kHasRefObject = 16
};
enum {
kNumWaves = 4
};
enum {
kRefDynaDecalMgr,
kRefBuoy,
kRefBumpMat,
kRefBumpDraw,
kRefBumpVShader,
kRefBumpPShader,
kRefBiasVShader,
kRefBiasPShader,
kRefRipVShader,
kRefRipPShader,
kRefShoreVShader,
kRefShorePShader,
kRefFixedVShader,
kRefFixedPShader,
kRefGraphShoreTex,
kRefBubbleShoreTex,
kRefEdgeShoreTex,
kRefGraphShoreMat,
kRefGraphShoreDraw,
kRefGraphVShader,
kRefGraphPShader,
kRefGraphShoreRT,
kRefShore,
kRefDecal,
kRefDecVShader,
kRefDecPShader,
kRefEnvMap,
kRefCosineLUT,
kRefRefObj
};
enum {
kGraphShorePasses = 3
};
enum {
kNumWindDep = 5
};
enum {
kNumTexWaves = 16
};
enum {
kBumpPerPass = 4
};
enum {
kNumBumpShaders = kNumTexWaves / kBumpPerPass
};
enum {
kCompositeSize = 256
};
enum {
kUpdateWaveKs = 0x1,
kRemakeBubble = 0x2,
kRemakeEdge = 0x4,
kReRenderEnvMap = 0x8,
kReInitWaves = 0x10
};
protected:
double fCurrTime;
double fLastTime;
plStatusLog* fStatusLog;
plGraphPlate* fStatusGraph;
UInt32 fTrialUpdate;
plFixedWaterState7 fState;
hsScalar fScrunchLen;
hsScalar fScrunchScale;
hsVector3 fWindDir;
hsScalar fMinLen;
hsScalar fMaxLen;
hsScalar fFreqScale;
hsScalar fTransCountDown;
int fTransistor;
hsScalar fTransDel;
hsScalar fTexTransCountDown;
int fTexTrans;
hsScalar fTexTransDel;
hsScalar fTexWaveFade[kNumTexWaves];
plWorldWave7 fWorldWaves[kNumWaves];
hsScalar fFreqMod[kNumWaves];
plRandom fRand;
plKey fSceneNode;
hsTArray<plDynaDecalMgr*> fDecalMgrs;
hsTArray<plSceneObject*> fBuoys;
hsTArray<plSceneObject*> fShores;
hsTArray<plSceneObject*> fDecals;
plSceneObject* fRefObj;
hsTArray<hsBounds3Ext> fTargBnds;
plLayer* fBiasLayer[2];
plLayer* fBumpLayers[kNumTexWaves];
hsGMaterial* fBumpMat;
plDrawableSpans* fBumpDraw;
plRenderRequest* fBumpReq;
plRenderRequestMsg* fBumpReqMsg;
plMipmap* fCosineLUT;
plShader* fBumpVShader[kNumBumpShaders];
plShader* fBumpPShader[kNumBumpShaders];
plShader* fBiasVShader;
plShader* fBiasPShader;
plBitmap* fEnvMap;
UInt32 fEnvSize;
hsScalar fEnvRefresh;
plLayer* fFixedLayers[4];
plShader* fRipVShader;
plShader* fRipPShader;
plShader* fShoreVShader;
plShader* fShorePShader;
plShader* fFixedVShader;
plShader* fFixedPShader;
enum DecalVType {
kDecalV1Lay,
kDecalV2Lay11,
kDecalV2Lay12,
kDecalVEnv,
kNumDecalVShaders
};
enum DecalPType {
kDecalPBB,
kDecalPaB,
kDecalPaM,
kDecalPaA,
kDecalPAB,
kDecalPAM,
kDecalPAA,
kDecalPMB,
kDecalPMM,
kDecalPMA,
kDecalPEnv,
kNumDecalPShaders
};
plShader* fDecalVShaders[kNumDecalVShaders];
plShader* fDecalPShaders[kNumDecalPShaders];
// Graph shore stuff
plMipmap* fGraphShoreTex;
plMipmap* fBubbleShoreTex;
plMipmap* fEdgeShoreTex;
hsGMaterial* fGraphShoreMat[kGraphShorePasses];
plDrawableSpans* fGraphShoreDraw[kGraphShorePasses];
plRenderTarget* fGraphShoreRT[kGraphShorePasses];
plRenderRequest* fGraphReq[kGraphShorePasses];
plRenderRequestMsg* fGraphReqMsg[kGraphShorePasses];
plShader* fGraphVShader[kGraphShorePasses];
plShader* fGraphPShader[kGraphShorePasses];
class GraphState
{
public:
float fAge;
float fInvLife;
float fUOff;
float fFreq[4];
float fPhase[4];
float fAmp[4];
};
GraphState fGraphState[kGraphShorePasses];
class WaveK
{
public:
// fK is the number of times the sine wave repeats across the texture. Must be an integer
// fS/fK is the base X component of the direction of the wave, with Y = 1.f - X. Note that X^2 + Y^2 != 1.
// fD allows the wave to get more off the Y direction
// So the X component will be Int(fS + fD*dispersion) / fK, because it must be an integer ratio to
// preserve tiling. Also, (fS + fD) must be <= fK (for the Y normalization).
// See the notes.
float fS;
float fK;
float fD;
};
WaveK fWaveKs[kNumTexWaves];
class TexWaveDesc
{
public:
hsScalar fPhase;
hsScalar fAmp;
hsScalar fLen;
hsScalar fFreq;
hsScalar fDirX;
hsScalar fDirY;
hsScalar fRotScale00;
hsScalar fRotScale01;
};
TexWaveDesc fTexWaves[kNumTexWaves];
class TexWaveWindDep
{
public:
hsScalar fWindSpeed;
hsScalar fHeight;
hsScalar fSpecular;
};
TexWaveWindDep fWindDeps[kNumWindDep];
void IInitWaveConsts();
void IInitState();
inline void IScrunch(hsPoint3& pos, hsVector3& norm) const;
void ICalcWindow(hsScalar dt);
void ICalcScale();
void IUpdateWaves(hsScalar dt);
void IUpdateWave(hsScalar dt, int i);
hsBool IAnyBoundsVisible(plPipeline* pipe) const;
void IInitWave(int i);
void IReInitWaves();
void IUpdateRefObject();
void IUpdateWindDir(hsScalar dt);
void IShiftCenter(plSceneObject* so) const;
void IFloatBuoys(hsScalar dt);
void IFloatBuoy(hsScalar dt, plSceneObject* so);
// Bookkeeping
void IAddTarget(const plKey& key);
void IRemoveTarget(const plKey& key);
void ISetWindSpeed(hsScalar s);
hsBool IOnReceive(plGenRefMsg* refMsg);
hsBool IOnRemove(plGenRefMsg* refMsg);
hsBool ITransContinue(hsScalar dt);
void IStartTransition(hsScalar dt);
hsScalar ITransitionDelay() const;
void ITransition(hsScalar dt);
hsBool ITransTexContinue(hsScalar dt);
void IStartTexTransition(hsScalar dt);
void ITransTex(hsScalar dt);
void IInitTexWave(int i);
void ISetupTextureWaves();
void IUpdateLayers(hsScalar dt);
void IUpdateBumpLayers(hsScalar dt);
plRenderRequest* ICreateRenderRequest(plRenderTarget* rt, plDrawableSpans* draw, hsScalar pri);
void ISubmitRenderRequests();
plRenderTarget* ICreateTransferRenderTarget(const char* name, int size);
plDrawableSpans* ICreateClearDrawable(plDrawableSpans* drawable, hsGMaterial* mat);
void IAddBumpBiasShaders(plLayer* layer);
plMipmap* ICreateBiasNoiseMap();
void IAddBumpBiasLayer(hsGMaterial* mat);
plMipmap* ICreateBumpBitmapFFP(hsScalar amp, hsScalar dx, hsScalar dy) const;
hsGMaterial* ICreateBumpLayersFFP();
plMipmap* ICreateBumpMipmapPS();
plLayer* ICreateBumpLayerPS(plMipmap* mipMap, hsGMaterial* bumpMat, int which);
hsGMaterial* ICreateBumpLayersPS();
plDrawableSpans* ICreateBumpDrawable();
plLayer* ICreateTotalEnvLayer(plBitmap* envMap, hsGMaterial* mat, int which, const char* pref);
plLayer* ICreateTotalLayer(plBitmap* bm, hsGMaterial* mat, int which, const char* suff);
hsGMaterial* ICreateFixedMatPS(hsGMaterial* mat, const int numUVWs);
void ICreateFixedMat(hsGMaterial* mat, const int numUVWs);
void ICheckTargetMaterials();
plDrawableSpans* ICreateGraphDrawable(plDrawableSpans* drawable, hsGMaterial* mat, int nWid);
plDrawableSpans* ICreateEmptyGraphDrawable(const char* name, UInt32 ref, int wich);
hsGMaterial* ICreateEmptyMaterial(const char* name, UInt32 ref, int which);
plLayer* ICreateBlankLayer(const char* name, int suff);
plMipmap* ICreateBlankTex(const char* name, int width, int height, UInt32 ref);
plMipmap* ICreateGraphShoreTex(int width, int height);
plMipmap* ICreateBubbleShoreTex(int width, int height);
void IRefillBubbleShoreTex();
plMipmap* ICreateEdgeShoreTex(int width, int height);
void IRefillEdgeShoreTex();
void ISetAsTexture(plLayer* lay, plBitmap* tex);
void ICreateGraphShoreLayer(hsGMaterial* mat, int iPass);
void ICreateGraphBubbleLayer(hsGMaterial* mat, int iPass);
void ICreateGraphEdgeLayer(hsGMaterial* mat, int iPass);
void ICreateGraphShoreMaterials();
plRenderTarget* ISetupGraphShoreRenderReq(int which);
void IMakeShoreLayer(hsGMaterial* mat, int which);
void ISetupShoreLayers(hsGMaterial* mat);
void ISetupGraphShore(hsGMaterial* mat);
void ICheckShoreMaterial(plSceneObject* so);
void ICheckShoreMaterials();
void ICheckDecalMaterial(plSceneObject* so);
void ICheckDecalMaterials();
void ISetupDecal(hsGMaterial* mat);
void ICheckDecalEnvLayers(hsGMaterial* mat);
void IAddGraphPShader(hsGMaterial* mat, int iPass);
void IAddGraphVShader(hsGMaterial* mat, int iPass);
void IUpdateGraphShader(hsScalar dt, int iPass);
void IInitGraph(int iPass);
void IShuffleDownGraphs(int iPass);
// type is either plLayRefMsg::kVertexShader or plLayRefMsg::kPixelShader.
void IAddShaderToLayers(hsGMaterial* mat, int iFirst, int iLast, UInt8 type, plShader* shader);
void IAddBumpPixelShader(hsGMaterial* mat, int iShader, int iFirst, int iLast);
void IAddBumpVertexShader(hsGMaterial* mat, int iShader, int iFirst, int iLast);
void IAddRipVertexShader(hsGMaterial* mat, const plRipVSConsts& ripConsts);
void IAddRipPixelShader(hsGMaterial* mat, const plRipVSConsts& ripConsts);
void IAddShoreVertexShader(hsGMaterial* mat);
void IAddShorePixelShader(hsGMaterial* mat);
void IAddFixedVertexShader(hsGMaterial* mat, const int numUVWs);
void IAddFixedPixelShader(hsGMaterial* mat);
plShader* IGetDecalPShader(hsGMaterial* mat);
plShader* ICreateDecalPShader(DecalPType t);
plShader* IGetDecalVShader(hsGMaterial* mat);
plShader* ICreateDecalVShader(DecalVType t);
void IUpdateShaders(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateBiasVShader();
void IUpdateBumpPShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateBumpVShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateRipPShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateRipVShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateShoreVShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateFixedVShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateFixedPShader(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
void IUpdateGraphShaders(plPipeline* pipe, hsScalar dt);
void IUpdateDecVShader(int t, plPipeline* pipe);
void IUpdateDecVShaders(plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l);
virtual int IShoreRef() const { return kRefShore; }
virtual int IDecalRef() const { return kRefDecal; }
inline void LogF(const char *format, ...) const;
inline void LogF(UInt32 color, const char *format, ...) const;
inline void IRestartLog() const;
inline void GraphLen(hsScalar len) const;
inline void IRestartGraph() const;
public:
plWaveSet7();
virtual ~plWaveSet7();
CLASSNAME_REGISTER( plWaveSet7 );
GETINTERFACE_ANY( plWaveSet7, plWaveSetBase );
virtual hsBool MsgReceive(plMessage* msg);
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty) { return false; }
Int32 GetNumProperties() const { return kNumProps; }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
hsScalar EvalPoint(hsPoint3& pos, hsVector3& norm);
// Getters and Setters for Python twiddling
//
// First a way to set new values. The secs parameter says how long to take
// blending to the new value from the current value.
//
// Geometric wave parameters. These are all safe to twiddle at any time or speed.
// The new settings take effect as new waves are spawned.
void SetGeoMaxLength(hsScalar s, hsScalar secs=0) { fState.fGeoState.fMaxLength.Set(s, secs); }
void SetGeoMinLength(hsScalar s, hsScalar secs=0) { fState.fGeoState.fMinLength.Set(s, secs); }
void SetGeoAmpOverLen(hsScalar s, hsScalar secs=0) { fState.fGeoState.fAmpOverLen.Set(s, secs); }
void SetGeoChop(hsScalar s, hsScalar secs=0) { fState.fGeoState.fChop.Set(s, secs); }
void SetGeoAngleDev(hsScalar s, hsScalar secs=0) { fState.fGeoState.fAngleDev.Set(s, secs); }
// Texture wave parameters. Safe to twiddle any time or speed.
// The new settings take effect as new waves are spawned.
void SetTexMaxLength(hsScalar s, hsScalar secs=0) { fState.fTexState.fMaxLength.Set(s, secs); }
void SetTexMinLength(hsScalar s, hsScalar secs=0) { fState.fTexState.fMinLength.Set(s, secs); }
void SetTexAmpOverLen(hsScalar s, hsScalar secs=0) { fState.fTexState.fAmpOverLen.Set(s, secs); }
void SetTexChop(hsScalar s, hsScalar secs=0) { fState.fTexState.fChop.Set(s, secs); }
void SetTexAngleDev(hsScalar s, hsScalar secs=0) { fState.fTexState.fAngleDev.Set(s, secs); }
// The size in feet of one tile of the ripple texture. If you change this (I don't
// recommend it), you need to change it very slowly or it will look very stupid.
void SetRippleScale(hsScalar s, hsScalar secs=0) { fState.fRippleScale.Set(s, secs); }
// The direction the wind is blowing (waves will be more or less perpindicular to wind dir).
// Change somewhat slowly, like over 30 seconds.
void SetWindDir(const hsVector3& s, hsScalar secs=0) { fState.fWindDir.Set(s, secs); }
// Change these gently, effect is immediate.
void SetSpecularNoise(hsScalar s, hsScalar secs=0) { hsVector3 spec = fState.fSpecVec; spec[plFixedWaterState7::kNoise] = s; fState.fSpecVec.Set(spec, secs); }
void SetSpecularStart(hsScalar s, hsScalar secs=0) { hsVector3 spec = fState.fSpecVec; spec[plFixedWaterState7::kSpecStart] = s; fState.fSpecVec.Set(spec, secs); }
void SetSpecularEnd(hsScalar s, hsScalar secs=0) { hsVector3 spec = fState.fSpecVec; spec[plFixedWaterState7::kSpecEnd] = s; fState.fSpecVec.Set(spec, secs); }
// Water Height is overriden if the ref object is animated.
void SetWaterHeight(hsScalar s, hsScalar secs=0) { fState.fWaterHeight.Set(s, secs); }
// Water Offset and DepthFalloff are complicated, and not immediately interesting to animate.
void SetWaterOffset(const hsVector3& s, hsScalar secs=0) { fState.fWaterOffset.Set(s, secs); }
void SetOpacOffset(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fWaterOffset; off.fX = s; fState.fWaterOffset.Set(off, secs); }
void SetReflOffset(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fWaterOffset; off.fY = s; fState.fWaterOffset.Set(off, secs); }
void SetWaveOffset(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fWaterOffset; off.fZ = s; fState.fWaterOffset.Set(off, secs); }
void SetDepthFalloff(const hsVector3& s, hsScalar secs=0) { fState.fDepthFalloff.Set(s, secs); }
void SetOpacFalloff(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fDepthFalloff; off.fX = s; fState.fDepthFalloff.Set(off, secs); }
void SetReflFalloff(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fDepthFalloff; off.fY = s; fState.fDepthFalloff.Set(off, secs); }
void SetWaveFalloff(hsScalar s, hsScalar secs=0) { hsVector3 off = fState.fDepthFalloff; off.fZ = s; fState.fDepthFalloff.Set(off, secs); }
// Max and Min Atten aren't very interesting, and will probably go away.
void SetMaxAtten(const hsVector3& s, hsScalar secs=0) { fState.fMaxAtten.Set(s, secs); }
void SetMinAtten(const hsVector3& s, hsScalar secs=0) { fState.fMinAtten.Set(s, secs); }
// Skipping the shore parameters, because they are never used.
// Water colors, adjust slowly, effect is immediate.
void SetWaterTint(const hsColorRGBA& s, hsScalar secs=0) { fState.fWaterTint.Set(s, secs); }
void SetWaterRGB(const hsVector3& col, hsScalar secs=0) { hsColorRGBA rgb; rgb.Set(col.fX, col.fY, col.fZ, GetWaterOpacity()); SetWaterTint(rgb, secs); }
void SetWaterOpacity(hsScalar s, hsScalar secs=0) { hsColorRGBA col = GetWaterTint(); col.a = s; SetWaterTint(col, secs); }
void SetSpecularTint(const hsColorRGBA& s, hsScalar secs=0) { fState.fSpecularTint.Set(s, secs); }
void SetSpecularRGB(const hsVector3& col, hsScalar secs=0) { hsColorRGBA rgb; rgb.Set(col.fX, col.fY, col.fZ, GetSpecularMute()); SetSpecularTint(rgb, secs); }
void SetSpecularMute(hsScalar s, hsScalar secs=0) { hsColorRGBA col = GetSpecularTint(); col.a = s; SetSpecularTint(col, secs); }
// The environment map is essentially projected onto a sphere. Moving the center of
// the sphere north will move the reflections north, changing the radius of the
// sphere effects parallax in the obvious way.
void SetEnvCenter(const hsPoint3& s, hsScalar secs=0) { fState.fEnvCenter.Set(s, secs); }
void SetEnvRadius(hsScalar s, hsScalar secs=0) { fState.fEnvRadius.Set(s, secs); }
// Now a way to get current values. See the accompanying Setter for notes on
// what the parameter means.
//
hsScalar GetGeoMaxLength() const { return fState.fGeoState.fMaxLength; }
hsScalar GetGeoMinLength() const { return fState.fGeoState.fMinLength; }
hsScalar GetGeoAmpOverLen() const { return fState.fGeoState.fAmpOverLen; }
hsScalar GetGeoChop() const { return fState.fGeoState.fChop; }
hsScalar GetGeoAngleDev() const { return fState.fGeoState.fAngleDev; }
hsScalar GetTexMaxLength() const { return fState.fTexState.fMaxLength; }
hsScalar GetTexMinLength() const { return fState.fTexState.fMinLength; }
hsScalar GetTexAmpOverLen() const { return fState.fTexState.fAmpOverLen; }
hsScalar GetTexChop() const { return fState.fTexState.fChop; }
hsScalar GetTexAngleDev() const { return fState.fTexState.fAngleDev; }
hsScalar GetRippleScale() const { return fState.fRippleScale; }
hsVector3 GetWindDir() const { return fState.fWindDir; }
hsScalar GetSpecularNoise() const { hsVector3 spec = fState.fSpecVec; return spec[plFixedWaterState7::kNoise]; }
hsScalar GetSpecularStart() const { hsVector3 spec = fState.fSpecVec; return spec[plFixedWaterState7::kSpecStart]; }
hsScalar GetSpecularEnd() const { hsVector3 spec = fState.fSpecVec; return spec[plFixedWaterState7::kSpecEnd]; }
hsScalar GetWaterHeight() const { return fState.fWaterHeight; }
hsVector3 GetWaterOffset() const { return fState.fWaterOffset; }
hsScalar GetOpacOffset() const { hsVector3 off = fState.fWaterOffset; return off.fX; }
hsScalar GetReflOffset() const { hsVector3 off = fState.fWaterOffset; return off.fY; }
hsScalar GetWaveOffset() const { hsVector3 off = fState.fWaterOffset; return off.fZ; }
hsVector3 GetDepthFalloff() const { return fState.fDepthFalloff; }
hsScalar GetOpacFalloff() const { hsVector3 off = fState.fDepthFalloff; return off.fX; }
hsScalar GetReflFalloff() const { hsVector3 off = fState.fDepthFalloff; return off.fY; }
hsScalar GetWaveFalloff() const { hsVector3 off = fState.fDepthFalloff; return off.fZ; }
hsVector3 GetMaxAtten() const { return fState.fMaxAtten; }
hsVector3 GetMinAtten() const { return fState.fMinAtten; }
hsColorRGBA GetWaterTint() const { return fState.fWaterTint; }
hsVector3 GetWaterRGB() const { hsColorRGBA col = GetWaterTint(); return hsVector3(col.r, col.g, col.b); }
hsScalar GetWaterOpacity() const { return GetWaterTint().a; }
hsColorRGBA GetSpecularTint() const { return fState.fSpecularTint; }
hsVector3 GetSpecularRGB() const { hsColorRGBA col = GetSpecularTint(); return hsVector3(col.r, col.g, col.b); }
hsScalar GetSpecularMute() const { return GetSpecularTint().a; }
hsPoint3 GetEnvCenter() const { return fState.fEnvCenter; }
hsScalar GetEnvRadius() const { return fState.fEnvRadius; }
// Export/debugging functions. For runtime, use message interface (plGenRefMsg, plWaveMsg).
void AddTarget(const plKey& key);
void RemoveTarget(const plKey& key);
void AddShoreTest(plKey& key);
void SetRefObject(plSceneObject* refObj);
void SetSceneNode(const plKey& key);
plKey GetSceneNode() const { return fSceneNode; }
void AddDynaDecalMgr(plKey& key);
void RemoveDynaDecalMgr(plKey& key);
void AddBuoy(plKey soKey);
void RemoveBuoy(plKey soKey);
virtual hsBool SetupRippleMat(hsGMaterial* mat, const plRipVSConsts& ripConsts);
virtual hsScalar GetHeight() const { return State().fWaterHeight; }
const plFixedWaterState7::WaveState& GeoState() const { return State().fGeoState; }
const plFixedWaterState7::WaveState& TexState() const { return State().fTexState; }
const plFixedWaterState7& State() const { return fState; }
void SetState(const plFixedWaterState7& state, hsScalar dur);
void SetEnvSize(UInt32 s) { fEnvSize = s; }
UInt32 GetEnvSize() const { return fEnvSize; }
void StopLog();
void StartLog();
hsBool Logging() const { return fStatusLog != nil; }
void StartGraph();
void StopGraph();
hsBool Graphing() const { return fStatusGraph != nil; }
};
#endif // plWaveSet7_inc