BVB Source Codes

CRYENGINE Show ParticleComponentRuntime.cpp Source code

Return Download CRYENGINE: download ParticleComponentRuntime.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Created:     02/04/2015 by Filipe amim
  5. //  Description:
  6. // -------------------------------------------------------------------------
  7. //
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11. #include "ParticleComponentRuntime.h"
  12. #include "ParticleEmitter.h"
  13. #include "ParticleFeature.h"
  14.  
  15. namespace pfx2
  16. {
  17.  
  18. extern EParticleDataType EPVF_Acceleration, EPVF_VelocityField;
  19.  
  20.  
  21. CParticleComponentRuntime::CParticleComponentRuntime(CParticleEffect* pEffect, CParticleEmitter* pEmitter, CParticleComponent* pComponent)
  22.         : m_pEffect(pEffect)
  23.         , m_pEmitter(pEmitter)
  24.         , m_pComponent(pComponent)
  25.         , m_bounds(AABB::RESET)
  26.         , m_active(false)
  27. {
  28. }
  29.  
  30. CParticleContainer& CParticleComponentRuntime::GetParentContainer()
  31. {
  32.         const SComponentParams& params = GetComponentParams();
  33.         if (!params.IsSecondGen())
  34.                 return GetEmitter()->GetParentContainer();
  35.         else
  36.                 return GetEmitter()->GetRuntimes()[params.m_parentId].pRuntime->GetCpuRuntime()->GetContainer();
  37. }
  38.  
  39. const CParticleContainer& CParticleComponentRuntime::GetParentContainer() const
  40. {
  41.         const SComponentParams& params = GetComponentParams();
  42.         if (!params.IsSecondGen())
  43.                 return GetEmitter()->GetParentContainer();
  44.         else
  45.                 return GetEmitter()->GetRuntimes()[params.m_parentId].pRuntime->GetCpuRuntime()->GetContainer();
  46. }
  47.  
  48. void CParticleComponentRuntime::Initialize()
  49. {
  50.         FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  51.  
  52.         CParticleComponent* pcomponent = GetComponent();
  53.  
  54.         m_container.ResetUsedData();
  55.         for (EParticleDataType type(0); type < EParticleDataType::size(); type = type + type.info().dimension)
  56.                 if (pcomponent->UseParticleData(type))
  57.                         m_container.AddParticleData(type);
  58.         m_container.Trim();
  59. }
  60.  
  61. void CParticleComponentRuntime::Reset()
  62. {
  63.         m_container.Clear();
  64.         m_subInstances.clear();
  65.         m_subInstances.shrink_to_fit();
  66.         m_subInstanceData.clear();
  67.         m_subInstanceData.shrink_to_fit();
  68. }
  69.  
  70. void CParticleComponentRuntime::SetActive(bool active)
  71. {
  72.         if (active == m_active)
  73.                 return;
  74.         m_active = active;
  75. }
  76.  
  77. void CParticleComponentRuntime::UpdateAll(const SUpdateContext& context)
  78. {
  79.         FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  80.  
  81.         AddRemoveNewBornsParticles(context);
  82.         UpdateParticles(context);
  83.         CalculateBounds();
  84. }
  85.  
  86. void CParticleComponentRuntime::AddRemoveNewBornsParticles(const SUpdateContext& context)
  87. {
  88.         FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  89.         CTimeProfiler profile(GetPSystem()->GetProfiler(), this, EPS_NewBornTime);
  90.  
  91.         m_container.RemoveNewBornFlags();
  92.         AddRemoveParticles(context);
  93.         UpdateNewBorns(context);
  94.         m_container.ResetSpawnedParticles();
  95. }
  96.  
  97. void CParticleComponentRuntime::UpdateParticles(const SUpdateContext& context)
  98. {
  99.         FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  100.         CTimeProfiler profile(GetPSystem()->GetProfiler(), this, EPS_UpdateTime);
  101.  
  102.         m_container.FillData(EPVF_Acceleration, 0.0f, context.m_updateRange);
  103.         m_container.FillData(EPVF_VelocityField, 0.0f, context.m_updateRange);
  104.  
  105.         UpdateFeatures(context);
  106.         AgeUpdate(context);
  107. }
  108.  
  109. void CParticleComponentRuntime::ComputeVertices(const SCameraInfo& camInfo, CREParticle* pRE, uint64 uRenderFlags, float fMaxPixels)
  110. {
  111.         if (GetComponent()->IsVisible())
  112.         {
  113.                 FUNCTION_PROFILER(GetISystem(), PROFILE_PARTICLE);
  114.                 CTimeProfiler profile(GetPSystem()->GetProfiler(), this, EPS_ComputeVerticesTime);
  115.  
  116.                 const SComponentParams& params = GetComponentParams();
  117.                 if (!params.IsValid())
  118.                         return;
  119.  
  120.                 for (auto& it : GetComponent()->GetUpdateList(EUL_Render))
  121.                         it->ComputeVertices(this, camInfo, pRE, uRenderFlags, fMaxPixels);
  122.         }
  123. }
  124.  
  125. void CParticleComponentRuntime::AddSubInstances(SInstance* pInstances, size_t count)
  126. {
  127.         CRY_PFX2_PROFILE_DETAIL;
  128.  
  129.         const SComponentParams& params = GetComponentParams();
  130.  
  131.         size_t firstInstance = m_subInstances.size();
  132.         size_t lastInstance = firstInstance + count;
  133.         m_subInstances.insert(m_subInstances.end(), pInstances, pInstances + count);
  134.         m_subInstanceData.resize(params.m_instanceDataStride * m_subInstances.size());
  135.         AlignInstances();
  136.  
  137.         for (auto& it : GetComponent()->GetUpdateList(EUL_InitSubInstance))
  138.                 it->InitSubInstance(this, firstInstance, lastInstance);
  139.  
  140.         DebugStabilityCheck();
  141. }
  142.  
  143. void CParticleComponentRuntime::RemoveAllSubInstances()
  144. {
  145.         m_subInstances.clear();
  146.         AlignInstances();
  147.         DebugStabilityCheck();
  148.         m_container.FillData(EPDT_ParentId, gInvalidId, m_container.GetFullRange());
  149. }
  150.  
  151. void CParticleComponentRuntime::ReparentParticles(const uint* swapIds, const uint numSwapIds)
  152. {
  153.         CRY_PFX2_PROFILE_DETAIL;
  154.  
  155.         const SComponentParams& params = GetComponentParams();
  156.         IOPidStream parentIds = m_container.GetIOPidStream(EPDT_ParentId);
  157.  
  158.         for (TParticleId particleId = 0; particleId != m_container.GetLastParticleId(); ++particleId)
  159.         {
  160.                 const TParticleId parentId = parentIds.Load(particleId);
  161.                 if (parentId != gInvalidId)
  162.                 {
  163.                         CRY_PFX2_ASSERT(parentId < numSwapIds);   // this particle was pointing to the wrong parentId already
  164.                         parentIds.Store(particleId, swapIds[parentId]);
  165.                 }
  166.         }
  167.  
  168.         size_t dataStride = params.m_instanceDataStride;
  169.         byte* pBytes = m_subInstanceData.data();
  170.         size_t toCopy = 0;
  171.         for (size_t i = 0; pBytes && i < m_subInstances.size(); ++i)
  172.         {
  173.                 m_subInstances[i].m_parentId = swapIds[m_subInstances[i].m_parentId];
  174.                 if (m_subInstances[i].m_parentId == gInvalidId)
  175.                         continue;
  176.                 m_subInstances[toCopy] = m_subInstances[i];
  177.                 memcpy(pBytes + dataStride * toCopy, pBytes + dataStride * i, dataStride);
  178.                 ++toCopy;
  179.         }
  180.         m_subInstances.erase(m_subInstances.begin() + toCopy, m_subInstances.end());
  181.         AlignInstances();
  182.  
  183.         DebugStabilityCheck();
  184. }
  185.  
  186. bool CParticleComponentRuntime::IsValidRuntimeForInitializationParameters(const SRuntimeInitializationParameters& parameters)
  187. {
  188.         return parameters.usesGpuImplementation == false;
  189. }
  190.  
  191. void CParticleComponentRuntime::MainPreUpdate()
  192. {
  193.         for (auto& it : GetComponent()->GetUpdateList(EUL_MainPreUpdate))
  194.                 it->MainPreUpdate(this);
  195. }
  196.  
  197. void CParticleComponentRuntime::GetSpatialExtents(const SUpdateContext& context, Array<const float, uint> scales, Array<float, uint> extents)
  198. {
  199.         for (auto& it : GetComponent()->GetUpdateList(EUL_GetExtents))
  200.                 it->GetSpatialExtents(context, scales, extents);
  201. }
  202.  
  203. void CParticleComponentRuntime::SpawnParticles(CParticleContainer::SSpawnEntry const& entry)
  204. {
  205.         if (entry.m_count > 0)
  206.                 m_spawnEntries.push_back(entry);
  207. }
  208.  
  209. void CParticleComponentRuntime::AddRemoveParticles(const SUpdateContext& context)
  210. {
  211.         CRY_PFX2_PROFILE_DETAIL;
  212.  
  213.         // #PFX2_TODO : split into 2 functions
  214.  
  215.         CParticleEffect* pEffect = GetEffect();
  216.         CParticleEmitter* pEmitter = GetEmitter();
  217.         const SComponentParams& params = GetComponentParams();
  218.         const bool hasChildren = params.HasChildren();
  219.         const bool hasKillFeatures = !GetComponent()->GetUpdateList(EUL_KillUpdate).empty();
  220.         const size_t maxParticles = m_container.GetMaxParticles();
  221.         const uint32 numParticles = m_container.GetNumParticles();
  222.         TIStream<uint8> states = m_container.GetTIStream<uint8>(EPDT_State);
  223.  
  224.         //////////////////////////////////////////////////////////////////////////
  225.  
  226.         if (hasKillFeatures)
  227.         {
  228.                 TParticleIdArray particleIds(*context.m_pMemHeap);
  229.                 particleIds.reserve(numParticles);
  230.  
  231.                 CRY_PFX2_FOR_ACTIVE_PARTICLES(context)
  232.                 {
  233.                         const uint8 state = states.Load(particleId);
  234.                         if (state == ES_Expired)
  235.                                 particleIds.push_back(particleId);
  236.                 }
  237.                 CRY_PFX2_FOR_END;
  238.                 if (!particleIds.empty())
  239.                 {
  240.                         for (auto& it : GetComponent()->GetUpdateList(EUL_KillUpdate))
  241.                                 it->KillParticles(context, &particleIds[0], particleIds.size());
  242.                 }
  243.         }
  244.  
  245.         //////////////////////////////////////////////////////////////////////////
  246.  
  247.         m_spawnEntries.clear();
  248.  
  249.         for (auto& it : GetComponent()->GetUpdateList(EUL_Spawn))
  250.                 it->SpawnParticles(context);
  251.  
  252.         TParticleIdArray particleIds(*context.m_pMemHeap);
  253.         particleIds.reserve(numParticles);
  254.  
  255.         CRY_PFX2_FOR_ACTIVE_PARTICLES(context)
  256.         {
  257.                 const uint8 state = states.Load(particleId);
  258.                 if (state == ES_Dead)
  259.                         particleIds.push_back(particleId);
  260.         }
  261.         CRY_PFX2_FOR_END;
  262.  
  263.         if (!m_spawnEntries.empty() || !particleIds.empty())
  264.         {
  265.                 const bool hasSwapIds = (hasChildren && !particleIds.empty());
  266.                 TParticleIdArray swapIds(*context.m_pMemHeap);
  267.                 swapIds.resize(hasSwapIds ? numParticles : 0);
  268.  
  269.                 m_container.AddRemoveParticles(m_spawnEntries.data(), m_spawnEntries.size(), &particleIds, &swapIds);
  270.  
  271.                 if (hasSwapIds)
  272.                 {
  273.                         for (auto& subComponentId : params.m_subComponentIds)
  274.                         {
  275.                                 ICommonParticleComponentRuntime* pSubRuntime = pEmitter->GetRuntimes()[subComponentId].pRuntime;
  276.                                 if (pSubRuntime->IsActive())
  277.                                         pSubRuntime->ReparentParticles(&swapIds[0], swapIds.size());
  278.                         }
  279.                 }
  280.         }
  281. }
  282.  
  283. void CParticleComponentRuntime::UpdateNewBorns(const SUpdateContext& context)
  284. {
  285.         CRY_PFX2_PROFILE_DETAIL;
  286.  
  287.         if (!m_container.HasSpawnedParticles())
  288.                 return;
  289.  
  290.         const float deltaTime = context.m_deltaTime;
  291.         const floatv deltaTimev = ToFloatv(deltaTime);
  292.         const SComponentParams& params = GetComponentParams();
  293.         CParticleContainer& parentContainer = GetParentContainer();
  294.  
  295.         // interpolate position and normAge over time and velocity
  296.         const IPidStream parentIds = m_container.GetIPidStream(EPDT_ParentId);
  297.         const IVec3Stream parentPositions = parentContainer.GetIVec3Stream(EPVF_Position);
  298.         const IVec3Stream parentVelocities = parentContainer.GetIVec3Stream(EPVF_Velocity);
  299.         IOVec3Stream positions = m_container.GetIOVec3Stream(EPVF_Position);
  300.         IOFStream normAges = m_container.GetIOFStream(EPDT_NormalAge);
  301.         CRY_PFX2_FOR_SPAWNED_PARTICLEGROUP(context)
  302.         {
  303.                 const floatv frameAge = normAges.Load(particleGroupId);
  304.                 const uint32v parentGroupId = parentIds.Load(particleGroupId);
  305.                 const Vec3v wParentPos = parentPositions.Load(parentGroupId);
  306.                 const Vec3v wParentVel = parentVelocities.Load(parentGroupId);
  307.                 const Vec3v wPosition = MAdd(wParentVel, frameAge * deltaTimev, wParentPos);
  308.                 positions.Store(particleGroupId, wPosition);
  309.         }
  310.         CRY_PFX2_FOR_END;
  311.  
  312.         // update orientation if any
  313.         if (m_container.HasData(EPQF_Orientation))
  314.         {
  315.                 const Quat defaultQuat = GetEmitter()->GetLocation().q;
  316.                 const IQuatStream parentQuats = parentContainer.GetIQuatStream(EPQF_Orientation, defaultQuat);
  317.                 IOQuatStream quats = m_container.GetIOQuatStream(EPQF_Orientation);
  318.                 CRY_PFX2_FOR_SPAWNED_PARTICLEGROUP(context)
  319.                 {
  320.                         const uint32v parentGroupId = parentIds.Load(particleGroupId);
  321.                         const Quatv wParentQuat = parentQuats.Load(parentGroupId);
  322.                         quats.Store(particleGroupId, wParentQuat);
  323.                 }
  324.                 CRY_PFX2_FOR_END;
  325.         }
  326.  
  327.         // neutral velocity
  328.         m_container.FillData(EPVF_Velocity, 0.0f, m_container.GetSpawnedRange());
  329.  
  330.         // initialize unormrand
  331.         if (m_container.HasData(EPDT_Random))
  332.         {
  333.                 IOFStream unormRands = m_container.GetIOFStream(EPDT_Random);
  334.                 CRY_PFX2_FOR_SPAWNED_PARTICLEGROUP(context)
  335.                 {
  336.                         const floatv unormRand = context.m_spawnRngv.RandUNorm();
  337.                         unormRands.Store(particleGroupId, unormRand);
  338.                 }
  339.                 CRY_PFX2_FOR_END;
  340.         }
  341.  
  342.         // feature init particles
  343.         m_container.FillData(EPDT_State, uint8(ES_NewBorn), m_container.GetSpawnedRange());
  344.         for (auto& it : GetComponent()->GetUpdateList(EUL_InitUpdate))
  345.                 it->InitParticles(context);
  346.  
  347.         // calculate inv lifetimes
  348.         IOFStream invLifeTimes = m_container.GetIOFStream(EPDT_InvLifeTime);
  349.         if (std::isfinite(params.m_baseParticleLifeTime))
  350.         {
  351.                 IFStream lifeTimes = m_container.GetIFStream(EPDT_LifeTime);
  352.                 CRY_PFX2_FOR_SPAWNED_PARTICLEGROUP(context)
  353.                 {
  354.                         const floatv lifetime = lifeTimes.Load(particleGroupId);
  355.                         const floatv invLifeTime = rcp_fast(max(lifetime, deltaTimev));
  356.                         invLifeTimes.Store(particleGroupId, invLifeTime);
  357.                 }
  358.                 CRY_PFX2_FOR_END;
  359.         }
  360.         else
  361.         {
  362.                 CRY_PFX2_FOR_SPAWNED_PARTICLEGROUP(context)
  363.                 invLifeTimes.Store(particleGroupId, ToFloatv(0.0f));
  364.                 CRY_PFX2_FOR_END;
  365.         }
  366.  
  367.         UpdateLocalSpace(m_container.GetSpawnedRange());
  368.  
  369.         // feature post init particles
  370.         for (auto& it : GetComponent()->GetUpdateList(EUL_PostInitUpdate))
  371.                 it->PostInitParticles(context);
  372. }
  373.  
  374. void CParticleComponentRuntime::UpdateFeatures(const SUpdateContext& context)
  375. {
  376.         CRY_PFX2_PROFILE_DETAIL;
  377.  
  378.         for (EParticleDataType type(0); type < EParticleDataType::size(); type = type + type.info().step())
  379.         {
  380.                 if (type.info().hasInit)
  381.                         m_container.CopyData(type, InitType(type), context.m_updateRange);
  382.         }
  383.  
  384.         for (auto& it : GetComponent()->GetUpdateList(EUL_PreUpdate))
  385.                 it->PreUpdate(context);
  386.        
  387.         for (auto& it : GetComponent()->GetUpdateList(EUL_Update))
  388.                 it->Update(context);
  389.  
  390.         UpdateLocalSpace(context.m_updateRange);
  391. }
  392.  
  393. void CParticleComponentRuntime::CalculateBounds()
  394. {
  395.         CRY_PFX2_PROFILE_DETAIL;
  396.         CTimeProfiler profile(GetPSystem()->GetProfiler(), this, EPS_UpdateTime);
  397.  
  398.         IVec3Stream positions = m_container.GetIVec3Stream(EPVF_Position);
  399.         IFStream sizes = m_container.GetIFStream(EPDT_Size);
  400.         const floatv fMin = ToFloatv(std::numeric_limits<float>::max());
  401.         const floatv fMax = ToFloatv(-std::numeric_limits<float>::max());
  402.  
  403.         Vec3v bbMin = Vec3v(fMin, fMin, fMin);
  404.         Vec3v bbMax = Vec3v(fMax, fMax, fMax);
  405.  
  406.         // PFX2_TODO : clean up this mess
  407. #ifdef CRY_PFX2_USE_SSE
  408.         // vector part
  409.         const TParticleId lastParticleId = m_container.GetLastParticleId();
  410.         const TParticleGroupId lastParticleGroupId = CRY_PFX2_PARTICLESGROUP_UPPER(lastParticleId) + 1 - CRY_PFX2_PARTICLESGROUP_STRIDE;
  411.         for (TParticleGroupId particleGroupId = 0; particleGroupId < lastParticleGroupId; particleGroupId += CRY_PFX2_PARTICLESGROUP_STRIDE)
  412.         {
  413.                 const floatv size = sizes.Load(particleGroupId);
  414.                 const Vec3v position = positions.Load(particleGroupId);
  415.                 bbMin = min(bbMin, Sub(position, size));
  416.                 bbMax = max(bbMax, Add(position, size));
  417.         }
  418.         m_bounds.min = HMin(bbMin);
  419.         m_bounds.max = HMax(bbMax);
  420.  
  421.         // linear part
  422.         for (TParticleId particleId = lastParticleGroupId.Get(); particleId < lastParticleId; ++particleId)
  423.         {
  424.                 const float size = sizes.Load(particleId);
  425.                 const Vec3 sizev = Vec3(size, size, size);
  426.                 const Vec3 position = positions.Load(particleId);
  427.                 m_bounds.min = min(m_bounds.min, position - sizev);
  428.                 m_bounds.max = max(m_bounds.max, position + sizev);
  429.         }
  430. #else
  431.         const TParticleId lastParticleId = m_container.GetLastParticleId();
  432.         for (TParticleId particleId = 0; particleId < lastParticleId; ++particleId)
  433.         {
  434.                 const float size = sizes.Load(particleId);
  435.                 const Vec3 sizev = Vec3(size, size, size);
  436.                 const Vec3 position = positions.Load(particleId);
  437.                 m_bounds.min = min(m_bounds.min, position - sizev);
  438.                 m_bounds.max = max(m_bounds.max, position + sizev);
  439.         }
  440. #endif
  441. }
  442.  
  443. void CParticleComponentRuntime::AgeUpdate(const SUpdateContext& context)
  444. {
  445.         CRY_PFX2_PROFILE_DETAIL;
  446.  
  447.         IFStream invLifeTimes = m_container.GetIFStream(EPDT_InvLifeTime);
  448.         IOFStream normAges = m_container.GetIOFStream(EPDT_NormalAge);
  449.         const floatv frameTime = ToFloatv(context.m_deltaTime);
  450.         const floatv zero = ToFloatv(0.0f);
  451.  
  452.         CRY_PFX2_FOR_ACTIVE_PARTICLESGROUP(context)
  453.         {
  454.                 const floatv invLifeTime = invLifeTimes.Load(particleGroupId);
  455.                 const floatv normAge0 = normAges.Load(particleGroupId);
  456.                 const floatv dT = DeltaTime(normAge0, frameTime);
  457.                 const floatv normalAge1 = MAdd(dT, invLifeTime, max(zero, normAge0));
  458.                 normAges.Store(particleGroupId, normalAge1);
  459.         }
  460.         CRY_PFX2_FOR_END;
  461.  
  462.         TIOStream<uint8> states = m_container.GetTIOStream<uint8>(EPDT_State);
  463.         CRY_PFX2_FOR_ACTIVE_PARTICLES(context)
  464.         {
  465.                 const float normalAge = normAges.Load(particleId);
  466.                 uint8 state = states.Load(particleId);
  467.                 if (state == ES_Expired)
  468.                         state = ES_Dead;
  469.                 if (normalAge >= 1.0f && state == ES_Alive)
  470.                         state = ES_Expired;
  471.                 states.Store(particleId, state);
  472.         }
  473.         CRY_PFX2_FOR_END;
  474. }
  475.  
  476. void CParticleComponentRuntime::UpdateLocalSpace(SUpdateRange range)
  477. {
  478.         CRY_PFX2_PROFILE_DETAIL;
  479.  
  480.         const bool hasLocalPositions = m_container.HasData(EPVF_LocalPosition);
  481.         const bool hasLocalVelocities = m_container.HasData(EPVF_LocalVelocity);
  482.         const bool hasLocalOrientations = m_container.HasData(EPQF_LocalOrientation) && m_container.HasData(EPQF_Orientation);
  483.  
  484.         if (!hasLocalPositions && !hasLocalVelocities && !hasLocalOrientations)
  485.                 return;
  486.  
  487.         const CParticleContainer& parentContainer = GetParentContainer();
  488.         const Quat defaultQuat = GetEmitter()->GetLocation().q;
  489.         const IPidStream parentIds = m_container.GetIPidStream(EPDT_ParentId);
  490.         const auto parentStates = parentContainer.GetTIStream<uint8>(EPDT_State);
  491.         const IVec3Stream parentPositions = parentContainer.GetIVec3Stream(EPVF_Position);
  492.         const IQuatStream parentOrientations = parentContainer.GetIQuatStream(EPQF_Orientation, defaultQuat);
  493.         const IVec3Stream worldPositions = m_container.GetIVec3Stream(EPVF_Position);
  494.         const IVec3Stream worldVelocities = m_container.GetIVec3Stream(EPVF_Velocity);
  495.         const IQuatStream worldOrientations = m_container.GetIQuatStream(EPQF_Orientation);
  496.         IOVec3Stream localPositions = m_container.GetIOVec3Stream(EPVF_LocalPosition);
  497.         IOVec3Stream localVelocities = m_container.GetIOVec3Stream(EPVF_LocalVelocity);
  498.         IOQuatStream localOrientations = m_container.GetIOQuatStream(EPQF_LocalOrientation);
  499.  
  500.         CRY_PFX2_FOR_RANGE_PARTICLES(range)
  501.         {
  502.                 const TParticleId parentId = parentIds.Load(particleId);
  503.                 const uint8 parentState = (parentId != gInvalidId) ? parentStates.Load(parentId) : ES_Expired;
  504.                 if (parentState == ES_Expired)
  505.                         continue;
  506.  
  507.                 const Vec3 wParentPos = parentPositions.Load(parentId);
  508.                 const Quat parentOrientation = parentOrientations.SafeLoad(parentId);
  509.                 const QuatT worldToParent = QuatT(wParentPos, parentOrientation).GetInverted();
  510.  
  511.                 if (hasLocalPositions)
  512.                 {
  513.                         const Vec3 wPosition = worldPositions.Load(particleId);
  514.                         const Vec3 oPosition = worldToParent * wPosition;
  515.                         localPositions.Store(particleId, oPosition);
  516.                 }
  517.  
  518.                 if (hasLocalVelocities)
  519.                 {
  520.                         const Vec3 wVelocity = worldVelocities.Load(particleId);
  521.                         const Vec3 oVelocity = worldToParent.q * wVelocity;
  522.                         localVelocities.Store(particleId, oVelocity);
  523.                 }
  524.  
  525.                 if (hasLocalOrientations)
  526.                 {
  527.                         const Quat wOrientation = worldOrientations.Load(particleId);
  528.                         const Quat oOrientation = worldToParent.q * wOrientation;
  529.                         localOrientations.Store(particleId, oOrientation);
  530.                 }
  531.         }
  532.         CRY_PFX2_FOR_END;
  533. }
  534.  
  535. void CParticleComponentRuntime::AlignInstances()
  536. {
  537.         CRY_PFX2_PROFILE_DETAIL;
  538.  
  539.         m_subInstances.reserve(CRY_PFX2_PARTICLESGROUP_UPPER(m_subInstances.size()) + 1);
  540.  
  541.         memset(
  542.           m_subInstances.data() + m_subInstances.size(),
  543.           ~0,
  544.           (m_subInstances.capacity() - m_subInstances.size()) * sizeof(TParticleId));
  545. }
  546.  
  547. void CParticleComponentRuntime::DebugStabilityCheck()
  548. {
  549. #if 0
  550.         #ifdef CRY_DEBUG_PARTICLE_SYSTEM
  551.         const CParticleContainer& parentContainer = GetParentContainer();
  552.         const TParticleId parentCount = parentContainer.GetLastParticleId();
  553.         IPidStream parentIds = m_container.GetIPidStream(EPDT_ParentId);
  554.  
  555.         CRY_PFX2_FOR_SPAWNED_PARTICLES(m_container, m_container.GetFullRange());
  556.         TParticleId parentId = parentIds.Load(particleId);
  557.         CRY_PFX2_ASSERT(parentIds.Load(particleId) != gInvalidId);      // recently spawn particles are not supposed to be orphan
  558.         CRY_PFX2_FOR_END;
  559.  
  560.         CRY_PFX2_FOR_ACTIVE_PARTICLES(m_container, m_container.GetFullRange());
  561.         {
  562.                 TParticleId parentId = parentIds.Load(particleId);
  563.                 CRY_PFX2_ASSERT(parentId < parentCount || parentId == gInvalidId);    // this particle is not pointing to the correct parent
  564.         }
  565.         CRY_PFX2_FOR_END;
  566.  
  567.         for (size_t i = 0; i < m_subInstances.size(); ++i)
  568.         {
  569.                 TParticleId parentId = m_subInstances[i].m_parentId;
  570.                 CRY_PFX2_ASSERT(parentId < parentCount);    // this instance is not pointing to the correct parent
  571.         }
  572.         #endif
  573. #endif
  574. }
  575.  
  576. void CParticleComponentRuntime::AccumCounts(SParticleCounts& counts)
  577. {
  578.         counts.EmittersAlloc += 1.0f;
  579.         counts.ParticlesAlloc += m_container.GetMaxParticles();
  580.         counts.EmittersActive += 1.0f;
  581.         counts.SubEmittersActive += 1.0f;
  582.         counts.ParticlesActive += m_container.GetLastParticleId();
  583.  
  584.         CParticleProfiler& profiler = GetPSystem()->GetProfiler();
  585.         profiler.AddEntry(this, EPS_ActiveParticles, uint(m_container.GetLastParticleId()));
  586.         profiler.AddEntry(this, EPS_AllocatedParticles, uint(m_container.GetMaxParticles()));
  587. }
  588.  
  589. }
  590.  
downloadParticleComponentRuntime.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