Files
jak-project/goalc/build_actor/common/animation_processing.h
Hat Kid e6260e48ab decompiler: support animation export and support master art groups in build-actor tool (#4260)
Adds support for exporting animations for foreground models. It's not
perfect and doesn't handle the Jak 2/3 animations very well in some
cases (scale can often get messed up, especially for the LZO compressed
ones, I have no idea what is going on with the data in those art groups
sometimes, so that'll have to be revisited later...), but it does a
decent job on Jak 1.

Additionally, the `build-actor` tool has also been changed to support
setting the `master-art-group-name` and `master-art-group-index` fields
to allow for custom art groups to link their animations to a different
master art group, which lets you add custom animations to vanilla art
groups.
2026-05-04 17:19:41 +02:00

78 lines
2.4 KiB
C++

#pragma once
#include <string>
#include <vector>
#include "common/common_types.h"
#include "common/math/Vector.h"
#include "third-party/tiny_gltf/tiny_gltf.h"
namespace anim {
struct UncompressedSingleJointAnim {
std::vector<math::Vector3f> trans_frames;
std::vector<math::Vector3f> scale_frames;
std::vector<math::Vector4f> quat_frames;
};
struct UncompressedJointAnim {
std::string name;
std::string master_art_group_name;
int master_art_group_index = -1;
std::vector<UncompressedSingleJointAnim> joints;
float framerate = 60;
int frames = 0;
};
struct CompressedMatrixMetadata {
bool is_animated[2];
};
struct CompressedFrame {
std::vector<u16> data16;
std::vector<u32> data32;
std::vector<u64> data64;
int size_bytes() const { return data16.size() * 2 + data32.size() * 4 + data64.size() * 8; }
};
struct CompressedJointMetadata {
bool animated_trans = false;
bool animated_quat = false;
bool animated_scale = false;
bool big_trans_mode = false;
};
struct CompressedAnim {
std::string name;
std::string master_art_group_name;
int master_art_group_index = -1;
CompressedFrame fixed;
std::vector<CompressedFrame> frames;
bool matrix_animated[2] = {false, false};
std::vector<CompressedJointMetadata> joint_metadata;
float framerate = 60;
};
/*!
* Load animation data from GLTF file.
* @param model The GLTF model containing the animation
* @param anim The animation to convert
* @param node_to_joint Mapping from GLTF node index to the joint index
* @param master_art_group The master art group to link this animation to, if set.
* @param master_art_group_index The index of the slot in the master art group to link this
* animation to.
* @param framerate Number of key-frames per second. (this doesn't have to match frame rate, the
* game will interpolate between keyframes as needed.)
*/
UncompressedJointAnim extract_anim_from_gltf(const tinygltf::Model& model,
const tinygltf::Animation& anim,
const std::map<int, int>& node_to_joint,
const std::string& master_art_group,
int master_art_group_index,
float framerate);
CompressedAnim compress_animation(const UncompressedJointAnim& in);
} // namespace anim