You're breathtaking!
This commit is contained in:
401
Source/Engine/Particles/ParticleEffect.h
Normal file
401
Source/Engine/Particles/ParticleEffect.h
Normal file
@@ -0,0 +1,401 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||
#include "Engine/Graphics/RenderTask.h"
|
||||
#include "ParticleSystem.h"
|
||||
#include "ParticlesSimulation.h"
|
||||
|
||||
/// <summary>
|
||||
/// Particle system parameter.
|
||||
/// </summary>
|
||||
API_CLASS(NoSpawn) class ParticleEffectParameter : public PersistentScriptingObject
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ParticleEffectParameter);
|
||||
friend ParticleEffect;
|
||||
private:
|
||||
|
||||
ParticleEffect* _effect = nullptr;
|
||||
int32 _emitterIndex;
|
||||
int32 _paramIndex;
|
||||
|
||||
void Init(ParticleEffect* effect, int32 emitterIndex, int32 paramIndex);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ParticleEffectParameter"/> class.
|
||||
/// </summary>
|
||||
ParticleEffectParameter()
|
||||
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
|
||||
{
|
||||
}
|
||||
|
||||
ParticleEffectParameter(const ParticleEffectParameter& other)
|
||||
: ParticleEffectParameter()
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
CRASH; // Not used
|
||||
#endif
|
||||
}
|
||||
|
||||
ParticleEffectParameter& operator=(const ParticleEffectParameter& other)
|
||||
{
|
||||
#if !BUILD_RELEASE
|
||||
CRASH; // Not used
|
||||
#endif
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if parameter object handle is valid.
|
||||
/// </summary>
|
||||
bool IsValid() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the emitter (not the emitter track but the emitter).
|
||||
/// </summary>
|
||||
API_PROPERTY() int32 GetEmitterIndex() const
|
||||
{
|
||||
return _emitterIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the emitter that this parameter belongs to.
|
||||
/// </summary>
|
||||
API_PROPERTY() ParticleEmitter* GetEmitter() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter index (in the emitter parameters list).
|
||||
/// </summary>
|
||||
API_PROPERTY() int32 GetParamIndex() const
|
||||
{
|
||||
return _paramIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter type.
|
||||
/// </summary>
|
||||
API_PROPERTY() VariantType GetParamType() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter unique ID.
|
||||
/// </summary>
|
||||
API_PROPERTY() Guid GetParamIdentifier() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the emitter track name.
|
||||
/// </summary>
|
||||
API_PROPERTY() const String& GetTrackName() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter name.
|
||||
/// </summary>
|
||||
API_PROPERTY() const String& GetName() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parameter flag that indicates whenever it's exposed to public.
|
||||
/// </summary>
|
||||
API_PROPERTY() bool GetIsPublic() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default value of the parameter (set in particle system asset).
|
||||
/// </summary>
|
||||
/// <returns>The default value.</returns>
|
||||
API_PROPERTY() Variant GetDefaultValue() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default value of the parameter (set in particle emitter asset).
|
||||
/// </summary>
|
||||
/// <returns>The default value.</returns>
|
||||
API_PROPERTY() Variant GetDefaultEmitterValue() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the parameter.
|
||||
/// </summary>
|
||||
/// <returns>The value.</returns>
|
||||
API_PROPERTY() Variant GetValue() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the parameter.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
API_PROPERTY() void SetValue(const Variant& value) const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the particle emitter parameter from the asset (the parameter instanced by this object).
|
||||
/// </summary>
|
||||
/// <returns>The particle emitter parameter overriden by this object.</returns>
|
||||
API_PROPERTY() GraphParameter* GetEmitterParameter() const;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The particle system instance that plays the particles simulation in the game.
|
||||
/// </summary>
|
||||
API_CLASS() class FLAXENGINE_API ParticleEffect : public Actor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(ParticleEffect);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The particles simulation update modes.
|
||||
/// </summary>
|
||||
API_ENUM() enum class SimulationUpdateMode
|
||||
{
|
||||
/// <summary>
|
||||
/// Use realtime simulation updates. Updates particles during every game logic update.
|
||||
/// </summary>
|
||||
Realtime = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Use fixed timestep delta time to update particles simulation with a custom frequency.
|
||||
/// </summary>
|
||||
FixedTimestep = 1,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The particle parameter override data.
|
||||
/// </summary>
|
||||
API_STRUCT() struct ParameterOverride
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ParameterOverride);
|
||||
|
||||
/// <summary>
|
||||
/// The name of the track that has overriden parameter.
|
||||
/// </summary>
|
||||
API_FIELD() String Track;
|
||||
|
||||
/// <summary>
|
||||
/// The overriden parameter id.
|
||||
/// </summary>
|
||||
API_FIELD() Guid Id;
|
||||
|
||||
/// <summary>
|
||||
/// The overriden value.
|
||||
/// </summary>
|
||||
API_FIELD() Variant Value;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
uint64 _lastUpdateFrame;
|
||||
float _lastMinDstSqr;
|
||||
Matrix _world;
|
||||
uint32 _parametersVersion = 0; // Version number for _parameters to be in sync with Instance.ParametersVersion
|
||||
Array<ParticleEffectParameter> _parameters; // Cached for scripting API
|
||||
Array<ParameterOverride> _parametersOverrides; // Cached parameter modifications to be applied to the parameters
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The particle system to play.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(null), EditorOrder(0)")
|
||||
AssetReference<ParticleSystem> ParticleSystem;
|
||||
|
||||
/// <summary>
|
||||
/// The instance data of the particle system.
|
||||
/// </summary>
|
||||
ParticleSystemInstance Instance;
|
||||
|
||||
/// <summary>
|
||||
/// The custom render task used as a view information source (effect will use its render buffers and rendering resolution information for particles simulation).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="NoSerialize, HideInEditor")
|
||||
ScriptingObjectReference<SceneRenderTask> CustomViewRenderTask;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The particles simulation update mode. Defines how to update particles emitter.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(SimulationUpdateMode.Realtime), EditorOrder(10)")
|
||||
SimulationUpdateMode UpdateMode = SimulationUpdateMode::Realtime;
|
||||
|
||||
/// <summary>
|
||||
/// The fixed timestep for simulation updates. Used only if UpdateMode is set to FixedTimestep.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(1.0f / 60.0f), EditorOrder(20), VisibleIf(nameof(IsFixedTimestep))")
|
||||
float FixedTimestep = 1.0f / 60.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The particles simulation speed factor. Scales the particle system update delta time. Can be used to speed up or slow down the particles.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(1.0f), EditorOrder(30)")
|
||||
float SimulationSpeed = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the particle effect should take into account the global game time scale for simulation updates.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(true), EditorOrder(40)")
|
||||
bool UseTimeScale = true;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the particle effect should loop when it finishes playing.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(true), EditorOrder(50)")
|
||||
bool IsLooping = true;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the particle simulation will be updated even when an actor cannot be seen by any camera. Otherwise, the simulation will stop running when the actor is off-screen.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), DefaultValue(true), EditorOrder(60)")
|
||||
bool UpdateWhenOffscreen = true;
|
||||
|
||||
/// <summary>
|
||||
/// The draw passes to use for rendering this object.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorDisplay(\"Particle Effect\"), EditorOrder(75), DefaultValue(DrawPass.Default)")
|
||||
DrawPass DrawModes = DrawPass::Default;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the actor world matrix transform.
|
||||
/// </summary>
|
||||
/// <param name="world">Result world matrix</param>
|
||||
FORCE_INLINE void GetWorld(Matrix* world) const
|
||||
{
|
||||
*world = _world;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effect parameters collection. Those parameters are instanced from the <see cref="ParticleSystem"/> that contains a linear list of emitters and every emitter has a list of own parameters.
|
||||
/// </summary>
|
||||
API_PROPERTY() const Array<ParticleEffectParameter>& GetParameters();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effect parameters collection version number. It can be used to track parameters changes that occur when particle system or one of the emitters gets reloaded/edited.
|
||||
/// </summary>
|
||||
API_PROPERTY() uint32 GetParametersVersion() const;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the particle parameter.
|
||||
/// </summary>
|
||||
/// <param name="emitterTrackName">The emitter track name (in particle system asset).</param>
|
||||
/// <param name="paramName">The emitter parameter name (in particle emitter asset).</param>
|
||||
/// <returns>The effect parameter or null if failed to find.</returns>
|
||||
API_FUNCTION() ParticleEffectParameter* GetParameter(const StringView& emitterTrackName, const StringView& paramName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the particle parameter.
|
||||
/// </summary>
|
||||
/// <param name="emitterTrackName">The emitter track name (in particle system asset).</param>
|
||||
/// <param name="paramId">The emitter parameter ID (in particle emitter asset).</param>
|
||||
/// <returns>The effect parameter or null if failed to find.</returns>
|
||||
API_FUNCTION() ParticleEffectParameter* GetParameter(const StringView& emitterTrackName, const Guid& paramId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the particle parameter value.
|
||||
/// </summary>
|
||||
/// <param name="emitterTrackName">The emitter track name (in particle system asset).</param>
|
||||
/// <param name="paramName">The emitter parameter name (in particle emitter asset).</param>
|
||||
/// <returns>The value.</returns>
|
||||
API_FUNCTION() Variant GetParameterValue(const StringView& emitterTrackName, const StringView& paramName);
|
||||
|
||||
/// <summary>
|
||||
/// Set the particle parameter value.
|
||||
/// </summary>
|
||||
/// <param name="emitterTrackName">The emitter track name (in particle system asset).</param>
|
||||
/// <param name="paramName">The emitter parameter name (in particle emitter asset).</param>
|
||||
/// <param name="value">The value to set.</param>
|
||||
API_FUNCTION() void SetParameterValue(const StringView& emitterTrackName, const StringView& paramName, const Variant& value);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the particle system parameters to the default values from asset.
|
||||
/// </summary>
|
||||
API_FUNCTION() void ResetParameters();
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current time position of the particle system timeline animation playback (in seconds).
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="NoSerialize, HideInEditor") float GetTime() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the current time position of the particle system timeline animation playback (in seconds).
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetTime(float time);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last game time when particle system was updated. Value -1 indicates no previous updates.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="NoSerialize, HideInEditor") float GetLastUpdateTime() const;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the last game time when particle system was updated. Value -1 indicates no previous updates.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetLastUpdateTime(float time);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the particles count (total). GPU particles count is read with one frame delay (due to GPU execution).
|
||||
/// </summary>
|
||||
API_PROPERTY() int32 GetParticlesCount() const;
|
||||
|
||||
/// <summary>
|
||||
/// Resets the particles simulation state (clears the instance state data but preserves the instance parameters values).
|
||||
/// </summary>
|
||||
API_FUNCTION() void ResetSimulation();
|
||||
|
||||
/// <summary>
|
||||
/// Performs the full particles simulation update (postponed for the next particle manager update).
|
||||
/// </summary>
|
||||
API_FUNCTION() void UpdateSimulation();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the actor bounds.
|
||||
/// </summary>
|
||||
void UpdateBounds();
|
||||
|
||||
/// <summary>
|
||||
/// Synchronizes this instance data with the particle system and all emitters data.
|
||||
/// </summary>
|
||||
void Sync();
|
||||
|
||||
#if USE_EDITOR
|
||||
protected:
|
||||
// Exposed parameters overrides for Editor Undo.
|
||||
API_PROPERTY(Attributes="HideInEditor, Serialize") Array<ParticleEffect::ParameterOverride> GetParametersOverrides();
|
||||
API_PROPERTY() void SetParametersOverrides(const Array<ParticleEffect::ParameterOverride>& value);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
void Update();
|
||||
void CacheModifiedParameters();
|
||||
void ApplyModifiedParameters();
|
||||
void OnParticleSystemModified();
|
||||
void OnParticleSystemLoaded();
|
||||
|
||||
public:
|
||||
|
||||
// [Actor]
|
||||
bool HasContentLoaded() const override;
|
||||
void Draw(RenderContext& renderContext) override;
|
||||
void DrawGeneric(RenderContext& renderContext) override;
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
#if USE_EDITOR
|
||||
BoundingBox GetEditorBox() const override
|
||||
{
|
||||
const Vector3 size(50);
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
// [Actor]
|
||||
void EndPlay() override;
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
void OnActiveInTreeChanged() override;
|
||||
void OnTransformChanged() override;
|
||||
};
|
||||
Reference in New Issue
Block a user