246 lines
7.1 KiB
C++
246 lines
7.1 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Channels/MovieSceneChannelEditorData.h"
|
|
#include "Containers/Array.h"
|
|
#include "Containers/ArrayView.h"
|
|
#include "HAL/Platform.h"
|
|
#include "HAL/PlatformCrt.h"
|
|
#include "Math/Range.h"
|
|
#include "Misc/AssertionMacros.h"
|
|
#include "Misc/FrameNumber.h"
|
|
#include "Misc/FrameTime.h"
|
|
#include "Misc/Optional.h"
|
|
#include "MovieSceneChannel.h"
|
|
#include "MovieSceneChannelData.h"
|
|
#include "MovieSceneChannelTraits.h"
|
|
#include "Serialization/StructuredArchive.h"
|
|
#include "Templates/UnrealTemplate.h"
|
|
#include "UObject/Class.h"
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "Curves/RealCurve.h"
|
|
|
|
#include "MovieSceneIntegerChannel.generated.h"
|
|
|
|
struct FFrameRate;
|
|
struct FKeyHandle;
|
|
struct FPropertyTag;
|
|
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneIntegerChannel : public FMovieSceneChannel
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
typedef int32 CurveValueType;
|
|
|
|
FMovieSceneIntegerChannel()
|
|
: PreInfinityExtrap(RCCE_Constant)
|
|
, PostInfinityExtrap(RCCE_Constant)
|
|
, bInterpolateLinearKeys(false)
|
|
, DefaultValue(0)
|
|
, bHasDefaultValue(false)
|
|
{}
|
|
|
|
/**
|
|
* Serialize this type from another
|
|
*/
|
|
MOVIESCENE_API bool SerializeFromMismatchedTag(const FPropertyTag& Tag, FStructuredArchive::FSlot Slot);
|
|
|
|
/**
|
|
* Access a mutable interface for this channel's data
|
|
*
|
|
* @return An object that is able to manipulate this channel's data
|
|
*/
|
|
FORCEINLINE TMovieSceneChannelData<int32> GetData()
|
|
{
|
|
return TMovieSceneChannelData<int32>(&Times, &Values, this, &KeyHandles);
|
|
}
|
|
|
|
/**
|
|
* Access a constant interface for this channel's data
|
|
*
|
|
* @return An object that is able to interrogate this channel's data
|
|
*/
|
|
FORCEINLINE TMovieSceneChannelData<const int32> GetData() const
|
|
{
|
|
return TMovieSceneChannelData<const int32>(&Times, &Values);
|
|
}
|
|
|
|
/**
|
|
* Const access to this channel's times
|
|
*/
|
|
FORCEINLINE TArrayView<const FFrameNumber> GetTimes() const
|
|
{
|
|
return Times;
|
|
}
|
|
|
|
/**
|
|
* Const access to this channel's values
|
|
*/
|
|
FORCEINLINE TArrayView<const int32> GetValues() const
|
|
{
|
|
return Values;
|
|
}
|
|
|
|
/**
|
|
* Check whether this channel has any data
|
|
*/
|
|
FORCEINLINE bool HasAnyData() const
|
|
{
|
|
return Times.Num() != 0 || bHasDefaultValue == true;
|
|
}
|
|
|
|
/**
|
|
* Evaluate this channel
|
|
*
|
|
* @param InTime The time to evaluate at
|
|
* @param OutValue A value to receive the result
|
|
* @return true if the channel was evaluated successfully, false otherwise
|
|
*/
|
|
MOVIESCENE_API bool Evaluate(FFrameTime InTime, int32& OutValue) const;
|
|
|
|
/**
|
|
* Evaluate the interpolated value when bInterpolateLinearKeys is true
|
|
*
|
|
* @param InTime The time to evaluate at
|
|
* @param OutValue A value to receive the result
|
|
* @return true if the channel was evaluated successfully, false otherwise
|
|
*/
|
|
MOVIESCENE_API bool EvaluateInterp(FFrameTime InTime, double& OutValue) const;
|
|
|
|
/**
|
|
* Set the channel's times and values to the requested values
|
|
*/
|
|
FORCEINLINE void Set(TArray<FFrameNumber> InTimes, TArray<int32> InValues)
|
|
{
|
|
check(InTimes.Num() == InValues.Num());
|
|
|
|
Times = MoveTemp(InTimes);
|
|
Values = MoveTemp(InValues);
|
|
|
|
KeyHandles.Reset();
|
|
for (int32 Index = 0; Index < Times.Num(); ++Index)
|
|
{
|
|
KeyHandles.AllocateHandle(Index);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add keys with these times to channel. The number of elements in both arrays much match or nothing is added.
|
|
* @param InTimes Times to add
|
|
* @param InValues Values to add
|
|
*/
|
|
FORCEINLINE void AddKeys(const TArray<FFrameNumber>& InTimes, const TArray<int32>& InValues)
|
|
{
|
|
check(InTimes.Num() == InValues.Num());
|
|
int32 Index = Times.Num();
|
|
Times.Append(InTimes);
|
|
Values.Append(InValues);
|
|
for (; Index < Times.Num(); ++Index)
|
|
{
|
|
KeyHandles.AllocateHandle(Index);
|
|
}
|
|
}
|
|
|
|
public:
|
|
|
|
// ~ FMovieSceneChannel Interface
|
|
MOVIESCENE_API virtual void GetKeys(const TRange<FFrameNumber>& WithinRange, TArray<FFrameNumber>* OutKeyTimes, TArray<FKeyHandle>* OutKeyHandles) override;
|
|
MOVIESCENE_API virtual void GetKeyTimes(TArrayView<const FKeyHandle> InHandles, TArrayView<FFrameNumber> OutKeyTimes) override;
|
|
MOVIESCENE_API virtual void SetKeyTimes(TArrayView<const FKeyHandle> InHandles, TArrayView<const FFrameNumber> InKeyTimes) override;
|
|
MOVIESCENE_API virtual void DuplicateKeys(TArrayView<const FKeyHandle> InHandles, TArrayView<FKeyHandle> OutNewHandles) override;
|
|
MOVIESCENE_API virtual void DeleteKeys(TArrayView<const FKeyHandle> InHandles) override;
|
|
MOVIESCENE_API virtual void DeleteKeysFrom(FFrameNumber InTime, bool bDeleteKeysBefore) override;
|
|
MOVIESCENE_API virtual void RemapTimes(const UE::MovieScene::IRetimingInterface& Retimer) override;
|
|
MOVIESCENE_API virtual TRange<FFrameNumber> ComputeEffectiveRange() const override;
|
|
MOVIESCENE_API virtual int32 GetNumKeys() const override;
|
|
MOVIESCENE_API virtual void Reset() override;
|
|
MOVIESCENE_API virtual void Offset(FFrameNumber DeltaPosition) override;
|
|
MOVIESCENE_API virtual void Optimize(const FKeyDataOptimizationParams& InParameters) override;
|
|
MOVIESCENE_API virtual void ClearDefault() override;
|
|
MOVIESCENE_API virtual FKeyHandle GetHandle(int32 Index) override;
|
|
MOVIESCENE_API virtual int32 GetIndex(FKeyHandle Handle) override;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Set this channel's default value that should be used when no keys are present
|
|
*
|
|
* @param InDefaultValue The desired default value
|
|
*/
|
|
FORCEINLINE void SetDefault(int32 InDefaultValue)
|
|
{
|
|
bHasDefaultValue = true;
|
|
DefaultValue = InDefaultValue;
|
|
}
|
|
|
|
/**
|
|
* Get this channel's default value that will be used when no keys are present
|
|
*
|
|
* @return (Optional) The channel's default value
|
|
*/
|
|
FORCEINLINE TOptional<int32> GetDefault() const
|
|
{
|
|
return bHasDefaultValue ? TOptional<int32>(DefaultValue) : TOptional<int32>();
|
|
}
|
|
|
|
/**
|
|
* Remove this channel's default value causing the channel to have no effect where no keys are present
|
|
*/
|
|
FORCEINLINE void RemoveDefault()
|
|
{
|
|
bHasDefaultValue = false;
|
|
}
|
|
|
|
public:
|
|
|
|
/** Pre-infinity extrapolation state, integer channel supports them all but linear since that requires a tangent*/
|
|
UPROPERTY()
|
|
TEnumAsByte<ERichCurveExtrapolation> PreInfinityExtrap;
|
|
|
|
/** Post-infinity extrapolation state, integer channel supports them all but linear since that requires a tangent*/
|
|
UPROPERTY()
|
|
TEnumAsByte<ERichCurveExtrapolation> PostInfinityExtrap;
|
|
|
|
/** Whether to evaluate linear keys as interpolated or not*/
|
|
UPROPERTY()
|
|
bool bInterpolateLinearKeys;
|
|
|
|
private:
|
|
|
|
UPROPERTY(meta=(KeyTimes))
|
|
TArray<FFrameNumber> Times;
|
|
|
|
UPROPERTY()
|
|
int32 DefaultValue;
|
|
|
|
UPROPERTY()
|
|
bool bHasDefaultValue;
|
|
|
|
UPROPERTY(meta=(KeyValues))
|
|
TArray<int32> Values;
|
|
|
|
/** This needs to be a UPROPERTY so it gets saved into editor transactions but transient so it doesn't get saved into assets. */
|
|
UPROPERTY(Transient)
|
|
FMovieSceneKeyHandleMap KeyHandles;
|
|
};
|
|
|
|
template<>
|
|
struct TStructOpsTypeTraits<FMovieSceneIntegerChannel> : public TStructOpsTypeTraitsBase2<FMovieSceneIntegerChannel>
|
|
{
|
|
enum { WithStructuredSerializeFromMismatchedTag = true };
|
|
};
|
|
|
|
template<>
|
|
struct TMovieSceneChannelTraits<FMovieSceneIntegerChannel> : TMovieSceneChannelTraitsBase<FMovieSceneIntegerChannel>
|
|
{
|
|
#if WITH_EDITOR
|
|
|
|
/** Integer channels can have external values (ie, they can get their values from external objects for UI purposes) */
|
|
typedef TMovieSceneExternalValue<int32> ExtendedEditorDataType;
|
|
|
|
#endif
|
|
};
|