/*==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 plDynaDecalMgr_inc #define plDynaDecalMgr_inc #include "pnNetCommon/plSynchedObject.h" #include "hsTemplates.h" #include "hsGeometry3.h" #include "hsMatrix44.h" #include "hsStlUtils.h" class plParticleSystem; class plPrintShape; class plDynaDecalEnableMsg; class plDynaDecal; class plDrawableSpans; class plGBufferGroup; class plIcicle; class hsGMaterial; class plBitmap; class plMipmap; class plSceneObject; class plArmatureMod; class hsStream; class hsResMgr; class plMessage; class plCutter; class plCutoutPoly; class plFlatGridMesh; class plDrawVisList; class plRenderLevel; class plAccessSpan; class plAuxSpan; class plDecalVtxFormat; class plPipeline; // plDynaDecalInfo - information we store specific to what we've // done about a specific avatar part or scene object. class plDynaDecalInfo { public: enum { kNone = 0x0, kImmersed = 0x1, kActive = 0x2 }; plKey fKey; double fLastTime; hsPoint3 fLastPos; double fWetTime; hsScalar fWetLength; UInt32 fFlags; plDynaDecalInfo& Init(const plKey& key); }; typedef std::map< UInt32, plDynaDecalInfo, std::less > plDynaDecalMap; // plDynaDecalMgr // Primary responsibilities: // Allocation of adequate buffer space in plGBufferGroup // Setup of decal materials // Allocation of auxSpans // Receive lists of polys, translate into drawable tris // Create DynaDecals and destroy them when they expire. // Assign vertex and index subsets to DynaDecals // Call Update on DynaDecals class plDynaDecalMgr : public plSynchedObject { public: enum DynaRefType { kRefMatPreShade, kRefMatRTShade, kRefTarget, kRefAvatar, kRefPartyObject, kRefParticles, kRefNextAvailable = 10 }; protected: static hsBool fDisableAccumulate; static hsBool fDisableUpdate; plDynaDecalMap fDecalMap; hsTArray fDecals; hsTArray fGroups; plCutter* fCutter; hsTArray fAuxSpans; hsGMaterial* fMatPreShade; hsGMaterial* fMatRTShade; hsTArray fTargets; hsTArray fPartyObjects; hsTArray fParticles; hsScalar fPartyTime; UInt16 fMaxNumVerts; UInt16 fMaxNumIdx; UInt32 fWaitOnEnable; hsScalar fWetLength; hsScalar fRampEnd; hsScalar fDecayStart; hsScalar fLifeSpan; hsScalar fIntensity; hsScalar fGridSizeU; hsScalar fGridSizeV; hsVector3 fScale; // some temp calculated stuff hsScalar fInitAtten; // These 4 are in normalized units [0..1], not feet. hsScalar fMinDepth; hsScalar fMinDepthRange; hsScalar fMaxDepth; hsScalar fMaxDepthRange; hsTArray fPartIDs; hsTArray fNotifies; const plPrintShape* IGetPrintShape(const plKey& objKey) const; const plPrintShape* IGetPrintShape(plArmatureMod* avMod, UInt32 id) const; virtual hsBool IHandleEnableMsg(const plDynaDecalEnableMsg* enaMsg); void INotifyActive(plDynaDecalInfo& info, const plKey& armKey, UInt32 id) const; void INotifyInactive(plDynaDecalInfo& info, const plKey& armKey, UInt32 id) const; hsBool IWetParts(const plDynaDecalEnableMsg* enaMsg); hsBool IWetPart(UInt32 id, const plDynaDecalEnableMsg* enaMsg); void IWetInfo(plDynaDecalInfo& info, const plDynaDecalEnableMsg* enaMsg) const; hsScalar IHowWet(plDynaDecalInfo& info, double t) const; plDynaDecalInfo& IGetDecalInfo(UInt32 id, const plKey& key); void IRemoveDecalInfo(UInt32 id); void IRemoveDecalInfos(const plKey& key); hsGMaterial* ISetAuxMaterial(plAuxSpan* aux, hsGMaterial* mat, hsBool rtLit); void IAllocAuxSpan(plAuxSpan* aux, UInt32 maxNumVerts, UInt32 maxNumIdx); plAuxSpan* IGetAuxSpan(plDrawableSpans* targ, int iSpan, hsGMaterial* mat, UInt16 numVerts, UInt16 numIdx); hsBool IMakeAuxRefs(plPipeline* pipe); UInt16* IGetBaseIdxPtr(const plAuxSpan* auxSpan) const; plDecalVtxFormat* IGetBaseVtxPtr(const plAuxSpan* auxSpan) const; virtual int INewDecal() = 0; plDynaDecal* IInitDecal(plAuxSpan* aux, double t, UInt16 numVerts, UInt16 numIdx); void IKillDecal(int i); void IUpdateDecals(double t); void ICountIncoming(hsTArray& src, UInt16& numVerts, UInt16& numIdx) const; hsBool IConvertPolysColor(plAuxSpan* auxSpan, plDynaDecal* decal, hsTArray& src); hsBool IConvertPolysAlpha(plAuxSpan* auxSpan, plDynaDecal* decal, hsTArray& src); hsBool IConvertPolysVS(plAuxSpan* auxSpan, plDynaDecal* decal, hsTArray& src); hsBool IConvertPolys(plAuxSpan* auxSpan, plDynaDecal* decal, hsTArray& src); hsBool IProcessPolys(plDrawableSpans* targ, int iSpan, double t, hsTArray& src); hsBool IHitTestPolys(hsTArray& src) const; hsBool IProcessGrid(plDrawableSpans* targ, int iSpan, hsGMaterial* mat, double t, const plFlatGridMesh& grid); hsBool IConvertFlatGrid(plAuxSpan* auxSpan, plDynaDecal* decal, const plFlatGridMesh& grid) const; hsBool ICutoutGrid(plDrawableSpans* drawable, int iSpan, hsGMaterial* mat, double secs); hsBool IHitTestFlatGrid(const plFlatGridMesh& grid) const; hsBool ICutoutList(hsTArray& drawVis, double secs); hsBool ICutoutObject(plSceneObject* so, double secs); hsBool ICutoutTargets(double secs); void ISetDepthFalloff(); // Sets from current cutter settings. virtual void ICutoutCallback(const hsTArray& cutouts, hsBool hasWaterHeight=false, hsScalar waterHeight=0.f); hsGMaterial* IConvertToEnvMap(hsGMaterial* mat, plBitmap* envMap); virtual void SetKey(plKey k); hsVector3 IReflectDir(hsVector3 dir) const; hsMatrix44 IL2WFromHit(hsPoint3 pos, hsVector3 dir) const; hsVector3 IRandomUp(hsVector3 dir) const; void IGetParticles(); public: plDynaDecalMgr(); virtual ~plDynaDecalMgr(); CLASSNAME_REGISTER( plDynaDecalMgr ); GETINTERFACE_ANY( plDynaDecalMgr, plSynchedObject ); virtual void Read(hsStream* stream, hsResMgr* mgr); virtual void Write(hsStream* stream, hsResMgr* mgr); virtual hsBool MsgReceive(plMessage* msg); // This is public, because you need to call it after creating // a DynaDecalMgr on the fly. It's normally called on Read(). void InitAuxSpans(); void SetScale(const hsVector3& v) { fScale = v; } const hsVector3& GetScale() const { return fScale; } void SetWaitOnEnable(hsBool on) { fWaitOnEnable = on; } hsBool GetWaitOnEnable() const { return fWaitOnEnable; } void SetWetLength(hsScalar f) { fWetLength = f; } void SetRampEnd(hsScalar f) { fRampEnd = f; } void SetDecayStart(hsScalar f) { fDecayStart = f; } void SetLifeSpan(hsScalar f) { fLifeSpan = f; } void SetIntensity(hsScalar f) { fIntensity = f; } hsScalar GetWetLength() const { return fWetLength; } hsScalar GetRampEnd() const { return fRampEnd; } hsScalar GetDecayStart() const { return fDecayStart; } hsScalar GetLifeSpan() const { return fLifeSpan; } hsScalar GetIntensity() const { return fIntensity; } void SetPartyTime(hsScalar secs) { fPartyTime = secs; } // Duration of particle spewage hsScalar GetPartyTime() const { return fPartyTime; } void ConvertToEnvMap(plBitmap* envMap); const plMipmap* GetMipmap() const; void AddNotify(const plKey& k) { fNotifies.Append(k); } UInt32 GetNumNotifies() const { return fNotifies.GetCount(); } const plKey& GetNotify(int i) const { return fNotifies[i]; } static void SetDisableAccumulate(hsBool on) { fDisableAccumulate = on; } static void ToggleDisableAccumulate() { fDisableAccumulate = !fDisableAccumulate; } static hsBool GetDisableAccumulate() { return fDisableAccumulate; } static void SetDisableUpdate(hsBool on) { fDisableUpdate = on; } static void ToggleDisableUpdate() { fDisableUpdate = !fDisableUpdate; } static hsBool GetDisableUpdate() { return fDisableUpdate; } }; #endif // plDynaDecalMgr_inc