134 lines
3.9 KiB
C
134 lines
3.9 KiB
C
|
|
//
|
||
|
|
// Created by martin on 11.04.25.
|
||
|
|
//
|
||
|
|
|
||
|
|
#ifndef ANIMATIONLIBRARY_H
|
||
|
|
#define ANIMATIONLIBRARY_H
|
||
|
|
|
||
|
|
#include <iostream>
|
||
|
|
|
||
|
|
#include "AnimGraph/AnimGraphData.h"
|
||
|
|
#include "ozz/base/io/archive.h"
|
||
|
|
#include "ozz/base/io/stream.h"
|
||
|
|
#include "ozz/base/log.h"
|
||
|
|
|
||
|
|
struct AnimLibrary {
|
||
|
|
typedef std::map<std::string, AnimationResource> AnimationResourceMap;
|
||
|
|
AnimationResourceMap mAnimations = {};
|
||
|
|
std::vector<ozz::animation::Animation*> mManagedAnimations = {};
|
||
|
|
|
||
|
|
AnimLibrary() = default;
|
||
|
|
~AnimLibrary() { Reset(); }
|
||
|
|
|
||
|
|
// Move operators. Needed to avoid duplicate frees on the managed animations.
|
||
|
|
AnimLibrary(AnimLibrary&& other)
|
||
|
|
: mAnimations(std::move(other.mAnimations)),
|
||
|
|
mManagedAnimations(std::move(other.mManagedAnimations)) {};
|
||
|
|
AnimLibrary& operator=(AnimLibrary&& other) {
|
||
|
|
mAnimations = other.mAnimations;
|
||
|
|
mManagedAnimations = std::move(other.mManagedAnimations);
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool AddAnimation(
|
||
|
|
const std::string& name,
|
||
|
|
ozz::animation::Animation* animation) {
|
||
|
|
AnimationResource animation_resource;
|
||
|
|
animation_resource.m_name = name;
|
||
|
|
animation_resource.m_animation = animation;
|
||
|
|
mAnimations[name] = animation_resource;
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool AddAnimationFile(const std::string& name, const std::string& filename) {
|
||
|
|
if (mAnimations.find(name) != mAnimations.end()) {
|
||
|
|
std::cerr << "Cannot add animation '" << name
|
||
|
|
<< "' to library. Animation already exists." << std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
ozz::animation::Animation* animation = new ozz::animation::Animation;
|
||
|
|
|
||
|
|
assert(!filename.empty());
|
||
|
|
ozz::io::File file(filename.c_str(), "rb");
|
||
|
|
if (!file.opened()) {
|
||
|
|
ozz::log::Err() << "Failed to open animation file " << filename << "."
|
||
|
|
<< std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
ozz::io::IArchive archive(&file);
|
||
|
|
if (!archive.TestTag<ozz::animation::Animation>()) {
|
||
|
|
ozz::log::Err() << "Failed to load animation instance from file "
|
||
|
|
<< filename << "." << std::endl;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Once the tag is validated, reading cannot fail.
|
||
|
|
archive >> *animation;
|
||
|
|
|
||
|
|
mManagedAnimations.push_back(animation);
|
||
|
|
|
||
|
|
AnimationResource animation_resource;
|
||
|
|
animation_resource.m_name = name;
|
||
|
|
animation_resource.m_animation = animation;
|
||
|
|
animation_resource.m_filename = filename;
|
||
|
|
|
||
|
|
mAnimations[name] = animation_resource;
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void Reset() {
|
||
|
|
for (ozz::animation::Animation* animation : mManagedAnimations) {
|
||
|
|
assert(animation->num_tracks() < 5);
|
||
|
|
delete animation;
|
||
|
|
}
|
||
|
|
|
||
|
|
mManagedAnimations.clear();
|
||
|
|
mAnimations.clear();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
inline void to_json(nlohmann::json& j, const AnimLibrary& animation_library) {
|
||
|
|
j["type"] = "AnimationLibrary";
|
||
|
|
|
||
|
|
for (AnimLibrary::AnimationResourceMap::const_iterator iter =
|
||
|
|
animation_library.mAnimations.cbegin();
|
||
|
|
iter != animation_library.mAnimations.cend();
|
||
|
|
++iter) {
|
||
|
|
j["animations"][iter->first] = iter->second;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
inline void from_json(const nlohmann::json& j, AnimLibrary& animation_library) {
|
||
|
|
animation_library.Reset();
|
||
|
|
|
||
|
|
if (!j.contains("type") || j["type"] != "AnimationLibrary") {
|
||
|
|
std::cerr << "Invalid type. Expected 'AnimationLibrary'." << std::endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!j.contains("animations")) {
|
||
|
|
std::cerr << "Invalid AnimationLibrary. Expected 'animations' key."
|
||
|
|
<< std::endl;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (nlohmann::json::const_iterator iter = j["animations"].begin();
|
||
|
|
iter != j["animations"].cend();
|
||
|
|
++iter) {
|
||
|
|
AnimationResource animation_resource = *iter;
|
||
|
|
|
||
|
|
if (!animation_resource.m_filename.empty()) {
|
||
|
|
animation_library.AddAnimationFile(
|
||
|
|
iter.key(),
|
||
|
|
j["animations"][iter.key()]["filename"]);
|
||
|
|
animation_library.mAnimations[iter.key()].m_sync_track =
|
||
|
|
animation_resource.m_sync_track;
|
||
|
|
} else {
|
||
|
|
animation_library.mAnimations[iter.key()] = *iter;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif //ANIMATIONLIBRARY_H
|