786 lines
27 KiB
C++
786 lines
27 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Containers/Array.h"
|
|
#include "Containers/ArrayView.h"
|
|
#include "Containers/ContainerAllocationPolicies.h"
|
|
#include "Containers/Set.h"
|
|
#include "Containers/UnrealString.h"
|
|
#include "CoreMinimal.h"
|
|
#include "CoreTypes.h"
|
|
#include "EntitySystem/MovieSceneEntityIDs.h"
|
|
#include "EntitySystem/MovieSceneEntitySystemTypes.h"
|
|
#include "Evaluation/MovieSceneEvaluationKey.h"
|
|
#include "Evaluation/MovieSceneEvaluationTree.h"
|
|
#include "Evaluation/MovieSceneSegment.h"
|
|
#include "Evaluation/MovieSceneTrackIdentifier.h"
|
|
#include "Math/NumericLimits.h"
|
|
#include "Math/Range.h"
|
|
#include "Misc/FrameNumber.h"
|
|
#include "Misc/Guid.h"
|
|
#include "MovieSceneFrameMigration.h"
|
|
#include "MovieSceneSequenceID.h"
|
|
#include "Serialization/Archive.h"
|
|
#include "Templates/Function.h"
|
|
#include "Templates/TypeHash.h"
|
|
#include "Templates/UnrealTemplate.h"
|
|
#include "UObject/Class.h"
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "UObject/WeakObjectPtr.h"
|
|
#include "UObject/WeakObjectPtrTemplates.h"
|
|
|
|
#include "MovieSceneEvaluationField.generated.h"
|
|
|
|
class UMovieSceneSequence;
|
|
class UObject;
|
|
struct FFrameNumber;
|
|
struct FMovieSceneSequenceHierarchy;
|
|
struct IMovieSceneSequenceTemplateStore;
|
|
class UMovieSceneCondition;
|
|
|
|
|
|
/**
|
|
* A key that uniquely identifies an entity by its owner and ID
|
|
*/
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldEntityKey
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
friend bool operator==(FMovieSceneEvaluationFieldEntityKey A, FMovieSceneEvaluationFieldEntityKey B)
|
|
{
|
|
return A.EntityOwner == B.EntityOwner && A.EntityID == B.EntityID;
|
|
}
|
|
friend bool operator!=(FMovieSceneEvaluationFieldEntityKey A, FMovieSceneEvaluationFieldEntityKey B)
|
|
{
|
|
return !(A == B);
|
|
}
|
|
friend uint32 GetTypeHash(FMovieSceneEvaluationFieldEntityKey In)
|
|
{
|
|
return GetTypeHash(In.EntityOwner) ^ In.EntityID;
|
|
}
|
|
|
|
/** The entity owner - either a UMovieSceneSection or perhaps a UMovieSceneTrack. Must implement the IMovieSceneEntityProvider interface */
|
|
UPROPERTY()
|
|
TWeakObjectPtr<UObject> EntityOwner;
|
|
|
|
/** The identifer for the entity within the owner. Normally this will be irrelevant (and 0), but may be used to identifier unique entities by index, or flags */
|
|
UPROPERTY()
|
|
uint32 EntityID = 0;
|
|
};
|
|
|
|
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldEntity
|
|
{
|
|
public:
|
|
|
|
GENERATED_BODY()
|
|
|
|
FMovieSceneEvaluationFieldEntity()
|
|
: SharedMetaDataIndex(INDEX_NONE)
|
|
{}
|
|
|
|
FMovieSceneEvaluationFieldEntity(const FMovieSceneEvaluationFieldEntityKey& InKey, int32 InSharedMetaDataIndex = INDEX_NONE)
|
|
: Key(InKey)
|
|
, SharedMetaDataIndex(InSharedMetaDataIndex)
|
|
{}
|
|
|
|
UPROPERTY()
|
|
FMovieSceneEvaluationFieldEntityKey Key;
|
|
|
|
UPROPERTY()
|
|
int32 SharedMetaDataIndex;
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldSharedEntityMetaData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY()
|
|
FGuid ObjectBindingID;
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldEntityMetaData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FMovieSceneEvaluationFieldEntityMetaData()
|
|
: ForcedTime(TNumericLimits<int32>::Lowest())
|
|
, Flags(ESectionEvaluationFlags::None)
|
|
, bEvaluateInSequencePreRoll(false)
|
|
, bEvaluateInSequencePostRoll(false)
|
|
{}
|
|
|
|
bool IsRedundant() const
|
|
{
|
|
return *this == FMovieSceneEvaluationFieldEntityMetaData();
|
|
}
|
|
|
|
friend bool operator==(const FMovieSceneEvaluationFieldEntityMetaData& A, const FMovieSceneEvaluationFieldEntityMetaData& B)
|
|
{
|
|
return A.ForcedTime == B.ForcedTime &&
|
|
A.Flags == B.Flags &&
|
|
A.bEvaluateInSequencePreRoll == B.bEvaluateInSequencePreRoll &&
|
|
A.bEvaluateInSequencePostRoll == B.bEvaluateInSequencePostRoll &&
|
|
A.OverrideBoundPropertyPath == B.OverrideBoundPropertyPath &&
|
|
A.Condition == B.Condition;
|
|
}
|
|
|
|
/* Optional condition that the entity can provide to be checked at runtime before import. If the condition fails, the entity will not be imported.
|
|
*/
|
|
UPROPERTY()
|
|
TSoftObjectPtr<const UMovieSceneCondition> Condition;
|
|
|
|
/** Opt-in - when this value is set, the entity should use this property path instead of the one defined on its generating section */
|
|
UPROPERTY()
|
|
FString OverrideBoundPropertyPath;
|
|
|
|
UPROPERTY()
|
|
FFrameNumber ForcedTime;
|
|
|
|
UPROPERTY()
|
|
ESectionEvaluationFlags Flags;
|
|
|
|
/** Opt-in - when no meta-data is present, or this value is false, this entity cannot be evaluated as part of sub-sequence preroll */
|
|
UPROPERTY()
|
|
uint8 bEvaluateInSequencePreRoll : 1;
|
|
|
|
/** Opt-in - when no meta-data is present, or this value is false, this entity cannot be evaluated as part of sub-sequence postroll */
|
|
UPROPERTY()
|
|
uint8 bEvaluateInSequencePostRoll : 1;
|
|
};
|
|
|
|
struct FMovieSceneEvaluationFieldEntityQuery
|
|
{
|
|
FMovieSceneEvaluationFieldEntity Entity;
|
|
int32 MetaDataIndex;
|
|
};
|
|
|
|
struct FMovieSceneEvaluationFieldEntityKeyFuncs : BaseKeyFuncs<FMovieSceneEvaluationFieldEntityQuery,FMovieSceneEvaluationFieldEntityKey,false>
|
|
{
|
|
static FORCEINLINE FMovieSceneEvaluationFieldEntityKey GetSetKey(const FMovieSceneEvaluationFieldEntityQuery& Element) { return Element.Entity.Key; }
|
|
static FORCEINLINE bool Matches(const FMovieSceneEvaluationFieldEntityKey& A, const FMovieSceneEvaluationFieldEntityKey& B) { return A == B; }
|
|
static FORCEINLINE uint32 GetKeyHash(const FMovieSceneEvaluationFieldEntityKey& Key) { return GetTypeHash(Key); }
|
|
};
|
|
using FMovieSceneEvaluationFieldEntitySet = TSet<FMovieSceneEvaluationFieldEntityQuery, FMovieSceneEvaluationFieldEntityKeyFuncs>;
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldEntityTree
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
bool Serialize(FArchive& Ar)
|
|
{
|
|
Ar << SerializedData;
|
|
return true;
|
|
}
|
|
|
|
bool Identical(const FMovieSceneEvaluationFieldEntityTree* Other, uint32 PortFlags) const
|
|
{
|
|
return Other->SerializedData == SerializedData;
|
|
}
|
|
|
|
struct FEntityAndMetaDataIndex
|
|
{
|
|
int32 EntityIndex;
|
|
int32 MetaDataIndex;
|
|
|
|
friend FArchive& operator<<(FArchive& Ar, FEntityAndMetaDataIndex& In)
|
|
{
|
|
return Ar << In.EntityIndex << In.MetaDataIndex;
|
|
}
|
|
friend bool operator==(const FEntityAndMetaDataIndex& A, const FEntityAndMetaDataIndex& B)
|
|
{
|
|
return A.EntityIndex == B.EntityIndex && A.MetaDataIndex == B.MetaDataIndex;
|
|
}
|
|
};
|
|
TMovieSceneEvaluationTree<FEntityAndMetaDataIndex> SerializedData;
|
|
};
|
|
template<> struct TStructOpsTypeTraits<FMovieSceneEvaluationFieldEntityTree> : public TStructOpsTypeTraitsBase2<FMovieSceneEvaluationFieldEntityTree>
|
|
{
|
|
enum { WithSerializer = true, WithIdentical = true, WithCopy = false };
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* High-level container which acts as a look-up-table for IMovieSceneEntityProviders and their entities and meta-data in a sequence
|
|
*
|
|
* Generally generated and accessed through UMovieSceneCompiledDataManager, but can also be used independently.
|
|
* Entity fields are constructed using FMovieSceneEntityComponentFieldBuilder which ensures the invariants of this class are
|
|
* maintained along with guaranteeing no redundant entries exist.
|
|
*/
|
|
USTRUCT()
|
|
struct FMovieSceneEntityComponentField
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/**
|
|
* Check if this field is empty
|
|
*/
|
|
bool IsEmpty() const
|
|
{
|
|
return Entities.Num() == 0;
|
|
}
|
|
|
|
/**
|
|
* Retrieve an entity from its index
|
|
*/
|
|
const FMovieSceneEvaluationFieldEntity& GetEntity(int32 EntityIndex) const
|
|
{
|
|
return Entities[EntityIndex];
|
|
}
|
|
|
|
/**
|
|
* Retrieve the meta-data for an entity
|
|
* @return The meta-data for an entity or nullptr if it has none associated with it
|
|
*/
|
|
const FMovieSceneEvaluationFieldEntityMetaData* FindMetaData(const FMovieSceneEvaluationFieldEntityQuery& InQuery) const
|
|
{
|
|
return InQuery.MetaDataIndex != INDEX_NONE ? &EntityMetaData[InQuery.MetaDataIndex] : nullptr;
|
|
}
|
|
|
|
/**
|
|
* Retrieve the shared meta-data for an entity
|
|
* @return The shared meta-data for an entity or nullptr if it has none associated with it
|
|
*/
|
|
const FMovieSceneEvaluationFieldSharedEntityMetaData* FindSharedMetaData(const FMovieSceneEvaluationFieldEntityQuery& InQuery) const
|
|
{
|
|
return InQuery.Entity.SharedMetaDataIndex != INDEX_NONE ? &SharedMetaData[InQuery.Entity.SharedMetaDataIndex] : nullptr;
|
|
}
|
|
|
|
/**
|
|
* Query the persistent entities for any given time within a sequence.
|
|
* @note: Persistent entities should remain alive until they are no longer present at the current time.
|
|
*
|
|
* @param QueryTime The time at which to query the field (in the TickResolution of the sequence this was generated from)
|
|
* @param OutRange Will receive the hull of the range that was intersected for which the resulting OutEntities remains constant
|
|
* @param OutEntities A set that will be populated with all the entities that exist at the specified time
|
|
*/
|
|
MOVIESCENE_API void QueryPersistentEntities(FFrameNumber QueryTime, TRange<FFrameNumber>& OutRange, FMovieSceneEvaluationFieldEntitySet& OutEntities) const;
|
|
|
|
/**
|
|
* Query the persistent entities for any given time within a sequence.
|
|
* @note: Persistent entities should remain alive until they are no longer present at the current time.
|
|
*
|
|
* @param QueryTime The time at which to query the field (in the TickResolution of the sequence this was generated from)
|
|
* @param QueryCallback A handler for dealing with the resulting entities
|
|
* @param OutRange Will receive the hull of the range that was intersected for which the resulting OutEntities remains constant
|
|
*/
|
|
MOVIESCENE_API void QueryPersistentEntities(FFrameNumber QueryTime, TFunctionRef<bool(const FMovieSceneEvaluationFieldEntityQuery&)> QueryCallback, TRange<FFrameNumber>& OutRange) const;
|
|
|
|
/**
|
|
* Check whether this field contains any one-shot entities
|
|
*/
|
|
MOVIESCENE_API bool HasAnyOneShotEntities() const;
|
|
|
|
/**
|
|
* Query the one-shot entities that overlap with the specified query range.
|
|
* @note: One-shot entities only ever live for a single frame of evaluation.
|
|
*
|
|
* @param QueryRange The ranger over which to query the field (in the TickResolution of the sequence this was generated from)
|
|
* @param OutEntities A set that will be populated with all the entities that overlapped at all with the specified range
|
|
*/
|
|
MOVIESCENE_API void QueryOneShotEntities(const TRange<FFrameNumber>& QueryRange, FMovieSceneEvaluationFieldEntitySet& OutEntityIndices) const;
|
|
|
|
private:
|
|
|
|
friend struct FMovieSceneEntityComponentFieldBuilder;
|
|
|
|
/** A hierarchical tree specifiying indices into the Entities array for any given time such persistent entities are active */
|
|
UPROPERTY()
|
|
FMovieSceneEvaluationFieldEntityTree PersistentEntityTree;
|
|
|
|
/** A hierarchical tree specifiying indices into the Entities array for any given time such one-shot entities are active */
|
|
UPROPERTY()
|
|
FMovieSceneEvaluationFieldEntityTree OneShotEntityTree;
|
|
|
|
/** 16 bytes - Flat array of unique entities. The 2 tree types specify indices into this array */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationFieldEntity> Entities;
|
|
|
|
/** 16 bytes - Optional meta-data for specific entities. Specified in FMovieSceneEvaluationFieldEntity::MetaDataIndex. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationFieldEntityMetaData> EntityMetaData;
|
|
|
|
/** 16 bytes - Optional shared meta-data for groups of entities. Specified in FMovieSceneEvaluationFieldEntity::SharedMetaDataIndex. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationFieldSharedEntityMetaData> SharedMetaData;
|
|
};
|
|
|
|
|
|
/**
|
|
* Builder class used for populating an FMovieSceneEntityComponentField with data.
|
|
* Ensures that null or redundant entities or meta-data are not added to the field, and that all indices are valid and correct.
|
|
*/
|
|
struct FMovieSceneEntityComponentFieldBuilder
|
|
{
|
|
static constexpr uint32 InvalidEntityID = ~0u;
|
|
|
|
/**
|
|
* Construction from a field to populate
|
|
*/
|
|
MOVIESCENE_API FMovieSceneEntityComponentFieldBuilder(FMovieSceneEntityComponentField* InField);
|
|
|
|
/**
|
|
* Destructor that cleans up redundant data if necessary
|
|
*/
|
|
MOVIESCENE_API ~FMovieSceneEntityComponentFieldBuilder();
|
|
|
|
/**
|
|
* Access the shared meta-data for all the entities created by this builder.
|
|
*/
|
|
MOVIESCENE_API FMovieSceneEvaluationFieldSharedEntityMetaData& GetSharedMetaData();
|
|
|
|
/**
|
|
* Access the index of the shared meta-data of this builder.
|
|
*/
|
|
MOVIESCENE_API int32 GetSharedMetaDataIndex() const;
|
|
|
|
/**
|
|
* Add meta-data to this tree returning its index within this builder
|
|
*
|
|
* @param InMetaData The meta-data to add.
|
|
* @return A unique index for this meta-data within this builder, or INDEX_NONE if the meta-data is redundant
|
|
*/
|
|
MOVIESCENE_API int32 AddMetaData(const FMovieSceneEvaluationFieldEntityMetaData& InMetaData);
|
|
|
|
/**
|
|
* Retrieve an index for the entity that is identified by the specified owner and ID
|
|
*
|
|
* @param EntityOwner The owner that produces the entity at runtime. Must implement the IMovieSceneEntityProvider interface
|
|
* @param EntityID (Optional) An identifier used to identify the entity inside IMovieSceneEntityProvider::ImportEntityImpl. Could be an index within an array or a set of flags.
|
|
* @return An index into this builder used to uniquely identify this entity.
|
|
*/
|
|
MOVIESCENE_API int32 FindOrAddEntity(UObject* EntityOwner, uint32 EntityID = 0);
|
|
|
|
/**
|
|
* Add a persistent entity to the field for a given range. Equivalent to AddPersistentEntity(Range, FindOrAddEntity(EntityOwner, EntityID)).
|
|
* @note: Persistent entities remain alive for the entire duration of their applicable ranges.
|
|
*
|
|
* @param Range The range within which this entity should be alive
|
|
* @param EntityOwner The owner that produces the entity at runtime. Must implement the IMovieSceneEntityProvider interface
|
|
* @param EntityID (Optional) An identifier used to identify the entity inside IMovieSceneEntityProvider::ImportEntityImpl. Could be an index within an array or a set of flags.
|
|
* @param MetaDataIndex (Optional) Meta-data to use for this entitiy within this range. See AddMetaData.
|
|
*/
|
|
MOVIESCENE_API void AddPersistentEntity(const TRange<FFrameNumber>& Range, UObject* EntityOwner, uint32 EntityID = 0, int32 InMetaDataIndex = INDEX_NONE);
|
|
|
|
/**
|
|
* Add a persistent entity to the field for a given range
|
|
* @note: Persistent entities remain alive for the entire duration of their applicable ranges.
|
|
*
|
|
* @param Range The range within which this entity should be alive
|
|
* @param LocalIndex The index to the entity retrieved from FindOrAddEntity.
|
|
* @param MetaDataIndex (Optional) Meta-data to use for this entitiy within this range. See AddMetaData.
|
|
*/
|
|
MOVIESCENE_API void AddPersistentEntity(const TRange<FFrameNumber>& Range, int32 LocalIndex, int32 InMetaDataIndex = INDEX_NONE);
|
|
|
|
/**
|
|
* Add a one-shot entity to the field for a given range. Equivalent to AddOneShotEntity(Range, FindOrAddEntity(EntityOwner, EntityID)).
|
|
* @note: One-shot entities are only ever alive for a single evaluation, regardless of the range within the field. This makes them ideal for events or triggers.
|
|
*
|
|
* @param Range The range within which this entity should be alive
|
|
* @param EntityOwner The owner that produces the entity at runtime. Must implement the IMovieSceneEntityProvider interface
|
|
* @param EntityID (Optional) An identifier used to identify the entity inside IMovieSceneEntityProvider::ImportEntityImpl. Could be an index within an array or a set of flags.
|
|
* @param MetaDataIndex (Optional) Meta-data to use for this entitiy within this range. See AddMetaData.
|
|
*/
|
|
MOVIESCENE_API void AddOneShotEntity(const TRange<FFrameNumber>& OneShotRange, UObject* EntityOwner, uint32 EntityID = 0, int32 InMetaDataIndex = INDEX_NONE);
|
|
|
|
/**
|
|
* Add a one-shot entity to the field for a given range
|
|
* @note: One-shot entities are only ever alive for a single evaluation, regardless of the range within the field. This makes them ideal for events or triggers.
|
|
*
|
|
* @param Range The range within which this entity should be alive
|
|
* @param LocalIndex The index to the entity retrieved from FindOrAddEntity.
|
|
* @param MetaDataIndex (Optional) Meta-data to use for this entitiy within this range. See AddMetaData.
|
|
*/
|
|
MOVIESCENE_API void AddOneShotEntity(const TRange<FFrameNumber>& OneShotRange, int32 LocalIndex, int32 InMetaDataIndex = INDEX_NONE);
|
|
|
|
private:
|
|
|
|
/** Convert a user-facing local index into KeyToFieldIndex, into an index within FMovieSceneEntityComponentField::Entities */
|
|
MOVIESCENE_API int32 LocalEntityIndexToFieldIndex(int32 LocalIndex);
|
|
|
|
/** Convert a user-facing local meta-data index into MetaDataToFieldIndex, into an index within FMovieSceneEntityComponentField::EntityMetaData */
|
|
MOVIESCENE_API int32 LocalMetaDataIndexToFieldIndex(int32 LocalIndex);
|
|
|
|
/** Array of entity keys and their field index within FMovieSceneEntityComponentField::Entities */
|
|
struct FKeyToIndex
|
|
{
|
|
FMovieSceneEvaluationFieldEntityKey Key;
|
|
int32 FieldIndex;
|
|
};
|
|
TArray<FKeyToIndex, TInlineAllocator<4>> KeyToFieldIndex;
|
|
|
|
struct FMetaDataToIndex
|
|
{
|
|
FMovieSceneEvaluationFieldEntityMetaData MetaData;
|
|
int32 FieldIndex;
|
|
};
|
|
TArray<FMetaDataToIndex, TInlineAllocator<2>> MetaDataToFieldIndex;
|
|
|
|
/** The field that we are building */
|
|
FMovieSceneEntityComponentField* Field;
|
|
|
|
/** (default: INDEX_NONE) The index into FMovieSceneEntityComponentField::SharedMetaData for all entities built by this builder, if it has been defined. */
|
|
int32 SharedMetaDataIndex;
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------
|
|
// Legacy track template field structures begin here
|
|
//---------------------------------------------------------
|
|
|
|
|
|
/** A pointer to a track held within an evaluation template */
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldTrackPtr
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
FMovieSceneEvaluationFieldTrackPtr(){}
|
|
|
|
/**
|
|
* Construction from a sequence ID, and the index of the track within that sequence's track list
|
|
*/
|
|
FMovieSceneEvaluationFieldTrackPtr(FMovieSceneSequenceIDRef InSequenceID, FMovieSceneTrackIdentifier InTrackIdentifier)
|
|
: SequenceID(InSequenceID)
|
|
, TrackIdentifier(InTrackIdentifier)
|
|
{}
|
|
|
|
/**
|
|
* Check for equality
|
|
*/
|
|
friend bool operator==(FMovieSceneEvaluationFieldTrackPtr A, FMovieSceneEvaluationFieldTrackPtr B)
|
|
{
|
|
return A.TrackIdentifier == B.TrackIdentifier && A.SequenceID == B.SequenceID;
|
|
}
|
|
|
|
/**
|
|
* Get a hashed representation of this type
|
|
*/
|
|
friend uint32 GetTypeHash(FMovieSceneEvaluationFieldTrackPtr LHS)
|
|
{
|
|
return HashCombine(GetTypeHash(LHS.TrackIdentifier), GetTypeHash(LHS.SequenceID));
|
|
}
|
|
|
|
/** The sequence ID that identifies to which sequence the track belongs */
|
|
UPROPERTY()
|
|
FMovieSceneSequenceID SequenceID;
|
|
|
|
/** The Identifier of the track inside the track map (see FMovieSceneEvaluationTemplate::Tracks) */
|
|
UPROPERTY()
|
|
FMovieSceneTrackIdentifier TrackIdentifier;
|
|
};
|
|
|
|
/** A pointer to a particular segment of a track held within an evaluation template */
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationFieldSegmentPtr : public FMovieSceneEvaluationFieldTrackPtr
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/**
|
|
* Default constructor
|
|
*/
|
|
FMovieSceneEvaluationFieldSegmentPtr(){}
|
|
|
|
/**
|
|
* Construction from a sequence ID, and the index of the track within that sequence's track list
|
|
*/
|
|
FMovieSceneEvaluationFieldSegmentPtr(FMovieSceneSequenceIDRef InSequenceID, FMovieSceneTrackIdentifier InTrackIdentifier, FMovieSceneSegmentIdentifier InSegmentID)
|
|
: FMovieSceneEvaluationFieldTrackPtr(InSequenceID, InTrackIdentifier)
|
|
, SegmentID(InSegmentID)
|
|
{}
|
|
|
|
/**
|
|
* Check for equality
|
|
*/
|
|
friend bool operator==(FMovieSceneEvaluationFieldSegmentPtr A, FMovieSceneEvaluationFieldSegmentPtr B)
|
|
{
|
|
return A.SegmentID == B.SegmentID && A.TrackIdentifier == B.TrackIdentifier && A.SequenceID == B.SequenceID;
|
|
}
|
|
|
|
/**
|
|
* Get a hashed representation of this type
|
|
*/
|
|
friend uint32 GetTypeHash(FMovieSceneEvaluationFieldSegmentPtr LHS)
|
|
{
|
|
return HashCombine(GetTypeHash(LHS.SegmentID), GetTypeHash(static_cast<FMovieSceneEvaluationFieldTrackPtr&>(LHS)));
|
|
}
|
|
|
|
/** The identifier of the segment within the track (see FMovieSceneEvaluationTrack::Segments) */
|
|
UPROPERTY()
|
|
FMovieSceneSegmentIdentifier SegmentID;
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneFieldEntry_EvaluationTrack
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY()
|
|
FMovieSceneEvaluationFieldTrackPtr TrackPtr;
|
|
|
|
UPROPERTY()
|
|
uint16 NumChildren = 0;
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMovieSceneFieldEntry_ChildTemplate
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FMovieSceneFieldEntry_ChildTemplate()
|
|
: ChildIndex(-1)
|
|
, Flags(ESectionEvaluationFlags::None)
|
|
, ForcedTime(TNumericLimits<int32>::Lowest())
|
|
{}
|
|
|
|
FMovieSceneFieldEntry_ChildTemplate(uint16 InChildIndex, ESectionEvaluationFlags InFlags, FFrameNumber InForcedTime)
|
|
: ChildIndex(InChildIndex)
|
|
, Flags(InFlags)
|
|
, ForcedTime(InForcedTime)
|
|
{}
|
|
|
|
UPROPERTY()
|
|
uint16 ChildIndex;
|
|
|
|
UPROPERTY()
|
|
ESectionEvaluationFlags Flags;
|
|
|
|
UPROPERTY()
|
|
FFrameNumber ForcedTime;
|
|
};
|
|
|
|
/** Lookup table index for a group of evaluation templates */
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationGroupLUTIndex
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FMovieSceneEvaluationGroupLUTIndex()
|
|
: NumInitPtrs(0)
|
|
, NumEvalPtrs(0)
|
|
{}
|
|
|
|
/** The number of initialization pointers are stored after &FMovieSceneEvaluationGroup::SegmentPtrLUT[0] + LUTOffset. */
|
|
UPROPERTY()
|
|
int32 NumInitPtrs;
|
|
|
|
/** The number of evaluation pointers are stored after &FMovieSceneEvaluationGroup::SegmentPtrLUT[0] + LUTOffset + NumInitPtrs. */
|
|
UPROPERTY()
|
|
int32 NumEvalPtrs;
|
|
};
|
|
|
|
/** Holds segment pointers for all segments that are active for a given range of the sequence */
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationGroup
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Array of indices that define all the flush groups in the range. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationGroupLUTIndex> LUTIndices;
|
|
|
|
/** */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneFieldEntry_EvaluationTrack> TrackLUT;
|
|
|
|
/** */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneFieldEntry_ChildTemplate> SectionLUT;
|
|
};
|
|
|
|
/** Struct that stores the key for an evaluated entity, and the index at which it was (or is to be) evaluated */
|
|
USTRUCT()
|
|
struct FMovieSceneOrderedEvaluationKey
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY()
|
|
FMovieSceneEvaluationKey Key;
|
|
|
|
UPROPERTY()
|
|
uint16 SetupIndex = 0;
|
|
|
|
UPROPERTY()
|
|
uint16 TearDownIndex = 0;
|
|
};
|
|
|
|
/** Informational meta-data that applies to a given time range */
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationMetaData
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/**
|
|
* Reset this meta-data
|
|
*/
|
|
void Reset()
|
|
{
|
|
ActiveSequences.Reset();
|
|
ActiveEntities.Reset();
|
|
}
|
|
|
|
/**
|
|
* Diff the active sequences this frame, with the specified previous frame's meta-data
|
|
*
|
|
* @param LastFrame Meta-data pertaining to the last frame
|
|
* @param NewSequences (Optional) Ptr to an array that will be populated with sequences that are new this frame
|
|
* @param ExpiredSequences (Optional) Ptr to an array that will be populated with sequences that are no longer being evaluated
|
|
*/
|
|
void DiffSequences(const FMovieSceneEvaluationMetaData& LastFrame, TArray<FMovieSceneSequenceID>* NewSequences, TArray<FMovieSceneSequenceID>* ExpiredSequences) const;
|
|
|
|
/**
|
|
* Diff the active entities (tracks and sections) this frame, with the specified previous frame's meta-data
|
|
*
|
|
* @param LastFrame Meta-data pertaining to the last frame
|
|
* @param NewKeys (Optional) Ptr to an array that will be populated with entities that are new this frame
|
|
* @param ExpiredKeys (Optional) Ptr to an array that will be populated with entities that are no longer being evaluated
|
|
*/
|
|
void DiffEntities(const FMovieSceneEvaluationMetaData& LastFrame, TArray<FMovieSceneOrderedEvaluationKey>* NewKeys, TArray<FMovieSceneOrderedEvaluationKey>* ExpiredKeys) const;
|
|
|
|
/** Array of sequences that are active in this time range. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneSequenceID> ActiveSequences;
|
|
|
|
/** Array of entities (tracks and/or sections) that are active in this time range. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneOrderedEvaluationKey> ActiveEntities;
|
|
};
|
|
|
|
/**
|
|
* Memory layout optimized primarily for speed of searching the applicable ranges
|
|
*/
|
|
USTRUCT()
|
|
struct FMovieSceneEvaluationField
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/**
|
|
* Efficiently find the entry that exists at the specified time, if any
|
|
*
|
|
* @param Time The time at which to seach
|
|
* @return The index within Ranges, Groups and MetaData that the current time resides, or INDEX_NONE if there is nothing to do at the requested time
|
|
*/
|
|
MOVIESCENE_API int32 GetSegmentFromTime(FFrameNumber Time) const;
|
|
|
|
/**
|
|
* Deduce the indices into Ranges and Groups that overlap with the specified time range
|
|
*
|
|
* @param Range The range to overlap with our field
|
|
* @return A range of indices for which GetRange() overlaps the specified Range, of the form [First, First+Num)
|
|
*/
|
|
MOVIESCENE_API TRange<int32> OverlapRange(const TRange<FFrameNumber>& Range) const;
|
|
|
|
/**
|
|
* Invalidate a range in this field
|
|
*
|
|
* @param Range The range to overlap with our field
|
|
* @return A range of indices into Ranges and Groups that overlap with the requested range
|
|
*/
|
|
MOVIESCENE_API void Invalidate(const TRange<FFrameNumber>& Range);
|
|
|
|
/**
|
|
* Insert a new range into this field
|
|
*
|
|
* @param InRange The total range to insert to the field. Will potentially be intersected with preexisting adjacent ranges
|
|
* @param InGroup The group defining what should happen at this time
|
|
* @param InMetaData The meta-data defining efficient access to what happens in this frame
|
|
* @return The index the entries were inserted at
|
|
*/
|
|
MOVIESCENE_API int32 Insert(const TRange<FFrameNumber>& InRange, FMovieSceneEvaluationGroup&& InGroup, FMovieSceneEvaluationMetaData&& InMetaData);
|
|
|
|
/**
|
|
* Add the specified data to this field, assuming the specified range lies after any other entries
|
|
*
|
|
* @param InRange The range to add
|
|
* @param InGroup The group defining what should happen at this time
|
|
* @param InMetaData The meta-data defining efficient access to what happens in this frame
|
|
*/
|
|
MOVIESCENE_API void Add(const TRange<FFrameNumber>& InRange, FMovieSceneEvaluationGroup&& InGroup, FMovieSceneEvaluationMetaData&& InMetaData);
|
|
|
|
/**
|
|
* Access this field's signature
|
|
*/
|
|
#if WITH_EDITORONLY_DATA
|
|
const FGuid& GetSignature() const
|
|
{
|
|
return Signature;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Access this field's size
|
|
*/
|
|
int32 Size() const
|
|
{
|
|
return Ranges.Num();
|
|
}
|
|
|
|
/**
|
|
* Access this entire field's set of ranges
|
|
*/
|
|
TArrayView<const FMovieSceneFrameRange> GetRanges() const
|
|
{
|
|
return Ranges;
|
|
}
|
|
|
|
/**
|
|
* Lookup a valid range by index
|
|
* @param Index The valid index within the ranges to lookup
|
|
* @return The range
|
|
*/
|
|
const TRange<FFrameNumber>& GetRange(int32 Index) const
|
|
{
|
|
return Ranges[Index].Value;
|
|
}
|
|
|
|
/**
|
|
* Lookup a valid evaluation group by entry index
|
|
* @param Index The valid index within the evaluation group array to lookup
|
|
* @return The group
|
|
*/
|
|
const FMovieSceneEvaluationGroup& GetGroup(int32 Index) const
|
|
{
|
|
return Groups[Index];
|
|
}
|
|
|
|
/**
|
|
* Lookup valid meta-data by entry index
|
|
* @param Index The valid index within the meta-data array to lookup
|
|
* @return The meta-data
|
|
*/
|
|
const FMovieSceneEvaluationMetaData& GetMetaData(int32 Index) const
|
|
{
|
|
return MetaData[Index];
|
|
}
|
|
|
|
private:
|
|
#if WITH_EDITORONLY_DATA
|
|
/** Signature that uniquely identifies any state this field can be in - regenerated on mutation */
|
|
UPROPERTY()
|
|
FGuid Signature;
|
|
#endif
|
|
|
|
/** Ranges stored separately for fast (cache efficient) lookup. Each index has a corresponding entry in FMovieSceneEvaluationField::Groups. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneFrameRange> Ranges;
|
|
|
|
/** Groups that store segment pointers for each of the above ranges. Each index has a corresponding entry in FMovieSceneEvaluationField::Ranges. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationGroup> Groups;
|
|
|
|
/** Meta data that maps to entries in the 'Ranges' array. */
|
|
UPROPERTY()
|
|
TArray<FMovieSceneEvaluationMetaData> MetaData;
|
|
};
|