228 lines
7.2 KiB
C++
228 lines
7.2 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/Level/Actors/PostFxVolume.h"
|
|
#include "SceneAnimation.h"
|
|
|
|
/// <summary>
|
|
/// The scene animation playback actor.
|
|
/// </summary>
|
|
API_CLASS() class FLAXENGINE_API SceneAnimationPlayer : public Actor, public IPostFxSettingsProvider
|
|
{
|
|
DECLARE_SCENE_OBJECT(SceneAnimationPlayer);
|
|
|
|
/// <summary>
|
|
/// Describes the scene animation updates frequency.
|
|
/// </summary>
|
|
API_ENUM() enum class UpdateModes
|
|
{
|
|
/// <summary>
|
|
/// Animation will be updated every game logic update.
|
|
/// </summary>
|
|
EveryUpdate = 0,
|
|
|
|
/// <summary>
|
|
/// Animation can be updated manually by the user scripts.
|
|
/// </summary>
|
|
Manual = 1,
|
|
};
|
|
|
|
private:
|
|
|
|
enum class PlayState
|
|
{
|
|
Stopped,
|
|
Paused,
|
|
Playing,
|
|
};
|
|
|
|
struct TrackInstance
|
|
{
|
|
ScriptingObjectReference<ScriptingObject> Object;
|
|
MonoObject* ManagedObject = nullptr;
|
|
MProperty* Property = nullptr;
|
|
MField* Field = nullptr;
|
|
MMethod* Method = nullptr;
|
|
int32 RestoreStateIndex = -1;
|
|
|
|
TrackInstance()
|
|
{
|
|
}
|
|
};
|
|
|
|
float _time = 0.0f;
|
|
float _lastTime = 0.0f;
|
|
PlayState _state = PlayState::Stopped;
|
|
Array<TrackInstance> _tracks;
|
|
Array<byte> _tracksDataStack;
|
|
Array<Actor*> _subActors;
|
|
Array<byte> _restoreData;
|
|
Camera* _cameraCutCam = nullptr;
|
|
bool _isUsingCameraCuts = false;
|
|
|
|
// PostFx settings to use
|
|
struct
|
|
{
|
|
CameraArtifactsSettings CameraArtifacts;
|
|
PostFxMaterialsSettings PostFxMaterials;
|
|
} _postFxSettings;
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// The scene animation to play.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(0), DefaultValue(null)")
|
|
AssetReference<SceneAnimation> Animation;
|
|
|
|
/// <summary>
|
|
/// The animation playback speed factor. Scales the timeline update delta time. Can be used to speed up or slow down the sequence.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(10), DefaultValue(1.0f)")
|
|
float Speed = 1.0f;
|
|
|
|
/// <summary>
|
|
/// The animation start time. Can be used to skip part of the sequence on begin.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(20), DefaultValue(0.0f)")
|
|
float StartTime = 0.0f;
|
|
|
|
/// <summary>
|
|
/// Determines whether the scene animation should take into account the global game time scale for simulation updates.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(30), DefaultValue(true)")
|
|
bool UseTimeScale = true;
|
|
|
|
/// <summary>
|
|
/// Determines whether the scene animation should loop when it finishes playing.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(40), DefaultValue(false)")
|
|
bool Loop = false;
|
|
|
|
/// <summary>
|
|
/// Determines whether the scene animation should auto play on game start.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\", \"Play On Start\"), EditorOrder(50), DefaultValue(false)")
|
|
bool PlayOnStart = false;
|
|
|
|
/// <summary>
|
|
/// Determines whether the scene animation should randomize the start time on play begin.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(60), DefaultValue(false)")
|
|
bool RandomStartTime = false;
|
|
|
|
/// <summary>
|
|
/// Determines whether the scene animation should restore initial state on playback stop. State is cached when animation track starts play after being stopped (not paused).
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\", \"Restore State On Stop\"), EditorOrder(70), DefaultValue(false)")
|
|
bool RestoreStateOnStop = false;
|
|
|
|
/// <summary>
|
|
/// The animation update mode.
|
|
/// </summary>
|
|
API_FIELD(Attributes="EditorDisplay(\"Scene Animation\"), EditorOrder(80), DefaultValue(UpdateModes.EveryUpdate)")
|
|
UpdateModes UpdateMode = UpdateModes::EveryUpdate;
|
|
|
|
public:
|
|
|
|
/// <summary>
|
|
/// Gets the value that determines whether the scene animation is playing.
|
|
/// </summary>
|
|
API_PROPERTY() FORCE_INLINE bool IsPlaying() const
|
|
{
|
|
return _state == PlayState::Playing;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the value that determines whether the scene animation is paused.
|
|
/// </summary>
|
|
API_PROPERTY() FORCE_INLINE bool IsPaused() const
|
|
{
|
|
return _state == PlayState::Paused;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the value that determines whether the scene animation is stopped.
|
|
/// </summary>
|
|
API_PROPERTY() FORCE_INLINE bool IsStopped() const
|
|
{
|
|
return _state == PlayState::Stopped;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the current animation playback time position (seconds).
|
|
/// </summary>
|
|
/// <returns>The animation playback time position (seconds).</returns>
|
|
API_PROPERTY(Attributes="NoSerialize, HideInEditor")
|
|
FORCE_INLINE float GetTime() const
|
|
{
|
|
return _time;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the current animation playback time position (seconds).
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
API_PROPERTY() void SetTime(float value);
|
|
|
|
/// <summary>
|
|
/// Starts playing the animation. Has no effect if animation is already playing.
|
|
/// </summary>
|
|
API_FUNCTION() void Play();
|
|
|
|
/// <summary>
|
|
/// Pauses the animation. Has no effect if animation is not playing.
|
|
/// </summary>
|
|
API_FUNCTION() void Pause();
|
|
|
|
/// <summary>
|
|
/// Stops playing the animation. Has no effect if animation is already stopped.
|
|
/// </summary>
|
|
API_FUNCTION() void Stop();
|
|
|
|
/// <summary>
|
|
/// Manually ticks the animation by performing the playback update with a given time delta.
|
|
/// </summary>
|
|
/// <param name="dt">The update delta time (in seconds). It does not get scaled by player Speed parameter.</param>
|
|
API_FUNCTION() void Tick(float dt);
|
|
|
|
private:
|
|
|
|
void Restore(SceneAnimation* anim, int32 stateIndexOffset);
|
|
bool TickPropertyTrack(int32 trackIndex, int32 stateIndexOffset, SceneAnimation* anim, float time, const SceneAnimation::Track& track, TrackInstance& state, void* target);
|
|
void Tick(SceneAnimation* anim, float time, float dt, int32 stateIndexOffset);
|
|
void Tick();
|
|
void OnAnimationModified();
|
|
void ResetState();
|
|
|
|
public:
|
|
|
|
// [Actor]
|
|
bool HasContentLoaded() const 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
|
|
|
|
// [IPostFxSettingsProvider]
|
|
void Collect(RenderContext& renderContext) override;
|
|
void Blend(PostProcessSettings& other, float weight) override;
|
|
|
|
protected:
|
|
|
|
// [Actor]
|
|
void BeginPlay(SceneBeginData* data) override;
|
|
void EndPlay() override;
|
|
void OnEnable() override;
|
|
void OnDisable() override;
|
|
void OnTransformChanged() override;
|
|
};
|