godot-module-template/engine/thirdparty/jolt_physics/Jolt/Skeleton/SkeletalAnimation.h

92 lines
3 KiB
C++

// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#include <Jolt/Core/Reference.h>
#include <Jolt/Core/Result.h>
#include <Jolt/Core/StreamUtils.h>
#include <Jolt/ObjectStream/SerializableObject.h>
JPH_NAMESPACE_BEGIN
class SkeletonPose;
/// Resource for a skinned animation
class JPH_EXPORT SkeletalAnimation : public RefTarget<SkeletalAnimation>
{
JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, SkeletalAnimation)
public:
/// Contains the current state of a joint, a local space transformation relative to its parent joint
class JointState
{
JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, JointState)
public:
/// Convert from a local space matrix
void FromMatrix(Mat44Arg inMatrix);
/// Convert to matrix representation
inline Mat44 ToMatrix() const { return Mat44::sRotationTranslation(mRotation, mTranslation); }
Quat mRotation = Quat::sIdentity(); ///< Local space rotation of the joint
Vec3 mTranslation = Vec3::sZero(); ///< Local space translation of the joint
};
/// Contains the state of a single joint at a particular time
class Keyframe : public JointState
{
JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Keyframe)
public:
float mTime = 0.0f; ///< Time of keyframe in seconds
};
using KeyframeVector = Array<Keyframe>;
/// Contains the animation for a single joint
class AnimatedJoint
{
JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, AnimatedJoint)
public:
String mJointName; ///< Name of the joint
KeyframeVector mKeyframes; ///< List of keyframes over time
};
using AnimatedJointVector = Array<AnimatedJoint>;
/// Get the length (in seconds) of this animation
float GetDuration() const;
/// Scale the size of all joints by inScale
void ScaleJoints(float inScale);
/// If the animation is looping or not. If an animation is looping, the animation will continue playing after completion
void SetIsLooping(bool inIsLooping) { mIsLooping = inIsLooping; }
bool IsLooping() const { return mIsLooping; }
/// Get the (interpolated) joint transforms at time inTime
void Sample(float inTime, SkeletonPose &ioPose) const;
/// Get joint samples
const AnimatedJointVector & GetAnimatedJoints() const { return mAnimatedJoints; }
AnimatedJointVector & GetAnimatedJoints() { return mAnimatedJoints; }
/// Saves the state of this animation in binary form to inStream.
void SaveBinaryState(StreamOut &inStream) const;
using AnimationResult = Result<Ref<SkeletalAnimation>>;
/// Restore a saved ragdoll from inStream
static AnimationResult sRestoreFromBinaryState(StreamIn &inStream);
private:
AnimatedJointVector mAnimatedJoints; ///< List of joints and keyframes
bool mIsLooping = true; ///< If this animation loops back to start
};
JPH_NAMESPACE_END