!I CL 1906107 //dev_game_hunt/xbox_candidate -> //ce/main
[CRYENGINE.git] / Code / CryEngine / CryCommon / CryParticleSystem / ParticleParams.h
blobac95cb441567f8789ba2efb6f4e4daf5c48ff5e5
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 // -------------------------------------------------------------------------
4 // File name: ParticleParams.h
5 // -------------------------------------------------------------------------
6 // History:
7 //
8 ////////////////////////////////////////////////////////////////////////////
10 #ifndef _PARTICLEPARAMS_H_
11 #define _PARTICLEPARAMS_H_ 1
13 #include <CryMath/FinalizingSpline.h>
14 #include <CryMath/Cry_Color.h>
15 #include <CryString/CryString.h>
16 #include <CryString/CryName.h>
18 #include <CryCore/CryCustomTypes.h>
19 #include <CryMath/Cry_Math.h>
20 #include <CryMath/Random.h>
21 #include <CryRenderer/IRenderer.h>
23 BASIC_TYPE_INFO(CCryName);
25 ///////////////////////////////////////////////////////////////////////
27 //! Use for practically infinite values, to simplify comparisons.
28 //! 1e9 s > 30 years, 1e9 m > earth-moon distance.
29 //! Convertible to int32.
30 #define fHUGE 1e9f
32 //! Convert certain parameters where zero denotes an essentially infinite value.
33 ILINE float ZeroIsHuge(float f)
35 return if_else(f, f, fHUGE);
38 //! For accessing specific information from variable parameters,
39 //! use VMIN, VMAX (from CryMath.h), and VRANDOM (defined here)
40 enum type_random { VRANDOM };
42 // Trinary enum, encodes yes/no/both state
44 //! Original names, compatible with serialization.
45 DEFINE_ENUM_VALS(ETrinaryNames, uint8,
46 If_False = 1,
47 If_True,
48 Both
51 struct ETrinary : ETrinaryNames
53 //! Initialized with bool value, or Both (default).
54 ETrinary(ETrinaryNames::E e = Both)
55 : ETrinaryNames(e) {}
56 ETrinary(bool b)
57 : ETrinaryNames(ETrinaryNames::E(1 << uint8(b))) {}
59 //! Test against ETrinary, or directly against bool.
60 uint8 operator*(ETrinary t) const
62 return +*this & + t;
64 uint8 operator*(bool b) const
66 return +*this & (1 << uint8(b));
70 //! \cond INTERNAL
71 //! Pseudo-random number generation, from a key.
72 class CChaosKey
74 public:
75 //! Initialize with an int.
76 explicit inline CChaosKey(uint32 uSeed)
77 : m_Key(uSeed) {}
79 explicit inline CChaosKey(float fSeed)
80 : m_Key((uint32)(fSeed * float(0xFFFFFFFF))) {}
82 explicit inline CChaosKey(void const* ptr)
83 : m_Key(uint32(size_t(ptr))) {}
85 CChaosKey Jumble(CChaosKey key2) const
87 return CChaosKey(Jumble(m_Key ^ key2.m_Key));
89 CChaosKey Jumble(void const* ptr) const
91 return Jumble(CChaosKey(ptr));
94 //! Scale input range.
95 inline float operator*(float fRange) const
97 return (float)m_Key / float(0xFFFFFFFF) * fRange;
99 inline uint32 operator*(uint32 nRange) const
101 return m_Key % nRange;
103 inline uint16 operator*(uint16 nRange) const
105 return m_Key % nRange;
108 uint32 GetKey() const
110 return m_Key;
113 //! Jumble with a range variable to produce a random value.
114 template<class T>
115 inline T Random(T const& Range) const
117 return Jumble(CChaosKey(&Range)) * Range;
120 private:
121 uint32 m_Key;
123 static inline uint32 Jumble(uint32 key)
125 key += ~rot_left(key, 15);
126 key ^= rot_right(key, 10);
127 key += rot_left(key, 3);
128 key ^= rot_right(key, 6);
129 key += ~rot_left(key, 11);
130 key ^= rot_right(key, 16);
131 return key;
134 static inline uint32 rot_left(uint32 u, int n)
136 return (u << n) | (u >> (32 - n));
138 static inline uint32 rot_right(uint32 u, int n)
140 return (u >> n) | (u << (32 - n));
143 //! \endcond
145 // Float storage
146 typedef TRangedType<float> SFloat;
147 typedef TRangedType<float, 0> UFloat;
148 typedef TRangedType<float, 0, 1> UnitFloat;
149 typedef TRangedType<float, 0, 2> Unit2Float;
150 typedef TRangedType<float, 0, 4> Unit4Float;
151 typedef TRangedType<float, -180, 180> SAngle;
152 typedef TRangedType<float, 0, 180> UHalfAngle;
153 typedef TRangedType<float, 0, 360> UFullAngle;
155 typedef TSmall<bool> TSmallBool;
156 typedef TSmall<bool, uint8, 0, 1> TSmallBoolTrue;
157 typedef TSmall<uint, uint8, 1> PosInt8;
159 template<class T>
160 struct TStorageTraits
162 typedef float TValue;
163 typedef UnitFloat8 TMod;
164 typedef UnitFloat TRandom;
167 template<>
168 struct TStorageTraits<SFloat>
170 typedef float TValue;
171 typedef UnitFloat8 TMod;
172 typedef Unit2Float TRandom;
175 template<>
176 struct TStorageTraits<SAngle>
178 typedef float TValue;
179 typedef UnitFloat8 TMod;
180 typedef Unit2Float TRandom;
183 template<class TFixed>
184 bool RandomActivate(const TFixed& chance)
186 return cry_random(0, chance.GetMaxStore() - 1) < chance.GetStore();
189 // Vec3 TypeInfo
191 typedef Vec3_tpl<SFloat> Vec3S;
192 typedef Vec3_tpl<UFloat> Vec3U;
194 // Color specialisations.
196 template<class T>
197 struct Color3 : Vec3_tpl<T>
199 Color3(T v = T(0))
200 : Vec3_tpl<T>(v) {}
202 Color3(T r, T g, T b)
203 : Vec3_tpl<T>(r, g, b) {}
205 Color3(Vec3_tpl<T> const& v)
206 : Vec3_tpl<T>(v) {}
208 template<class T2>
209 Color3(Vec3_tpl<T2> const& c)
210 : Vec3_tpl<T>(c) {}
212 operator ColorF() const
213 { return ColorF(this->x, this->y, this->z, 1.f); }
215 //! Implement color multiplication.
216 Color3& operator*=(Color3 const& c)
217 { this->x *= c.x; this->y *= c.y; this->z *= c.z; return *this; }
220 template<class T>
221 Color3<T> operator*(Color3<T> const& c, Color3<T> const& d)
222 { return Color3<T>(c.x * d.x, c.y * d.y, c.z * d.z); }
224 typedef Color3<float> Color3F;
225 typedef Color3<UnitFloat8> Color3B;
227 class RandomColor : public UnitFloat8
229 public:
230 inline RandomColor(float f = 0.f, bool bRandomHue = false)
231 : UnitFloat8(f), m_bRandomHue(bRandomHue)
234 Color3F GetRandom() const
236 if (m_bRandomHue)
238 ColorB clr(cry_random_uint32());
239 float fScale = float(*this) / 255.f;
240 return Color3F(clr.r * fScale, clr.g * fScale, clr.b * fScale);
242 else
244 return Color3F(cry_random(0.0f, float(*this)));
248 bool HasRandomHue() const
249 { return m_bRandomHue; }
251 AUTO_STRUCT_INFO;
253 protected:
254 TSmallBool m_bRandomHue;
257 template<>
258 struct TStorageTraits<Color3F>
260 typedef Color3F TValue;
261 typedef Color3<UnitFloat8> TMod;
262 typedef RandomColor TRandom;
265 // Spline implementation class.
266 template<>
267 inline const CTypeInfo& TypeInfo(ISplineInterpolator**)
269 static CTypeInfo Info("ISplineInterpolator*", sizeof(void*), alignof(void*));
270 return Info;
273 template<class S>
274 class TCurve : public spline::OptSpline<typename TStorageTraits<S>::TValue>
276 typedef TCurve<S> TThis;
277 typedef typename TStorageTraits<S>::TValue T;
278 typedef typename TStorageTraits<S>::TMod TMod;
279 typedef spline::OptSpline<T> super_type;
281 public:
282 using_type(super_type, source_spline);
283 using_type(super_type, key_type);
285 using super_type::num_keys;
286 using super_type::key;
287 using super_type::empty;
288 using super_type::min_value;
289 using super_type::interpolate;
291 // Implement serialization.
292 string ToString(FToString flags = {}) const;
293 bool FromString(cstr str, FFromString flags = {});
295 // Access operators
296 T operator()(float fTime) const
298 T val;
299 interpolate(fTime, val);
300 return val;
303 T operator()(type_max) const
305 return T(1);
308 T operator()(type_min) const
310 T val;
311 min_value(val);
312 return val;
315 struct CCustomInfo;
316 CUSTOM_STRUCT_INFO(CCustomInfo)
319 // Composite parameter types, incorporating base value, randomness, and lifetime curves.
321 template<class S>
322 struct TVarParam : S
324 typedef typename TStorageTraits<S>::TValue T;
326 //! Random variation capability.
327 using_type(TStorageTraits<S>, TRandom);
329 struct SRandom : TRandom
331 SRandom(TRandom r = TRandom(0))
332 : TRandom(r) {}
334 const TRandom& Range() const
335 { return static_cast<const TRandom&>(*this); }
337 // Access operators.
339 T operator()(type_max) const
340 { return T(1); }
342 T operator()(type_min) const
343 { return T(1) - T(Range()); }
345 T operator()(float fInterp) const
346 { return T(1) + T(Range() * (fInterp - 1.f)); }
348 T operator()(CChaosKey key) const
350 if (!!Range())
351 return T(1) - T(key.Random(Range()));
352 else
353 return T(1);
356 T operator()(type_random) const
358 if (!!Range())
359 return T(1) - T(ParamRandom(Range()));
360 else
361 return T(1);
364 private:
365 static Color3F ParamRandom(RandomColor const& rc)
367 return rc.GetRandom();
370 static float ParamRandom(float v)
372 return cry_random(0.0f, v);
376 TVarParam()
377 : S()
381 TVarParam(const T& tBase)
382 : S(tBase)
386 void Set(const T& tBase)
388 Base() = tBase;
390 void Set(const T& tBase, const TRandom& tRan)
392 Base() = tBase;
393 m_Random = tRan;
396 // Value extraction.
398 S& Base()
400 return static_cast<S&>(*this);
402 const S& Base() const
404 return static_cast<const S&>(*this);
407 ILINE bool operator!() const
409 return Base() == S(0);
412 //! Value access is base value modified by random function.
413 template<class R>
414 T operator()(R r) const
416 return Base() * m_Random(r);
419 // Legacy helper
420 ILINE T GetMaxValue() const
422 return Base();
425 ILINE TRandom GetRandomRange() const
427 return m_Random;
430 ILINE T GetValueFromMod(T val) const
432 return T(Base()) * val;
435 AUTO_STRUCT_INFO;
437 protected:
439 SRandom m_Random; //!< Random variation, multiplicative.
442 template<class S>
443 struct TVarEParam : TVarParam<S>
445 typedef TVarParam<S> TSuper;
446 typedef typename TStorageTraits<S>::TValue T;
448 ILINE TVarEParam()
452 ILINE TVarEParam(const T& tBase)
453 : TSuper(tBase)
457 // Value extraction.
459 T operator()(type_max) const
461 return TSuper::operator()(VMAX);
464 T operator()(type_min) const
466 return TSuper::operator()(VMIN) * m_EmitterStrength(VMIN);
469 template<class R, class E>
470 T operator()(R r, E e) const
472 return TSuper::operator()(r) * m_EmitterStrength(e);
475 const TCurve<S>& GetStrengthCurve() const
477 return m_EmitterStrength;
480 AUTO_STRUCT_INFO;
482 protected:
483 TCurve<S> m_EmitterStrength;
485 // Dependent name nonsense.
486 using TSuper::Base;
487 using TSuper::m_Random;
490 ///////////////////////////////////////////////////////////////////////
491 template<class S>
492 struct TVarEPParam : TVarEParam<S>
494 typedef TVarEParam<S> TSuper;
495 typedef typename TStorageTraits<S>::TValue T;
497 TVarEPParam()
500 TVarEPParam(const T& tBase)
501 : TSuper(tBase)
504 // Value extraction.
506 T operator()(type_max) const
508 return TSuper::operator()(VMAX);
511 T operator()(type_min) const
513 return TSuper::operator()(VMIN) * m_ParticleAge(VMIN);
516 template<class R, class E, class P>
517 T operator()(R r, E e, P p) const
519 return TSuper::operator()(r, e) * m_ParticleAge(p);
522 // Additional helpers
523 T GetVarMod(float fEStrength) const
525 return m_Random(VRANDOM) * m_EmitterStrength(fEStrength);
528 ILINE T GetValueFromBase(T val, float fParticleAge) const
530 return val * m_ParticleAge(fParticleAge);
533 ILINE T GetValueFromMod(T val, float fParticleAge) const
535 return T(Base()) * val * m_ParticleAge(fParticleAge);
538 const TCurve<S>& GetAgeCurve() const
540 return m_ParticleAge;
543 using TSuper::GetValueFromMod;
545 AUTO_STRUCT_INFO;
547 protected:
549 TCurve<S> m_ParticleAge;
551 // Dependent name nonsense.
552 using TSuper::Base;
553 using TSuper::m_Random;
554 using TSuper::m_EmitterStrength;
557 ///////////////////////////////////////////////////////////////////////
558 template<class S>
559 struct TRangeParam
561 S Min;
562 S Max;
564 TRangeParam()
566 TRangeParam(S _min, S _max)
567 : Min(_min), Max(_max) {}
569 S Interp(float t) const
570 { return Min * (1.f - t) + Max * t; }
572 AUTO_STRUCT_INFO;
575 ///////////////////////////////////////////////////////////////////////
576 //! Special surface type enum.
577 //! \cond INTERNAL
578 struct CSurfaceTypeIndex
580 uint16 nIndex;
582 STRUCT_INFO;
584 //! \endcond
586 ///////////////////////////////////////////////////////////////////////
587 //! Particle system parameters.
588 struct ParticleParams
590 // <Group=Emitter>
591 string sComment;
592 TSmallBool bEnabled = true; //!< Set false to disable this effect.
594 DEFINE_ENUM(EInheritance,
595 System,
596 Standard,
597 Parent
599 EInheritance eInheritance; //!< Source of ParticleParams used as base for this effect (for serialization, display, etc).
601 DEFINE_ENUM(ESpawn,
602 Direct,
603 ParentStart,
604 ParentCollide,
605 ParentDeath
607 ESpawn eSpawnIndirection; //!< Direct: spawn from emitter location; else spawn from each particle in parent emitter.
609 TVarEParam<UFloat> fCount; //!< Number of particles alive at once.
610 struct SMaintainDensity : UFloat
612 UFloat fReduceLifeTime;
613 UFloat fReduceAlpha; //!< <SoftMax=1> Reduce alpha inversely to count increase.
614 UFloat fReduceSize;
615 AUTO_STRUCT_INFO;
616 } fMaintainDensity; //!< <SoftMax=1> Increase count when emitter moves to maintain spatial density.
618 // <Group=Timing>
619 TSmallBool bContinuous; //!< Emit particles gradually until Count reached (rate = Count / ParticleLifeTime).
620 TVarParam<SFloat> fSpawnDelay; //!< Delay the emitter start time by this value.
621 TVarParam<UFloat> fEmitterLifeTime; //!< Lifetime of the emitter, 0 if infinite. Always emits at least Count particles.
622 TVarParam<UFloat> fPulsePeriod; //!< Time between auto-restarts of emitter; 0 if never.
623 TVarEParam<UFloat> fParticleLifeTime; //!< Lifetime of particles, 0 if indefinite (die with emitter).
624 TSmallBool bRemainWhileVisible; //!< Particles will only die when not rendered (by any viewport).
626 // <Group=Location>
627 Vec3S vPositionOffset; //!< Spawn offset from the emitter position
628 Vec3U vRandomOffset; //!< Random offset of emission relative position to the spawn position
629 UnitFloat fOffsetRoundness; //!< Fraction of emit volume corners to round: 0 = box, 1 = ellipsoid
630 UnitFloat fOffsetInnerFraction; //!< Fraction of inner emit volume to avoid
631 EGeomType eAttachType; //!< Which geometry to use for attached entity
632 EGeomForm eAttachForm; //!< Which aspect of attached geometry to emit from
634 // <Group=Angles>
635 TVarEParam<UHalfAngle> fFocusAngle; //!< Angle to vary focus from default (Y axis), for variation.
636 TVarEParam<SFloat> fFocusAzimuth; //!< <SoftMax=360> Angle to rotate focus about default, for variation. 0 = Z axis.
637 TVarEParam<UnitFloat> fFocusCameraDir; //!< Rotate emitter focus partially or fully to face camera.
638 TSmallBool bFocusGravityDir; //!< Uses negative gravity dir, rather than emitter Y, as focus dir.
639 TSmallBool bFocusRotatesEmitter; //!< Focus rotation affects offset and particle orientation; else affects just emission direction.
640 TSmallBool bEmitOffsetDir; //!< Default emission direction parallel to emission offset from origin.
641 TVarEParam<UHalfAngle> fEmitAngle; //!< Angle from focus dir (emitter Y), in degrees. RandomVar determines min angle.
643 DEFINE_ENUM(EFacing,
644 Camera,
645 CameraX,
646 Free,
647 Horizontal,
648 Velocity,
649 Water,
650 Terrain,
651 Decal
653 EFacing eFacing; //!< Orientation of particle face.
654 TSmallBool bOrientToVelocity; //!< Particle X axis aligned to velocity direction.
655 UnitFloat fCurvature = 1; //!< For Facing=Camera, fraction that normals are curved to a spherical shape.
657 // <Group=Appearance>
658 DEFINE_ENUM_VALS(EBlend, uint8,
659 AlphaBased = OS_ALPHA_BLEND,
660 Additive = OS_ADD_BLEND,
661 Multiplicative = OS_MULTIPLY_BLEND,
662 Opaque = 0,
663 _ColorBased = OS_ADD_BLEND,
664 _None = 0
666 EBlend eBlendType = EBlend::AlphaBased; //!< Blend rendering type.
667 CCryName sTexture; //!< Texture asset for sprite.
668 CCryName sMaterial; //!< Material (overrides texture).
670 struct STextureTiling
672 PosInt8 nTilesX, nTilesY; //!< Number of tiles texture is split into.
673 uint8 nFirstTile = 0; //!< First (or only) tile to use.
674 PosInt8 nVariantCount; //!< Number of randomly selectable tiles; 0 or 1 if no variation.
675 PosInt8 nAnimFramesCount; //!< Number of tiles (frames) of animation; 0 or 1 if no animation.
676 DEFINE_ENUM(EAnimationCycle,
677 Once,
678 Loop,
679 Mirror
681 EAnimationCycle eAnimCycle; //!< How animation cycles.
682 TSmallBool bAnimBlend; //!< Blend textures between frames.
683 UnitFloat8 fFlipChance; //!< Chance each particle will flip in X direction.
684 UFloat fAnimFramerate; //!< <SoftMax=60> Tex framerate; 0 = 1 cycle / particle life.
685 TCurve<UFloat> fAnimCurve; //!< Animation curve.
687 STextureTiling()
689 TCurve<UFloat>::source_spline source;
690 TCurve<UFloat>::key_type key;
691 key.time = 0.0f;
692 key.value = 0.0f;
693 key.flags = SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_OUT_SHIFT;
694 source.insert_key(key);
695 key.time = 1.0f;
696 key.value = 1.0f;
697 key.flags = SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_IN_SHIFT;
698 source.insert_key(key);
699 fAnimCurve.from_source(source);
702 uint GetTileCount() const
704 return nTilesX * nTilesY - nFirstTile;
707 uint GetFrameCount() const
709 return nVariantCount * nAnimFramesCount;
712 float GetAnimPos(float fAge, float fRelativeAge) const
714 // Select anim frame based on particle age.
715 float fAnimPos = 0.0f;
716 if (fAnimFramerate > 0.f)
718 fAnimPos = fAge * fAnimFramerate / nAnimFramesCount;
719 if (eAnimCycle == eAnimCycle.Loop)
720 fAnimPos = fmod(fAnimPos, 1.f);
721 else if (eAnimCycle == eAnimCycle.Mirror)
722 fAnimPos = 1.f - abs(fmod(fAnimPos, 2.f) - 1.f);
723 else
724 fAnimPos = min(fAnimPos, 1.f);
726 else
727 fAnimPos = fRelativeAge;
728 fAnimPos = fAnimCurve(fAnimPos);
729 return fAnimPos;
732 float GetAnimPosScale() const
734 // Scale animation position to frame number
735 if (eAnimCycle)
736 return float(nAnimFramesCount);
737 else if (bAnimBlend)
738 return float(nAnimFramesCount - 1);
739 else
740 // If not cycling, reducing slightly to avoid hitting 1.
741 return float(nAnimFramesCount) - 0.001f;
744 void Correct()
746 nFirstTile = std::min<uint>(nFirstTile, nTilesX * nTilesY - 1);
747 nAnimFramesCount = std::min<uint>(nAnimFramesCount, GetTileCount());
748 nVariantCount = std::min<uint>(nVariantCount, GetTileCount() / nAnimFramesCount);
751 AUTO_STRUCT_INFO;
754 STextureTiling TextureTiling; //!< Tiling of texture for animation and variation.
755 TSmallBool bTessellation; //!< If hardware supports, tessellate particles for better shadowing and curved connected particles.
756 TSmallBool bOctagonalShape; //!< Use octagonal shape for textures instead of quad.
757 struct SSoftParticle : TSmallBool
759 UFloat fSoftness; //!< Soft particles scale.
760 SSoftParticle()
761 : fSoftness(1.0f) {}
762 AUTO_STRUCT_INFO;
763 } bSoftParticle; //!< Soft intersection with background.
764 CCryName sGeometry; //!< Geometry for 3D particles.
765 DEFINE_ENUM(EGeometryPieces,
766 Whole,
767 RandomPiece,
768 AllPieces
770 EGeometryPieces eGeometryPieces; //!< Which geometry pieces to emit.
771 TSmallBool bNoOffset; //!< Disable centering of geometry.
772 TVarEPParam<UFloat> fAlpha = 1; //!< <SoftMax=1> Alpha value (opacity, or multiplier for additive).
773 struct SAlphaClip
775 TRangeParam<UFloat> fScale; //!< <SoftMax=1> Final alpha multiplier, for particle alpha 0 to 1.
776 TRangeParam<UnitFloat> fSourceMin; //!< Source alpha clip min, for particle alpha 0 to 1.
777 TRangeParam<UnitFloat> fSourceWidth; //!< Source alpha clip range, for particle alpha 0 to 1.
779 SAlphaClip()
780 : fScale(0, 1), fSourceWidth(1, 1) {}
782 AUTO_STRUCT_INFO;
783 } AlphaClip; //!< Alpha clipping settings, for particle alpha 0 to 1.
784 TVarEPParam<Color3F> cColor = Color3F(1); //!< Color modulation.
786 // <Group=Lighting>
787 UFloat fDiffuseLighting = 1; //!< <SoftMax=1> Multiplier for particle dynamic lighting.
788 UnitFloat fDiffuseBacklighting; //!< Fraction of diffuse lighting applied in all directions.
789 UFloat fEmissiveLighting; //!< <SoftMax=1> Multiplier for particle emissive lighting.
791 TSmallBool bReceiveShadows; //!< Shadows will cast on these particles.
792 TSmallBool bCastShadows; //!< Particles will cast shadows (currently only geom particles).
793 TSmallBool bNotAffectedByFog; //!< Ignore fog.
795 struct SLightSource
797 TSmallBool bAffectsThisAreaOnly; //!< Affect current clip volume only.
798 TVarEPParam<UFloat> fRadius; //!< <SoftMax=10> Radius of light.
799 TVarEPParam<UFloat> fIntensity; //!< <SoftMax=10> Intensity of light (color from Appearance/Color).
800 DEFINE_ENUM(ELightAffectsFog,
802 FogOnly,
803 Both
805 ELightAffectsFog eLightAffectsFog;
806 SLightSource()
807 : eLightAffectsFog(ELightAffectsFog::No) {}
808 AUTO_STRUCT_INFO;
809 } LightSource; //!< Per-particle light generation.
811 // <Group=Audio>
812 CCryName sStartTrigger; //!< Audio start trigger to execute.
813 CCryName sStopTrigger; //!< Audio stop trigger to execute.
814 TVarEParam<UFloat> fSoundFXParam = 1; //!< Custom real-time sound modulation parameter.
815 DEFINE_ENUM(ESoundControlTime,
816 EmitterLifeTime,
817 EmitterExtendedLifeTime,
818 EmitterPulsePeriod
820 ESoundControlTime eSoundControlTime; //!< The sound control time type.
822 // <Group=Size>
823 TVarEPParam<UFloat> fSize = 1; //!< <SoftMax=8> Particle radius, for sprites; size scale for geometry.
824 TVarEPParam<UFloat> fAspect = 1; //!< <SoftMax=8> X-to-Y scaling factor.
825 TVarEPParam<SFloat> fPivotX; //!< <SoftMin=-1> <SoftMax=1> Pivot offset in X direction.
826 TVarEPParam<SFloat> fPivotY; //!< <SoftMin=-1> <SoftMax=1> Pivot offset in Y direction.
828 struct SStretch : TVarEPParam<UFloat>
830 SFloat fOffsetRatio; //!< <SoftMin=-1> $<SoftMax=1> Move particle center this fraction in direction of stretch.
831 AUTO_STRUCT_INFO;
832 } fStretch; //!< <SoftMax=1> Stretch particle into moving direction, amount in seconds.
833 struct STailLength : TVarEPParam<UFloat>
835 uint8 nTailSteps = 0; //!< <SoftMax=16> Number of tail segments.
836 AUTO_STRUCT_INFO;
837 } fTailLength; //!< <SoftMax=10> Length of tail in seconds.
838 UFloat fMinPixels; //!< <SoftMax=10> Augment true size with this many pixels.
840 // Connection
841 struct SConnection : TSmallBool
843 TSmallBool bConnectParticles; //!< Particles are drawn connected serially.
844 TSmallBool bConnectToOrigin; //!< Newest particle connected to emitter origin.
845 DEFINE_ENUM(ETextureMapping,
846 PerParticle,
847 PerStream
849 ETextureMapping eTextureMapping; //!< Basis of texture coord mapping (particle or stream).
850 TSmallBool bTextureMirror; //!< Mirror alternating texture tiles; else wrap.
851 SFloat fTextureFrequency; //!< <SoftMax=8> Number of texture wraps in line.
853 SConnection() :
854 bTextureMirror(true), fTextureFrequency(1.f) {}
855 AUTO_STRUCT_INFO;
856 } Connection;
858 // <Group=Movement>
859 TVarEParam<SFloat> fSpeed; //!< Initial speed of a particle.
860 SFloat fInheritVelocity; //!< <SoftMin=0> $<SoftMax=1> Fraction of emitter's velocity to inherit.
861 struct SAirResistance : TVarEPParam<UFloat>
863 UFloat fRotationalDragScale; //!< <SoftMax=1> Multiplier to AirResistance, for rotational motion.
864 UFloat fWindScale; //!< <SoftMax=1> Artificial adjustment to environmental wind.
866 SAirResistance()
867 : fRotationalDragScale(1), fWindScale(1) {}
868 AUTO_STRUCT_INFO;
869 } fAirResistance; //!< <SoftMax=10> Air drag value, in inverse seconds.
870 TVarEPParam<SFloat> fGravityScale; //!< <SoftMin=-1> $<SoftMax=1> Multiplier for world gravity.
871 Vec3S vAcceleration; //!< Explicit world-space acceleration vector.
872 TVarEPParam<UFloat> fTurbulence3DSpeed; //!< <SoftMax=10> 3D random turbulence force.
873 TVarEPParam<UFloat> fTurbulenceSize; //!< <SoftMax=10> Radius of vortex rotation (axis is direction of movement).
874 TVarEPParam<SFloat> fTurbulenceSpeed; //!< <SoftMin=-360> $<SoftMax=360> Angular speed of vortex rotation.
876 struct SMoveRelativeEmitter : TSmallBool
878 TSmallBool& base() { return *this; }
879 TSmallBool bIgnoreRotation; //!< Ignore emitter rotation when updating particles.
880 TSmallBool bIgnoreSize; //!< Ignore emitter size when updating particles.
881 TSmallBool bMoveTail; //!< Tail segments also move with emitter.
882 bool ScaleWithSize() const { return +*this && !bIgnoreSize; }
883 AUTO_STRUCT_INFO;
884 } bMoveRelativeEmitter; //!< Particle motion is in emitter space.
886 TSmallBool bBindEmitterToCamera; //!< Emitter attached to main render camera.
887 TSmallBool bSpaceLoop; //!< Loops particles within emission volume, or within Camera Max Distance.
889 struct STargetAttraction
891 DEFINE_ENUM(ETargeting,
892 External,
893 OwnEmitter,
894 Ignore
896 ETargeting eTarget; //!< Source of target attractor.
897 TSmallBool bExtendSpeed; //!< Extend particle speed as necessary to reach target in normal lifetime.
898 TSmallBool bShrink; //!< Shrink particle as it approaches target.
899 TSmallBool bOrbit; //!< Orbit target at specified distance, rather than disappearing.
900 TVarEPParam<SFloat> fRadius; //!< Radius of attractor, for vanishing or orbiting.
901 AUTO_STRUCT_INFO;
902 } TargetAttraction; //!< Specify target attractor behavior.
904 // <Group=Rotation>
905 Vec3_tpl<SAngle> vInitAngles; //!< Initial rotation in symmetric angles (degrees).
906 Vec3_tpl<UFullAngle> vRandomAngles; //!< Bidirectional random angle variation.
907 Vec3S vRotationRate; //!< <SoftMin=-360> $<SoftMax=360> Rotation speed (degree/sec).
908 Vec3U vRandomRotationRate; //!< <SoftMax=360> Random variation of rotation speed.
910 // <Group=Collision>
911 DEFINE_ENUM(EPhysics,
912 None,
913 SimpleCollision,
914 SimplePhysics,
915 RigidBody
917 EPhysics ePhysicsType; //!< What kind of physics simulation to run on particle.
918 TSmallBool bCollideTerrain; //!< Collides with terrain (if Physics <> none).
919 TSmallBool bCollideStaticObjects; //!< Collides with static physics objects (if Physics <> none).
920 TSmallBool bCollideDynamicObjects; //!< Collides with dynamic physics objects (if Physics <> none).
921 UnitFloat8 fCollisionFraction = 1; //!< Fraction of emitted particles that actually perform collisions.
922 UFloat fCollisionCutoffDistance; //!< Maximum distance up until collisions are respected (0 = infinite).
923 uint8 nMaxCollisionEvents = 0; //!< Max # collision events per particle (0 = no limit).
924 DEFINE_ENUM(ECollisionResponse,
925 Die,
926 Ignore,
927 Stop
929 ECollisionResponse eFinalCollision; //!< What to do on final collision (when MaxCollisions > 0).
930 CSurfaceTypeIndex sSurfaceType; //!< Surface type for physicalized particles.
931 SFloat fElasticity; //!< <SoftMin=0> $<SoftMax=1> Collision bounce coefficient: 0 = no bounce, 1 = full bounce.
932 UFloat fDynamicFriction; //!< <SoftMax=10> Sliding drag value, in inverse seconds.
933 UFloat fThickness = 1; //!< <SoftMax=1> Lying thickness ratio - for physicalized particles only.
934 UFloat fDensity = 1000; //!< <SoftMax=2000> Mass density for physicslized particles.
936 // <Group=Visibility>
937 UFloat fViewDistanceAdjust = 1; //!< <SoftMax=1> Multiplier to automatic distance fade-out.
938 UFloat fCameraMaxDistance; //!< <SoftMax=100> Max distance from camera to render particles.
939 UFloat fCameraMinDistance; //!< <SoftMax=100> Min distance from camera to render particles.
940 SFloat fCameraDistanceOffset; //!< <SoftMin=-1> <SoftMax=1> Offset the emitter away from the camera.
941 SFloat fSortOffset; //!< <SoftMin=-1> <SoftMax=1> Offset distance used for sorting.
942 SFloat fSortBoundsScale; //!< <SoftMin=-1> <SoftMax=1> Choose emitter point for sorting; 1 = bounds nearest, 0 = origin, -1 = bounds farthest.
943 TSmallBool bDrawNear; //!< Render particle in near space (weapon).
944 TSmallBool bDrawOnTop; //!< Render particle on top of everything (no depth test).
945 ETrinary tVisibleIndoors; //!< Whether visible indoors / outdoors / both.
946 ETrinary tVisibleUnderwater; //!< Whether visible under / above water / both.
947 UnitFloat fFadeAtViewCosAngle; //!< Angle to camera at which particles start to fade out.
949 // <Group=Advanced>
950 DEFINE_ENUM(EForce,
951 None,
952 Wind,
953 Gravity,
954 // Compatibility
955 _Target
957 EForce eForceGeneration; //!< Generate physical forces if set.
958 UFloat fFillRateCost = 1; //!< Adjustment to max screen fill allowed per emitter.
959 TFixed<uint8, MAX_HEATSCALE> fHeatScale; //!< Multiplier to thermal vision.
960 UnitFloat fSphericalApproximation = 1; //!< Align the particle to the tangent of the sphere.
961 UFloat fPlaneAlignBlendDistance; //!< Distance when blend to camera plane aligned particles starts.
963 TRangedType<uint8, 0, 2> nSortQuality; //!< Sort new particles as accurately as possible into list, by main camera distance.
964 TSmallBool bForceDynamicBounds; //!< Always update particles and compute actual bounds for visibility.
965 TSmallBool bHalfRes; //!< Use half resolution rendering.
966 TSmallBoolTrue bStreamable; //!< Texture/geometry allowed to be streamed.
967 TSmallBool bVolumeFog; //!< Use as a participating media of volumetric fog.
968 Unit4Float fVolumeThickness = 1; //!< Thickness factor for particle size.
970 // <Group=Configuration>
971 DEFINE_ENUM(EConfigSpecBrief,
972 Low,
973 Medium,
974 High,
975 VeryHigh
977 EConfigSpecBrief eConfigMin = EConfigSpecBrief::Low; //!< Minimum config spec this effect runs in.
978 EConfigSpecBrief eConfigMax = EConfigSpecBrief::VeryHigh; //!< Maximum config spec this effect runs in.
980 struct SPlatforms
982 TSmallBoolTrue PCDX, PS4, XBoxOne, XBoxOneX;
983 AUTO_STRUCT_INFO;
984 } Platforms; //!< Platforms this effect runs on.
986 // Derived properties
987 bool HasEquilibrium() const
989 return (bContinuous && !fEmitterLifeTime) || fPulsePeriod;
991 float GetMaxSpawnDelay() const
993 return eSpawnIndirection >= ESpawn::ParentCollide ? fHUGE : fSpawnDelay.GetMaxValue();
995 float GetMaxEmitterLife() const
997 return GetMaxSpawnDelay() + (bContinuous ? ZeroIsHuge(fEmitterLifeTime.GetMaxValue()) : 0.f);
999 float GetMaxParticleLife() const
1001 return if_else(fParticleLifeTime, fParticleLifeTime.GetMaxValue(), ZeroIsHuge(fEmitterLifeTime.GetMaxValue()));
1003 uint8 GetTailSteps() const
1005 return fTailLength ? fTailLength.nTailSteps : 0;
1007 bool HasVariableVertexCount() const
1009 return GetTailSteps() || Connection;
1011 float GetMaxRotationAngle() const
1013 if (vRotationRate.x != 0.f || vRotationRate.z != 0.f || vRandomRotationRate.x != 0 || vRandomRotationRate.z != 0.f)
1014 return gf_PI;
1015 return DEG2RAD(max(abs(vInitAngles.x) + abs(vRandomAngles.x), abs(vInitAngles.z) + abs(vRandomAngles.z)));
1017 AABB GetEmitOffsetBounds() const
1019 return AABB(vPositionOffset - vRandomOffset, vPositionOffset + vRandomOffset);
1021 float GetFullTextureArea() const
1023 // World area corresponding to full texture, thus multiplied by tile count.
1024 return sqr(2.f * fSize.GetMaxValue()) * float(TextureTiling.nTilesX * TextureTiling.nTilesY);
1026 float GetAlphaFromMod(float fMod) const
1028 return fAlpha.GetMaxValue() * AlphaClip.fScale.Interp(fMod);
1030 bool NeedsExtendedBounds() const
1032 // Bounds need extending on movement unless bounds always restricted relative to emitter.
1033 if (bMoveRelativeEmitter)
1034 return GetTailSteps() && !bMoveRelativeEmitter.bMoveTail;
1035 return !bSpaceLoop;
1038 AUTO_STRUCT_INFO;
1041 #endif