BVB Source Codes

CRYENGINE Show ParticleJobManager.cpp Source code

Return Download CRYENGINE: download ParticleJobManager.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Created:     13/03/2015 by Filipe amim
  5. //  Description:
  6. // -------------------------------------------------------------------------
  7. //
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11. #include "ParticleManager.h"
  12. #include "ParticleEmitter.h"
  13. #include "ParticleComponentRuntime.h"
  14. #include "ParticleSystem.h"
  15. #include "ParticleProfiler.h"
  16. #include "ParticleJobManager.h"
  17. #include <CryRenderer/IGpuParticles.h>
  18.  
  19. CRY_PFX2_DBG
  20.  
  21. DECLARE_JOB("Particles : AddRemoveParticles", TAddRemoveJob, pfx2::CParticleJobManager::Job_AddRemoveParticles);
  22. DECLARE_JOB("Particles : UpdateParticles", TUpdateParticlesJob_, pfx2::CParticleJobManager::Job_UpdateParticles);
  23. DECLARE_JOB("Particles : PostUpdateParticles", TPostUpdateParticlesJob, pfx2::CParticleJobManager::Job_PostUpdateParticles);
  24. DECLARE_JOB("Particles : CalculateBounds", TCalculateBoundsJob, pfx2::CParticleJobManager::Job_CalculateBounds);
  25.  
  26. namespace pfx2
  27. {
  28.  
  29. stl::TPoolAllocator<TPostUpdateParticlesJob>& GetPostJobPool()
  30. {
  31.         static stl::TPoolAllocator<TPostUpdateParticlesJob> pool;
  32.         return pool;
  33. }
  34.  
  35. void CParticleJobManager::AddEmitter(CParticleEmitter* pEmitter)
  36. {
  37.         CRY_PFX2_ASSERT(!m_updateState.IsRunning());
  38.  
  39.         const auto& runtimeRefs = pEmitter->GetRuntimes();
  40.  
  41.         for (uint i = 0; i < runtimeRefs.size(); ++i)
  42.         {
  43.                 auto pCpuRuntime = runtimeRefs[i].pRuntime->GetCpuRuntime();
  44.                 if (!pCpuRuntime)
  45.                         continue;
  46.                 const SComponentParams& params = pCpuRuntime->GetComponentParams();
  47.                 const bool isActive = pCpuRuntime->IsActive();
  48.                 const bool isSecondGen = params.IsSecondGen();
  49.                 if (isActive && !isSecondGen)
  50.                 {
  51.                         size_t refIdx = m_componentRefs.size();
  52.                         m_firstGenComponentsRef.push_back(refIdx);
  53.                         m_componentRefs.push_back(SComponentRef(pCpuRuntime));
  54.                         SComponentRef& componentRef = m_componentRefs.back();
  55.                         componentRef.m_firstChild = m_componentRefs.size();
  56.                         componentRef.m_pPostSubUpdates = GetPostJobPool().New(m_componentRefs.size() - 1);
  57.                         componentRef.m_pPostSubUpdates->SetClassInstance(this);
  58.                         AddComponentRecursive(pEmitter, refIdx);
  59.                 }
  60.         }
  61. }
  62.  
  63. void CParticleJobManager::AddComponentRecursive(CParticleEmitter* pEmitter, size_t parentRefIdx)
  64. {
  65.         const CParticleComponentRuntime* pParentComponentRuntime = m_componentRefs[parentRefIdx].m_pComponentRuntime;
  66.         const SComponentParams& parentParams = pParentComponentRuntime->GetComponentParams();
  67.         const auto& runtimeRefs = pEmitter->GetRuntimes();
  68.  
  69.         for (auto& childComponentId : parentParams.m_subComponentIds)
  70.         {
  71.                 auto pChildComponent = runtimeRefs[childComponentId].pRuntime->GetCpuRuntime();
  72.                 if (!pChildComponent)
  73.                         continue;
  74.                 const bool isActive = pChildComponent->IsActive();
  75.                 if (isActive)
  76.                 {
  77.                         const SComponentParams& childParams = pChildComponent->GetComponentParams();
  78.                         m_componentRefs.push_back(SComponentRef(pChildComponent));
  79.                         SComponentRef& componentRef = m_componentRefs.back();
  80.                         componentRef.m_pPostSubUpdates = GetPostJobPool().New(m_componentRefs.size() - 1);
  81.                         componentRef.m_pPostSubUpdates->SetClassInstance(this);
  82.                         ++m_componentRefs[parentRefIdx].m_numChildren;
  83.                 }
  84.         }
  85.  
  86.         size_t numChildrend = m_componentRefs[parentRefIdx].m_numChildren;
  87.         size_t firstChild = m_componentRefs[parentRefIdx].m_firstChild;
  88.         for (size_t i = 0; i < numChildrend; ++i)
  89.         {
  90.                 size_t childRefIdx = firstChild + i;
  91.                 m_componentRefs[childRefIdx].m_firstChild = m_componentRefs.size();
  92.                 AddComponentRecursive(pEmitter, childRefIdx);
  93.         }
  94. }
  95.  
  96. void CParticleJobManager::AddDeferredRender(CParticleComponentRuntime* pRuntime, const SRenderContext& renderContext)
  97. {
  98.         SDeferredRender render(pRuntime, renderContext);
  99.         m_deferredRenders.push_back(render);
  100. }
  101.  
  102. void CParticleJobManager::ScheduleComputeVertices(CParticleComponentRuntime* pComponentRuntime, CRenderObject* pRenderObject, const SRenderContext& renderContext)
  103. {
  104.         CParticleManager* pPartManager = static_cast<CParticleManager*>(gEnv->pParticleManager);
  105.         const SComponentParams& params = pComponentRuntime->GetComponentParams();
  106.  
  107.         SAddParticlesToSceneJob& job = pPartManager->GetParticlesToSceneJob(renderContext.m_passInfo);
  108.         job.pPVC = pComponentRuntime;
  109.         job.pRenderObject = pRenderObject;
  110.         job.pShaderItem = &params.m_pMaterial->GetShaderItem();
  111.         job.nCustomTexId = renderContext.m_renderParams.nTextureID;
  112. }
  113.  
  114. void CParticleJobManager::KernelUpdateAll()
  115. {
  116.         if (m_firstGenComponentsRef.empty())
  117.                 return;
  118.  
  119.         FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  120.  
  121.           CRY_PFX2_ASSERT(!m_updateState.IsRunning());
  122.  
  123.         CVars* pCVars = static_cast<C3DEngine*>(gEnv->p3DEngine)->GetCVars();
  124.  
  125.         if (pCVars->e_ParticlesThread)
  126.         {
  127.                 for (size_t i = 0; i < m_componentRefs.size(); ++i)
  128.                         m_updateState.SetRunning();
  129.                 for (size_t idx : m_firstGenComponentsRef)
  130.                 {
  131.                         SComponentRef& componentRef = m_componentRefs[idx];
  132.                         TAddRemoveJob job(idx);
  133.                         job.SetClassInstance(this);
  134.                         job.Run();
  135.                 }
  136.         }
  137.         else
  138.         {
  139.                 for (auto& componentRef : m_componentRefs)
  140.                 {
  141.                         SUpdateContext context = SUpdateContext(componentRef.m_pComponentRuntime);
  142.                         componentRef.m_pComponentRuntime->AddRemoveNewBornsParticles(context);
  143.                 }
  144.                 for (auto& componentRef : m_componentRefs)
  145.                 {
  146.                         SUpdateContext context = SUpdateContext(componentRef.m_pComponentRuntime);
  147.                         if (context.m_container.GetLastParticleId() != 0)
  148.                                 componentRef.m_pComponentRuntime->UpdateParticles(context);
  149.                         componentRef.m_pComponentRuntime->CalculateBounds();
  150.                 }
  151.         }
  152. }
  153.  
  154. void CParticleJobManager::SynchronizeUpdate()
  155. {
  156.         if (m_firstGenComponentsRef.empty())
  157.                 return;
  158.         CRY_PROFILE_FUNCTION(PROFILE_PARTICLE);
  159.         gEnv->pJobManager->WaitForJob(m_updateState);
  160. }
  161.  
  162. void CParticleJobManager::DeferredRender()
  163. {
  164.         CRY_PROFILE_FUNCTION(PROFILE_PARTICLE);
  165.  
  166.         for (const SDeferredRender& render : m_deferredRenders)
  167.         {
  168.                 CParticleComponentRuntime* pRuntime = render.m_pRuntime;
  169.                 CParticleComponent* pComponent = pRuntime->GetComponent();
  170.                 CParticleEmitter* pEmitter = pRuntime->GetEmitter();
  171.                 SRenderContext renderContext(render.m_rParam, render.m_passInfo);
  172.                 renderContext.m_distance = render.m_distance;
  173.                 renderContext.m_lightVolumeId = render.m_lightVolumeId;
  174.                 renderContext.m_fogVolumeId = render.m_fogVolumeId;
  175.                 pComponent->RenderDeferred(pEmitter, pRuntime, renderContext);
  176.         }
  177.  
  178.         ClearAll();
  179. }
  180.  
  181. void CParticleJobManager::Job_AddRemoveParticles(uint componentRefIdx)
  182. {
  183.         CParticleProfiler& profiler = GetPSystem()->GetProfiler();
  184.         CParticleComponentRuntime* pRuntime = m_componentRefs[componentRefIdx].m_pComponentRuntime;
  185.         GetPSystem()->GetProfiler().AddEntry(pRuntime, EPS_Jobs);
  186.  
  187.         DoAddRemove(m_componentRefs[componentRefIdx]);
  188.         ScheduleUpdateParticles(componentRefIdx);
  189. }
  190.  
  191. void CParticleJobManager::Job_UpdateParticles(uint componentRefIdx, SUpdateRange updateRange)
  192. {
  193.         CParticleProfiler& profiler = GetPSystem()->GetProfiler();
  194.         CParticleComponentRuntime* pRuntime = m_componentRefs[componentRefIdx].m_pComponentRuntime;
  195.         GetPSystem()->GetProfiler().AddEntry(pRuntime, EPS_Jobs);
  196.  
  197.         SUpdateContext context = SUpdateContext(pRuntime, updateRange);
  198.         pRuntime->UpdateParticles(context);
  199. }
  200.  
  201. void CParticleJobManager::Job_PostUpdateParticles(uint componentRefIdx)
  202. {
  203.         CParticleProfiler& profiler = GetPSystem()->GetProfiler();
  204.         CParticleComponentRuntime* pRuntime = m_componentRefs[componentRefIdx].m_pComponentRuntime;
  205.         GetPSystem()->GetProfiler().AddEntry(pRuntime, EPS_Jobs);
  206.  
  207.         ScheduleChildrenComponents(m_componentRefs[componentRefIdx]);
  208.         ScheduleCalculateBounds(componentRefIdx);
  209. }
  210.  
  211. void CParticleJobManager::Job_CalculateBounds(uint componentRefIdx)
  212. {
  213.         CParticleProfiler& profiler = GetPSystem()->GetProfiler();
  214.         CParticleComponentRuntime* pRuntime = m_componentRefs[componentRefIdx].m_pComponentRuntime;
  215.         GetPSystem()->GetProfiler().AddEntry(pRuntime, EPS_Jobs);
  216.  
  217.         pRuntime->CalculateBounds();
  218.         m_updateState.SetStopped();
  219. }
  220.  
  221. void CParticleJobManager::ScheduleUpdateParticles(uint componentRefIdx)
  222. {
  223.         CRY_PROFILE_FUNCTION(PROFILE_PARTICLE);
  224.  
  225.         SComponentRef& componentRef = m_componentRefs[componentRefIdx];
  226.         componentRef.m_subUpdateState.SetRunning();
  227.  
  228.         componentRef.m_subUpdateState.RegisterPostJob(componentRef.m_pPostSubUpdates);
  229.  
  230.         const size_t particleCountThreshold = 1024 * 8;
  231.         const CParticleContainer& container = componentRef.m_pComponentRuntime->GetContainer();
  232.         const TParticleId lastParticleId = container.GetLastParticleId();
  233.  
  234.         for (TParticleId pId = 0; pId < lastParticleId; pId += particleCountThreshold)
  235.         {
  236.                 SUpdateRange range;
  237.                 range.m_firstParticleId = pId;
  238.                 range.m_lastParticleId = MIN(pId + particleCountThreshold, lastParticleId);
  239.  
  240.                 TUpdateParticlesJob_ job(componentRefIdx, range);
  241.                 job.RegisterJobState(&componentRef.m_subUpdateState);
  242.                 job.SetClassInstance(this);
  243.                 job.Run();
  244.         }
  245.  
  246.         componentRef.m_subUpdateState.SetStopped();
  247. }
  248.  
  249. void CParticleJobManager::ScheduleChildrenComponents(SComponentRef& componentRef)
  250. {
  251.         CRY_PROFILE_FUNCTION(PROFILE_PARTICLE);
  252.  
  253.         for (size_t i = 0; i < componentRef.m_numChildren; ++i)
  254.         {
  255.                 TAddRemoveJob job(componentRef.m_firstChild + i);
  256.                 job.SetClassInstance(this);
  257.                 job.Run();
  258.         }
  259. }
  260.  
  261. void CParticleJobManager::ScheduleCalculateBounds(uint componentRefIdx)
  262. {
  263.         TCalculateBoundsJob calculateBoundsJob(componentRefIdx);
  264.         calculateBoundsJob.SetClassInstance(this);
  265.         calculateBoundsJob.Run();
  266. }
  267.  
  268. void CParticleJobManager::DoAddRemove(const SComponentRef& componentRef)
  269. {
  270.         SUpdateContext context = SUpdateContext(componentRef.m_pComponentRuntime);
  271.         componentRef.m_pComponentRuntime->AddRemoveNewBornsParticles(context);
  272. }
  273.  
  274. void CParticleJobManager::ClearAll()
  275. {
  276.         CRY_PROFILE_FUNCTION(PROFILE_PARTICLE);
  277.  
  278.         CRY_PFX2_ASSERT(!m_updateState.IsRunning());
  279.         for (auto& componentRef : m_componentRefs)
  280.                 GetPostJobPool().Delete(componentRef.m_pPostSubUpdates);
  281.         m_deferredRenders.clear();
  282.         m_firstGenComponentsRef.clear();
  283.         m_componentRefs.clear();
  284. }
  285.  
  286. }
  287.  
downloadParticleJobManager.cpp 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