Files
UnrealEngineUWP/Engine/Source/Developer/AnimationDataController/Private/AnimDataController.cpp

2144 lines
78 KiB
C++
Raw Normal View History

Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
#include "AnimDataController.h"
#include "AnimDataControllerActions.h"
#include "MovieSceneTimeHelpers.h"
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
#include "Animation/AnimData/IAnimationDataModel.h"
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
#include "Animation/AnimData/CurveIdentifier.h"
#include "Animation/AnimSequence.h"
#include "Algo/Transform.h"
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
#include "Animation/AnimationSettings.h"
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
#include "UObject/NameTypes.h"
#include "Animation/AnimCurveTypes.h"
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
#include "Animation/AnimSequenceHelpers.h"
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
#include "Math/UnrealMathUtility.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(AnimDataController)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
#define LOCTEXT_NAMESPACE "AnimDataController"
#if WITH_EDITOR
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
void UAnimDataController::SetModel(TScriptInterface<IAnimationDataModel> InModel)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
if (Model != nullptr)
{
Model->GetModifiedEvent().RemoveAll(this);
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ModelInterface = InModel;
Model = CastChecked<UAnimDataModel>(InModel.GetObject(), ECastCheckedType::NullAllowed);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ChangeTransactor.SetTransactionObject(Model.Get());
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::OpenBracket(const FText& InTitle, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (UE::FChangeTransactor::CanTransactChanges() && !ChangeTransactor.IsTransactionPending())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
ChangeTransactor.OpenTransaction(InTitle);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FCloseBracketAction>(bShouldTransact, InTitle.ToString());
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
if (BracketDepth == 0)
{
FBracketPayload Payload;
Payload.Description = InTitle.ToString();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::BracketOpened, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
++BracketDepth;
}
void UAnimDataController::CloseBracket(bool bShouldTransact /*= true*/)
{
ValidateModel();
if (BracketDepth == 0)
{
Report(ELogVerbosity::Error, LOCTEXT("NoExistingBracketError", "Attempt to close bracket that was not previously opened"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return;
}
--BracketDepth;
if (BracketDepth == 0)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (UE::FChangeTransactor::CanTransactChanges())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
ensure(ChangeTransactor.IsTransactionPending());
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FOpenBracketAction>(bShouldTransact, TEXT("Open Bracket"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
ChangeTransactor.CloseTransaction();
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::BracketClosed);
}
}
void UAnimDataController::SetNumberOfFrames(FFrameNumber Length, bool bShouldTransact)
{
ValidateModel();
const FFrameNumber CurrentNumberOfFrames = Model->GetNumberOfFrames();
const int32 DeltaFrames = FMath::Abs(Length.Value - CurrentNumberOfFrames.Value);
const FFrameNumber T0 = Length > CurrentNumberOfFrames ? CurrentNumberOfFrames : CurrentNumberOfFrames - DeltaFrames;
const FFrameNumber T1 = Length > CurrentNumberOfFrames ? Length : CurrentNumberOfFrames;
ResizeNumberOfFrames(Length, T0, T1, bShouldTransact);
}
void UAnimDataController::ResizeNumberOfFrames(FFrameNumber NewLength, FFrameNumber T0, FFrameNumber T1, bool bShouldTransact)
{
ValidateModel();
const TRange<FFrameNumber> PlayRange(TRange<FFrameNumber>::BoundsType::Inclusive(0), TRange<FFrameNumber>::BoundsType::Exclusive(FMath::Max(1, Model->GetNumberOfKeys())));
if (NewLength >= 0)
{
if (NewLength != Model->GetNumberOfFrames())
{
// Ensure that T0 is within the current play range
if (PlayRange.Contains(T0))
{
// Ensure that the start and end length of either removal or insertion are valid
if (T0 < T1)
{
FTransaction Transaction = ConditionalTransaction(LOCTEXT("ResizePlayLength", "Resizing Play Length"), bShouldTransact);
const FFrameRate CurrentFrameRate = Model->GetFrameRate();
const FFrameNumber CurrentNumberOfFrames = Model->GetNumberOfFrames();
FSequenceLengthChangedPayload Payload;
PRAGMA_DISABLE_DEPRECATION_WARNINGS
Payload.T0 = static_cast<float>(CurrentFrameRate.AsSeconds(T0));
Payload.T1 = static_cast<float>(CurrentFrameRate.AsSeconds(T1));
Payload.PreviousLength = static_cast<float>(CurrentFrameRate.AsSeconds(CurrentNumberOfFrames));
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
PRAGMA_ENABLE_DEPRECATION_WARNINGS
Payload.PreviousNumberOfFrames = CurrentNumberOfFrames;
Payload.Frame0 = T0;
Payload.Frame1 = T1;
ConditionalAction<UE::Anim::FResizePlayLengthInFramesAction>(bShouldTransact, Model.Get(), Payload.Frame0, Payload.Frame1);
Model->NumberOfFrames = NewLength.Value;
Model->NumberOfKeys = Model->NumberOfFrames + 1;
Model->GetNotifier().Notify<FSequenceLengthChangedPayload>(EAnimDataModelNotifyType::SequenceLengthChanged, Payload);
}
else
{
ReportErrorf(LOCTEXT("InvalidEndTimeError", "Invalid T1, smaller that T0 value: T0 {0}, T1 {1}"), FText::AsNumber(T0.Value), FText::AsNumber(T0.Value));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidStartTimeError", "Invalid T0, not within existing play range: T0 {0}, Play Length {1}"), FText::AsNumber(T0.Value), FText::AsNumber(Model->GetPlayLength()));
}
}
else if (Model->bPopulated)
{
ReportWarningf(LOCTEXT("SamePlayLengthWarning", "New play length is same as existing one: {0} frames"), FText::AsNumber(NewLength.Value));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidPlayLengthError", "Invalid play length value provided: {0} frames"), FText::AsNumber(NewLength.Value));
}
}
void UAnimDataController::ResizeInFrames(FFrameNumber NewLength, FFrameNumber T0, FFrameNumber T1, bool bShouldTransact)
{
ValidateModel();
const int32 CurrentNumberOFrames = Model->GetNumberOfFrames();
const TRange<FFrameNumber> PlayRange(TRange<FFrameNumber>::BoundsType::Inclusive(0), TRange<FFrameNumber>::BoundsType::Exclusive(FMath::Max(1,Model->GetNumberOfKeys())));
if (NewLength >= 0)
{
if (NewLength != Model->GetNumberOfFrames())
{
// Ensure that T0 is within the current play range
if (PlayRange.Contains(T0))
{
// Ensure that the start and end length of either removal or insertion are valid
if (T0 < T1)
{
FBracket Bracket = ConditionalBracket(LOCTEXT("ResizeModel", "Resizing Animation Data"), bShouldTransact);
const bool bInserted = NewLength > CurrentNumberOFrames;
ResizeNumberOfFrames(NewLength, T0, T1, bShouldTransact);
const FFrameRate CurrentFrameRate = Model->GetFrameRate();
ResizeCurves(static_cast<float>(CurrentFrameRate.AsSeconds(NewLength)), bInserted, static_cast<float>(CurrentFrameRate.AsSeconds(T0)), static_cast<float>(CurrentFrameRate.AsSeconds(T1)), bShouldTransact);
ResizeAttributes(static_cast<float>(CurrentFrameRate.AsSeconds(NewLength)), bInserted, static_cast<float>(CurrentFrameRate.AsSeconds(T0)), static_cast<float>(CurrentFrameRate.AsSeconds(T1)), bShouldTransact);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
}
else
{
ReportErrorf(LOCTEXT("InvalidEndTimeError", "Invalid T1, smaller that T0 value: T0 {0}, T1 {1}"), FText::AsNumber(T0.Value), FText::AsNumber(T1.Value));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidStartTimeError", "Invalid T0, not within existing play range: T0 {0}, Play Length {1}"), FText::AsNumber(T0.Value), FText::AsNumber(CurrentNumberOFrames));
}
}
else if (Model->bPopulated)
{
ReportWarningf(LOCTEXT("SameGetPlayLengthWarning", "New play length is same as existing one: {0} frames"), FText::AsNumber(CurrentNumberOFrames));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidGetPlayLengthError", "Invalid play length value provided: {0} frames"), FText::AsNumber(CurrentNumberOFrames));
**New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Mike.Zyracki #jira UE-131296 #preflight 62a308a8b0150a87f9d6891b [CL 20593017 by Jurre deBaare in ue5-main branch]
2022-06-10 06:24:32 -04:00
}
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
void UAnimDataController::SetPlayLength(float Length, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
SetNumberOfFrames(ConvertSecondsToFrameNumber(Length), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::Resize(float Length, float T0, float T1, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ResizeInFrames(ConvertSecondsToFrameNumber(Length), ConvertSecondsToFrameNumber(T0), ConvertSecondsToFrameNumber(T1), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::SetFrameRate(FFrameRate FrameRate, bool bShouldTransact /*= true*/)
{
ValidateModel();
// Disallow invalid frame-rates, or 0.0 intervals
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const double FrameRateInterval = FrameRate.AsInterval();
if ( FrameRate.IsValid() && !FMath::IsNearlyZero(FrameRateInterval) && FrameRateInterval > 0.0)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
// Need to verify framerate
const FFrameRate CurrentFrameRate = Model->GetFrameRate();
if (FrameRate.IsMultipleOf(CurrentFrameRate) || FrameRate.IsFactorOf(CurrentFrameRate) || !Model->bPopulated)
{
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetFrameRate", "Setting Frame Rate"), bShouldTransact);
ConditionalAction<UE::Anim::FSetFrameRateAction>(bShouldTransact, Model.Get());
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const FFrameNumber CurrentNumberOfFrames = Model->GetNumberOfFrames();
const FFrameTime ConvertedLastFrameTime = FFrameRate::TransformTime(CurrentNumberOfFrames, CurrentFrameRate, FrameRate);
ensure(FMath::IsNearlyZero(ConvertedLastFrameTime.GetSubFrame()) || !Model->bPopulated);
**New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Mike.Zyracki #jira UE-131296 #preflight 62a308a8b0150a87f9d6891b [CL 20593017 by Jurre deBaare in ue5-main branch]
2022-06-10 06:24:32 -04:00
Model->FrameRate = FrameRate;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->NumberOfFrames = ConvertedLastFrameTime.GetFrame().Value;
**New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Mike.Zyracki #jira UE-131296 #preflight 62a308a8b0150a87f9d6891b [CL 20593017 by Jurre deBaare in ue5-main branch]
2022-06-10 06:24:32 -04:00
Model->NumberOfKeys = Model->NumberOfFrames + 1;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FFrameRateChangedPayload Payload;
Payload.PreviousFrameRate = CurrentFrameRate;
Model->GetNotifier().Notify(EAnimDataModelNotifyType::FrameRateChanged, Payload);
}
else
{
ReportErrorf(LOCTEXT("NonCompatibleFrameRateError", "Incompatible frame rate provided: {0} not a multiple or fact or {1}"), FrameRate.ToPrettyText(), CurrentFrameRate.ToPrettyText());
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
else
{
ReportErrorf(LOCTEXT("InvalidFrameRateError", "Invalid frame rate provided: {0}"), FrameRate.ToPrettyText());
}
}
void UAnimDataController::UpdateCurveNamesFromSkeleton(const USkeleton* Skeleton, ERawCurveTrackTypes SupportedCurveType, bool bShouldTransact /*= true*/)
{
ValidateModel();
if (Skeleton)
{
if (IsSupportedCurveType(SupportedCurveType))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("ValidateRawCurves", "Validating Animation Curve Names"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
switch (SupportedCurveType)
{
case ERawCurveTrackTypes::RCT_Float:
{
const FSmartNameMapping* NameMapping = Skeleton->GetSmartNameContainer(USkeleton::AnimCurveMappingName);
for (FFloatCurve& FloatCurve : Model->CurveData.FloatCurves)
{
FSmartName NewSmartName = FloatCurve.Name;
NameMapping->GetName(FloatCurve.Name.UID, NewSmartName.DisplayName);
if (NewSmartName != FloatCurve.Name)
{
const FAnimationCurveIdentifier CurrentId(FloatCurve.Name, SupportedCurveType);
const FAnimationCurveIdentifier NewId(NewSmartName, SupportedCurveType);
RenameCurve(CurrentId, NewId, bShouldTransact);
}
}
break;
}
case ERawCurveTrackTypes::RCT_Transform:
{
const FSmartNameMapping* NameMapping = Skeleton->GetSmartNameContainer(USkeleton::AnimTrackCurveMappingName);
for (FTransformCurve& TransformCurve : Model->CurveData.TransformCurves)
{
FSmartName NewSmartName = TransformCurve.Name;
NameMapping->GetName(TransformCurve.Name.UID, NewSmartName.DisplayName);
if (NewSmartName != TransformCurve.Name)
{
const FAnimationCurveIdentifier CurrentId(TransformCurve.Name, SupportedCurveType);
const FAnimationCurveIdentifier NewId(NewSmartName, SupportedCurveType);
RenameCurve(CurrentId, NewId, bShouldTransact);
}
}
break;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("UpdateCurveInvalidSkeletonError", "Invalid USkeleton supplied"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
void UAnimDataController::FindOrAddCurveNamesOnSkeleton(USkeleton* Skeleton, ERawCurveTrackTypes SupportedCurveType, bool bShouldTransact)
{
ValidateModel();
if (Skeleton)
{
if (IsSupportedCurveType(SupportedCurveType))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("FindOrAddRawCurveNames", "Updating Skeleton with Animation Curve Names"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
switch (SupportedCurveType)
{
case ERawCurveTrackTypes::RCT_Float:
{
for (FFloatCurve& FloatCurve : Model->CurveData.FloatCurves)
{
FSmartName NewSmartName = FloatCurve.Name;
Skeleton->VerifySmartName(USkeleton::AnimCurveMappingName, NewSmartName);
if (NewSmartName != FloatCurve.Name)
{
const FAnimationCurveIdentifier CurrentId(FloatCurve.Name, SupportedCurveType);
const FAnimationCurveIdentifier NewId(NewSmartName, SupportedCurveType);
RenameCurve(CurrentId, NewId, bShouldTransact);
}
}
break;
}
case ERawCurveTrackTypes::RCT_Transform:
{
for (FTransformCurve& TransformCurve : Model->CurveData.TransformCurves)
{
FSmartName NewSmartName = TransformCurve.Name;
Skeleton->VerifySmartName(USkeleton::AnimTrackCurveMappingName, NewSmartName);
if (NewSmartName != TransformCurve.Name)
{
const FAnimationCurveIdentifier CurrentId(TransformCurve.Name, SupportedCurveType);
const FAnimationCurveIdentifier NewId(NewSmartName, SupportedCurveType);
RenameCurve(CurrentId, NewId, bShouldTransact);
}
}
break;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("FindOrAddCurveInvalidSkeletonError", "Invalid USkeleton supplied "));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
bool UAnimDataController::RemoveBoneTracksMissingFromSkeleton(const USkeleton* Skeleton, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return false;
}
if (Skeleton)
{
TArray<FName> TracksToBeRemoved;
TArray<FName> TracksUpdated;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
const FReferenceSkeleton& ReferenceSkeleton = Skeleton->GetReferenceSkeleton();
for (FBoneAnimationTrack& Track : Model->BoneAnimationTracks)
{
// Try find correct bone index
const int32 BoneIndex = ReferenceSkeleton.FindBoneIndex(Track.Name);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (BoneIndex != INDEX_NONE && BoneIndex != Track.BoneTreeIndex)
{
// Update bone index
Track.BoneTreeIndex = BoneIndex;
TracksUpdated.Add(Track.Name);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
else if (BoneIndex == INDEX_NONE)
{
// Remove track
TracksToBeRemoved.Add(Track.Name);
Reportf(ELogVerbosity::Display, LOCTEXT("InvalidBoneIndexWarning", "Unable to find bone index, animation track will be removed: {0}"), FText::FromName(Track.Name));
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
if (TracksToBeRemoved.Num() || TracksUpdated.Num())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("RemoveBoneTracksMissingFromSkeleton", "Validating Bone Animation Track Data against Skeleton"), bShouldTransact);
for (const FName& TrackName : TracksToBeRemoved)
{
RemoveBoneTrack(TrackName);
}
for (const FName& TrackName : TracksUpdated)
{
FAnimationTrackChangedPayload Payload;
Payload.Name = TrackName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackChanged, Payload);
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
return TracksToBeRemoved.Num() > 0 || TracksUpdated.Num() > 0;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidSkeletonError", "Invalid USkeleton supplied"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
return false;
}
void UAnimDataController::UpdateAttributesFromSkeleton(const USkeleton* Skeleton, bool bShouldTransact)
{
ValidateModel();
if (Skeleton)
{
// Verifying that bone (names) for attribute data exist on new skeleton
TArray<FAnimationAttributeIdentifier> ToRemoveIdentifiers;
TArray<TPair<FAnimationAttributeIdentifier, int32>> ToDuplicateIdentifiers;
for (const FAnimatedBoneAttribute& Attribute : Model->AnimatedBoneAttributes)
{
const int32 NewBoneIndex = Skeleton->GetReferenceSkeleton().FindBoneIndex(Attribute.Identifier.GetBoneName());
if (NewBoneIndex == INDEX_NONE)
{
ToRemoveIdentifiers.Add(Attribute.Identifier);
}
else if(NewBoneIndex != Attribute.Identifier.GetBoneIndex())
{
ToDuplicateIdentifiers.Add(TPair<FAnimationAttributeIdentifier, int32>(Attribute.Identifier, NewBoneIndex));
}
}
if (ToRemoveIdentifiers.Num() || ToDuplicateIdentifiers.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("VerifyAttributeBoneNames", "Remapping Animation Attribute Data"), bShouldTransact);
for (const FAnimationAttributeIdentifier& Identifier : ToRemoveIdentifiers)
{
RemoveAttribute(Identifier);
}
for (const TPair<FAnimationAttributeIdentifier, int32>& Pair : ToDuplicateIdentifiers)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const FAnimationAttributeIdentifier& DuplicateIdentifier = Pair.Key;
FAnimationAttributeIdentifier NewIdentifier(DuplicateIdentifier.GetName(), Pair.Value, DuplicateIdentifier.GetBoneName(), DuplicateIdentifier.GetType());
DuplicateAttribute(Pair.Key, NewIdentifier);
RemoveAttribute(Pair.Key);
}
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidSkeletonError", "Invalid USkeleton supplied"));
}
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
void UAnimDataController::ResetModel(bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("ResetModel", "Clearing Animation Data"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (Model->GetOuter()->IsA<UAnimSequence>())
{
RemoveAllBoneTracks(bShouldTransact);
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
RemoveAllCurvesOfType(ERawCurveTrackTypes::RCT_Float, bShouldTransact);
RemoveAllCurvesOfType(ERawCurveTrackTypes::RCT_Transform, bShouldTransact);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
RemoveAllAttributes(bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
SetFrameRate(UAnimationSettings::Get()->GetDefaultFrameRate(), bShouldTransact);
SetNumberOfFrames(1, bShouldTransact);
Model->GetNotifier().Notify(EAnimDataModelNotifyType::Reset);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
bool UAnimDataController::AddCurve(const FAnimationCurveIdentifier& CurveId, int32 CurveFlags /*= EAnimAssetCurveFlags::AACF_Editable*/, bool bShouldTransact /*= true*/)
{
ValidateModel();
if (CurveId.InternalName.IsValid())
{
if (IsSupportedCurveType(CurveId.CurveType))
{
if (!Model->FindCurve(CurveId))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("AddRawCurve", "Adding Animation Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FCurveAddedPayload Payload;
Payload.Identifier = CurveId;
auto AddNewCurve = [CurveName = CurveId.InternalName, CurveFlags](auto& CurveTypeArray)
{
CurveTypeArray.Add({ CurveName, CurveFlags});
};
switch (CurveId.CurveType)
{
case ERawCurveTrackTypes::RCT_Transform:
AddNewCurve(Model->CurveData.TransformCurves);
break;
case ERawCurveTrackTypes::RCT_Float:
AddNewCurve(Model->CurveData.FloatCurves);
break;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(CurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRemoveCurveAction>(bShouldTransact, CurveId);
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveAdded, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("ExistingCurveNameWarning", "Curve with name {0} and type {1} ({2}) already exists"), FText::FromName(CurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(CurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(CurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
ReportWarningf(LOCTEXT("InvalidCurveIdentifierWarning", "Invalid curve identifier provided: name: {0}, UID: {1} type: {2}"), FText::FromName(CurveId.InternalName.DisplayName), FText::AsNumber(CurveId.InternalName.UID), FText::FromString(CurveTypeAsString));
}
return false;
}
bool UAnimDataController::DuplicateCurve(const FAnimationCurveIdentifier& CopyCurveId, const FAnimationCurveIdentifier& NewCurveId, bool bShouldTransact /*= true*/)
{
ValidateModel();
ERawCurveTrackTypes SupportedCurveType = CopyCurveId.CurveType;
if (CopyCurveId.InternalName.IsValid() && NewCurveId.InternalName.IsValid())
{
if (IsSupportedCurveType(SupportedCurveType))
{
if (CopyCurveId.CurveType == NewCurveId.CurveType)
{
if (Model->FindCurve(CopyCurveId))
{
if (!Model->FindCurve(NewCurveId))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("CopyRawCurve", "Duplicating Animation Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
auto DuplicateCurve = [NewCurveName = NewCurveId.InternalName](auto& CurveDataArray, const auto& SourceCurve)
{
auto& DuplicatedCurve = CurveDataArray.Add_GetRef( { NewCurveName, SourceCurve.GetCurveTypeFlags() });
DuplicatedCurve.CopyCurve(SourceCurve);
};
switch (SupportedCurveType)
{
case ERawCurveTrackTypes::RCT_Transform:
DuplicateCurve(Model->CurveData.TransformCurves, Model->GetTransformCurve(CopyCurveId));
break;
case ERawCurveTrackTypes::RCT_Float:
DuplicateCurve(Model->CurveData.FloatCurves, Model->GetFloatCurve(CopyCurveId));
break;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
FCurveAddedPayload Payload;
Payload.Identifier = NewCurveId;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveAdded, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRemoveCurveAction>(bShouldTransact, NewCurveId);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(NewCurveId.CurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("ExistingCurveNameWarning", "Curve with name {0} and type {1} ({2}) already exists"), FText::FromName(NewCurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(NewCurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CopyCurveId.CurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("CurveNameToDuplicateNotFoundWarning", "Could not find curve with name {0} and type {1} ({2}) for duplication"), FText::FromName(NewCurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(NewCurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
return false;
}
bool UAnimDataController::RemoveCurve(const FAnimationCurveIdentifier& CurveId, bool bShouldTransact /*= true*/)
{
ValidateModel();
ERawCurveTrackTypes SupportedCurveType = CurveId.CurveType;
if (CurveId.InternalName.IsValid())
{
if (IsSupportedCurveType(CurveId.CurveType))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (Model->FindCurve(CurveId) != nullptr)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RemoveCurve", "Removing Animation Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
switch (SupportedCurveType)
{
case ERawCurveTrackTypes::RCT_Transform:
{
const FTransformCurve& TransformCurve = Model->GetTransformCurve(CurveId);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddTransformCurveAction>(bShouldTransact, CurveId, TransformCurve.GetCurveTypeFlags(), TransformCurve);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Model->CurveData.TransformCurves.RemoveAll([Name = TransformCurve.Name](const FTransformCurve& ToRemoveCurve) { return ToRemoveCurve.Name == Name; });
break;
}
case ERawCurveTrackTypes::RCT_Float:
{
const FFloatCurve& FloatCurve = Model->GetFloatCurve(CurveId);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddFloatCurveAction>(bShouldTransact, CurveId, FloatCurve.GetCurveTypeFlags(), FloatCurve.FloatCurve.GetConstRefOfKeys(), FloatCurve.Color);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Model->CurveData.FloatCurves.RemoveAll([Name = FloatCurve.Name](const FFloatCurve& ToRemoveCurve) { return ToRemoveCurve.Name == Name; });
break;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
FCurveRemovedPayload Payload;
Payload.Identifier = CurveId;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveRemoved, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("UnableToFindCurveForRemovalWarning", "Unable to find curve: {0} of type {1}"), FText::FromName(CurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString));
}
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(CurveId.CurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
return false;
}
void UAnimDataController::RemoveAllCurvesOfType(ERawCurveTrackTypes SupportedCurveType /*= ERawCurveTrackTypes::RCT_Float*/, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("DeleteAllRawCurve", "Deleting All Animation Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
switch (SupportedCurveType)
{
case ERawCurveTrackTypes::RCT_Transform:
{
TArray<FTransformCurve> TransformCurves = Model->CurveData.TransformCurves;
for (const FTransformCurve& Curve : TransformCurves)
{
RemoveCurve(FAnimationCurveIdentifier(Curve.Name, ERawCurveTrackTypes::RCT_Transform), bShouldTransact);
}
break;
}
case ERawCurveTrackTypes::RCT_Float:
{
TArray<FFloatCurve> FloatCurves = Model->CurveData.FloatCurves;
for (const FFloatCurve& Curve : FloatCurves)
{
RemoveCurve(FAnimationCurveIdentifier(Curve.Name, ERawCurveTrackTypes::RCT_Float), bShouldTransact);
}
break;
}
case ERawCurveTrackTypes::RCT_Vector:
default:
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
bool UAnimDataController::SetCurveFlag(const FAnimationCurveIdentifier& CurveId, EAnimAssetCurveFlags Flag, bool bState /*= true*/, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ERawCurveTrackTypes SupportedCurveType = CurveId.CurveType;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FAnimCurveBase* Curve = nullptr;
if (SupportedCurveType == ERawCurveTrackTypes::RCT_Float)
{
Curve = Model->FindMutableFloatCurveById(CurveId);
}
else if (SupportedCurveType == ERawCurveTrackTypes::RCT_Transform)
{
Curve = Model->FindMutableTransformCurveById(CurveId);
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (Curve)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetCurveFlag", "Setting Raw Curve Flag"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
const int32 CurrentFlags = Curve->GetCurveTypeFlags();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetCurveFlagsAction>(bShouldTransact, CurveId, CurrentFlags, SupportedCurveType);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FCurveFlagsChangedPayload Payload;
Payload.Identifier = CurveId;
Payload.OldFlags = Curve->GetCurveTypeFlags();
Curve->SetCurveTypeFlag(Flag, bState);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveFlagsChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("UnableToFindCurveWarning", "Unable to find curve: {0} of type {1}"), FText::FromName(CurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString));
}
return false;
}
bool UAnimDataController::SetCurveFlags(const FAnimationCurveIdentifier& CurveId, int32 Flags, bool bShouldTransact /*= true*/)
{
ValidateModel();
FAnimCurveBase* Curve = nullptr;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ERawCurveTrackTypes SupportedCurveType = CurveId.CurveType;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (SupportedCurveType == ERawCurveTrackTypes::RCT_Float)
{
Curve = Model->FindMutableFloatCurveById(CurveId);
}
else if (SupportedCurveType == ERawCurveTrackTypes::RCT_Transform)
{
Curve = Model->FindMutableTransformCurveById(CurveId);
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("InvalidCurveTypeWarning", "Invalid curve type provided: {0} ({1})"), FText::FromString(CurveTypeAsString), FText::AsNumber(static_cast<int32>(SupportedCurveType)));
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (Curve)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetRawCurveFlag", "Setting Raw Curve Flags"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
const int32 CurrentFlags = Curve->GetCurveTypeFlags();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetCurveFlagsAction>(bShouldTransact, CurveId, CurrentFlags, SupportedCurveType);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FCurveFlagsChangedPayload Payload;
Payload.Identifier = CurveId;
Payload.OldFlags = Curve->GetCurveTypeFlags();
Curve->SetCurveTypeFlags(Flags);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveFlagsChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(SupportedCurveType);
ReportWarningf(LOCTEXT("UnableToFindCurveForRemovalWarning", "Unable to find curve: {0} of type {1}"), FText::FromName(CurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString));
}
return false;
}
bool UAnimDataController::SetTransformCurveKeys(const FAnimationCurveIdentifier& CurveId, const TArray<FTransform>& TransformValues, const TArray<float>& TimeKeys, bool bShouldTransact /*= true*/)
{
ValidateModel();
if (TransformValues.Num() == TimeKeys.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (Model->FindMutableTransformCurveById(CurveId) != nullptr)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("SetTransformCurveKeys_Bracket", "Setting Transform Curve Keys"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
struct FKeys
{
FKeys(int32 NumKeys)
{
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
ChannelKeys[ChannelIndex].SetNum(NumKeys);
}
}
TArray<FRichCurveKey> ChannelKeys[3];
};
FKeys TranslationKeys(TransformValues.Num());
FKeys RotationKeys(TransformValues.Num());
FKeys ScaleKeys(TransformValues.Num());
FKeys* SubCurveKeys[3] = { &TranslationKeys, &RotationKeys, &ScaleKeys };
// Generate the curve keys
for (int32 KeyIndex = 0; KeyIndex < TransformValues.Num(); ++KeyIndex)
{
const FTransform& Value = TransformValues[KeyIndex];
const float& Time = TimeKeys[KeyIndex];
const FVector Translation = Value.GetLocation();
const FVector Rotation = Value.GetRotation().Euler();
const FVector Scale = Value.GetScale3D();
auto SetKey = [Time, KeyIndex](FKeys& Key, const FVector& Vector)
{
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Key.ChannelKeys[ChannelIndex][KeyIndex] = FRichCurveKey(Time, static_cast<float>(Vector[ChannelIndex]));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
};
SetKey(TranslationKeys, Translation);
SetKey(RotationKeys, Rotation);
SetKey(ScaleKeys, Scale);
}
for (int32 SubCurveIndex = 0; SubCurveIndex < 3; ++SubCurveIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ETransformCurveChannel Channel = static_cast<ETransformCurveChannel>(SubCurveIndex);
const FKeys* CurveKeys = SubCurveKeys[SubCurveIndex];
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const EVectorCurveChannel Axis = static_cast<EVectorCurveChannel>(ChannelIndex);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FAnimationCurveIdentifier TargetCurveIdentifier = CurveId;
UAnimationCurveIdentifierExtensions::GetTransformChildCurveIdentifier(TargetCurveIdentifier, Channel, Axis);
SetCurveKeys(TargetCurveIdentifier, CurveKeys->ChannelKeys[ChannelIndex], bShouldTransact);
}
}
return true;
}
else
{
ReportWarningf(LOCTEXT("UnableToFindTransformCurveWarning", "Unable to find transform curve: {0}"), FText::FromName(CurveId.InternalName.DisplayName));
}
}
else
{
// time value mismatch
ReportWarningf(LOCTEXT("InvalidNumberOfTimeAndKeyEntriesWarning", "Number of times and key entries do not match: number of time values {0}, number of key values {1}"), FText::AsNumber(TimeKeys.Num()), FText::AsNumber(TransformValues.Num()));
}
return false;
}
bool UAnimDataController::SetTransformCurveKey(const FAnimationCurveIdentifier& CurveId, float Time, const FTransform& Value, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (Model->FindMutableTransformCurveById(CurveId) != nullptr)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("AddTransformCurveKey_Bracket", "Setting Transform Curve Key"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
struct FKeys
{
FRichCurveKey ChannelKeys[3];
};
FKeys VectorKeys[3];
// Generate the rich curve keys
const FVector Translation = Value.GetLocation();
const FVector Rotation = Value.GetRotation().Euler();
const FVector Scale = Value.GetScale3D();
auto SetKey = [Time](FKeys& Key, const FVector& Vector)
{
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Key.ChannelKeys[ChannelIndex] = FRichCurveKey(Time, static_cast<float>(Vector[ChannelIndex]));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
};
SetKey(VectorKeys[0], Translation);
SetKey(VectorKeys[1], Rotation);
SetKey(VectorKeys[2], Scale);
for (int32 SubCurveIndex = 0; SubCurveIndex < 3; ++SubCurveIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ETransformCurveChannel Channel = static_cast<ETransformCurveChannel>(SubCurveIndex);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
const FKeys& VectorCurveKeys = VectorKeys[SubCurveIndex];
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const EVectorCurveChannel Axis = static_cast<EVectorCurveChannel>(ChannelIndex);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FAnimationCurveIdentifier TargetCurveIdentifier = CurveId;
UAnimationCurveIdentifierExtensions::GetTransformChildCurveIdentifier(TargetCurveIdentifier, Channel, Axis);
SetCurveKey(TargetCurveIdentifier, VectorCurveKeys.ChannelKeys[ChannelIndex], bShouldTransact);
}
}
return true;
}
else
{
ReportWarningf(LOCTEXT("UnableToFindTransformCurveWarning", "Unable to find transform curve: {0}"), FText::FromName(CurveId.InternalName.DisplayName));
}
return false;
}
bool UAnimDataController::RemoveTransformCurveKey(const FAnimationCurveIdentifier& CurveId, float Time, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (Model->FindMutableTransformCurveById(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
const FString BaseCurveName = CurveId.InternalName.DisplayName.ToString();
const TArray<FString> SubCurveNames = { TEXT( "Translation"), TEXT( "Rotation"), TEXT( "Scale") };
const TArray<FString> ChannelCurveNames = { TEXT("X"), TEXT("Y"), TEXT("Z") };
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("RemoveTransformCurveKey_Bracket", "Deleting Animation Transform Curve Key"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
for (int32 SubCurveIndex = 0; SubCurveIndex < 3; ++SubCurveIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ETransformCurveChannel Channel = static_cast<ETransformCurveChannel>(SubCurveIndex);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const EVectorCurveChannel Axis = static_cast<EVectorCurveChannel>(ChannelIndex);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FAnimationCurveIdentifier TargetCurveIdentifier = CurveId;
UAnimationCurveIdentifierExtensions::GetTransformChildCurveIdentifier(TargetCurveIdentifier, Channel, Axis);
RemoveCurveKey(TargetCurveIdentifier, Time, bShouldTransact);
}
}
return true;
}
else
{
ReportWarningf(LOCTEXT("UnableToFindTransformCurveWarning", "Unable to find transform curve: {0}"), FText::FromName(CurveId.InternalName.DisplayName));
}
return false;
}
bool UAnimDataController::RenameCurve(const FAnimationCurveIdentifier& CurveToRenameId, const FAnimationCurveIdentifier& NewCurveId, bool bShouldTransact /*= true*/)
{
ValidateModel();
if (NewCurveId.IsValid())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
if (CurveToRenameId != NewCurveId)
{
if (CurveToRenameId.CurveType == NewCurveId.CurveType)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FAnimCurveBase* Curve = Model->FindMutableCurveById(CurveToRenameId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RenameCurve", "Renaming Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FCurveRenamedPayload Payload;
Payload.Identifier = FAnimationCurveIdentifier(Curve->Name, CurveToRenameId.CurveType);
Curve->Name = NewCurveId.InternalName;
Payload.NewIdentifier = NewCurveId;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRenameCurveAction>(bShouldTransact, NewCurveId, CurveToRenameId);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveRenamed, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveToRenameId.CurveType);
ReportWarningf(LOCTEXT("UnableToFindCurveWarning", "Unable to find curve: {0} of type {1}"), FText::FromName(CurveToRenameId.InternalName.DisplayName), FText::FromString(CurveTypeAsString));
}
}
else
{
const FString CurrentCurveTypeAsString = GetCurveTypeValueName(CurveToRenameId.CurveType);
const FString NewCurveTypeAsString = GetCurveTypeValueName(NewCurveId.CurveType);
ReportWarningf(LOCTEXT("MismatchOfCurveTypesWarning", "Different curve types provided between current and new curve names: {0} ({1}) and {2} ({3})"), FText::FromName(CurveToRenameId.InternalName.DisplayName), FText::FromString(CurrentCurveTypeAsString),
FText::FromName(NewCurveId.InternalName.DisplayName), FText::FromString(NewCurveTypeAsString));
}
}
else
{
ReportWarningf(LOCTEXT("MatchingCurveNamesWarning", "Provided curve names are the same: {0}"), FText::FromName(CurveToRenameId.InternalName.DisplayName));
}
}
else
{
ReportWarningf(LOCTEXT("InvalidCurveIdentiferProvidedWarning", "Invalid new curve identifier provided: {2} ({3})"), FText::FromName(NewCurveId.InternalName.DisplayName), FText::AsNumber(NewCurveId.InternalName.UID));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
return false;
}
bool UAnimDataController::SetCurveColor(const FAnimationCurveIdentifier& CurveId, FLinearColor Color, bool bShouldTransact)
{
ValidateModel();
if (CurveId.IsValid())
{
if (CurveId.CurveType == ERawCurveTrackTypes::RCT_Float)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FFloatCurve* Curve = Model->FindMutableFloatCurveById(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("ChangingCurveColor", "Changing Curve Color"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetCurveColorAction>(bShouldTransact, CurveId, Curve->Color);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Curve->Color = Color;
FCurveChangedPayload Payload;
Payload.Identifier = CurveId;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveColorChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
const FString CurveTypeAsString = GetCurveTypeValueName(CurveId.CurveType);
ReportWarningf(LOCTEXT("UnableToFindCurveWarning", "Unable to find curve: {0} of type {1}"), FText::FromName(CurveId.InternalName.DisplayName), FText::FromString(CurveTypeAsString));
}
}
else
{
Report(ELogVerbosity::Warning, LOCTEXT("NonSupportedCurveColorSetWarning", "Changing curve color is currently only supported for float curves"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
ReportWarningf(LOCTEXT("InvalidCurveIdentifier", "Invalid Curve Identifier : {0} ({1})"), FText::FromName(CurveId.InternalName.DisplayName), FText::AsNumber(CurveId.InternalName.UID));
}
return false;
}
bool UAnimDataController::ScaleCurve(const FAnimationCurveIdentifier& CurveId, float Origin, float Factor, bool bShouldTransact /*= true*/)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ERawCurveTrackTypes SupportedCurveType = CurveId.CurveType;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (SupportedCurveType == ERawCurveTrackTypes::RCT_Float)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FFloatCurve* Curve = Model->FindMutableFloatCurveById(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("ScalingCurve", "Scaling Curve"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Curve->FloatCurve.ScaleCurve(Origin, Factor);
FCurveScaledPayload Payload;
Payload.Identifier = CurveId;
Payload.Factor = Factor;
Payload.Origin = Origin;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FScaleCurveAction>(bShouldTransact, CurveId, Origin, 1.0f / Factor, SupportedCurveType);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveScaled, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
ReportWarningf(LOCTEXT("UnableToFindFloatCurveWarning", "Unable to find float curve: {0}"), FText::FromName(CurveId.InternalName.DisplayName));
}
}
else
{
Report(ELogVerbosity::Warning, LOCTEXT("NonSupportedCurveScalingWarning", "Scaling curves is currently only supported for float curves"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
return false;
}
bool UAnimDataController::SetCurveKey(const FAnimationCurveIdentifier& CurveId, const FRichCurveKey& Key, bool bShouldTransact)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FRichCurve* RichCurve = Model->GetMutableRichCurve(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
FCurveChangedPayload Payload;
Payload.Identifier = CurveId;
// Set or add rich curve value
const FKeyHandle Handle = RichCurve->FindKey(Key.Time, 0.f);
if (Handle != FKeyHandle::Invalid())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetNamedCurveKey", "Setting Curve Key"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Cache old value for action
const FRichCurveKey CurrentKey = RichCurve->GetKey(Handle);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetRichCurveKeyAction>(bShouldTransact, CurveId, CurrentKey);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Set the new value
RichCurve->SetKeyValue(Handle, Key.Value);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
else
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("AddNamedCurveKey", "Adding Curve Key"), bShouldTransact);
ConditionalAction<UE::Anim::FRemoveRichCurveKeyAction>(bShouldTransact, CurveId, Key.Time);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Add the new key
RichCurve->AddKey(Key.Time, Key.Value);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
return true;
}
return false;
}
bool UAnimDataController::RemoveCurveKey(const FAnimationCurveIdentifier& CurveId, float Time, bool bShouldTransact)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FRichCurve* RichCurve = Model->GetMutableRichCurve(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
FCurveChangedPayload Payload;
Payload.Identifier = CurveId;
// Remove key at time value
const FKeyHandle Handle = RichCurve->FindKey(Time, 0.f);
if (Handle != FKeyHandle::Invalid())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RemoveNamedCurveKey", "Removing Curve Key"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Cached current value for action
const FRichCurveKey CurrentKey = RichCurve->GetKey(Handle);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddRichCurveKeyAction>(bShouldTransact, CurveId, CurrentKey);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
RichCurve->DeleteKey(Handle);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
ReportErrorf(LOCTEXT("RichCurveKeyNotFoundError", "Unable to find rich curve key: curve name {0}, time {1}"), FText::FromName(CurveId.InternalName.DisplayName), FText::AsNumber(Time));
}
}
return false;
}
bool UAnimDataController::SetCurveKeys(const FAnimationCurveIdentifier& CurveId, const TArray<FRichCurveKey>& CurveKeys, bool bShouldTransact)
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (FRichCurve* RichCurve = Model->GetMutableRichCurve(CurveId))
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SettingNamedCurveKeys", "Setting Curve Keys"), bShouldTransact);
ConditionalAction<UE::Anim::FSetRichCurveKeysAction>(bShouldTransact, CurveId, RichCurve->GetConstRefOfKeys());
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Set rich curve values
RichCurve->SetKeys(CurveKeys);
FCurveChangedPayload Payload;
Payload.Identifier = CurveId;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
return false;
}
bool UAnimDataController::SetCurveAttributes(const FAnimationCurveIdentifier& CurveId, const FCurveAttributes& Attributes, bool bShouldTransact)
{
ValidateModel();
FRichCurve* RichCurve = Model->GetMutableRichCurve(CurveId);
if (RichCurve)
{
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SettingNamedCurveAttributes", "Setting Curve Attributes"), bShouldTransact);
FCurveAttributes CurrentAttributes;
CurrentAttributes.SetPreExtrapolation(RichCurve->PreInfinityExtrap);
CurrentAttributes.SetPostExtrapolation(RichCurve->PostInfinityExtrap);
ConditionalAction<UE::Anim::FSetRichCurveAttributesAction>(bShouldTransact, CurveId, CurrentAttributes);
if(Attributes.HasPreExtrapolation())
{
RichCurve->PreInfinityExtrap = Attributes.GetPreExtrapolation();
}
if(Attributes.HasPostExtrapolation())
{
RichCurve->PostInfinityExtrap = Attributes.GetPostExtrapolation();
}
FCurveChangedPayload Payload;
Payload.Identifier = CurveId;
Model->GetNotifier().Notify(EAnimDataModelNotifyType::CurveChanged, Payload);
return true;
}
return false;
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
void UAnimDataController::NotifyPopulated()
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->bPopulated = true;
Model->GetNotifier().Notify(EAnimDataModelNotifyType::Populated);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::NotifyBracketOpen()
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::BracketOpened);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::NotifyBracketClosed()
{
ValidateModel();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::BracketClosed);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
void UAnimDataController::ResizePlayLength(float Length, float T0, float T1, bool bShouldTransact)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ResizeNumberOfFrames(ConvertSecondsToFrameNumber(Length), ConvertSecondsToFrameNumber(T0), ConvertSecondsToFrameNumber(T1), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
int32 UAnimDataController::AddBoneTrack(FName BoneName, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return INDEX_NONE;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("AddBoneTrack", "Adding Animation Data Track"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return InsertBoneTrack(BoneName, INDEX_NONE, bShouldTransact);
}
int32 UAnimDataController::InsertBoneTrack(FName BoneName, int32 DesiredIndex, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return INDEX_NONE;
}
const int32 TrackIndex = Model->GetBoneTrackIndexByName(BoneName);
if (TrackIndex == INDEX_NONE)
{
if (Model->GetNumBoneTracks() >= MAX_ANIMATION_TRACKS)
{
ReportWarningf(LOCTEXT("MaxNumberOfTracksReachedWarning", "Cannot add track with name {0}. An animation sequence cannot contain more than 65535 tracks"), FText::FromName(BoneName));
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
return INDEX_NONE;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
else
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("InsertBoneTrack", "Inserting Animation Data Track"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
// Determine correct index to do insertion at
const int32 InsertIndex = Model->BoneAnimationTracks.IsValidIndex(DesiredIndex) ? DesiredIndex : Model->BoneAnimationTracks.Num();
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
int32 BoneIndex = INDEX_NONE;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (const UAnimSequence* AnimationSequence = Model->GetAnimationSequence())
{
if (const USkeleton* Skeleton = AnimationSequence->GetSkeleton())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
BoneIndex = Skeleton->GetReferenceSkeleton().FindBoneIndex(BoneName);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
if (BoneIndex == INDEX_NONE)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ReportErrorf(LOCTEXT("UnableToFindBoneIndexWarning", "Unable to retrieve bone index for track: {0}"), FText::FromName(BoneName));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("UnableToGetOuterSkeletonError", "Unable to retrieve Skeleton for outer Animation Sequence"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("UnableToGetOuterAnimSequenceError", "Unable to retrieve outer Animation Sequence"));
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (BoneIndex != INDEX_NONE)
{
FBoneAnimationTrack& NewTrack = Model->BoneAnimationTracks.InsertDefaulted_GetRef(InsertIndex);
NewTrack.Name = BoneName;
NewTrack.BoneTreeIndex = BoneIndex;
**New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Mike.Zyracki #jira UE-131296 #preflight 62a308a8b0150a87f9d6891b [CL 20593017 by Jurre deBaare in ue5-main branch]
2022-06-10 06:24:32 -04:00
FAnimationTrackAddedPayload Payload;
Payload.Name = BoneName;
Payload.TrackIndex = InsertIndex;
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify<FAnimationTrackAddedPayload>(EAnimDataModelNotifyType::TrackAdded, Payload);
ConditionalAction<UE::Anim::FRemoveTrackAction>(bShouldTransact, BoneName);
**New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Mike.Zyracki #jira UE-131296 #preflight 62a308a8b0150a87f9d6891b [CL 20593017 by Jurre deBaare in ue5-main branch]
2022-06-10 06:24:32 -04:00
return InsertIndex;
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
else
{
ReportWarningf(LOCTEXT("TrackNameAlreadyExistsWarning", "Track with name {0} already exists"), FText::FromName(BoneName));
}
return TrackIndex;
}
bool UAnimDataController::RemoveBoneTrack(FName BoneName, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return false;
}
const FBoneAnimationTrack* ExistingTrackPtr = Model->FindBoneTrackByName(BoneName);
if (ExistingTrackPtr != nullptr)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RemoveBoneTrack", "Removing Animation Data Track"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
const int32 TrackIndex = Model->BoneAnimationTracks.IndexOfByPredicate([ExistingTrackPtr](const FBoneAnimationTrack& Track)
{
return Track.Name == ExistingTrackPtr->Name;
});
ensure(TrackIndex != INDEX_NONE);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddTrackAction>(bShouldTransact,*ExistingTrackPtr);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Model->BoneAnimationTracks.RemoveAt(TrackIndex);
FAnimationTrackRemovedPayload Payload;
Payload.Name = BoneName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackRemoved, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
ReportWarningf(LOCTEXT("UnableToFindTrackWarning", "Could not find track with name {0}"), FText::FromName(BoneName));
}
return false;
}
void UAnimDataController::RemoveAllBoneTracks(bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return;
}
TArray<FName> TrackNames;
Model->GetBoneTrackNames(TrackNames);
if (TrackNames.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("RemoveAllBoneTracks", "Removing all Animation Data Tracks"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
for (const FName& TrackName : TrackNames)
{
RemoveBoneTrack(TrackName, bShouldTransact);
}
}
}
bool UAnimDataController::SetBoneTrackKeys(FName BoneName, const TArray<FVector>& PositionalKeys, const TArray<FQuat>& RotationalKeys, const TArray<FVector>& ScalingKeys, bool bShouldTransact /*= true*/)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
if (!ModelInterface->GetAnimationSequence())
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
return false;
}
// Validate key format
const int32 MaxNumKeys = FMath::Max(FMath::Max(PositionalKeys.Num(), RotationalKeys.Num()), ScalingKeys.Num());
if (MaxNumKeys > 0)
{
const bool bValidPosKeys = PositionalKeys.Num() == MaxNumKeys;
const bool bValidRotKeys = RotationalKeys.Num() == MaxNumKeys;
const bool bValidScaleKeys = ScalingKeys.Num() == MaxNumKeys;
if (bValidPosKeys && bValidRotKeys && bValidScaleKeys)
{
if (FBoneAnimationTrack* TrackPtr = Model->FindMutableBoneTrackByName(BoneName))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetTrackKeysTransaction", "Setting Animation Data Track keys"), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetTrackKeysAction>(bShouldTransact, *TrackPtr);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
TrackPtr->InternalTrackData.PosKeys.SetNum(MaxNumKeys);
TrackPtr->InternalTrackData.ScaleKeys.SetNum(MaxNumKeys);
TrackPtr->InternalTrackData.RotKeys.SetNum(MaxNumKeys);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
for(int32 KeyIndex = 0; KeyIndex<MaxNumKeys; KeyIndex++)
{
TrackPtr->InternalTrackData.PosKeys[KeyIndex] = FVector3f(PositionalKeys[KeyIndex]);
TrackPtr->InternalTrackData.ScaleKeys[KeyIndex] = FVector3f(ScalingKeys[KeyIndex]);
TrackPtr->InternalTrackData.RotKeys[KeyIndex] = FQuat4f(RotationalKeys[KeyIndex]);
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
FAnimationTrackChangedPayload Payload;
Payload.Name = BoneName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackChanged, Payload);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
return true;
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackNameWarning", "Track with name {0} does not exist"), FText::FromName(BoneName));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidTrackKeyDataError", "Invalid track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
}
else
{
ReportErrorf(LOCTEXT("MissingTrackKeyDataError", "Missing track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
return false;
}
bool UAnimDataController::SetBoneTrackKeys(FName BoneName, const TArray<FVector3f>& PositionalKeys, const TArray<FQuat4f>& RotationalKeys, const TArray<FVector3f>& ScalingKeys, bool bShouldTransact /*= true*/)
{
if (!CheckOuterClass(UAnimSequence::StaticClass()))
{
return false;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetTrackKeysTransaction", "Setting Animation Data Track keys"), bShouldTransact);
// Validate key format
const int32 MaxNumKeys = FMath::Max(FMath::Max(PositionalKeys.Num(), RotationalKeys.Num()), ScalingKeys.Num());
if (MaxNumKeys > 0)
{
const bool bValidPosKeys = PositionalKeys.Num() == MaxNumKeys;
const bool bValidRotKeys = RotationalKeys.Num() == MaxNumKeys;
const bool bValidScaleKeys = ScalingKeys.Num() == MaxNumKeys;
if (bValidPosKeys && bValidRotKeys && bValidScaleKeys)
{
if (FBoneAnimationTrack* TrackPtr = Model->FindMutableBoneTrackByName(BoneName))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetTrackKeysAction>(bShouldTransact, *TrackPtr);
TrackPtr->InternalTrackData.PosKeys = PositionalKeys;
TrackPtr->InternalTrackData.RotKeys = RotationalKeys;
TrackPtr->InternalTrackData.ScaleKeys = ScalingKeys;
FAnimationTrackChangedPayload Payload;
Payload.Name = BoneName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackChanged, Payload);
return true;
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackNameWarning", "Track with name {0} does not exist"), FText::FromName(BoneName));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidTrackKeyDataError", "Invalid track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
}
else
{
ReportErrorf(LOCTEXT("MissingTrackKeyDataError", "Missing track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
return false;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
static int32 DiscreteInclusiveLower(const TRange<int32>& InRange)
{
check(!InRange.GetLowerBound().IsOpen());
// Add one for exclusive lower bounds since they start on the next subsequent frame
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
static constexpr int32 Offsets[] = { 0, 1 };
const int32 OffsetIndex = (int32)InRange.GetLowerBound().IsExclusive();
return InRange.GetLowerBound().GetValue() + Offsets[OffsetIndex];
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
static int32 DiscreteExclusiveUpper(const TRange<int32>& InRange)
{
check(!InRange.GetUpperBound().IsOpen());
// Add one for inclusive upper bounds since they finish on the next subsequent frame
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
static constexpr int32 Offsets[] = { 0, 1 };
const int32 OffsetIndex = (int32)InRange.GetUpperBound().IsInclusive();
return InRange.GetUpperBound().GetValue() + Offsets[OffsetIndex];
}
bool UAnimDataController::UpdateBoneTrackKeys(FName BoneName, const FInt32Range& KeyRangeToSet, const TArray<FVector3f>& PositionalKeys, const TArray<FQuat4f>& RotationalKeys, const TArray<FVector3f>& ScalingKeys, bool bShouldTransact)
{
if (!CheckOuterClass(UAnimSequence::StaticClass()))
{
return false;
}
// Validate key format
const int32 MaxNumKeys = FMath::Max(FMath::Max(PositionalKeys.Num(), RotationalKeys.Num()), ScalingKeys.Num());
const int32 RangeMin = DiscreteInclusiveLower(KeyRangeToSet);
const int32 RangeMax = DiscreteExclusiveUpper(KeyRangeToSet);
if (MaxNumKeys > 0)
{
const bool bValidPosKeys = PositionalKeys.Num() == MaxNumKeys;
const bool bValidRotKeys = RotationalKeys.Num() == MaxNumKeys;
const bool bValidScaleKeys = ScalingKeys.Num() == MaxNumKeys;
if (bValidPosKeys && bValidRotKeys && bValidScaleKeys)
{
const int32 NumKeysToSet = RangeMax - RangeMin;
if (NumKeysToSet == MaxNumKeys)
{
if (FBoneAnimationTrack* TrackPtr = Model->FindMutableBoneTrackByName(BoneName))
{
const FInt32Range TrackKeyRange(0, TrackPtr->InternalTrackData.PosKeys.Num());
if(TrackKeyRange.Contains(KeyRangeToSet))
{
FRawAnimSequenceTrack& InternalTrackData = TrackPtr->InternalTrackData;
TArray<FVector3f>& TrackPosKeys = InternalTrackData.PosKeys;
TArray<FQuat4f>& TrackRotKeys = InternalTrackData.RotKeys;
TArray<FVector3f>& TrackScaleKeys = InternalTrackData.ScaleKeys;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetTrackKeysRangeTransaction", "Setting Animation Data Track keys"), bShouldTransact);
ConditionalAction<UE::Anim::FSetTrackKeysAction>(bShouldTransact, *TrackPtr);
int32 KeyIndex = 0;
for (int32 FrameIndex = RangeMin; FrameIndex < RangeMax; ++FrameIndex, ++KeyIndex)
{
TrackPosKeys[FrameIndex] = PositionalKeys[KeyIndex];
TrackRotKeys[FrameIndex] = RotationalKeys[KeyIndex];
TrackScaleKeys[FrameIndex] = ScalingKeys[KeyIndex];
}
FAnimationTrackChangedPayload Payload;
Payload.Name = BoneName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackChanged, Payload);
return true;
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackSetFrameRange", "Range of to-be-set bone track (with name {0}) keys does not overlap existing range"), FText::FromName(BoneName));
}
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackNameWarning", "Track with name {0} does not exist"), FText::FromName(BoneName));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidKeyIndexRangeError",
"Invalid key index range bound [{0}, {1}], expected to equal the size of the positional, rotational and scaling keys {2}"),
FText::AsNumber(RangeMin),
FText::AsNumber(RangeMax),
FText::AsNumber(MaxNumKeys));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidTrackKeyDataError", "Invalid track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
}
else
{
ReportErrorf(LOCTEXT("MissingTrackKeyDataError", "Missing track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
return false;
}
bool UAnimDataController::UpdateBoneTrackKeys(FName BoneName, const FInt32Range& KeyRangeToSet, const TArray<FVector>& PositionalKeys, const TArray<FQuat>& RotationalKeys, const TArray<FVector>& ScalingKeys, bool bShouldTransact)
{
if (!CheckOuterClass(UAnimSequence::StaticClass()))
{
return false;
}
// Validate key format
const int32 MaxNumKeys = FMath::Max(FMath::Max(PositionalKeys.Num(), RotationalKeys.Num()), ScalingKeys.Num());
const int32 RangeMin = DiscreteInclusiveLower(KeyRangeToSet);
const int32 RangeMax = DiscreteExclusiveUpper(KeyRangeToSet);
if (MaxNumKeys > 0)
{
const bool bValidPosKeys = PositionalKeys.Num() == MaxNumKeys;
const bool bValidRotKeys = RotationalKeys.Num() == MaxNumKeys;
const bool bValidScaleKeys = ScalingKeys.Num() == MaxNumKeys;
if (bValidPosKeys && bValidRotKeys && bValidScaleKeys)
{
const int32 NumKeysToSet = RangeMax - RangeMin;
if (NumKeysToSet == MaxNumKeys)
{
if (FBoneAnimationTrack* TrackPtr = Model->FindMutableBoneTrackByName(BoneName))
{
const FInt32Range TrackKeyRange(0, TrackPtr->InternalTrackData.PosKeys.Num());
if(TrackKeyRange.Contains(KeyRangeToSet))
{
FRawAnimSequenceTrack& InternalTrackData = TrackPtr->InternalTrackData;
TArray<FVector3f>& TrackPosKeys = InternalTrackData.PosKeys;
TArray<FQuat4f>& TrackRotKeys = InternalTrackData.RotKeys;
TArray<FVector3f>& TrackScaleKeys = InternalTrackData.ScaleKeys;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SetTrackKeysTransaction", "Setting Animation Data Track keys"), bShouldTransact);
ConditionalAction<UE::Anim::FSetTrackKeysAction>(bShouldTransact, *TrackPtr);
int32 KeyIndex = 0;
for (int32 FrameIndex = RangeMin; FrameIndex < RangeMax; ++FrameIndex, ++KeyIndex)
{
TrackPosKeys[FrameIndex] = FVector3f(PositionalKeys[KeyIndex]);
TrackRotKeys[FrameIndex] = FQuat4f(RotationalKeys[KeyIndex]);
TrackScaleKeys[FrameIndex] = FVector3f(ScalingKeys[KeyIndex]);
}
FAnimationTrackChangedPayload Payload;
Payload.Name = BoneName;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::TrackChanged, Payload);
return true;
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackSetFrameRange", "Range of to-be-set bone track (with name {0}) keys does not overlap existing range"), FText::FromName(BoneName));
}
}
else
{
ReportWarningf(LOCTEXT("InvalidTrackNameWarning", "Track with name {0} does not exist"), FText::FromName(BoneName));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidKeyIndexRangeError",
"Invalid key index range bound [{0}, {1}], expected to equal the size of the positional, rotational and scaling keys {2}"),
FText::AsNumber(KeyRangeToSet.GetLowerBoundValue()),
FText::AsNumber(KeyRangeToSet.GetUpperBoundValue()),
FText::AsNumber(MaxNumKeys));
}
}
else
{
ReportErrorf(LOCTEXT("InvalidTrackKeyDataError", "Invalid track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
}
else
{
ReportErrorf(LOCTEXT("MissingTrackKeyDataError", "Missing track key data, expected uniform data: number of positional keys {0}, number of rotational keys {1}, number of scaling keys {2}"), FText::AsNumber(PositionalKeys.Num()), FText::AsNumber(RotationalKeys.Num()), FText::AsNumber(ScalingKeys.Num()));
}
return false;
}
void UAnimDataController::ResizeCurves(float NewLength, bool bInserted, float T0, float T1, bool bShouldTransact /*= true*/)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("ResizeCurves", "Resizing all Curves"), bShouldTransact);
for (FFloatCurve& Curve : Model->CurveData.FloatCurves)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
FFloatCurve ResizedCurve = Curve;
ResizedCurve.Resize(NewLength, bInserted, T0, T1);
SetCurveKeys(FAnimationCurveIdentifier(Curve.Name, ERawCurveTrackTypes::RCT_Float), ResizedCurve.FloatCurve.GetConstRefOfKeys(), bShouldTransact);
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
for (FTransformCurve& Curve : Model->CurveData.TransformCurves)
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
{
FTransformCurve ResizedCurve = Curve;
for (int32 SubCurveIndex = 0; SubCurveIndex < 3; ++SubCurveIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const ETransformCurveChannel Channel = static_cast<ETransformCurveChannel>(SubCurveIndex);
FVectorCurve& SubCurve = *ResizedCurve.GetVectorCurveByIndex(SubCurveIndex);
for (int32 ChannelIndex = 0; ChannelIndex < 3; ++ChannelIndex)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const EVectorCurveChannel Axis = static_cast<EVectorCurveChannel>(ChannelIndex);
FAnimationCurveIdentifier TargetCurveIdentifier = FAnimationCurveIdentifier(Curve.Name, ERawCurveTrackTypes::RCT_Transform);
UAnimationCurveIdentifierExtensions::GetTransformChildCurveIdentifier(TargetCurveIdentifier, Channel, Axis);
FRichCurve& ChannelCurve = SubCurve.FloatCurves[ChannelIndex];
ChannelCurve.ReadjustTimeRange(0, NewLength, bInserted, T0, T1);
SetCurveKeys(TargetCurveIdentifier, ChannelCurve.GetConstRefOfKeys(), bShouldTransact);
}
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
}
}
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
void UAnimDataController::ResizeAttributes(float NewLength, bool bInserted, float T0, float T1, bool bShouldTransact)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("ResizeAttributes", "Resizing all Attributes"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
for (FAnimatedBoneAttribute& Attribute : Model->AnimatedBoneAttributes)
{
FAttributeCurve ResizedCurve = Attribute.Curve;
ResizedCurve.ReadjustTimeRange(0, NewLength, bInserted, T0, T1);
// Generate arrays necessary for API
TArray<float> Times;
TArray<const void*> Values;
const TArray<FAttributeKey>& Keys = ResizedCurve.GetConstRefOfKeys();
for (int32 KeyIndex = 0; KeyIndex < ResizedCurve.GetNumKeys(); ++KeyIndex)
{
Times.Add(Keys[KeyIndex].Time);
Values.Add(Keys[KeyIndex].GetValuePtr<void>());
}
SetAttributeKeys(Attribute.Identifier, Times, Values, Attribute.Curve.GetScriptStruct(), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
}
bool UAnimDataController::AddAttribute(const FAnimationAttributeIdentifier& AttributeIdentifier, bool bShouldTransact /*= true*/)
{
if (AttributeIdentifier.IsValid())
{
const bool bAttributeAlreadyExists = Model->AnimatedBoneAttributes.ContainsByPredicate([AttributeIdentifier](const FAnimatedBoneAttribute& Attribute) -> bool
{
return Attribute.Identifier == AttributeIdentifier;
});
if (!bAttributeAlreadyExists)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("AddAttribute", "Adding Animated Bone Attribute"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
FAnimatedBoneAttribute& Attribute = Model->AnimatedBoneAttributes.AddDefaulted_GetRef();
Attribute.Identifier = AttributeIdentifier;
Attribute.Curve.SetScriptStruct(AttributeIdentifier.GetType());
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRemoveAtributeAction>(bShouldTransact, AttributeIdentifier);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
FAttributeAddedPayload Payload;
Payload.Identifier = AttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeAdded, Payload);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
return true;
}
else
{
ReportErrorf(LOCTEXT("AttributeAlreadyExists", "Attribute identifier provided already exists: {0} {1} ({2}) {3}"),
FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetBoneName()), FText::AsNumber(AttributeIdentifier.GetBoneIndex()), FText::FromName(AttributeIdentifier.GetType()->GetFName()));
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeIdentifier", "Invalid attribute identifier provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
return false;
}
bool UAnimDataController::RemoveAttribute(const FAnimationAttributeIdentifier& AttributeIdentifier, bool bShouldTransact /*= true*/)
{
if (AttributeIdentifier.IsValid())
{
const int32 AttributeIndex = Model->AnimatedBoneAttributes.IndexOfByPredicate([AttributeIdentifier](const FAnimatedBoneAttribute& Attribute) -> bool
{
return Attribute.Identifier == AttributeIdentifier;
});
if (AttributeIndex != INDEX_NONE)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RemoveAttribute", "Removing Animated Bone Attribute"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddAtributeAction>(bShouldTransact, Model->AnimatedBoneAttributes[AttributeIndex]);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
Model->AnimatedBoneAttributes.RemoveAtSwap(AttributeIndex);
FAttributeRemovedPayload Payload;
Payload.Identifier = AttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeRemoved, Payload);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
return true;
}
else
{
ReportErrorf(LOCTEXT("AttributeNotFound", "Attribute identifier provided was not found: {0} {1} ({2}) {3}"),
FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetBoneName()), FText::AsNumber(AttributeIdentifier.GetBoneIndex()), FText::FromName(AttributeIdentifier.GetType()->GetFName()));
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeIdentifier", "Invalid attribute identifier provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
return false;
}
int32 UAnimDataController::RemoveAllAttributesForBone(const FName& BoneName, bool bShouldTransact)
{
int32 NumRemovedAttributes = 0;
// Generate list of attribute identifiers, matching the bone name, for removal
TArray<FAnimationAttributeIdentifier> Identifiers;
Algo::TransformIf(Model->AnimatedBoneAttributes, Identifiers,
[BoneName](const FAnimatedBoneAttribute& Attribute) -> bool
{
return Attribute.Identifier.GetBoneName() == BoneName;
},
[](const FAnimatedBoneAttribute& Attribute)
{
return Attribute.Identifier;
}
);
if (Identifiers.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("RemoveAllAttributesForBone", "Removing all Attributes for Bone"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
for (const FAnimationAttributeIdentifier& Identifier : Identifiers)
{
NumRemovedAttributes += RemoveAttribute(Identifier, bShouldTransact) ? 1 : 0;
}
}
return NumRemovedAttributes;
}
int32 UAnimDataController::RemoveAllAttributes(bool bShouldTransact)
{
int32 NumRemovedAttributes = 0;
TArray<FAnimationAttributeIdentifier> Identifiers;
Algo::Transform(Model->AnimatedBoneAttributes, Identifiers, [](const FAnimatedBoneAttribute& Attribute)
{
return Attribute.Identifier;
});
if (Identifiers.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FBracket Bracket = ConditionalBracket(LOCTEXT("RemoveAllAttributes", "Removing all Attributes"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
for (const FAnimationAttributeIdentifier& Identifier : Identifiers)
{
NumRemovedAttributes += RemoveAttribute(Identifier, bShouldTransact) ? 1: 0;
}
}
return NumRemovedAttributes;
}
bool UAnimDataController::SetAttributeKey_Internal(const FAnimationAttributeIdentifier& AttributeIdentifier, float Time, const void* KeyValue, const UScriptStruct* TypeStruct, bool bShouldTransact /*= true*/)
{
if (AttributeIdentifier.IsValid())
{
if (KeyValue)
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FAnimatedBoneAttribute* AttributePtr = Model->AnimatedBoneAttributes.FindByPredicate([AttributeIdentifier](const FAnimatedBoneAttribute& Attribute)
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
{
return Attribute.Identifier == AttributeIdentifier;
});
if (AttributePtr)
{
if (TypeStruct == AttributePtr->Identifier.GetType())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SettingAttributeKey", "Setting Animated Bone Attribute key"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
FAttributeCurve& Curve = AttributePtr->Curve;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const FKeyHandle KeyHandle = Curve.FindKey(Time);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
// In case the key does not yet exist one will be added, and thus the undo is a remove
if (KeyHandle == FKeyHandle::Invalid())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRemoveAtributeKeyAction>(bShouldTransact, AttributeIdentifier, Time);
Curve.UpdateOrAddTypedKey(Time, KeyValue, TypeStruct);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
// In case the key does exist it will be updated , and thus the undo is a revert to the current value
else
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetAtributeKeyAction>(bShouldTransact, AttributeIdentifier, Curve.GetKey(KeyHandle));
Curve.UpdateOrAddTypedKey(Time, KeyValue, TypeStruct);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
FAttributeChangedPayload Payload;
Payload.Identifier = AttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeChanged, Payload);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
return true;
}
else
{
ReportErrorf(LOCTEXT("AttributeTypeDoesNotMatchKeyType", "Key type does not match attribute: {0} {1}"),
FText::FromName(AttributePtr->Identifier.GetType()->GetFName()), FText::FromName(TypeStruct->GetFName()));
}
}
else
{
ReportErrorf(LOCTEXT("AttributeNotFound", "Attribute identifier provided was not found: {0} {1} ({2}) {3}"),
FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetBoneName()), FText::AsNumber(AttributeIdentifier.GetBoneIndex()), FText::FromName(AttributeIdentifier.GetType()->GetFName()));
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeKey", "Invalid attribute key value provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeIdentifier", "Invalid attribute identifier provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
return false;
}
bool UAnimDataController::SetAttributeKeys_Internal(const FAnimationAttributeIdentifier& AttributeIdentifier, TArrayView<const float> Times, TArrayView<const void*> KeyValues, const UScriptStruct* TypeStruct, bool bShouldTransact)
{
if (AttributeIdentifier.IsValid())
{
if (Times.Num() == KeyValues.Num())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FAnimatedBoneAttribute* AttributePtr = Model->AnimatedBoneAttributes.FindByPredicate([AttributeIdentifier](const FAnimatedBoneAttribute& Attribute)
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
{
return Attribute.Identifier == AttributeIdentifier;
});
if (AttributePtr)
{
if (TypeStruct == AttributePtr->Identifier.GetType())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("SettingAttributeKeys", "Setting Animated Bone Attribute keys"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
FAnimatedBoneAttribute& Attribute = *AttributePtr;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FSetAtributeKeysAction>(bShouldTransact, Attribute);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
Attribute.Curve.SetKeys(Times, KeyValues);
FAttributeChangedPayload Payload;
Payload.Identifier = AttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeChanged, Payload);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
return true;
}
else
{
ReportErrorf(LOCTEXT("AttributeTypeDoesNotMatchKeyType", "Key type does not match attribute: {0} {1}"),
FText::FromName(AttributePtr->Identifier.GetType()->GetFName()), FText::FromName(TypeStruct->GetFName()));
}
}
else
{
ReportErrorf(LOCTEXT("AttributeNotFound", "Attribute identifier provided was not found: {0} {1} ({2}) {3}"),
FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetBoneName()), FText::AsNumber(AttributeIdentifier.GetBoneIndex()), FText::FromName(AttributeIdentifier.GetType()->GetFName()));
}
}
else
{
ReportErrorf(LOCTEXT("AttributeKeysMismatch", "Non matching number of key time/values: time entries {0} key entries {1}"),
FText::AsNumber(Times.Num()), FText::AsNumber(KeyValues.Num()));
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeIdentifier", "Invalid attribute identifier provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
return false;
}
bool UAnimDataController::RemoveAttributeKey(const FAnimationAttributeIdentifier& AttributeIdentifier, float Time, bool bShouldTransact /*= true*/)
{
if (AttributeIdentifier.IsValid())
{
FAnimatedBoneAttribute* AttributePtr = Model->AnimatedBoneAttributes.FindByPredicate([AttributeIdentifier](const FAnimatedBoneAttribute& Attribute)
{
return Attribute.Identifier == AttributeIdentifier;
});
if (AttributePtr)
{
FAttributeCurve& Curve = AttributePtr->Curve;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
const FKeyHandle KeyHandle = Curve.FindKey(Time);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
if (KeyHandle != FKeyHandle::Invalid())
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("RemovingAttributeKey", "Removing Animated Bone Attribute key"), bShouldTransact);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FAddAtributeKeyAction>(bShouldTransact, AttributeIdentifier, Curve.GetKey(KeyHandle));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
Curve.DeleteKey(KeyHandle);
FAttributeAddedPayload Payload;
Payload.Identifier = AttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeChanged, Payload);
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
return true;
}
else
{
Report(ELogVerbosity::Warning, LOCTEXT("AttributeKeyNotFound", "Attribute does not contain key for provided time"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
}
else
{
ReportErrorf(LOCTEXT("AttributeNotFound", "Attribute identifier provided was not found: {0} {1} ({2}) {3}"),
FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetBoneName()), FText::AsNumber(AttributeIdentifier.GetBoneIndex()), FText::FromName(AttributeIdentifier.GetType()->GetFName()));
}
}
else
{
Report(ELogVerbosity::Error, LOCTEXT("InvalidAttributeIdentifier", "Invalid attribute identifier provided"));
New Animation Attributes system, replacing Custom Attributes: + Attribute structures to UAnimDataModel * These are sampled/copied into AnimSequence whenever they change + Attribute related Notifies and Payloads + Controller API and Actions for Attribute related behaviour + Type traits (TAttributeTypeTraitsBase) to determine support functionality for user-defined attribute types + TAttributeContainer equivalent to TCustomAttributes, used for keeping track of attributes at runtime in a TMap similar fashion * Has two exported specializations FStack/Heap-AttributeContainer + IAttributeBlendOperator interface used for Attribute related operations in Anim graph * Allows for user-defined blending behaviour for their associated types + TAttributeBlendOperator providing out-of-the-box blending behaviour for user-defined types + FAttributeBlendData helper structure, this encapsulates and abstracts the blend / attribute operations * Exposes two iterators, allowing BlendOperator to loop through (type) overlapping Attributes and unique attributes + Float/Integer/String Animation Attribute structures used to support legacy TVariant CustomAttribute data types + Transform animation attribute structure to add support for single-FTransform based attributes + FAnimationAttributeIdentifier identifier used to reference an attribute in a script-friendly manor + AttributeTypes static API for registering Attribute types + FAttributeCurve providing a curve-type with an Attribute type as its underlying key-value + TWrappedAttribute helper structure to wrap end template operate on raw memory (TArray buffer) + Added tests for * Attribute related controller functionality and actions * Attribute curve key reduction * Evaluating attributes from AnimSequence * Attribute operations (blend, accumulate etc) * Functional testing for blendspace attribute evaluation and blending * Changed default attribute blend type to Blend vs Override * Updated FBX import/export paths to handle and use new Attribute data structures * Attribute data is now incorporated into animation source data DDC key * Deprecated Custom Attributes stored on AnimSequence get converted into their equivalent Attribute structures * Deprecated all previous CustomAttribute structures, APIs and files * Corrected some comments in UAnimDataController.h * Updated existing custom attribute tests to adhere to new blend expectations/behaviour * Updated AnimSequence resize tests to also incorporate an attribute curve * Changed layered bone blend to use .5 blend weight vs 1.0 to cover more behaviour * Added transform attribute used to compare against bone transform during pre-existing functional testing (blended only) - Deleted CustomAttributes details customization #rb Thomas.Sarkanen #fyi kiaran.ritchie, koray.hagen, timothy.daoust [CL 15568420 by Jurre deBaare in ue5-main branch]
2021-03-02 09:04:09 -04:00
}
return false;
}
bool UAnimDataController::DuplicateAttribute(const FAnimationAttributeIdentifier& AttributeIdentifier, const FAnimationAttributeIdentifier& NewAttributeIdentifier, bool bShouldTransact)
{
ValidateModel();
if (AttributeIdentifier.IsValid() && NewAttributeIdentifier.IsValid())
{
if (AttributeIdentifier.GetType() == NewAttributeIdentifier.GetType())
{
const FAnimatedBoneAttribute* ExistingAttributePtr = Model->FindAttribute(NewAttributeIdentifier);
if (ExistingAttributePtr == nullptr)
{
if(const FAnimatedBoneAttribute* AttributePtr = Model->FindAttribute(AttributeIdentifier))
{
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
FTransaction Transaction = ConditionalTransaction(LOCTEXT("DuplicateAttribute", "Duplicating Animation Attribute"), bShouldTransact);
FAnimatedBoneAttribute& DuplicateAttribute = Model->AnimatedBoneAttributes.AddDefaulted_GetRef();
DuplicateAttribute.Identifier = NewAttributeIdentifier;
DuplicateAttribute.Curve = AttributePtr->Curve;
FAttributeAddedPayload Payload;
Payload.Identifier = NewAttributeIdentifier;
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
Model->GetNotifier().Notify(EAnimDataModelNotifyType::AttributeAdded, Payload);
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
ConditionalAction<UE::Anim::FRemoveAtributeAction>(bShouldTransact, NewAttributeIdentifier);
return true;
}
else
{
ReportWarningf(LOCTEXT("AttributeNameToDuplicateNotFoundWarning", "Could not find attribute with name {0} and type {1} for duplication"), FText::FromName(AttributeIdentifier.GetName()), FText::FromString(AttributeIdentifier.GetType()->GetName()));
}
}
else
{
ReportWarningf(LOCTEXT("ExistingAttributeWarning", "Attribute with name {0} already exists"), FText::FromName(AttributeIdentifier.GetName()));
}
}
else
{
ReportWarningf(LOCTEXT("InvalidAttributeTypeWarning", "Attribute types do not match: {0} ({1})"), FText::FromString(AttributeIdentifier.GetType()->GetName()), FText::FromString(AttributeIdentifier.GetType()->GetName()));
}
}
else
{
ReportWarningf(LOCTEXT("InvalidAttributeIdentifierWarning", "Invalid attribute identifier(s) provided: {0} and/or {1}"), FText::FromName(AttributeIdentifier.GetName()), FText::FromName(AttributeIdentifier.GetName()));
}
return false;
}
Reintroducing AnimationDataModel refactor with additional memory and cooktime optimizations. **Animation Data Model load/cook time and memory optimizations** - Added SetKeysOnly to FMovieSceneFloatChannel, allowing to only set value/frames values and skip allocating key handles - Added EvaluateWithCache to TMovieSceneCurveChannelImpl, allowing to evaluate multiple curves using a caching data structure holding the frame-indices resulting from the FrameTime -> indexes calculationg - UFKControlRig::GetControlName/GetControlTargetName, added thread_local mapping cache and optimized FName generation - Made the sequencer bone curve keys 'sparse' again, if constant it just sets the default value for the curve otherwise it is still uniform - Only resample keys when compressing, and clear them on any significant model changes and when save-during-cook has been completed - Routed ::Presave for AnimSequencerDataModel directly through to UMovieSceneSignedObject to skip compiling cooked sequencer that that will/should never cooked and packaged - Added some significant pass-by-reference changes to AnimSequencerModel APIs (passing large arrays by value previously) :doh: - Optimized GenerateLegacyBoneData Original CL description: **New** - Engine - IAnimationDataModel interface - AnimationData plugin - AnimSequencerDataModel, sequencer based implementation of IAnimationDataModel - AnimSequencerDataController, controller for above (implementation of IAnimationDataController) - Added FCompressedRichCurve::PopulateCurve, allowing users to convert back to a FRichCurve for validation/debugging - Added DefaultFrameRate to AnimationSettings, this replaces the hardcoded 30FPS in code - Added ::GetKeyIndicesFromTime which takes FFrameRate - Added AnimSequenceBase::OnAnimModelLoaded, this is required for correct postloading behaviour of data model (specifically AnimSequencerDataModel, as it depends on data from its outer ? anim sequence) - Added IAnimationDataModel ::Evaluate which now takes responsibility for evaluating raw animation bone, curve and attribute data. And moved all trackbased evaluation code into AnimDataModel.cpp - Added a.ForceEvalRawData allowing to force evaluation of source data - Added a.SkipDDC to force compressing animation data locally **Changed** - Reparent UAnimDataModel to IAnimationDataModel interface, and rejig behaviour - AnimSequenceBase now reference AnimDataModel as IAnimationDataModel - Upgrade path for legacy to IAnimationDataModel and existing UAnimDataModel to IAnimationDataModel through IAnimationDataController::PopulateWithExisting - IAnimationDataModel data is now frame(number/rate/time) based rather than seconds/keyindices. This enforces frameborder aligned data from now on. - Moved RichCurve evaluation code from RichCurve.cpp to separate file and consolidated all instances of copy-pasta behaviour - Updated/removed deprecated EngineTests around AnimSequences - Changed many instances to use a FFrameTime together with a known FFrameRate versus seconds and sequencelength in float involving frame \/ time calculations (including instances of FAnimKeyHelper) - Switched anim sequence evaluation to use double in Extraction context for time value and patched up places with static\_cast\<double\> - FRichCurve::Eval - Make sure we always evaluate keys when T >= Key0.Time and T <= KeyN.Time to deal with crazy userweighted tangents - Fixed WeightedKeyDataAdapter::GetKeyInterpMode/GetKeyTangentWeightMode retrieving invalid values, as it was indexing according to KeyIndex rather than KeyIndex\*2. This made it so that values were misinterpreted. - Fixed WeightedEvalForTwoKeys for compressed data retrieving GetKeyInterpMode and GetKeyTangentWeightMode using the wrong index value. As they are not indexed using KeyDataHandle type. - Fixed issue where compression could crash when containing zero-key scale additivebase track (tries to retrieve) - Replaced instances of NULL with nullptr - Moved required decompression information into FAnimSequenceDecompressionContext and reimplemented decompression within UE::Anim::Decompression namespace and new file - Deprecated ::GetRawDataGuid and replaced with GetDataModel()->GenerateGuid() - Fixed UAnimStreamable evaluation/compression (previously broken with MVC refactor) - Updated Animation exporting pipeline to be frame-based rather than seconds - Deprecated RetargetPose, replaced with FRetargetingScope (used within AnimModel::Evaluate) - Fixed BaseAdditiveAnimation array become invalid/incorrect when removing zero-additve tracks during compression - Updated EngineTest animation sequence related tests to new APIs (while maintaining deprecated path testing as well for now) - AnimDataController / Animation Sequence tests now generate a USkeleton for the transient animation sequence (used to perform the test on) **Removed** - Unused file/class AnimData/AnimDataNotifyCollector.h #rb Thomas.Sarkanen, Mike.Zyracki #jira UE-131296 #preflight 631f6897a9331c69c3a34d1e [CL 21980597 by Jurre deBaare in ue5-main branch]
2022-09-13 06:41:15 -04:00
void UAnimDataController::UpdateWithSkeleton(USkeleton* TargetSkeleton, bool bShouldTransact)
{
RemoveBoneTracksMissingFromSkeleton(TargetSkeleton);
}
void UAnimDataController::PopulateWithExistingModel(TScriptInterface<IAnimationDataModel> InModel)
{
Model->BoneAnimationTracks = InModel->GetBoneAnimationTracks();
Model->FrameRate = InModel->GetFrameRate();
Model->NumberOfFrames = InModel->GetNumberOfFrames();
Model->NumberOfKeys = InModel->GetNumberOfFrames() + 1;
Model->CurveData = InModel->GetCurveData();
Model->AnimatedBoneAttributes = InModel->GetAttributes();
// Ensure curve name UIDs are validated against the outer skeleton as they are not copied over through FSmartName
if (const UAnimSequenceBase* AnimSequenceBase = Cast<UAnimSequenceBase>(InModel.GetObject()->GetOuter()))
{
FindOrAddCurveNamesOnSkeleton(AnimSequenceBase->GetSkeleton(), ERawCurveTrackTypes::RCT_Float);
FindOrAddCurveNamesOnSkeleton(AnimSequenceBase->GetSkeleton(), ERawCurveTrackTypes::RCT_Transform);
}
}
Animation data MVC refactor #jira UE-104234 #rb Thomas.Sarkanen, Martin.Wilson, Alexis.Matte, Michael.Zyracki + Introduced UAnimDataModel, this currently represents the source data for bone and curve animation. It contains: + Bone animation tracks (FBoneAnimationTrack) + Key data (coarse) + Name + Bone tree index + Curve data (FAnimationCurveData) + Float Curves + Transform Curves + Play length + Sampling rate + Used for deriving the expected number of keys/frames when combined with the PlayLength + Transient data for supporting backwards compatibility APIs + (Dynamic) delegate which broadcasts the mutation Notifies + Introduced UAnimDataController, this has sole authority over mutating data contained by UAnimDataModel + API functionality allows to transform the contained data in all ways currently expected in the engine. + Any mutation will add an undo/redo-able FChange object into the transaction buffer + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo + Broadcasts change notifies alongside a payload object containing details about the change + Interested systems/objects can register to these changes through UAnimDataModel::OnModelModified event + Almost all functionality is exposed to both Blueprint and Python scripting + Allows for opening 'Brackets', these define the beginning and end of a chain of mutations. Allowing anything registered to OnModelModified to halt responding to the notifies until the (top-level) bracket is closed + Undo/redo actions + Each mutation to the UAnimDataModel is covered by a 'Action' which is based of FChange and is used to insert a undo/redo-able operation into the transactions buffer + Introduced EAnimDataModelNotifType and per-notify payload types. These are used to update views, and any model derived data + Introduced FAnimationCurveIdentifier, exposed to scripting, this is used for referencing a curve by name and type when passed to the controller + Allows for targetting a specific RichCurve as part of a TransformCurve + Introduced FAnimationDataNotifyCollectorused for keeping track of which notifies of type EAnimDataModelNotifType are broadcasted between top-level EAnimDataModelNotifType::BracketOpened and EAnimDataModelNotifType::BracketClosed notifies + Added CanTransact to UEngine, returns whether or not a transaction can be made + Added UAnimCompositeBase::SetCompositeLength, used for runtime changing of play length value + Animation Sequence helpers, containing 'helper' functionality for both AnimSequence and AnimDataModel * Animation Sequence Base + virtual PopulateModel, called during upgrade path for converting existing (legacy) data to the new UAnimDataModel data + virtual OnModelModified, registered to the Model's OnModified event to handle any Notifies and payloads + Added UAnimDataModel sub-object (editor only) + Added UAnimDataController instance (transient and editor only) + FAnimationDataNotifyCollector to keep track of model bracketed notifies * Deprecated * SetSequenceLength() * RefreshCurveData() * MarkRawDataAsModified() * RegisterOnAnimCurvesChanged() * UnregisterOnAnimCurvesChanged() * UnregisterOnAnimTrackCurvesChanged() * RegisterOnAnimTrackCurvesChanged() * Public access to RawCurveData * Animation Sequence + Implements PopulateModel/OnModelModified for AnimationSequence related data + Added TargetFrameRate, currently locked to the initial sampling rate, but allows for resampling the UAnimDataModel data according to the set rate + Added NumberOfSampledKeys (editor only), populated by resampling process + Added NumberOfSampledFrames (editor only), populated by resampling process + Added ResampledAnimationTrackData (editor only and transient), populated by resampling process + Added bBlockCompressionRequests (editor only), used for blocking compression during automation tests * Deprecated * SetNumberOfSampledKeys() * MarkRawDataAsModified() * GetRawAnimationData() * GetAnimationTrackNames() * AddNewRawTrack() * GetRawTrackToSkeletonMapTable() * GetRawAnimationTrack() * GetRawAnimationTrack() * UpdateFrameRate() * ExtractBoneTransform() * CompressRawAnimData() * GetSkeletonIndexFromRawDataTrackIndex() * RecycleAnimSequence() * CleanAnimSequenceForImport() * CopyNotifies() * PostProcessSequence() * AddLoopingInterpolation() * RemoveAllTracks() * DoesContainTransformCurves() * InsertFramesToRawAnimData() * CropRawAnimData() * RemoveTrack() * InsertTrack() * ResizeSequence() * Non-editor access to GetUncompressedRawSize() * Non-editor access to GetApproxRawSize() * Public access to UpdateCompressedCurveName() * NumberOfKeys * SamplingFrameRate * TrackToSkeletonMapTable * RawAnimationData * AnimationTrackNames * Animation Streamable * Model from source Sequence is duplicated rather than copying animation data * Deprecated ERawCurveTrackTypes::RCT_Vector (marked as hidden) + Added automated test for + All script exposed controller functionality + Undo/redo actions * Updated existing AnimSequence tests with deprecation and new expected data + Base data for compression is now populated from the 'resampled' version stored on the AnimSequence + Data cleanup and validation is now performed during compression + Track sanitization is now performed during compression (normalizing Quats and clamping near-zero values to zero) + Key reduction + Invalid track (missing bone from skeleton) removal + Curve name validation against skeleton * Replaced RawCurves with Float curves * Updated DDC key - Removed all Guid generation related functionality (now part of the model) * AnimSequenceBase model registers to AnimModel's notify event, used for refreshing the tracks * Replaces the in-place calling of RefreshTracks() * All curve tracks now hold a const CurveType* rather than a CurveType*/& for introspection of its data + Any mutations now go through the controller API + Uses AnimationCurveIdentifier to set Transform's per-channel tracks * RichCurveEditorModelNamed conformed to model/controller + Any modifications are applied to an temporary CurveType which always contains a copy of the const-ptr after any previous mutation + Registers to the outer AnimModel's notify event, used for updating the cached curve data + Registers to CurveModifiedDelegate, used for copying the temp curve data to the model using SetCurveKeys * Not-ideal but point that I got to for V1 * Would be replaced with either refactoring FRichCurve to be MVC like, or by calling UAnimDataController functionality from an implementation of FRichCurveEditorModel * Mark FChange overrides as final for swap/command change permutations * Changed FCompoundChange GetDescription to return concatenation of all sub-changes * Added GetDescription to FTransaction which returns the ToString() value of any contained FChange entries. * Entries in SUndoHistory tab now have a ToolTip showing the GetDescription() value + FChangeTransactor helper object allows for keeping track of (compounded) FChange's and inserting them into GUndo * Deprecation handling, conforming code to new APIs and exposing structure/objects/properties to scripting * Conforming AnimSequence importing from FBX to Model/Controller changes [CL 15106211 by Jurre deBaare in ue5-main branch]
2021-01-15 06:41:11 -04:00
#endif // WITH_EDITOR
#undef LOCTEXT_NAMESPACE // "AnimDataController"