Compare commits
4 Commits
36c7f7a11e
...
5d01dfcca2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5d01dfcca2 | ||
![]() |
89fedce539 | ||
![]() |
f6f7e92cea | ||
![]() |
d32c247cc0 |
@ -45,8 +45,6 @@ set(ThirdPartyIncludeDeps
|
||||
|
||||
# Shared code by main executable and tests
|
||||
add_library(AnimTestbedCode OBJECT
|
||||
src/SyncTrack.cc
|
||||
src/SyncTrack.h
|
||||
src/ozzutils.cc
|
||||
src/AnimGraph/AnimGraphNodes.cc
|
||||
src/AnimGraph/AnimGraphNodes.h
|
||||
@ -59,7 +57,11 @@ add_library(AnimTestbedCode OBJECT
|
||||
src/AnimGraph/AnimNode.cc
|
||||
src/AnimGraph/AnimNode.h
|
||||
src/AnimGraph/AnimGraphResource.cc
|
||||
src/AnimGraph/AnimGraphResource.h)
|
||||
src/AnimGraph/AnimGraphResource.h
|
||||
src/AnimGraph/SyncTrack.cc
|
||||
src/AnimGraph/SyncTrack.h
|
||||
src/AnimGraph/AnimLibrary.h
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
AnimTestbedCode
|
||||
@ -150,6 +152,9 @@ target_sources(runtests PRIVATE
|
||||
tests/AnimGraphEvalTests.cc
|
||||
tests/NodeDescriptorTests.cc
|
||||
tests/SyncTrackTests.cc
|
||||
tests/AnimDataTests.cc
|
||||
tests/TestAnimData.cc
|
||||
tests/TestAnimData.h
|
||||
tests/main.cc
|
||||
${ozz_offline_test_objs}
|
||||
)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define ANIMTESTBED_ANIMGRAPHBLENDTREE_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "AnimNode.h"
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include <ozz/base/maths/soa_transform.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@ -33,11 +32,33 @@ struct AnimDataRef {
|
||||
Pose* ptr = nullptr;
|
||||
};
|
||||
|
||||
struct AnimationFileResource {
|
||||
struct AnimationResource {
|
||||
std::string m_name;
|
||||
std::string m_filename;
|
||||
|
||||
ozz::animation::Animation* m_animation;
|
||||
SyncTrack m_sync_track;
|
||||
};
|
||||
|
||||
inline void to_json(
|
||||
nlohmann::json& j,
|
||||
const AnimationResource& animation_resource) {
|
||||
j["type"] = "AnimationResource";
|
||||
j["name"] = animation_resource.m_name;
|
||||
j["filename"] = animation_resource.m_filename;
|
||||
j["synctrack"] = animation_resource.m_sync_track;
|
||||
}
|
||||
|
||||
inline void from_json(
|
||||
const nlohmann::json& j,
|
||||
AnimationResource& animation_resource) {
|
||||
assert(j["type"] == "AnimationResource");
|
||||
|
||||
animation_resource.m_name = j["name"];
|
||||
animation_resource.m_filename = j["filename"];
|
||||
animation_resource.m_sync_track = j["synctrack"];
|
||||
}
|
||||
|
||||
struct AnimDataAllocator {
|
||||
struct PoseList {
|
||||
Pose* m_anim_data = nullptr;
|
||||
@ -109,7 +130,7 @@ struct AnimGraphContext {
|
||||
AnimGraph* m_graph = nullptr;
|
||||
ozz::animation::Skeleton* m_skeleton = nullptr;
|
||||
|
||||
typedef std::map<std::string, AnimationFileResource> AnimationFileMap;
|
||||
typedef std::map<std::string, AnimationResource> AnimationFileMap;
|
||||
AnimationFileMap m_animation_map;
|
||||
|
||||
void freeAnimations() {
|
||||
|
@ -151,7 +151,11 @@ bool AnimSamplerNode::Init(AnimGraphContext& context) {
|
||||
|
||||
archive >> *m_animation;
|
||||
|
||||
context.m_animation_map[m_filename] = {m_animation, SyncTrack()};
|
||||
context.m_animation_map[m_filename] = {
|
||||
m_filename,
|
||||
m_filename,
|
||||
m_animation,
|
||||
SyncTrack()};
|
||||
}
|
||||
|
||||
assert(context.m_skeleton != nullptr);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef ANIMTESTBED_ANIMGRAPHRESOURCE_H
|
||||
#define ANIMTESTBED_ANIMGRAPHRESOURCE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "3rdparty/json/json.hpp"
|
||||
#include "AnimGraphNodes.h"
|
||||
|
||||
|
133
src/AnimGraph/AnimLibrary.h
Normal file
133
src/AnimGraph/AnimLibrary.h
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// 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
|
@ -3,7 +3,3 @@
|
||||
//
|
||||
|
||||
#include "SyncTrack.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <sstream>
|
@ -15,6 +15,7 @@
|
||||
#include "imnodes.h"
|
||||
#include "misc/cpp/imgui_stdlib.h"
|
||||
#include "nfd.h"
|
||||
#include "ozz/base/log.h"
|
||||
#include "src/AnimGraph/AnimGraphResource.h"
|
||||
|
||||
struct EditorState {
|
||||
@ -154,21 +155,7 @@ void SyncTrackEditor(SyncTrack* sync_track) {
|
||||
}
|
||||
|
||||
ImGui::Text("Marker:");
|
||||
for (int i = 0; i < sync_track->m_num_intervals; i++) {
|
||||
ImGui::Text("%2d:", i);
|
||||
ImGui::SameLine();
|
||||
std::ostringstream marker_stream;
|
||||
marker_stream << i;
|
||||
ImGui::SliderFloat(
|
||||
marker_stream.str().c_str(),
|
||||
&sync_track->m_sync_markers[i],
|
||||
0.f,
|
||||
1.f);
|
||||
}
|
||||
|
||||
if (ImGui::Button("Update Intervals")) {
|
||||
sync_track->CalcIntervals();
|
||||
}
|
||||
ImGui::Text("TODO");
|
||||
}
|
||||
|
||||
void SkinnedMeshWidget(SkinnedMesh* skinned_mesh) {
|
||||
|
@ -4,9 +4,13 @@
|
||||
|
||||
#include "SkinnedMesh.h"
|
||||
|
||||
#include <HandmadeMath.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include "ozz/animation/runtime/local_to_model_job.h"
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/io/stream.h"
|
||||
#include "ozz/base/log.h"
|
||||
|
||||
SkinnedMesh::~SkinnedMesh() {
|
||||
while (m_animations.size() > 0) {
|
||||
ozz::animation::Animation* animation_ptr =
|
||||
@ -98,4 +102,3 @@ void SkinnedMesh::CalcModelMatrices() {
|
||||
}
|
||||
|
||||
void SkinnedMesh::DrawSkeleton() {}
|
||||
|
||||
|
@ -5,21 +5,13 @@
|
||||
#ifndef ANIMTESTBED_SKINNEDMESH_H
|
||||
#define ANIMTESTBED_SKINNEDMESH_H
|
||||
|
||||
// ozz-animation headers
|
||||
#include <cmath> // fmodf
|
||||
#include <memory> // std::unique_ptr, std::make_unique
|
||||
#include "AnimGraph/SyncTrack.h"
|
||||
|
||||
#include "SyncTrack.h"
|
||||
#include "ozz/animation/runtime/animation.h"
|
||||
#include "ozz/animation/runtime/local_to_model_job.h"
|
||||
#include "ozz/animation/runtime/sampling_job.h"
|
||||
#include "ozz/animation/runtime/skeleton.h"
|
||||
#include "ozz/base/containers/vector.h"
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/io/stream.h"
|
||||
#include "ozz/base/log.h"
|
||||
#include "ozz/base/maths/soa_transform.h"
|
||||
#include "ozz/base/maths/vec_float.h"
|
||||
|
||||
struct SkinnedMesh {
|
||||
SkinnedMesh() : m_sync_track_override(false), m_override_anim(0.f) {}
|
||||
|
@ -5,37 +5,13 @@
|
||||
#include "SkinnedMeshResource.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "3rdparty/json/json.hpp"
|
||||
|
||||
inline void to_json(nlohmann::json& j, const SyncTrack& syncTrack) {
|
||||
j["type"] = "SyncTrack";
|
||||
j["duration"] = syncTrack.m_duration;
|
||||
for (int i = 0; i < syncTrack.m_num_intervals; i++) {
|
||||
j["markers"][i] = syncTrack.m_sync_markers[i];
|
||||
}
|
||||
}
|
||||
|
||||
inline void from_json(const nlohmann::json& j, SyncTrack& syncTrack) {
|
||||
if (!j.contains("type") || j["type"] != "SyncTrack") {
|
||||
std::cerr << "Unable to parse SyncTrack: wrong json type!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
syncTrack.m_duration = j["duration"];
|
||||
syncTrack.m_num_intervals = j["markers"].size();
|
||||
|
||||
if (syncTrack.m_num_intervals > cSyncTrackMaxIntervals) {
|
||||
std::cerr << "Invalid number of sync intervals: found " << syncTrack.m_num_intervals << " maximum is " << cSyncTrackMaxIntervals << "." << std::endl;
|
||||
syncTrack = SyncTrack();
|
||||
}
|
||||
|
||||
for (int i = 0; i < syncTrack.m_num_intervals; i++) {
|
||||
syncTrack.m_sync_markers[i] = j["markers"].at(i);
|
||||
}
|
||||
}
|
||||
|
||||
inline void to_json(nlohmann::json& j, const SkinnedMeshResource& skinnedMeshResource) {
|
||||
inline void to_json(
|
||||
nlohmann::json& j,
|
||||
const SkinnedMeshResource& skinnedMeshResource) {
|
||||
j["type"] = "SkinnedMeshResource";
|
||||
j["skeleton"]["file"] = skinnedMeshResource.m_skeleton_file;
|
||||
for (int i = 0; i < skinnedMeshResource.m_animation_files.size(); i++) {
|
||||
@ -44,15 +20,18 @@ inline void to_json(nlohmann::json& j, const SkinnedMeshResource& skinnedMeshRes
|
||||
}
|
||||
}
|
||||
|
||||
inline void from_json(const nlohmann::json& j, SkinnedMeshResource& skinnedMeshResource) {
|
||||
inline void from_json(
|
||||
const nlohmann::json& j,
|
||||
SkinnedMeshResource& skinnedMeshResource) {
|
||||
if (!j.contains("type") || j["type"] != "SkinnedMeshResource") {
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: wrong json type!" << std::endl;
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: wrong json type!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!j.contains("skeleton") || !j["skeleton"].contains("file")) {
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: no skeleton file found!" << std::endl;
|
||||
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: no skeleton file found!"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
skinnedMeshResource.m_skeleton_file = j["skeleton"]["file"];
|
||||
@ -61,13 +40,18 @@ inline void from_json(const nlohmann::json& j, SkinnedMeshResource& skinnedMeshR
|
||||
int num_animations = j["animations"].size();
|
||||
|
||||
for (int i = 0; i < num_animations; i++) {
|
||||
if (!j["animations"][i].contains("file") || !j["animations"][i].contains("sync_track")) {
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: invalid animation definition" << std::endl;
|
||||
if (!j["animations"][i].contains("file")
|
||||
|| !j["animations"][i].contains("sync_track")) {
|
||||
std::cerr << "Unable to parse SkinnedMeshResource: invalid animation "
|
||||
"definition"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
skinnedMeshResource.m_animation_files.push_back(j["animations"][i]["file"]);
|
||||
skinnedMeshResource.m_sync_tracks.push_back(j["animations"][i]["sync_track"].get<SyncTrack>());
|
||||
skinnedMeshResource.m_animation_files.push_back(
|
||||
j["animations"][i]["file"]);
|
||||
skinnedMeshResource.m_sync_tracks.push_back(
|
||||
j["animations"][i]["sync_track"].get<SyncTrack>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -108,5 +92,3 @@ void SkinnedMeshResource::createInstance(SkinnedMesh& skinnedMesh) const {
|
||||
skinnedMesh.m_animation_sync_track.back() = m_sync_tracks[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "SyncTrack.h"
|
||||
#include "AnimGraph/SyncTrack.h"
|
||||
#include "SkinnedMesh.h"
|
||||
|
||||
struct SkinnedMeshResource {
|
||||
|
41
tests/AnimDataTests.cc
Normal file
41
tests/AnimDataTests.cc
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// Created by martin on 11.04.25.
|
||||
//
|
||||
|
||||
#include "3rdparty/json/json.hpp"
|
||||
#include "AnimGraph/AnimLibrary.h"
|
||||
#include "TestAnimData.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
using namespace nlohmann;
|
||||
|
||||
TEST_CASE("Serialize AnimLibrary", "[AnimLibrary]") {
|
||||
AnimLibrary library;
|
||||
|
||||
TestAnimData::SingleBoneSkeleton single_bone_testdata;
|
||||
|
||||
REQUIRE(library.AddAnimationFile(
|
||||
"translation_x",
|
||||
single_bone_testdata.animation_translate_x_resource.m_filename));
|
||||
REQUIRE(library.AddAnimationFile(
|
||||
"translation_y",
|
||||
single_bone_testdata.animation_translate_y_resource.m_filename));
|
||||
|
||||
// serialize
|
||||
json library_data;
|
||||
library_data = library;
|
||||
|
||||
// deserialize
|
||||
AnimLibrary library_deserialized;
|
||||
library_deserialized = library_data;
|
||||
|
||||
CHECK(library_deserialized.mAnimations.size() == library.mAnimations.size());
|
||||
for (AnimLibrary::AnimationResourceMap::const_iterator iter =
|
||||
library.mAnimations.cbegin();
|
||||
iter != library.mAnimations.cend();
|
||||
++iter) {
|
||||
CHECK(
|
||||
library_deserialized.mAnimations.find(iter->first)
|
||||
!= library_deserialized.mAnimations.end());
|
||||
}
|
||||
}
|
@ -199,9 +199,13 @@ TEST_CASE_METHOD(
|
||||
AnimGraphContext graph_context;
|
||||
graph_context.m_skeleton = skeleton.get();
|
||||
graph_context.m_animation_map["trans_x"] = {
|
||||
"trans_x",
|
||||
"",
|
||||
animation_translate_x.get(),
|
||||
animation_translate_x_sync_track};
|
||||
graph_context.m_animation_map["trans_y"] = {
|
||||
"trans_y",
|
||||
"",
|
||||
animation_translate_y.get(),
|
||||
animation_translate_y_sync_track};
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Created by martin on 16.11.21.
|
||||
//
|
||||
|
||||
#include "SyncTrack.h"
|
||||
#include "AnimGraph/SyncTrack.h"
|
||||
#include "catch.hpp"
|
||||
|
||||
TEST_CASE("Basic", "[SyncTrack]") {
|
||||
|
117
tests/TestAnimData.cc
Normal file
117
tests/TestAnimData.cc
Normal file
@ -0,0 +1,117 @@
|
||||
//
|
||||
// Created by martin on 11.04.25.
|
||||
//
|
||||
|
||||
#include "TestAnimData.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ozz/animation/offline/animation_builder.h"
|
||||
#include "ozz/animation/offline/raw_animation.h"
|
||||
#include "ozz/animation/offline/raw_skeleton.h"
|
||||
#include "ozz/base/io/archive.h"
|
||||
#include "ozz/base/log.h"
|
||||
|
||||
namespace TestAnimData {
|
||||
|
||||
SingleBoneSkeleton::SingleBoneSkeleton() {
|
||||
using namespace ozz::animation::offline;
|
||||
|
||||
RawSkeleton raw_skeleton;
|
||||
RawSkeleton::Joint raw_joint;
|
||||
|
||||
raw_joint.name = "Bone0";
|
||||
raw_joint.transform.translation.x = 1.f;
|
||||
raw_joint.transform.translation.y = 2.f;
|
||||
raw_joint.transform.translation.z = 3.f;
|
||||
|
||||
raw_skeleton.roots.push_back(raw_joint);
|
||||
|
||||
SkeletonBuilder skeleton_builder;
|
||||
skeleton = skeleton_builder(raw_skeleton);
|
||||
|
||||
// SingleBoneSkeleton Animations
|
||||
ozz::animation::offline::RawAnimation raw_animation_translation_x;
|
||||
raw_animation_translation_x.name = "TranslationX";
|
||||
RawAnimation::JointTrack bone0_track;
|
||||
RawAnimation::JointTrack::Translations bone0_translations;
|
||||
|
||||
// animation_translate_x
|
||||
RawAnimation::TranslationKey translation_key;
|
||||
translation_key.time = 0.f;
|
||||
translation_key.value = ozz::math::Float3(0.f, 0.f, 0.f);
|
||||
bone0_translations.push_back(translation_key);
|
||||
|
||||
translation_key.time = 1.f;
|
||||
translation_key.value = ozz::math::Float3(1.f, 0.f, 0.f);
|
||||
bone0_translations.push_back(translation_key);
|
||||
|
||||
bone0_track.translations = bone0_translations;
|
||||
raw_animation_translation_x.tracks.push_back(bone0_track);
|
||||
raw_animation_translation_x.duration = 1.f;
|
||||
if (!raw_animation_translation_x.Validate()) {
|
||||
std::cerr << "Error: could animation raw data invalid!" << std::endl;
|
||||
}
|
||||
|
||||
AnimationBuilder animation_builder;
|
||||
animation_translate_x = animation_builder(raw_animation_translation_x);
|
||||
|
||||
animation_translate_x_resource.m_animation = animation_translate_x.get();
|
||||
SaveAnimation("single_bone_translation_z.ozz", animation_translate_x.get());
|
||||
animation_translate_x_resource.m_name = "single_bone_translation_z";
|
||||
animation_translate_x_resource.m_filename = "single_bone_translation_z.ozz";
|
||||
|
||||
// animation_translate_y
|
||||
ozz::animation::offline::RawAnimation raw_animation_translation_y;
|
||||
raw_animation_translation_y.name = "TranslationY";
|
||||
bone0_translations.clear();
|
||||
|
||||
translation_key.time = 0.f;
|
||||
translation_key.value = ozz::math::Float3(0.f, 0.f, 0.f);
|
||||
bone0_translations.push_back(translation_key);
|
||||
|
||||
translation_key.time = 1.f;
|
||||
translation_key.value = ozz::math::Float3(0.f, 1.f, 0.f);
|
||||
bone0_translations.push_back(translation_key);
|
||||
|
||||
bone0_track.translations = bone0_translations;
|
||||
raw_animation_translation_y.tracks.push_back(bone0_track);
|
||||
raw_animation_translation_y.duration = 1.f;
|
||||
if (!raw_animation_translation_y.Validate()) {
|
||||
std::cerr << "Error: could animation raw data invalid!" << std::endl;
|
||||
}
|
||||
|
||||
animation_translate_y = animation_builder(raw_animation_translation_y);
|
||||
|
||||
animation_translate_y_resource.m_animation = animation_translate_y.get();
|
||||
SaveAnimation("single_bone_translation_y.ozz", animation_translate_y.get());
|
||||
animation_translate_y_resource.m_name = "single_bone_translation_y";
|
||||
animation_translate_y_resource.m_filename = "single_bone_translation_y.ozz";
|
||||
}
|
||||
|
||||
bool SingleBoneSkeleton::SaveSkeleton(
|
||||
const char* filename,
|
||||
ozz::animation::Skeleton* skeleton) {
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SingleBoneSkeleton::SaveAnimation(
|
||||
const char* filename,
|
||||
ozz::animation::Animation* animation) {
|
||||
ozz::io::File file(filename, "wb");
|
||||
if (!file.opened()) {
|
||||
ozz::log::Err() << "Failed to create animation file " << filename << "."
|
||||
<< std::endl;
|
||||
delete animation;
|
||||
return false;
|
||||
}
|
||||
|
||||
ozz::io::OArchive archive(&file);
|
||||
|
||||
archive << *animation;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace TestAnimData
|
37
tests/TestAnimData.h
Normal file
37
tests/TestAnimData.h
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by martin on 11.04.25.
|
||||
//
|
||||
|
||||
#ifndef TESTANIMDATA_H
|
||||
#define TESTANIMDATA_H
|
||||
|
||||
#include "AnimGraph/AnimGraphData.h"
|
||||
#include "AnimGraph/SyncTrack.h"
|
||||
#include "ozz/animation/offline/skeleton_builder.h"
|
||||
#include "ozz/animation/runtime/animation.h"
|
||||
#include "ozz/animation/runtime/skeleton.h"
|
||||
|
||||
namespace TestAnimData {
|
||||
|
||||
struct SingleBoneSkeleton {
|
||||
SingleBoneSkeleton();
|
||||
|
||||
ozz::unique_ptr<ozz::animation::Skeleton> skeleton = nullptr;
|
||||
|
||||
ozz::unique_ptr<ozz::animation::Animation> animation_translate_x = nullptr;
|
||||
AnimationResource animation_translate_x_resource;
|
||||
SyncTrack animation_translate_x_sync_track = {};
|
||||
|
||||
ozz::unique_ptr<ozz::animation::Animation> animation_translate_y = nullptr;
|
||||
AnimationResource animation_translate_y_resource;
|
||||
SyncTrack animation_translate_y_sync_track = {};
|
||||
|
||||
bool SaveSkeleton(const char* filename, ozz::animation::Skeleton* skeleton);
|
||||
bool SaveAnimation(
|
||||
const char* filename,
|
||||
ozz::animation::Animation* animation);
|
||||
};
|
||||
|
||||
} // namespace TestAnimData
|
||||
|
||||
#endif //TESTANIMDATA_H
|
Loading…
x
Reference in New Issue
Block a user