BVB Source Codes

CRYENGINE Show ParticleManager.h Source code

Return Download CRYENGINE: download ParticleManager.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   ParticleManager.h
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description:
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //      - 03:2006                                : Modified by Jan M眉ller (Serialization)
  12. //
  13. ////////////////////////////////////////////////////////////////////////////
  14.  
  15. #ifndef PART_MANAGER
  16. #define PART_MANAGER
  17.  
  18. #include "ParticleEffect.h"
  19. #include <CryCore/BitFiddling.h>
  20. #include "ParticleList.h"
  21. #include "ParticleEnviron.h"
  22. #include "ParticleMemory.h"
  23. #include <CrySystem/Profilers/IPerfHud.h>
  24.  
  25. #if !defined(_RELEASE)
  26. // when not in release, collect information about vertice/indice pool usage
  27.         #define PARTICLE_COLLECT_VERT_IND_POOL_USAGE
  28. #endif
  29.  
  30. class CParticleEmitter;
  31. class CParticleContainer;
  32. class CParticleBatchDataManager;
  33.  
  34. //PERFHUD
  35. class CParticleWidget : public ICryPerfHUDWidget
  36. {
  37. public:
  38.         CParticleWidget(minigui::IMiniCtrl* pParentMenu, ICryPerfHUD* pPerfHud, CParticleManager* m_pPartManager);
  39.         ~CParticleWidget();
  40.  
  41.         virtual void Reset() {}
  42.         virtual void Update();
  43.         virtual bool ShouldUpdate();
  44.         virtual void LoadBudgets(XmlNodeRef perfXML) {}
  45.         virtual void SaveStats(XmlNodeRef statsXML)  {}
  46.         virtual void Enable(int mode);
  47.         virtual void Disable()                       { m_pTable->Hide(true); }
  48.  
  49. protected:
  50.  
  51.         minigui::IMiniTable*         m_pTable;
  52.         CParticleManager*            m_pPartMgr;
  53.  
  54.         EPerfHUD_ParticleDisplayMode m_displayMode;
  55. };
  56.  
  57. // data to store vertices/indices pool usage
  58. struct SVertexIndexPoolUsage
  59. {
  60.         uint32      nVertexMemory;
  61.         uint32      nIndexMemory;
  62.         const char* pContainerName;
  63. };
  64.  
  65. //////////////////////////////////////////////////////////////////////////
  66. // Helper class for particle job management
  67. class CParticleBatchDataManager : public Cry3DEngineBase, public IParticleManager
  68. {
  69. public:
  70.  
  71.         CParticleBatchDataManager()
  72.                 : m_nUsedStates(0)
  73.         {
  74.                 for (int i = 0; i < RT_COMMAND_BUF_COUNT; ++i)
  75.                 {
  76.                         for (int j = 0; j < MAX_RECURSION_LEVELS; ++j)
  77.                         {
  78.                                 m_ParticlesJobStart[i][j] = 0;
  79.                         }
  80.                 }
  81.         }
  82.  
  83.         // Free all memory used by manager
  84.         void                     ResetData();
  85.  
  86.         JobManager::SJobState*   AddUpdateJob(CParticleEmitter* pEmitter);
  87.  
  88.         SAddParticlesToSceneJob& GetParticlesToSceneJob(const SRenderingPassInfo& passInfo)
  89.         { return *m_ParticlesToScene[passInfo.ThreadID()].push_back(); }
  90.  
  91.         void SyncAllUpdateParticlesJobs();
  92.  
  93.         void GetMemoryUsage(ICrySizer* pSizer) const;
  94.  
  95.         // IParticleManager partial implementation
  96.         virtual void PrepareForRender(const SRenderingPassInfo& passInfo);
  97.         virtual void FinishParticleRenderTasks(const SRenderingPassInfo& passInfo);
  98.  
  99. private:
  100.  
  101.         JobManager::SJobState* GetJobState()
  102.         {
  103.                 assert(m_nUsedStates <= m_UpdateParticleStates.size());
  104.                 if (m_nUsedStates == m_UpdateParticleStates.size())
  105.                         m_UpdateParticleStates.push_back(new JobManager::SJobState);
  106.  
  107.                 JobManager::SJobState* pJobState = m_UpdateParticleStates[m_nUsedStates++];
  108.                 assert(pJobState);
  109.  
  110.                 return pJobState;
  111.         }
  112.  
  113.         DynArray<SAddParticlesToSceneJob> m_ParticlesToScene[RT_COMMAND_BUF_COUNT];
  114.         int                               m_ParticlesJobStart[RT_COMMAND_BUF_COUNT][MAX_RECURSION_LEVELS];
  115.         DynArray<JobManager::SJobState*>  m_UpdateParticleStates;
  116.         int                               m_nUsedStates;
  117. };
  118.  
  119. //////////////////////////////////////////////////////////////////////////
  120. // Top class of particle system
  121. class CParticleManager : public IVisAreaCallback, public CParticleBatchDataManager
  122. {
  123. public:
  124.         CParticleManager(bool bEnable);
  125.         ~CParticleManager();
  126.  
  127.         friend class CParticleWidget;
  128.  
  129.         // Provide access to extended CPartManager functions only to particle classes.
  130.         ILINE static CParticleManager* Instance()
  131.         {
  132.                 return static_cast<CParticleManager*>(m_pPartManager);
  133.         }
  134.  
  135.         //////////////////////////////////////////////////////////////////////////
  136.         // IParticleManager implementation
  137.  
  138.         void                   SetDefaultEffect(const IParticleEffect* pEffect);
  139.         const IParticleEffect* GetDefaultEffect()
  140.         { return m_pDefaultEffect; }
  141.         const ParticleParams&  GetDefaultParams(int nVersion = 0) const
  142.         { return GetDefaultParams(ParticleParams::EInheritance::System, nVersion); }
  143.  
  144.         IParticleEffect*           CreateEffect();
  145.         void                       DeleteEffect(IParticleEffect* pEffect);
  146.         IParticleEffect*           FindEffect(cstr sEffectName, cstr sSource = "", bool bLoad = true);
  147.         IParticleEffect*           LoadEffect(cstr sEffectName, XmlNodeRef& effectNode, bool bLoadResources, const cstr sSource = NULL);
  148.         bool                       LoadLibrary(cstr sParticlesLibrary, XmlNodeRef& libNode, bool bLoadResources);
  149.         bool                       LoadLibrary(cstr sParticlesLibrary, cstr sParticlesLibraryFile = NULL, bool bLoadResources = false);
  150.         void                       ClearCachedLibraries();
  151.  
  152.         IParticleEffectIteratorPtr GetEffectIterator();
  153.  
  154.         IParticleEmitter*          CreateEmitter(const ParticleLoc& loc, const ParticleParams& Params, const SpawnParams* pSpawnParams = NULL);
  155.         void                       DeleteEmitter(IParticleEmitter* pEmitter);
  156.         void                       DeleteEmitters(FEmitterFilter filter);
  157.         IParticleEmitter*          SerializeEmitter(TSerialize ser, IParticleEmitter* pEmitter = NULL);
  158.  
  159.         // Processing
  160.         void Update();
  161.         void RenderDebugInfo();
  162.  
  163.         void OnFrameStart();
  164.         void Reset();
  165.         void ClearRenderResources(bool bForceClear);
  166.         void ClearDeferredReleaseResources();
  167.         void Serialize(TSerialize ser);
  168.         void PostSerialize(bool bReading);
  169.  
  170.         void SetTimer(ITimer* pTimer) { g_pParticleTimer = pTimer; };
  171.  
  172.         // Stats
  173.         void GetMemoryUsage(ICrySizer* pSizer) const;
  174.         void GetCounts(SParticleCounts& counts);
  175.         void ListEmitters(cstr sDesc = "", bool bForce = false);
  176.         void ListEffects();
  177.         void PrintParticleMemory();
  178.  
  179.         typedef VectorMap<const IParticleEffect*, SParticleCounts> TEffectStats;
  180.         void CollectEffectStats(TEffectStats& mapEffectStats, float SParticleCounts::* pSortField) const;
  181.  
  182.         //PerfHUD
  183.         virtual void CreatePerfHUDWidget();
  184.  
  185.         // Summary:
  186.         //       Registers new particle events listener.
  187.         virtual void AddEventListener(IParticleEffectListener* pListener);
  188.         virtual void RemoveEventListener(IParticleEffectListener* pListener);
  189.  
  190.         //////////////////////////////////////////////////////////////////////////
  191.         // IVisAreaCallback implementation
  192.         void OnVisAreaDeleted(IVisArea* pVisArea);
  193.  
  194.         //////////////////////////////////////////////////////////////////////////
  195.         // Particle effects.
  196.         //////////////////////////////////////////////////////////////////////////
  197.         void       RenameEffect(CParticleEffect* pEffect, cstr sNewName);
  198.         XmlNodeRef ReadLibrary(cstr sParticlesLibrary);
  199.         XmlNodeRef ReadEffectNode(cstr sEffectName);
  200.  
  201.         void       SetDefaultEffect(cstr sEffectName)
  202.         {
  203.                 SetDefaultEffect(FindEffect(sEffectName));
  204.         }
  205.         const ParticleParams& GetDefaultParams(ParticleParams::EInheritance eInheritance, int nVersion = 0) const;
  206.         void                  ReloadAllEffects();
  207.  
  208.         //////////////////////////////////////////////////////////////////////////
  209.         // Emitters.
  210.         //////////////////////////////////////////////////////////////////////////
  211.         CParticleEmitter*   CreateEmitter(const ParticleLoc& loc, const IParticleEffect* pEffect, const SpawnParams* pSpawnParams = NULL);
  212.         void                UpdateEmitters(IParticleEffect* pEffect);
  213.  
  214.         SPhysEnviron const& GetPhysEnviron()
  215.         {
  216.                 if (!(m_PhysEnv.m_nNonUniformFlags & EFF_LOADED))
  217.                         m_PhysEnv.GetWorldPhysAreas(~0, true);
  218.                 return m_PhysEnv;
  219.         }
  220.  
  221. #ifdef bEVENT_TIMINGS
  222.         struct SEventTiming
  223.         {
  224.                 const CParticleEffect* pEffect;
  225.                 uint32                 nContainerId;
  226.                 threadID               nThread;
  227.                 cstr                   sEvent;
  228.                 float                  timeStart, timeEnd;
  229.         };
  230.         int        AddEventTiming(cstr sEvent, const CParticleContainer* pCont);
  231.  
  232.         inline int StartEventTiming(cstr sEvent, const CParticleContainer* pCont)
  233.         {
  234.                 if (pCont && (GetCVars()->e_ParticlesDebug & AlphaBits('ed')))
  235.                 {
  236.                         WriteLock lock(m_EventLock);
  237.                         return AddEventTiming(sEvent, pCont) * m_iEventSwitch;
  238.                 }
  239.                 else
  240.                         return 0;
  241.         }
  242.         inline void EndEventTiming(int iEvent)
  243.         {
  244.                 WriteLock lock(m_EventLock);
  245.                 iEvent *= m_iEventSwitch;
  246.                 if (iEvent > 0)
  247.                         m_aEvents[iEvent].timeEnd = GetParticleTimer()->GetAsyncCurTime();
  248.         }
  249. #endif
  250.  
  251.         ILINE uint32 GetAllowedEnvironmentFlags() const
  252.         {
  253.                 return m_nAllowedEnvironmentFlags;
  254.         }
  255.         ILINE TrinaryFlags<uint64> const& GetRenderFlags() const
  256.         {
  257.                 return m_RenderFlags;
  258.         }
  259.         static float GetMaxAngularDensity(const CCamera& camera)
  260.         {
  261.                 return camera.GetAngularResolution() / max(GetCVars()->e_ParticlesMinDrawPixels, 0.125f) * 2.0f;
  262.         }
  263.         bool CanAccessFiles(cstr sObject, cstr sSource = "") const;
  264.  
  265.         // light profiler functions
  266.         ILINE virtual SParticleLightProfileCounts& GetLightProfileCounts() { return m_lightProfile; }
  267.  
  268.         // functions to collect which particle container need the most memory
  269.         // to store vertices/indices
  270.         void         DumpAndResetVertexIndexPoolUsage();
  271.         virtual void AddVertexIndexPoolUsageEntry(uint32 nVertexMemory, uint32 nIndexMemory, const char* pContainerName);
  272.         virtual void MarkAsOutOfMemory();
  273.  
  274.         uint32       GetPhysAreaChangedProxy(CParticleEmitter* pEmitter, uint16 uPhysicsMask);
  275.         void         UpdatePhysAreaChangedProxy(CParticleEmitter* pEmitter, uint32 nProxyId, bool bValid);
  276.         void         CleanOldPhysAreaChangedProxies();
  277.         void         AddUpdatedPhysArea(const SAreaChangeRecord& rec);
  278.         void         UpdatePhysAreasChanged();
  279.  
  280. private:
  281.  
  282.         friend struct CParticleEffectIterator;
  283.  
  284.         struct CCompCStr
  285.         {
  286.                 bool operator()(cstr a, cstr b) const
  287.                 {
  288.                         return stricmp(a, b) < 0;
  289.                 }
  290.         };
  291.  
  292.         //////////////////////////////////////////////////////////////////////////
  293.         // Map of particle effect case-insensitive name to interface pointer.
  294.         // The name key points to the name string in the actual effect,
  295.         // so there is no string duplication.
  296.         //typedef std::map< cstr, _smart_ptr<CParticleEffect>, CCompCStr > TEffectsList;
  297.         // special key class, use md5 instead of a strcmp as an map key
  298.         class SEffectsKey
  299.         {
  300.         public:
  301.                 SEffectsKey() { u64[0] = 0; u64[1] = 0; }
  302.                 SEffectsKey(const cstr& sName);
  303.  
  304.                 bool operator<(const SEffectsKey& rOther) const
  305.                 {
  306.                         return u64[0] == rOther.u64[0] ? u64[1] < rOther.u64[1] : u64[0] < rOther.u64[0];
  307.                 }
  308.  
  309.                 void GetMemoryUsage(ICrySizer* pSizer) const {}
  310.         private:
  311.                 union
  312.                 {
  313.                         char   c16[16];
  314.                         uint64 u64[2];
  315.                 };
  316.         };
  317.  
  318.         typedef VectorMap<SEffectsKey, _smart_ptr<CParticleEffect>> TEffectsList;
  319.         TEffectsList                m_Effects;
  320.  
  321.         _smart_ptr<CParticleEffect> m_pDefaultEffect;
  322.         ParticleParams const*       m_pLastDefaultParams;
  323.  
  324.         typedef std::list<IParticleEffectListener*> TListenersList;
  325.         TListenersList m_ListenersList;
  326.  
  327.         //////////////////////////////////////////////////////////////////////////
  328.         // Loaded particle libs.
  329.         std::map<string, XmlNodeRef, stl::less_stricmp<string>> m_LoadedLibs;
  330.  
  331.         //////////////////////////////////////////////////////////////////////////
  332.         // Particle effects emitters, top-level only.
  333.         //////////////////////////////////////////////////////////////////////////
  334.         ParticleList<CParticleEmitter>
  335.                               m_Emitters;
  336.  
  337.         bool                  m_bEnabled;
  338.         bool                  m_bRegisteredListener;
  339.         _smart_ptr<IMaterial> m_pPartLightShader;
  340.  
  341.         // Force features on/off depending on engine config.
  342.         uint32               m_nAllowedEnvironmentFlags;        // Which particle features are allowed.
  343.         TrinaryFlags<uint64> m_RenderFlags;                     // OS_ and FOB_ flags.
  344.  
  345.         SPhysEnviron         m_PhysEnv;                         // Per-frame computed physics area information.
  346.  
  347.         bool IsRuntime() const
  348.         {
  349.                 ESystemGlobalState eState = gEnv->pSystem->GetSystemGlobalState();
  350.                 return !gEnv->IsEditing() && (eState > ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_END);
  351.         }
  352.  
  353.         void UpdateEngineData();
  354.  
  355.         // Listener for physics events.
  356.         static int StaticOnPhysAreaChange(const EventPhys* pEvent)
  357.         {
  358.                 CParticleManager::Instance()->OnPhysAreaChange(pEvent);
  359.                 return 0;
  360.         }
  361.         void OnPhysAreaChange(const EventPhys* pEvent)
  362.         {
  363.                 m_PhysEnv.OnPhysAreaChange(static_cast<const EventPhysAreaChange&>(*pEvent));
  364.         }
  365.  
  366.         CParticleEffect* FindLoadedEffect(cstr sEffectName);
  367.         void             EraseEmitter(CParticleEmitter* pEmitter);
  368.  
  369.         // Console command interface.
  370.         static void CmdParticleListEffects(IConsoleCmdArgs*)
  371.         {
  372.                 Instance()->ListEffects();
  373.         }
  374.  
  375.         static void CmdParticleListEmitters(IConsoleCmdArgs*)
  376.         {
  377.                 Instance()->ListEmitters("", true);
  378.         }
  379.         static void CmdParticleMemory(IConsoleCmdArgs*)
  380.         {
  381.                 Instance()->PrintParticleMemory();
  382.         }
  383.  
  384.         bool LoadPreloadLibList(const cstr filename, const bool bLoadResources);
  385.  
  386. #ifdef bEVENT_TIMINGS
  387.         DynArray<SEventTiming> m_aEvents;
  388.         int                    m_iEventSwitch;
  389.         CSpinLock              m_EventLock;
  390.         float                  m_timeThreshold;
  391.  
  392.         void LogEvents();
  393. #endif
  394.  
  395.         SParticleCounts  m_GlobalCounts;
  396.  
  397.         CParticleWidget* m_pWidget;
  398.  
  399.         // per frame lightwight timing informations
  400.         SParticleLightProfileCounts m_lightProfile;
  401.  
  402. #if defined(PARTICLE_COLLECT_VERT_IND_POOL_USAGE)
  403.         enum { nVertexIndexPoolUsageEntries = 5};
  404.         SVertexIndexPoolUsage m_arrVertexIndexPoolUsage[nVertexIndexPoolUsageEntries];
  405.         uint32                m_nRequieredVertexPoolMemory;
  406.         uint32                m_nRequieredIndexPoolMemory;
  407.         uint32                m_nRendererParticleContainer;
  408.         bool                  m_bOutOfVertexIndexPoolMemory;
  409. #endif
  410.  
  411.         struct SPhysAreaNodeProxy
  412.         {
  413.                 void Reset()
  414.                 {
  415.                         pEmitter = (CParticleEmitter*)(intptr_t)-1;
  416.                         bIsValid = false;
  417.                         bbox.Reset();
  418.                 }
  419.  
  420.                 CParticleEmitter* pEmitter;     // Emitter
  421.                 uint16            uPhysicsMask; // Bit mask of physics interested in
  422.                 bool              bIsValid;     // Does the proxy carry valid data
  423.                 AABB              bbox;         // Bounding box of render node
  424.         };
  425.         CThreadSafeRendererContainer<SPhysAreaNodeProxy> m_physAreaChangedProxies;
  426.         CryCriticalSection                               m_PhysAreaChangeLock;
  427.         PodArray<SAreaChangeRecord>                      m_listPhysAreasChanged;
  428. };
  429.  
  430. struct CParticleEffectIterator : public IParticleEffectIterator
  431. {
  432.         CParticleEffectIterator(CParticleManager* pManager)
  433.                 : m_refs(0)
  434.         {
  435.                 if (pManager)
  436.                 {
  437.                         for (CParticleManager::TEffectsList::iterator it = pManager->m_Effects.begin(); it != pManager->m_Effects.end(); ++it)
  438.                         {
  439.                                 CParticleEffect* pEffect = it->second.get();
  440.                                 if (!pEffect->IsNull())
  441.                                         m_effects.push_back(pEffect);
  442.                         }
  443.                 }
  444.                 m_iter = m_effects.begin();
  445.         }
  446.  
  447.         virtual void             AddRef()         { m_refs++; }
  448.         virtual void             Release()        { if (--m_refs == 0) delete this; }
  449.  
  450.         virtual IParticleEffect* Next()           { return m_iter != m_effects.end() ? *m_iter++ : NULL; }
  451.         virtual int              GetCount() const { return m_effects.size(); }
  452.  
  453. private:
  454.         int                m_refs;
  455.         typedef std::vector<IParticleEffect*> TEffects;
  456.         TEffects           m_effects;
  457.         TEffects::iterator m_iter;
  458. };
  459.  
  460. #ifdef bEVENT_TIMINGS
  461.  
  462. class CEventProfilerSection : public CFrameProfilerSection, public Cry3DEngineBase
  463. {
  464. public:
  465.         CEventProfilerSection(CFrameProfiler* pProfiler, const CParticleContainer* pCont = 0)
  466.                 : CFrameProfilerSection(pProfiler)
  467.         {
  468.                 m_iEvent = m_pPartManager->StartEventTiming(pProfiler->m_name, pCont);
  469.         }
  470.         ~CEventProfilerSection()
  471.         {
  472.                 m_pPartManager->EndEventTiming(m_iEvent);
  473.         }
  474. protected:
  475.         int m_iEvent;
  476. };
  477.  
  478.         #define FUNCTION_PROFILER_CONTAINER(pCont)                                                               \
  479.           static CFrameProfiler staticFrameProfiler(PROFILE_PARTICLE, EProfileDescription::UNDEFINED, __FUNC__); \
  480.           CEventProfilerSection eventProfilerSection(&staticFrameProfiler, pCont);
  481.  
  482. #else
  483.  
  484.         #define FUNCTION_PROFILER_CONTAINER(pCont) FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE)
  485.  
  486. #endif
  487.  
  488. #endif // PART_MANAGER
  489.  
downloadParticleManager.h Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top