412 lines
14 KiB
C++
412 lines
14 KiB
C++
// Copyright (c) 2012-2021 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 ScriptingObject
|
|
{
|
|
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()
|
|
: ScriptingObject(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;
|
|
int32 _sceneRenderingKey = -1;
|
|
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();
|
|
|
|
/// <summary>
|
|
/// Gets the render task to use for particles simulation (eg. depth buffer collisions or view information).
|
|
/// </summary>
|
|
SceneRenderTask* GetRenderTask() const;
|
|
|
|
#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();
|
|
#if USE_EDITOR
|
|
void UpdateExecuteInEditor();
|
|
#endif
|
|
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 OnLayerChanged() override;
|
|
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;
|
|
};
|