1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 // -------------------------------------------------------------------------
4 // File name: ParticleParams.h
5 // -------------------------------------------------------------------------
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.
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
,
51 struct ETrinary
: ETrinaryNames
53 //! Initialized with bool value, or Both (default).
54 ETrinary(ETrinaryNames::E e
= Both
)
57 : ETrinaryNames(ETrinaryNames::E(1 << uint8(b
))) {}
59 //! Test against ETrinary, or directly against bool.
60 uint8
operator*(ETrinary t
) const
64 uint8
operator*(bool b
) const
66 return +*this & (1 << uint8(b
));
71 //! Pseudo-random number generation, from a key.
75 //! Initialize with an int.
76 explicit inline CChaosKey(uint32 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
113 //! Jumble with a range variable to produce a random value.
115 inline T
Random(T
const& Range
) const
117 return Jumble(CChaosKey(&Range
)) * Range
;
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);
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
));
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
;
160 struct TStorageTraits
162 typedef float TValue
;
163 typedef UnitFloat8 TMod
;
164 typedef UnitFloat TRandom
;
168 struct TStorageTraits
<SFloat
>
170 typedef float TValue
;
171 typedef UnitFloat8 TMod
;
172 typedef Unit2Float TRandom
;
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();
191 typedef Vec3_tpl
<SFloat
> Vec3S
;
192 typedef Vec3_tpl
<UFloat
> Vec3U
;
194 // Color specialisations.
197 struct Color3
: Vec3_tpl
<T
>
202 Color3(T r
, T g
, T b
)
203 : Vec3_tpl
<T
>(r
, g
, b
) {}
205 Color3(Vec3_tpl
<T
> const& v
)
209 Color3(Vec3_tpl
<T2
> const& 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; }
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
230 inline RandomColor(float f
= 0.f
, bool bRandomHue
= false)
231 : UnitFloat8(f
), m_bRandomHue(bRandomHue
)
234 Color3F
GetRandom() const
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
);
244 return Color3F(cry_random(0.0f
, float(*this)));
248 bool HasRandomHue() const
249 { return m_bRandomHue
; }
254 TSmallBool m_bRandomHue
;
258 struct TStorageTraits
<Color3F
>
260 typedef Color3F TValue
;
261 typedef Color3
<UnitFloat8
> TMod
;
262 typedef RandomColor TRandom
;
265 // Spline implementation class.
267 inline const CTypeInfo
& TypeInfo(ISplineInterpolator
**)
269 static CTypeInfo
Info("ISplineInterpolator*", sizeof(void*), alignof(void*));
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
;
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
= {});
296 T
operator()(float fTime
) const
299 interpolate(fTime
, val
);
303 T
operator()(type_max
) const
308 T
operator()(type_min
) const
316 CUSTOM_STRUCT_INFO(CCustomInfo
)
319 // Composite parameter types, incorporating base value, randomness, and lifetime curves.
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))
334 const TRandom
& Range() const
335 { return static_cast<const TRandom
&>(*this); }
339 T
operator()(type_max
) const
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
351 return T(1) - T(key
.Random(Range()));
356 T
operator()(type_random
) const
359 return T(1) - T(ParamRandom(Range()));
365 static Color3F
ParamRandom(RandomColor
const& rc
)
367 return rc
.GetRandom();
370 static float ParamRandom(float v
)
372 return cry_random(0.0f
, v
);
381 TVarParam(const T
& tBase
)
386 void Set(const T
& tBase
)
390 void Set(const T
& tBase
, const TRandom
& tRan
)
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.
414 T
operator()(R r
) const
416 return Base() * m_Random(r
);
420 ILINE T
GetMaxValue() const
425 ILINE TRandom
GetRandomRange() const
430 ILINE T
GetValueFromMod(T val
) const
432 return T(Base()) * val
;
439 SRandom m_Random
; //!< Random variation, multiplicative.
443 struct TVarEParam
: TVarParam
<S
>
445 typedef TVarParam
<S
> TSuper
;
446 typedef typename TStorageTraits
<S
>::TValue T
;
452 ILINE
TVarEParam(const T
& tBase
)
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
;
483 TCurve
<S
> m_EmitterStrength
;
485 // Dependent name nonsense.
487 using TSuper::m_Random
;
490 ///////////////////////////////////////////////////////////////////////
492 struct TVarEPParam
: TVarEParam
<S
>
494 typedef TVarEParam
<S
> TSuper
;
495 typedef typename TStorageTraits
<S
>::TValue T
;
500 TVarEPParam(const T
& tBase
)
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
;
549 TCurve
<S
> m_ParticleAge
;
551 // Dependent name nonsense.
553 using TSuper::m_Random
;
554 using TSuper::m_EmitterStrength
;
557 ///////////////////////////////////////////////////////////////////////
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
; }
575 ///////////////////////////////////////////////////////////////////////
576 //! Special surface type enum.
578 struct CSurfaceTypeIndex
586 ///////////////////////////////////////////////////////////////////////
587 //! Particle system parameters.
588 struct ParticleParams
592 TSmallBool bEnabled
= true; //!< Set false to disable this effect.
594 DEFINE_ENUM(EInheritance
,
599 EInheritance eInheritance
; //!< Source of ParticleParams used as base for this effect (for serialization, display, etc).
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.
616 } fMaintainDensity
; //!< <SoftMax=1> Increase count when emitter moves to maintain spatial density.
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).
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
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.
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
,
663 _ColorBased
= OS_ADD_BLEND
,
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
,
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.
689 TCurve
<UFloat
>::source_spline source
;
690 TCurve
<UFloat
>::key_type key
;
693 key
.flags
= SPLINE_KEY_TANGENT_LINEAR
<< SPLINE_KEY_TANGENT_OUT_SHIFT
;
694 source
.insert_key(key
);
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
);
724 fAnimPos
= min(fAnimPos
, 1.f
);
727 fAnimPos
= fRelativeAge
;
728 fAnimPos
= fAnimCurve(fAnimPos
);
732 float GetAnimPosScale() const
734 // Scale animation position to frame number
736 return float(nAnimFramesCount
);
738 return float(nAnimFramesCount
- 1);
740 // If not cycling, reducing slightly to avoid hitting 1.
741 return float(nAnimFramesCount
) - 0.001f
;
746 nFirstTile
= std::min
<uint
>(nFirstTile
, nTilesX
* nTilesY
- 1);
747 nAnimFramesCount
= std::min
<uint
>(nAnimFramesCount
, GetTileCount());
748 nVariantCount
= std::min
<uint
>(nVariantCount
, GetTileCount() / nAnimFramesCount
);
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.
763 } bSoftParticle
; //!< Soft intersection with background.
764 CCryName sGeometry
; //!< Geometry for 3D particles.
765 DEFINE_ENUM(EGeometryPieces
,
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).
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.
780 : fScale(0, 1), fSourceWidth(1, 1) {}
783 } AlphaClip
; //!< Alpha clipping settings, for particle alpha 0 to 1.
784 TVarEPParam
<Color3F
> cColor
= Color3F(1); //!< Color modulation.
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.
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
,
805 ELightAffectsFog eLightAffectsFog
;
807 : eLightAffectsFog(ELightAffectsFog::No
) {}
809 } LightSource
; //!< Per-particle light generation.
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
,
817 EmitterExtendedLifeTime
,
820 ESoundControlTime eSoundControlTime
; //!< The sound control time type.
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.
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.
837 } fTailLength
; //!< <SoftMax=10> Length of tail in seconds.
838 UFloat fMinPixels
; //!< <SoftMax=10> Augment true size with this many pixels.
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
,
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.
854 bTextureMirror(true), fTextureFrequency(1.f
) {}
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.
867 : fRotationalDragScale(1), fWindScale(1) {}
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
; }
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
,
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.
902 } TargetAttraction
; //!< Specify target attractor behavior.
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.
911 DEFINE_ENUM(EPhysics
,
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
,
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.
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
,
977 EConfigSpecBrief eConfigMin
= EConfigSpecBrief::Low
; //!< Minimum config spec this effect runs in.
978 EConfigSpecBrief eConfigMax
= EConfigSpecBrief::VeryHigh
; //!< Maximum config spec this effect runs in.
982 TSmallBoolTrue PCDX
, PS4
, XBoxOne
, XBoxOneX
;
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
)
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
;