BVB Source Codes

CRYENGINE Show FeatureSecondGen.cpp Source code

Return Download CRYENGINE: download FeatureSecondGen.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Created:     18/12/2014 by Filipe amim
  5. //  Description:
  6. // -------------------------------------------------------------------------
  7. //
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11. #include "ParticleSystem/ParticleFeature.h"
  12. #include "ParticleSystem/ParticleEmitter.h"
  13. #include "FeatureCollision.h"
  14.  
  15. CRY_PFX2_DBG
  16.  
  17. namespace pfx2
  18. {
  19.  
  20. //////////////////////////////////////////////////////////////////////////
  21.  
  22. SERIALIZATION_DECLARE_ENUM(ESecondGenMode,
  23.                            All,
  24.                            Random
  25.                            )
  26.  
  27. class CFeatureSecondGenBase : public CParticleFeature
  28. {
  29. public:
  30.         CFeatureSecondGenBase()
  31.                 : m_probability(1.0f)
  32.                 , m_mode(ESecondGenMode::All) {}
  33.  
  34.         void ResolveDependency(CParticleComponent* pComponent) override
  35.         {
  36.                 CRY_PFX2_ASSERT(pComponent);
  37.  
  38.                 CParticleEffect* pEffect = pComponent->GetEffect();
  39.  
  40.                 m_componentIds.clear();
  41.                 for (auto& componentName : m_componentNames)
  42.                 {
  43.                         TComponentId componentId = ResolveIdForName(pComponent, componentName);
  44.                         const bool isvalid = componentId != gInvalidId;
  45.                         if (isvalid)
  46.                         {
  47.                                 const bool isUnique = std::find(m_componentIds.begin(), m_componentIds.end(), componentId) == m_componentIds.end();
  48.                                 if (isUnique)
  49.                                 {
  50.                                         CParticleComponent* pSubComp = pEffect->GetCComponent(componentId);
  51.                                         if (pSubComp->SetSecondGeneration(pComponent))
  52.                                                 m_componentIds.push_back(componentId);
  53.                                 }
  54.                         }
  55.                 }
  56.         }
  57.  
  58.         void Serialize(Serialization::IArchive& ar) override
  59.         {
  60.                 CParticleFeature::Serialize(ar);
  61.                 ar(m_mode, "Mode", "Mode");
  62.                 ar(m_probability, "Probability", "Probability");
  63.                 ar(m_componentNames, "Components", "!Components");
  64.                 if (ar.isInput())
  65.                         VersionFix(ar);
  66.         }
  67.  
  68.         uint GetNumConnectors() const override
  69.         {
  70.                 return m_componentNames.size();
  71.         }
  72.  
  73.         const char* GetConnectorName(uint connectorId) const override
  74.         {
  75.                 if (connectorId >= m_componentNames.size())
  76.                         return nullptr;
  77.                 return m_componentNames[connectorId];
  78.         }
  79.  
  80.         void ConnectTo(const char* pOtherName) override
  81.         {
  82.                 auto it = FindComponentName(pOtherName);
  83.                 if (it == m_componentNames.end())
  84.                         m_componentNames.push_back(pOtherName);
  85.         }
  86.  
  87.         void DisconnectFrom(const char* pOtherName) override
  88.         {
  89.                 auto it = FindComponentName(pOtherName);
  90.                 if (it != m_componentNames.end())
  91.                         m_componentNames.erase(it);
  92.         }
  93.  
  94. protected:
  95.         ILINE void TriggerParticles(const SUpdateContext& context, const TParticleId* pParticleIdTriggers, uint triggerCount)
  96.         {
  97.                 if (m_mode == ESecondGenMode::All)
  98.                         TriggerAll(context, pParticleIdTriggers, triggerCount);
  99.                 else
  100.                         TriggerRandom(context, pParticleIdTriggers, triggerCount);
  101.         }
  102.  
  103. private:
  104.         ILINE void TriggerAll(const SUpdateContext& context, const TParticleId* pParticleIdTriggers, uint triggerCount)
  105.         {
  106.                 CParticleContainer& container = context.m_container;
  107.                 TParticleHeap::Array<CParticleComponentRuntime::SInstance> newInstances(*context.m_pMemHeap);
  108.                 newInstances.reserve(triggerCount);
  109.                 const uint numEntries = m_componentIds.size();
  110.  
  111.                 for (uint i = 0; i < numEntries; ++i)
  112.                 {
  113.                         const TComponentId componentId = m_componentIds[i];
  114.                         ICommonParticleComponentRuntime* pChildComponentRuntime =
  115.                           context.m_runtime.GetEmitter()->GetRuntimes()[componentId].pRuntime;
  116.                         SChaosKey chaosKey = context.m_spawnRng;
  117.  
  118.                         for (uint j = 0; j < triggerCount; ++j)
  119.                         {
  120.                                 const TParticleId particleId = pParticleIdTriggers[j];
  121.                                 const bool trigger = (chaosKey.RandUNorm() <= m_probability);
  122.                                 if (trigger)
  123.                                 {
  124.                                         CParticleComponentRuntime::SInstance instance;
  125.                                         instance.m_parentId = container.GetRealId(particleId);
  126.                                         newInstances.push_back(instance);
  127.                                 }
  128.                         }
  129.                         pChildComponentRuntime->AddSubInstances(newInstances.data(), newInstances.size());
  130.                         newInstances.clear();
  131.                 }
  132.         }
  133.  
  134.         ILINE void TriggerRandom(const SUpdateContext& context, const TParticleId* pParticleIdTriggers, uint triggerCount)
  135.         {
  136.                 CParticleContainer& container = context.m_container;
  137.                 TParticleHeap::Array<CParticleComponentRuntime::SInstance> newInstances(*context.m_pMemHeap);
  138.                 newInstances.reserve(triggerCount);
  139.                 const uint numEntries = m_componentIds.size();
  140.  
  141.                 for (uint i = 0; i < numEntries; ++i)
  142.                 {
  143.                         const TComponentId componentId = m_componentIds[i];
  144.                         ICommonParticleComponentRuntime* pChildComponentRuntime =
  145.                           context.m_runtime.GetEmitter()->GetRuntimes()[componentId].pRuntime;
  146.                         SChaosKey chaosKey = context.m_spawnRng;
  147.  
  148.                         for (uint j = 0; j < triggerCount; ++j)
  149.                         {
  150.                                 const TParticleId particleId = pParticleIdTriggers[j];
  151.                                 const float u = chaosKey.RandUNorm();
  152.                                 const float v = chaosKey.RandUNorm() * numEntries;
  153.                                 const bool trigger = (u <= m_probability);
  154.                                 const bool inRange = v >= float(i) && v < (float(i) + 1.0f);
  155.                                 if (trigger && inRange)
  156.                                 {
  157.                                         CParticleComponentRuntime::SInstance instance;
  158.                                         instance.m_parentId = container.GetRealId(particleId);
  159.                                         newInstances.push_back(instance);
  160.                                 }
  161.                         }
  162.                         pChildComponentRuntime->AddSubInstances(newInstances.data(), newInstances.size());
  163.                         newInstances.clear();
  164.                 }
  165.         }
  166.  
  167.         std::vector<string>::iterator FindComponentName(const char* pOther)
  168.         {
  169.                 auto it = std::find_if(m_componentNames.begin(), m_componentNames.end(),
  170.                                        [pOther](const string& componentName)
  171.                         {
  172.                                 return strcmp(componentName.c_str(), pOther) == 0;
  173.                   });
  174.                 return it;
  175.         }
  176.  
  177.         TComponentId ResolveIdForName(CParticleComponent* pComponent, const string& componentName)
  178.         {
  179.                 TComponentId compId = pComponent->GetComponentId();
  180.                 CParticleEffect* pEffect = pComponent->GetEffect();
  181.                 TComponentId subComponentId = gInvalidId;
  182.  
  183.                 if (componentName == pComponent->GetName())
  184.                 {}  // TODO - user error - user set this component as sub component for itself.
  185.                 for (TComponentId i = 0; i < pEffect->GetNumComponents(); ++i)
  186.                 {
  187.                         CParticleComponent* pSubComp = pEffect->GetCComponent(i);
  188.                         if (pSubComp->GetName() == componentName)
  189.                         {
  190.                                 subComponentId = i;
  191.                                 break;
  192.                         }
  193.                 }
  194.                 if (subComponentId == gInvalidId)
  195.                 {}      // TODO - user error - sub component name was not found
  196.                 return subComponentId;
  197.         }
  198.  
  199.         void VersionFix(Serialization::IArchive& ar)
  200.         {
  201.                 switch (GetVersion(ar))
  202.                 {
  203.                 case 3:
  204.                         {
  205.                                 string subComponentName;
  206.                                 ar(subComponentName, "subComponent", "Trigger Component");
  207.                                 ConnectTo(subComponentName);
  208.                         }
  209.                         break;
  210.                 }
  211.         }
  212.  
  213.         std::vector<string>       m_componentNames;
  214.         std::vector<TComponentId> m_componentIds;
  215.         SUnitFloat                m_probability;
  216.         ESecondGenMode            m_mode;
  217. };
  218.  
  219. //////////////////////////////////////////////////////////////////////////
  220.  
  221. class CFeatureSecondGenOnSpawn : public CFeatureSecondGenBase
  222. {
  223. public:
  224.         CRY_PFX2_DECLARE_FEATURE
  225.  
  226.         virtual void AddToComponent(CParticleComponent* pComponent, SComponentParams* pParams) override
  227.         {
  228.                 CFeatureSecondGenBase::AddToComponent(pComponent, pParams);
  229.                 if (GetNumConnectors() != 0)
  230.                         pComponent->AddToUpdateList(EUL_InitUpdate, this);
  231.         }
  232.  
  233.         virtual void InitParticles(const SUpdateContext& context) override
  234.         {
  235.                 CRY_PFX2_PROFILE_DETAIL;
  236.  
  237.                 TParticleHeap::Array<TParticleId> triggers(*context.m_pMemHeap);
  238.                 triggers.reserve(context.m_container.GetNumSpawnedParticles());
  239.                 CRY_PFX2_FOR_SPAWNED_PARTICLES(context)
  240.                 {
  241.                         triggers.push_back(particleId);
  242.                 }
  243.                 CRY_PFX2_FOR_END;
  244.                 TriggerParticles(context, triggers.data(), triggers.size());
  245.         }
  246. };
  247.  
  248. CRY_PFX2_IMPLEMENT_FEATURE_WITH_CONNECTOR(CParticleFeature, CFeatureSecondGenOnSpawn, "SecondGen", "OnSpawn", colorSecondGen);
  249.  
  250. //////////////////////////////////////////////////////////////////////////
  251.  
  252. class CFeatureSecondGenOnDeath : public CFeatureSecondGenBase
  253. {
  254. public:
  255.         CRY_PFX2_DECLARE_FEATURE
  256.  
  257.         virtual void AddToComponent(CParticleComponent* pComponent, SComponentParams* pParams) override
  258.         {
  259.                 CFeatureSecondGenBase::AddToComponent(pComponent, pParams);
  260.                 if (GetNumConnectors() != 0)
  261.                         pComponent->AddToUpdateList(EUL_KillUpdate, this);
  262.         }
  263.  
  264.         void KillParticles(const SUpdateContext& context, TParticleId* pParticles, size_t count) override
  265.         {
  266.                 TriggerParticles(context, pParticles, count);
  267.         }
  268. };
  269.  
  270. CRY_PFX2_IMPLEMENT_FEATURE_WITH_CONNECTOR(CParticleFeature, CFeatureSecondGenOnDeath, "SecondGen", "OnDeath", colorSecondGen);
  271.  
  272. //////////////////////////////////////////////////////////////////////////
  273.  
  274. class CFeatureSecondGenOnCollide : public CFeatureSecondGenBase
  275. {
  276. public:
  277.         CRY_PFX2_DECLARE_FEATURE
  278.  
  279.         virtual void AddToComponent(CParticleComponent* pComponent, SComponentParams* pParams) override
  280.         {
  281.                 CFeatureSecondGenBase::AddToComponent(pComponent, pParams);
  282.                 if (GetNumConnectors() != 0)
  283.                         pComponent->AddToUpdateList(EUL_Update, this);
  284.         }
  285.  
  286.         virtual void Update(const SUpdateContext& context) override
  287.         {
  288.                 CRY_PFX2_PROFILE_DETAIL;
  289.  
  290.                 CParticleContainer& container = context.m_container;
  291.                 const TIStream<SContactPoint> contactPoints = container.GetTIStream<SContactPoint>(EPDT_ContactPoint);
  292.                 TParticleHeap::Array<TParticleId> triggers(*context.m_pMemHeap);
  293.                 triggers.reserve(container.GetLastParticleId());
  294.  
  295.                 CRY_PFX2_FOR_ACTIVE_PARTICLES(context)
  296.                 {
  297.                         const SContactPoint contact = contactPoints.Load(particleId);
  298.                         if (contact.m_flags & uint(EContactPointsFlags::Collided))
  299.                                 triggers.push_back(particleId);
  300.                 }
  301.                 CRY_PFX2_FOR_END;
  302.  
  303.                 TriggerParticles(context, triggers.data(), triggers.size());
  304.         }
  305. };
  306.  
  307. CRY_PFX2_IMPLEMENT_FEATURE_WITH_CONNECTOR(CParticleFeature, CFeatureSecondGenOnCollide, "SecondGen", "OnCollide", colorSecondGen);
  308.  
  309. }
  310.  
downloadFeatureSecondGen.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