BVB Source Codes

CRYENGINE Show Modifiers.cpp Source code

Return Download CRYENGINE: download Modifiers.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  Created:     25/03/2015 by Filipe amim
  5. //  Description:
  6. // -------------------------------------------------------------------------
  7. //
  8. ////////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "StdAfx.h"
  11. #include <CryMath/PNoise3.h>
  12. #include "ParamMod.h"
  13. #include "ParticleSystem/ParticleComponentRuntime.h"
  14. #include "TimeSource.h"
  15.  
  16. CRY_PFX2_DBG
  17.  
  18. namespace pfx2
  19. {
  20.  
  21. class CFTimeSource : public CTimeSource, public IModifier
  22. {
  23. public:
  24.         virtual EModDomain GetDomain() const
  25.         {
  26.                 return CTimeSource::GetDomain();
  27.         }
  28. };
  29.  
  30. //////////////////////////////////////////////////////////////////////////
  31. // CModCurve
  32.  
  33. class CModCurve : public CFTimeSource
  34. {
  35. public:
  36.         CModCurve() {}
  37.  
  38.         virtual bool CanCreate(const IParamModContext& context) const
  39.         {
  40.                 return context.HasInit();
  41.         }
  42.  
  43.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  44.         {
  45.                 if (m_spline.HasKeys())
  46.                         CTimeSource::AddToParam(pComponent, pParam, this);
  47.         }
  48.  
  49.         virtual void Serialize(Serialization::IArchive& ar)
  50.         {
  51.                 IModifier::Serialize(ar);
  52.                 CTimeSource::SerializeInplace(ar);
  53.                 string desc = ar.isEdit() ? GetSourceDescription() : "";
  54.                 Serialization::SContext _splineContext(ar, desc.data());
  55.                 ar(m_spline, "Curve", "Curve");
  56.         }
  57.  
  58.         virtual void Sample(float* samples, const int numSamples) const
  59.         {
  60.                 for (int i = 0; i < numSamples; ++i)
  61.                 {
  62.                         const float point = (float)i / numSamples;
  63.                         float dataIn = samples[i];
  64.                         float spline = m_spline.Interpolate(point);
  65.                         float dataOut = dataIn * spline;
  66.                         samples[i] = dataOut;
  67.                 }
  68.         }
  69.  
  70.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  71.         {
  72.                 CRY_PFX2_PROFILE_DETAIL;
  73.                 CTimeSource::Dispatch<CModCurve>(context, range, stream, domain);
  74.         }
  75.  
  76.         template<typename TTimeKernel>
  77.         void DoModify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TTimeKernel& timeKernel) const
  78.         {
  79.                 const floatv rate = ToFloatv(m_timeScale);
  80.                 const floatv offset = ToFloatv(m_timeBias);
  81.  
  82.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  83.                 {
  84.                         const floatv inValue = stream.Load(particleGroupId);
  85.                         const floatv time = MAdd(timeKernel.Sample(particleGroupId), rate, offset);
  86.                         const floatv value = m_spline.Interpolate(time);
  87.                         const floatv outvalue = Mul(inValue, value);
  88.                         stream.Store(particleGroupId, outvalue);
  89.                 }
  90.                 CRY_PFX2_FOR_END;
  91.         }
  92.  
  93.         virtual Range GetMinMax() const
  94.         {
  95.                 return m_spline.GetValueRange();
  96.         }
  97.  
  98. private:
  99.         CParticleSpline m_spline;
  100. };
  101.  
  102. SERIALIZATION_CLASS_NAME(IModifier, CModCurve, "Curve", "Curve");
  103.  
  104. //////////////////////////////////////////////////////////////////////////
  105. // CModDoubleCurve
  106.  
  107. class CModDoubleCurve : public CFTimeSource
  108. {
  109. public:
  110.         CModDoubleCurve() {}
  111.  
  112.         virtual bool CanCreate(const IParamModContext& context) const
  113.         {
  114.                 return context.HasInit();
  115.         }
  116.  
  117.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  118.         {
  119.                 if (m_spline.HasKeys())
  120.                 {
  121.                         CTimeSource::AddToParam(pComponent, pParam, this);
  122.                         pComponent->AddParticleData(EPDT_Random);
  123.                 }
  124.         }
  125.  
  126.         virtual void Serialize(Serialization::IArchive& ar)
  127.         {
  128.                 IModifier::Serialize(ar);
  129.                 CTimeSource::SerializeInplace(ar);
  130.                 string desc = ar.isEdit() ? GetSourceDescription() : "";
  131.                 Serialization::SContext _splineContext(ar, desc.data());
  132.                 ar(m_spline, "DoubleCurve", "Double Curve");
  133.         }
  134.  
  135.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  136.         {
  137.                 CRY_PFX2_PROFILE_DETAIL;
  138.                 CTimeSource::Dispatch<CModDoubleCurve>(context, range, stream, domain);
  139.         }
  140.  
  141.         template<typename TimeKernel>
  142.         void DoModify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel) const
  143.         {
  144.                 CRY_PFX2_PROFILE_DETAIL;
  145.  
  146.                 const CParticleContainer& container = context.m_container;
  147.                 const IFStream unormRands = container.GetIFStream(EPDT_Random);
  148.                 const floatv rate = ToFloatv(m_timeScale);
  149.                 const floatv offset = ToFloatv(m_timeBias);
  150.  
  151.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  152.                 {
  153.                         const floatv unormRand = unormRands.Load(particleGroupId);
  154.                         const floatv inValue = stream.Load(particleGroupId);
  155.                         const floatv time = MAdd(timeKernel.Sample(particleGroupId), rate, offset);
  156.                         const floatv value = m_spline.Interpolate(time, unormRand);
  157.                         const floatv outvalue = Mul(inValue, value);
  158.                         stream.Store(particleGroupId, outvalue);
  159.                 }
  160.                 CRY_PFX2_FOR_END;
  161.         }
  162.  
  163.         virtual Range GetMinMax() const
  164.         {
  165.                 return m_spline.GetValueRange();
  166.         }
  167.  
  168. private:
  169.         CParticleDoubleSpline m_spline;
  170. };
  171.  
  172. SERIALIZATION_CLASS_NAME(IModifier, CModDoubleCurve, "DoubleCurve", "Double Curve");
  173.  
  174. //////////////////////////////////////////////////////////////////////////
  175. // CModRandom
  176.  
  177. class CModRandom : public IModifier
  178. {
  179. public:
  180.         CModRandom(float amount = 0.0f)
  181.                 : m_amount(amount)
  182.         {}
  183.  
  184.         virtual bool CanCreate(const IParamModContext& context) const
  185.         {
  186.                 return context.HasInit();
  187.         }
  188.  
  189.         virtual EModDomain GetDomain() const
  190.         {
  191.                 return EMD_PerParticle;
  192.         }
  193.  
  194.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  195.         {
  196.                 pParam->AddToInitParticles(this);
  197.         }
  198.  
  199.         virtual void Serialize(Serialization::IArchive& ar)
  200.         {
  201.                 IModifier::Serialize(ar);
  202.                 ar(m_amount, "Amount", "Amount");
  203.         }
  204.  
  205.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  206.         {
  207.                 CRY_PFX2_PROFILE_DETAIL;
  208.  
  209.                 SChaosKeyV::Range randRange(1.0f - m_amount, 1.0f);
  210.  
  211.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  212.                 {
  213.                         const floatv inValue = stream.Load(particleGroupId);
  214.                         const floatv value = context.m_spawnRngv.Rand(randRange);
  215.                         const floatv outvalue = Mul(inValue, value);
  216.                         stream.Store(particleGroupId, outvalue);
  217.                 }
  218.                 CRY_PFX2_FOR_END;
  219.         }
  220.  
  221.         virtual Range GetMinMax() const
  222.         {
  223.                 return Range(1.0f - m_amount, 1.0f);
  224.         }
  225.  
  226. private:
  227.  
  228.         UFloat m_amount;
  229. };
  230.  
  231. SERIALIZATION_CLASS_NAME(IModifier, CModRandom, "Random", "Random");
  232.  
  233. //////////////////////////////////////////////////////////////////////////
  234. // CModNoise
  235.  
  236. SERIALIZATION_DECLARE_ENUM(EParamNoiseMode,
  237.                            Smooth,
  238.                            Fractal,
  239.                            Pulse,
  240.                            _Random
  241.                            )
  242.  
  243. class CModNoise : public CFTimeSource
  244. {
  245. public:
  246.         CModNoise()
  247.                 : m_amount(0.0f)
  248.                 , m_pulseWidth(0.5f)
  249.                 , m_mode(EParamNoiseMode::Smooth) {}
  250.  
  251.         virtual bool CanCreate(const IParamModContext& context) const
  252.         {
  253.                 return context.HasInit();
  254.         }
  255.  
  256.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  257.         {
  258.                 CTimeSource::AddToParam(pComponent, pParam, this);
  259.         }
  260.  
  261.         virtual void Serialize(Serialization::IArchive& ar)
  262.         {
  263.                 IModifier::Serialize(ar);
  264.                 CTimeSource::SerializeInplace(ar);
  265.                 ar(m_mode, "Mode", "Mode");
  266.                 ar(m_amount, "Amount", "Amount");
  267.                 if (m_mode == EParamNoiseMode::Pulse)
  268.                         ar(m_pulseWidth, "PulseWidth", "Pulse Width");
  269.  
  270.                 if (ar.isInput())
  271.                         VersionFix(ar);
  272.         }
  273.  
  274.         virtual IModifier* VersionFixReplace() const
  275.         {
  276.                 if (m_mode == EParamNoiseMode::_Random)
  277.                         return new CModRandom(m_amount);
  278.                 return nullptr;
  279.         }
  280.  
  281.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  282.         {
  283.                 CRY_PFX2_PROFILE_DETAIL;
  284.                 CTimeSource::Dispatch<CModNoise>(context, range, stream, domain);
  285.         }
  286.  
  287.         template<typename TimeKernel>
  288.         void DoModify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel) const
  289.         {
  290.                 CRY_PFX2_PROFILE_DETAIL;
  291.  
  292.                 switch (m_mode)
  293.                 {
  294.                 case EParamNoiseMode::Smooth:
  295.                         Modify(context, range, stream, timeKernel,
  296.                                [](floatv time){ return Smooth(time); });
  297.                         break;
  298.                 case EParamNoiseMode::Fractal:
  299.                         Modify(context, range, stream, timeKernel,
  300.                                [](floatv time){ return Fractal(time); });
  301.                         break;
  302.                 case EParamNoiseMode::Pulse:
  303.                         Modify(context, range, stream, timeKernel,
  304.                                [this](floatv time){ return Pulse(time); });
  305.                         break;
  306.                 }
  307.         }
  308.  
  309.         virtual Range GetMinMax() const
  310.         {
  311.                 return Range(1.0f - m_amount, 1.0f);
  312.         }
  313.  
  314. private:
  315.         template<typename TimeKernel, typename ModeFn>
  316.         ILINE void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel, ModeFn modeFn) const
  317.         {
  318.                 const floatv one = ToFloatv(1.0f);
  319.                 const floatv amount = ToFloatv(m_amount);
  320.                 const floatv rate = ToFloatv(m_timeScale);
  321.                 const floatv offset = ToFloatv(m_timeBias);
  322.  
  323.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  324.                 {
  325.                         const floatv inValue = stream.Load(particleGroupId);
  326.                         const floatv time = MAdd(timeKernel.Sample(particleGroupId), rate, offset);
  327.                         const floatv value = modeFn(time);
  328.                         const floatv outvalue = Mul(inValue, Sub(one, Mul(value, amount)));
  329.                         stream.Store(particleGroupId, outvalue);
  330.                 }
  331.                 CRY_PFX2_FOR_END;
  332.         }
  333.  
  334.         // PFX2_TODO : properly vectorize this code and make it not dependent on SSE4.1
  335.         ILINE static floatv UPNoise(floatv x)
  336.         {
  337.                 CPNoise3& noiseGen = *gEnv->pSystem->GetNoiseGen();
  338. #ifndef CRY_PFX2_USE_SSE
  339.                 return noiseGen.Noise1D(x) * 2.5f;
  340. #else
  341.                 const float x0 = get_element<0>(x);
  342.                 const float x1 = get_element<1>(x);
  343.                 const float x2 = get_element<2>(x);
  344.                 const float x3 = get_element<3>(x);
  345.                 const float v0 = noiseGen.Noise1D(x0);
  346.                 const float v1 = noiseGen.Noise1D(x1);
  347.                 const float v2 = noiseGen.Noise1D(x2);
  348.                 const float v3 = noiseGen.Noise1D(x3);
  349.                 return _mm_mul_ps(_mm_set_ps(v3, v2, v1, v0), _mm_set1_ps(2.5f));
  350. #endif
  351.         }
  352.  
  353.         ILINE static floatv Smooth(floatv time)
  354.         {
  355.                 const floatv half = ToFloatv(0.5f);
  356.                 return MAdd(UPNoise(time), half, half);
  357.         }
  358.  
  359.         ILINE static floatv Fractal(floatv time)
  360.         {
  361.                 const floatv two = ToFloatv(2.0f);
  362.                 const floatv four = ToFloatv(4.0f);
  363.                 const floatv half = ToFloatv(0.5f);
  364.                 const floatv quarter = ToFloatv(0.25f);
  365.                 floatv fractal = UPNoise(time);
  366.                 fractal = MAdd(UPNoise(Mul(time, two)), half, fractal);
  367.                 fractal = MAdd(UPNoise(Mul(time, four)), quarter, fractal);
  368.                 return MAdd(fractal, half, half);
  369.         }
  370.  
  371.         ILINE floatv Pulse(floatv time) const
  372.         {
  373.                 const floatv one = ToFloatv(1.0f);
  374.                 const floatv pulseWidth = ToFloatv(m_pulseWidth);
  375.                 return if_else_zero(UPNoise(time) < pulseWidth, one);
  376.         }
  377.  
  378.         void VersionFix(Serialization::IArchive& ar)
  379.         {
  380.                 if (GetVersion(ar) <= 8)
  381.                 {
  382.                         float rate;
  383.                         if (ar(rate, "Rate", "Rate"))
  384.                                 m_timeScale *= rate;
  385.                 }
  386.         }
  387.  
  388.         SFloat          m_amount;
  389.         UUnitFloat      m_pulseWidth;
  390.         EParamNoiseMode m_mode;
  391. };
  392.  
  393. SERIALIZATION_CLASS_NAME(IModifier, CModNoise, "Noise", "Noise");
  394.  
  395. //////////////////////////////////////////////////////////////////////////
  396. // CModWave
  397.  
  398. SERIALIZATION_DECLARE_ENUM(EWaveType,
  399.                            Sin,
  400.                            Saw,
  401.                            Pulse
  402.                            )
  403.  
  404. class CModWave : public CFTimeSource
  405. {
  406. public:
  407.         CModWave()
  408.                 : m_waveType(EWaveType::Sin)
  409.                 , m_amplitude(1.0f)
  410.                 , m_bias(0.5f)
  411.                 , m_inverse(false) {}
  412.  
  413.         virtual bool CanCreate(const IParamModContext& context) const
  414.         {
  415.                 return context.HasInit();
  416.         }
  417.  
  418.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  419.         {
  420.                 CTimeSource::AddToParam(pComponent, pParam, this);
  421.         }
  422.  
  423.         virtual void Serialize(Serialization::IArchive& ar)
  424.         {
  425.                 IModifier::Serialize(ar);
  426.                 CTimeSource::SerializeInplace(ar);
  427.                 ar(m_waveType, "Wave", "Wave");
  428.                 ar(m_amplitude, "Amplitude", "Amplitude");
  429.                 ar(m_bias, "Bias", "Bias");
  430.                 ar(m_inverse, "Inverse", "Inverse");
  431.                 if (ar.isInput())
  432.                         VersionFix(ar);
  433.         }
  434.  
  435.         void VersionFix(Serialization::IArchive& ar)
  436.         {
  437.                 if (GetVersion(ar) <= 8)
  438.                 {
  439.                         float rate, phase;
  440.                         if (ar(rate, "Rate"))
  441.                                 m_timeScale *= rate;
  442.                         if (ar(phase, "Phase"))
  443.                                 m_timeBias -= phase * m_timeScale;
  444.                 }
  445.         }
  446.  
  447.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  448.         {
  449.                 CRY_PFX2_PROFILE_DETAIL;
  450.                 CTimeSource::Dispatch<CModWave>(context, range, stream, domain);
  451.         }
  452.  
  453.         template<typename TimeKernel>
  454.         void DoModify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel) const
  455.         {
  456.                 switch (m_waveType)
  457.                 {
  458.                 case EWaveType::Sin:
  459.                         Modify(context, range, stream, timeKernel,
  460.                                [](floatv time) { return Sin(time); });
  461.                         break;
  462.                 case EWaveType::Saw:
  463.                         Modify(context, range, stream, timeKernel,
  464.                                [](floatv time) { return Saw(time); });
  465.                         break;
  466.                 case EWaveType::Pulse:
  467.                         Modify(context, range, stream, timeKernel,
  468.                                [](floatv time) { return Pulse(time); });
  469.                         break;
  470.                 }
  471.         }
  472.  
  473.         virtual Range GetMinMax() const
  474.         {
  475.                 return Range(m_bias - m_amplitude * 0.5f, m_bias + m_amplitude * 0.5f);
  476.         }
  477.  
  478. private:
  479.         template<typename TimeKernel, typename WaveFn>
  480.         void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel, WaveFn waveFn) const
  481.         {
  482.                 const floatv mult = ToFloatv(m_amplitude * (m_inverse ? -1.0f : 1.0f) * 0.5f);
  483.                 const floatv bias = ToFloatv(m_bias);
  484.                 const floatv rate = ToFloatv(m_timeScale);
  485.                 const floatv offset = ToFloatv(m_timeBias);
  486.  
  487.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range);
  488.                 {
  489.                         const floatv inValue = stream.Load(particleGroupId);
  490.                         const floatv time = MAdd(timeKernel.Sample(particleGroupId), rate, offset);
  491.                         const floatv sample = waveFn(time);
  492.                         const floatv value = MAdd(sample, mult, bias);
  493.                         const floatv outvalue = Mul(inValue, value);
  494.                         stream.Store(particleGroupId, outvalue);
  495.                 }
  496.                 CRY_PFX2_FOR_END;
  497.         }
  498.  
  499.         // PFX2_TODO : improve functions and place them in a common library
  500. #ifdef CRY_PFX2_USE_SSE
  501.         ILINE static floatv SinApproax(floatv x)
  502.         {
  503.                 const floatv one = ToFloatv(1.0f);
  504.                 const floatv half = ToFloatv(0.5f);
  505.                 const floatv negHalfPi = ToFloatv(-gf_PI * 0.5f);
  506.                 const floatv pi = ToFloatv(gf_PI);
  507.                 const floatv ipi = ToFloatv(1.0f / gf_PI);
  508.                 const floatv ipi2 = ToFloatv(1.0f / gf_PI2);
  509.  
  510.                 const floatv x1 = MAdd(frac(Mul(x, ipi)), pi, negHalfPi);
  511.                 const floatv m = signnz(frac(Mul(x, ipi2)) - half);
  512.  
  513.                 const floatv p0 = ToFloatv(-0.4964738f);
  514.                 const floatv p1 = ToFloatv(0.036957536f);
  515.                 const floatv x2 = Mul(x1, x1);
  516.                 const floatv x4 = Mul(x2, x2);
  517.                 const floatv result = Mul(MAdd(x4, p1, MAdd(x2, p0, one)), m);
  518.  
  519.                 return result;
  520.         }
  521.  
  522.         ILINE static floatv CosApproax(floatv x)
  523.         {
  524.                 const floatv halfPi = ToFloatv(gf_PI * 0.5f);
  525.                 return SinApproax(Sub(x, halfPi));
  526.         }
  527. #else
  528.  
  529.         ILINE static floatv CosApproax(floatv x)
  530.         {
  531.                 return cosf(x);
  532.         }
  533.  
  534. #endif
  535.  
  536.         ILINE static floatv Sin(floatv time)
  537.         {
  538.                 return -CosApproax(time * ToFloatv(gf_PI2));
  539.         }
  540.  
  541.         ILINE static floatv Saw(floatv time)
  542.         {
  543.                 const floatv f = frac(time);
  544.                 return f + f - ToFloatv(1.0f);
  545.         }
  546.  
  547.         ILINE static floatv Pulse(floatv time)
  548.         {
  549.                 const floatv half = ToFloatv(0.5f);
  550.                 return signnz(half - frac(time));
  551.         }
  552.  
  553.         EWaveType m_waveType;
  554.         UFloat10  m_rate;
  555.         UFloat    m_amplitude;
  556.         SFloat    m_phase;
  557.         SFloat    m_bias;
  558.         bool      m_inverse;
  559. };
  560.  
  561. SERIALIZATION_CLASS_NAME(IModifier, CModWave, "Wave", "Wave");
  562.  
  563. //////////////////////////////////////////////////////////////////////////
  564. // CModInherit
  565.  
  566. class CModInherit : public IModifier
  567. {
  568. public:
  569.         CModInherit()
  570.                 : m_spawnOnly(true) {}
  571.  
  572.         virtual bool CanCreate(const IParamModContext& context) const
  573.         {
  574.                 return context.GetDomain() >= EMD_PerParticle && context.CanInheritParent();
  575.         }
  576.  
  577.         virtual EModDomain GetDomain() const
  578.         {
  579.                 return EMD_PerParticle;
  580.         }
  581.  
  582.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  583.         {
  584.                 if (m_spawnOnly)
  585.                         pParam->AddToInitParticles(this);
  586.                 else
  587.                         pParam->AddToUpdate(this);
  588.         }
  589.  
  590.         virtual void Serialize(Serialization::IArchive& ar)
  591.         {
  592.                 IModifier::Serialize(ar);
  593.                 ar(m_spawnOnly, "SpawnOnly", "Spawn Only");
  594.         }
  595.  
  596.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  597.         {
  598.                 CRY_PFX2_PROFILE_DETAIL;
  599.  
  600.                 CParticleContainer& container = context.m_container;
  601.                 CParticleContainer& parentContainer = context.m_parentContainer;
  602.                 if (!parentContainer.HasData(streamType))
  603.                         return;
  604.                 IPidStream parentIds = context.m_container.GetIPidStream(EPDT_ParentId);
  605.                 IFStream parentStream = parentContainer.GetIFStream(streamType);
  606.  
  607.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  608.                 {
  609.                         const TParticleIdv parentId = parentIds.Load(particleGroupId);
  610.                         const floatv input = stream.Load(particleGroupId);
  611.                         const floatv parent = parentStream.Load(parentId, 0.0f);
  612.                         const floatv output = Mul(input, parent);
  613.                         stream.Store(particleGroupId, output);
  614.                 }
  615.                 CRY_PFX2_FOR_END;
  616.         }
  617.  
  618.         virtual Range GetMinMax() const
  619.         {
  620.                 // PFX2_TODO: Wrong! Depends on inherited value
  621.                 return Range(0.0f, 1.0f);
  622.         }
  623. private:
  624.         bool m_spawnOnly;
  625. };
  626.  
  627. SERIALIZATION_CLASS_NAME(IModifier, CModInherit, "Inherit", "Inherit");
  628.  
  629. //////////////////////////////////////////////////////////////////////////
  630. // CModLinear
  631.  
  632. class CModLinear : public CFTimeSource
  633. {
  634. public:
  635.         CModLinear() {}
  636.  
  637.         virtual bool CanCreate(const IParamModContext& context) const
  638.         {
  639.                 return true;
  640.         }
  641.  
  642.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam)
  643.         {
  644.                 CTimeSource::AddToParam(pComponent, pParam, this);
  645.         }
  646.  
  647.         virtual void Serialize(Serialization::IArchive& ar)
  648.         {
  649.                 IModifier::Serialize(ar);
  650.                 CTimeSource::SerializeInplace(ar);
  651.         }
  652.  
  653.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const
  654.         {
  655.                 CRY_PFX2_PROFILE_DETAIL;
  656.                 CTimeSource::Dispatch<CModLinear>(context, range, stream, domain);
  657.         }
  658.  
  659.         template<typename TimeKernel>
  660.         void DoModify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, const TimeKernel& timeKernel) const
  661.         {
  662.                 const floatv rate = ToFloatv(m_timeScale);
  663.                 const floatv offset = ToFloatv(m_timeBias);
  664.  
  665.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  666.                 {
  667.                         const floatv inValue = stream.Load(particleGroupId);
  668.                         const floatv time = MAdd(timeKernel.Sample(particleGroupId), rate, offset);
  669.                         const floatv outvalue = Mul(inValue, time);
  670.                         stream.Store(particleGroupId, outvalue);
  671.                 }
  672.                 CRY_PFX2_FOR_END;
  673.         }
  674.  
  675.         virtual Range GetMinMax() const
  676.         {
  677.                 // PFX2_TODO: Wrong! Depends on TimeSource range
  678.                 return Range(Adjust(0.0f)) | Adjust(1.0f);
  679.         }
  680. };
  681.  
  682. SERIALIZATION_CLASS_NAME(IModifier, CModLinear, "Linear", "Linear");
  683.  
  684. //////////////////////////////////////////////////////////////////////////
  685. // CModConfigSpec
  686.  
  687. struct SSpecData
  688. {
  689.         char* m_pName;
  690.         char* m_pLabel;
  691.         uint  m_index;
  692. };
  693.  
  694. const SSpecData gConfigSpecs[] =
  695. {
  696.         { "Low",      "Low",            CONFIG_LOW_SPEC },
  697.         { "Medium",   "Medium",         CONFIG_MEDIUM_SPEC },
  698.         { "High",     "High",           CONFIG_HIGH_SPEC },
  699.         { "VeryHigh", "Very High",      CONFIG_VERYHIGH_SPEC },
  700.         { "XBO",      "XBox One",       CONFIG_DURANGO },
  701.         { "PS4",      "Playstation 4",  CONFIG_ORBIS },
  702. };
  703.  
  704. const uint gNumConfigSpecs = sizeof(gConfigSpecs) / sizeof(gConfigSpecs[0]);
  705.  
  706. class CModConfigSpec : public IModifier
  707. {
  708. public:
  709.         CModConfigSpec()
  710.                 : m_range(1.0f, 1.0f)
  711.                 , m_spawnOnly(true)
  712.         {
  713.                 for (uint i = 0; i < gNumConfigSpecs; ++i)
  714.                         m_specMultipliers[i] = 1.0f;
  715.         }
  716.  
  717.         virtual void AddToParam(CParticleComponent* pComponent, IParamMod* pParam) override
  718.         {
  719.                 if (m_spawnOnly)
  720.                         pParam->AddToInitParticles(this);
  721.                 else
  722.                         pParam->AddToUpdate(this);
  723.         }
  724.  
  725.         virtual EModDomain GetDomain() const override
  726.         {
  727.                 return EMD_PerParticle;
  728.         }
  729.  
  730.         virtual Range GetMinMax() const override
  731.         {
  732.                 return m_range;
  733.         }
  734.  
  735.         virtual void Serialize(Serialization::IArchive& ar) override
  736.         {
  737.                 IModifier::Serialize(ar);
  738.  
  739.                 for (uint i = 0; i < gNumConfigSpecs; ++i)
  740.                         ar(m_specMultipliers[i], gConfigSpecs[i].m_pName, gConfigSpecs[i].m_pLabel);
  741.                 m_range = Range(m_specMultipliers[0], m_specMultipliers[0]);
  742.                 for (uint i = 1; i < gNumConfigSpecs; ++i)
  743.                         m_range = Range(min(m_range.start, m_specMultipliers[1]), max(m_range.end, m_specMultipliers[0]));
  744.  
  745.                 const auto& context = GetContext(ar);
  746.                 if (context.GetDomain() == EMD_PerInstance)
  747.                         m_spawnOnly = false;
  748.                 else if (!context.HasUpdate())
  749.                         m_spawnOnly = true;
  750.                 else
  751.                         ar(m_spawnOnly, "SpawnOnly", "Spawn Only");
  752.         }
  753.  
  754.         virtual void Modify(const SUpdateContext& context, const SUpdateRange& range, IOFStream stream, EParticleDataType streamType, EModDomain domain) const override
  755.         {
  756.                 CRY_PFX2_PROFILE_DETAIL;
  757.  
  758.                 CVars* pCVars = static_cast<C3DEngine*>(gEnv->p3DEngine)->GetCVars();
  759.                 const ESystemConfigSpec configSpec = gEnv->pSystem->GetConfigSpec();
  760.                 const uint particleSpec = pCVars->e_ParticlesQuality != 0 ? pCVars->e_ParticlesQuality : configSpec;
  761.  
  762.                 floatv multiplier = ToFloatv(1.0f);
  763.                 for (uint i = 0; i < gNumConfigSpecs; ++i)
  764.                 {
  765.                         if (gConfigSpecs[i].m_index == particleSpec)
  766.                         {
  767.                                 multiplier = ToFloatv(m_specMultipliers[i]);
  768.                                 break;
  769.                         }
  770.                 }
  771.  
  772.                 CRY_PFX2_FOR_RANGE_PARTICLESGROUP(range)
  773.                 {
  774.                         const floatv inValue = stream.Load(particleGroupId);
  775.                         const floatv outvalue = inValue * multiplier;
  776.                         stream.Store(particleGroupId, outvalue);
  777.                 }
  778.                 CRY_PFX2_FOR_END;
  779.         }
  780.  
  781. private:
  782.         ILINE IParamModContext& GetContext(Serialization::IArchive& ar) const
  783.         {
  784.                 IParamModContext* pContext = ar.context<IParamModContext>();
  785.                 CRY_PFX2_ASSERT(pContext != nullptr);
  786.                 return *pContext;
  787.         }
  788.  
  789.         float m_specMultipliers[gNumConfigSpecs];
  790.         Range m_range;
  791.         bool  m_spawnOnly;
  792. };
  793.  
  794. SERIALIZATION_CLASS_NAME(IModifier, CModConfigSpec, "ConfigSpec", "Config Spec");
  795.  
  796. }
  797.  
downloadModifiers.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