/*==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==*/ #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 fDecalMgrs; hsTArray fBuoys; hsTArray fShores; hsTArray fDecals; plSceneObject* fRefObj; hsTArray 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