Skip to content

Commit

Permalink
Add serialization to SkeletalAnimation (#1372)
Browse files Browse the repository at this point in the history
Small changes to add SkeletalAnimation::SaveBinaryState and SkeletalAnimation::sRestoreFromBinaryState features for serializing and deserializing the SkeletalAnimation instances.

Also added a public facing API to change the mIsLooping flag which was previously always true
  • Loading branch information
GustavoSilvera authored Dec 4, 2024
1 parent 24c4873 commit 4257d30
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Jolt/Skeleton/SkeletalAnimation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <Jolt/Skeleton/SkeletalAnimation.h>
#include <Jolt/Skeleton/SkeletonPose.h>
#include <Jolt/ObjectStream/TypeDeclarations.h>
#include <Jolt/Core/StreamIn.h>
#include <Jolt/Core/StreamOut.h>

JPH_NAMESPACE_BEGIN

Expand Down Expand Up @@ -107,4 +109,57 @@ void SkeletalAnimation::Sample(float inTime, SkeletonPose &ioPose) const
}
}

void SkeletalAnimation::SaveBinaryState(StreamOut &inStream) const
{
inStream.Write((uint32)mAnimatedJoints.size());
for (const AnimatedJoint &j : mAnimatedJoints)
{
// Write Joint name and number of keyframes
inStream.Write(j.mJointName);
inStream.Write((uint32)j.mKeyframes.size());
for (const Keyframe &k : j.mKeyframes)
{
inStream.Write(k.mTime);
inStream.Write(k.mRotation);
inStream.Write(k.mTranslation);
}
}

// Save additional parameters
inStream.Write(mIsLooping);
}

SkeletalAnimation::AnimationResult SkeletalAnimation::sRestoreFromBinaryState(StreamIn &inStream)
{
AnimationResult result;

Ref<SkeletalAnimation> animation = new SkeletalAnimation;

// Restore animated joints
uint32 len = 0;
inStream.Read(len);
animation->mAnimatedJoints.resize(len);
for (AnimatedJoint &j : animation->mAnimatedJoints)
{
// Read joint name
inStream.Read(j.mJointName);

// Read keyframes
len = 0;
inStream.Read(len);
j.mKeyframes.resize(len);
for (Keyframe &k : j.mKeyframes)
{
inStream.Read(k.mTime);
inStream.Read(k.mRotation);
inStream.Read(k.mTranslation);
}
}

// Read additional parameters
inStream.Read(animation->mIsLooping);
result.Set(animation);
return result;
}

JPH_NAMESPACE_END
14 changes: 14 additions & 0 deletions Jolt/Skeleton/SkeletalAnimation.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#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
Expand Down Expand Up @@ -62,13 +64,25 @@ class JPH_EXPORT SkeletalAnimation : public RefTarget<SkeletalAnimation>
/// 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
Expand Down

0 comments on commit 4257d30

Please sign in to comment.