Motion Matching: Fixed several bugs and improved anim graph node RPE layout
* Fixed several crashes that happened when adjusting the cost function in the UI.
* Automatically hide the trajectory path radius and path speed properties when the mode is set to target-based.
* Re-ordered the properties for better grouping.
Motion Matching: Moved discard event check into consolidated IsFrameDiscarded() method
* Moved the extract events call and the check for a discard frame event to the IsFrameDiscarded() function.
* Added class description for the frame database and ported the comments to //! and //<
Motion Matching: Fixed crash on empty KD-tree
Motion Matching: Automatic target mode for trajectory query
* Consolidated the different automatic path generation modes into a single automatic demo mode.
* Moved the static phase variable to a member so that multiple instances won't follow the same path and speedup the phase increment.
Motion Matching: Added class description and member comments
* Added description for Feature, FeatureMatrix, FeatureTrajectory classes.
* Changed default residual type to absolute as that results in better visual quality.
* Moved to //! doxygen style code to not affect /**/ sourounding temporary code commenting.
->DataElement(AZ::Edit::UIHandlers::Default,&BlendTreeMotionMatchNode::m_maxKdTreeDepth,"Max kdTree depth","The maximum number of hierarchy levels in the kdTree.")
->DataElement(AZ::Edit::UIHandlers::Default,&BlendTreeMotionMatchNode::m_minFramesPerKdTreeNode,"Min kdTree node size","The minimum number of frames to store per kdTree node.")
//! A feature is a property extracted from the animation data and is used by the motion matching algorithm to find the next best matching frame.
//! Examples of features are the position of the feet joints, the linear or angular velocity of the knee joints or the trajectory history and future
//! trajectory of the root joint. We can also encode environment sensations like obstacle positions and height, the location of the sword of an enemy
//! character or a football's position and velocity. Their purpose is to describe a frame of the animation by their key characteristics and sometimes
//! enhance the actual keyframe data (pos/rot/scale per joint) by e.g. taking the time domain into account and calculate the velocity or acceleration,
//! or a whole trajectory to describe where the given joint came from to reach the frame and the path it moves along in the near future.
//! @Note: Features are extracted and stored relative to a given joint, in most cases the motion extraction or root joint, and thus are in model-space.
//! This makes the search algorithm invariant to the character location and orientation and the extracted features, like e.g. a joint position or velocity,
//! translate and rotate along with the character.
AZ::Colorm_debugColor=AZ::Colors::Green;//< Color used for debug visualizations to identify the feature.
boolm_debugDrawEnabled=false;//< Are debug visualizations enabled for this feature?
floatm_costFactor=1.0f;//< The cost factor for the feature is multiplied with the actual and can be used to change a feature's influence in the motion matching search.
ResidualTypem_residualType=ResidualType::Squared;//< How do we calculate the differences (residuals) between the input query values and the frames in the motion database that sum up the feature cost.
ResidualTypem_residualType=ResidualType::Absolute;//< How do we calculate the differences (residuals) between the input query values and the frames in the motion database that sum up the feature cost.
// Instance data (depends on the feature schema or actor instance).
FeatureMatrix::Indexm_featureColumnOffset;//< Float/Value offset, starting column for where the feature should be places at.
//! The feature matrix is a NxM matrix which stores the extracted feature values for all frames in our motion database based upon a given feature schema.
//! The feature schema defines the order of the columns and values and is used to identify values and find their location inside the matrix.
//! A 3D position feature storing XYZ values e.g. will use three columns in the feature matrix. Every component of a feature is linked to a column index,
//! so e.g. the left foot position Y value might be at column index 6. The group of values or columns that belong to a given feature is what we call a feature block.
//! The accumulated number of dimensions for all features in the schema, while the number of dimensions might vary per feature, form the number of columns of the feature matrix.
//! Each row represents the features of a single frame of the motion database. The number of rows of the feature matrix is defined by the number.
//! Matches the root joint past and future trajectory.
//! For each frame in the motion database, the position and facing direction relative to the current frame of the joint will be evaluated for a past and future time window.
//! The past and future samples together form the trajectory of the current frame within the time window. This basically describes where the character came from to reach the
//! current frame and where it will go when continuing to play the animation.
// This is basically a database of frames (which point to motion objects), together with meta data per frame.
// No actual pose data is stored directly inside this class, just references to the right sample times inside specific motions.
//! A set of frames from your animations sampled at a given sample rate is stored in the frame database. A frame object knows about its index in the frame database,
//! the animation it belongs to and the sample time in seconds. It does not hold the actual sampled pose for memory reasons as the `EMotionFX::Motion` already store the
//! transform keyframes.
//! The sample rate of the animation might differ from the sample rate used for the frame database. For example, your animations might be recorded with 60 Hz while we only want
//! to extract the features with a sample rate of 30 Hz. As the motion matching algorithm is blending between the frames in the motion database while playing the animation window
//! between the jumps/blends, it can make sense to have animations with a higher sample rate than we use to extract the features.
//! A frame of the motion database can be used to sample a pose from which we can extract the features. It also provides functionality to sample a pose with a time offset to that frame.
//! This can be handy in order to calculate joint velocities or trajectory samples.
//! When importing animations, frames that are within the range of a discard frame motion event are ignored and won't be added to the motion database. Discard motion events can be
//! used to cut out sections of the imported animations that are unwanted like a stretching part between two dance cards.
// The settings used when importing motions into the frame database.
// Used in combination with ImportFrames().
//! The settings used when importing motions into the frame database.
//! Used in combination with ImportFrames().
structEMFX_APIFrameImportSettings
{
size_tm_sampleRate=30;/**< Sample at 30 frames per second on default. */
boolm_autoShrink=true;/**< Automatically shrink the internal frame arrays to their minimum size afterwards. */
size_tm_sampleRate=30;//< Sample at 30 frames per second on default.
boolm_autoShrink=true;//< Automatically shrink the internal frame arrays to their minimum size afterwards.
};
FrameDatabase();
virtual~FrameDatabase();
// Main functions.
AZStd::tuple<size_t,size_t>ImportFrames(Motion*motion,constFrameImportSettings&settings,boolmirrored);// Returns the number of imported frames and the number of discarded frames as second element.
voidClear();// Clear the data, so you can re-initialize it with new data.
AZStd::tuple<size_t,size_t>ImportFrames(Motion*motion,constFrameImportSettings&settings,boolmirrored);//< Returns the number of imported frames and the number of discarded frames as second element.
voidClear();//< Clear the data, so you can re-initialize it with new data.
voidExtractActiveMotionEventDatas(constMotion*motion,floattime,AZStd::vector<EventData*>&activeEventDatas)const;// Vector will be cleared internally.
private:
AZStd::vector<Frame>m_frames;/**< The collection of frames. Keep in mind these don't hold a pose, but reference to a given frame/time value inside a given motion. */
AZStd::vector<Frame>m_frames;//< The collection of frames. Keep in mind these don't hold a pose, but reference to a given frame/time value inside a given motion.
AZ_Error("Motion Matching",false,"Cannot initialize KD-tree. KD-tree dimension (%d) has to be between 1 and 20. Please use Feature::SetIncludeInKdTree(false) on some features.",m_numDimensions);
AZ_Error("Motion Matching",false,"Cannot initialize KD-tree. KD-tree dimension (%d) has to be between 1 and %zu. Please use Feature::SetIncludeInKdTree(false) on some features.",m_numDimensions,maxNumDimensions);