/*==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 hsOscillator_inc #define hsOscillator_inc #include "hsPerterber.h" #include "hsTemplates.h" #include "hsGeometry3.h" #include "../plIntersect/hsBounds.h" class hsStream; class plPipeline; class hsWave { protected: hsPoint3 fWorldCenter; hsPoint3 fLocalCenter; hsScalar fWorldFrequency; // 1.0 / Period hsScalar fLocalFrequency; hsScalar fWorldAmplitude; hsScalar fLocalAmplitude; hsScalar fPhase; hsScalar fRate; // how long a crest takes to reach next crest hsScalar fStartSecs; hsScalar fSecsToLive; hsScalar fInnerRadius; hsScalar fOuterRadius; hsScalar fAttenuateOutScale; hsScalar AgeScale(hsScalar secs) const; public: void Accumulate(const hsPoint3& pos, const hsVector3& localZ, hsVector3& accum, hsVector3& accumNorm) const; hsScalar ScaledAmplitude(hsScalar secs) const; void Init(hsScalar secs, hsPoint3& center, hsScalar per, hsScalar amp, hsScalar rate, hsScalar life, hsBool32 attenOut=false); void Update(hsScalar secs, const hsMatrix44& l2w, const hsMatrix44& w2l); hsBool32 IsSpent(hsScalar secs) const; void Kill() { fStartSecs = fSecsToLive = 0; } void AttenuateOut(hsBool32 on) { fAttenuateOutScale = (on ? 1.f : 0); } hsBool32 GetAttenuateOut() { return fAttenuateOutScale > 0; } void Save(hsStream* s, hsScalar secs); void Load(hsStream* s, hsScalar secs); }; class hsOscillator : public hsPerterber { protected: hsTArray fWaves; hsTArray fTempWaves; hsMatrix44 fLocalToWorld; hsMatrix44 fWorldToLocal; hsPoint3 fWorldCenter; hsPoint3 fLocalCenter; hsVector3 fWorldAttenScale; hsVector3 fLocalAttenScale; hsBounds3Ext fWorldCenterBounds; hsScalar fMinPeriod; hsScalar fMaxPeriod; hsScalar fMinAmplitude; hsScalar fMaxAmplitude; hsScalar fMinRate; hsScalar fMaxRate; hsScalar fMinLife; hsScalar fMaxLife; hsVector3 fLocalX; hsVector3 fLocalY; hsVector3 fLocalZ; hsScalar IAttenuate(const hsPoint3& in) const; void ISpawnWave(hsScalar secs, int i); virtual void IUpdate(hsScalar secs, plPipeline* pipe, const hsMatrix44& l2w, const hsMatrix44& w2l); virtual void IPerterb(const hsPoint3& in, hsGVertex3& out) const; public: hsOscillator(); virtual ~hsOscillator(); virtual void AdjustWorldBounds(const hsMatrix44& l2w, const hsMatrix44& w2l, hsBounds3Ext& bnd) const; virtual UInt32 GetType() const { return kTypeOscillator; } // Don't call these, use base class LabelAndWrite() and CreateAndRead() virtual void Read(hsStream* s); virtual void Write(hsStream* s); virtual void Load(hsStream* s, hsScalar secs); virtual void Save(hsStream* s, hsScalar secs); void SetPeriodRange(hsScalar lo, hsScalar hi) { fMinPeriod = lo; fMaxPeriod = hi; } void SetAmplitudeRange(hsScalar lo, hsScalar hi) { fMinAmplitude = lo; fMaxAmplitude = hi; } void SetRateRange(hsScalar lo, hsScalar hi) { fMinRate = lo; fMaxRate = hi; } void SetLifeRange(hsScalar lo, hsScalar hi) { fMinLife = lo; fMaxLife = hi; } hsScalar GetMinPeriod() const { return fMinPeriod; } hsScalar GetMaxPeriod() const { return fMaxPeriod; } hsScalar GetMinAmplitude() const { return fMinAmplitude; } hsScalar GetMaxAmplitude() const { return fMaxAmplitude; } hsScalar GetMinRate() const { return fMinRate; } hsScalar GetMaxRate() const { return fMaxRate; } hsScalar GetMinLife() const { return fMinLife; } hsScalar GetMaxLife() const { return fMaxLife; } void SetWorldAttenScale(const hsVector3& s) { fWorldAttenScale = s; } void SetWorldCenterBounds(const hsBounds3Ext& bnd) { fWorldCenterBounds = bnd; } const hsVector3& GetWorldAttenScale() const { return fWorldAttenScale; } const hsBounds3Ext& GetWorldCenterBounds() const { return fWorldCenterBounds; } void SetNumWaves(int n); UInt32 GetNumWaves() const { return fWaves.GetCount(); } hsWave& GetWeakestWave(hsScalar secs); hsWave& GetTempWave(hsScalar secs); virtual void Init(Int32 nParams, hsScalar* params); static hsGTriMesh* MakeWaveMesh(int nSpokes, const hsPoint3& center, hsScalar minRad, hsScalar maxRad, hsScalar uRange, hsScalar vRange, hsScalar attenStartFrac, hsBool32 stitch); }; #endif // hsOscillator_inc