From 6deda4129825b4b77fb7179f43d4bb7a755c4813 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Fri, 5 Sep 2025 09:55:25 -0300 Subject: feat Add hierarchy to skeletal mesh --- src/blu_cat/com/binary_reader.cpp | 8 ++++++++ src/blu_cat/com/binary_reader.hpp | 3 +++ src/blu_cat/com/numbers.hpp | 1 + src/blu_cat/gra/animation.cpp | 7 ++++--- src/blu_cat/gra/animation.hpp | 7 ++++--- src/blu_cat/gra/skeletal_mesh.cpp | 8 ++++++-- src/blu_cat/gra/skeletal_model.cpp | 40 ++++++++++++++++++++++---------------- 7 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/blu_cat/com/binary_reader.cpp b/src/blu_cat/com/binary_reader.cpp index bb4d231..d572ec9 100644 --- a/src/blu_cat/com/binary_reader.cpp +++ b/src/blu_cat/com/binary_reader.cpp @@ -67,6 +67,14 @@ BinaryReader::read_ui8() return this->data[this->_pointer++]; } +UI32 +BinaryReader::read_ui16() +{ + UI8 b1{this->data[_pointer++]}, b2{this->data[_pointer++]}; + + return b1 << 8 | b2; +} + UI32 BinaryReader::read_ui32() { diff --git a/src/blu_cat/com/binary_reader.hpp b/src/blu_cat/com/binary_reader.hpp index fec88b6..7b7309c 100644 --- a/src/blu_cat/com/binary_reader.hpp +++ b/src/blu_cat/com/binary_reader.hpp @@ -42,6 +42,9 @@ public: UI8 read_ui8(); + UI32 + read_ui16(); + UI32 read_ui32(); diff --git a/src/blu_cat/com/numbers.hpp b/src/blu_cat/com/numbers.hpp index 1fd3400..6f0ca47 100644 --- a/src/blu_cat/com/numbers.hpp +++ b/src/blu_cat/com/numbers.hpp @@ -60,6 +60,7 @@ typedef uint_fast64_t UI64F; typedef std::float32_t F32; typedef std::float64_t F64; +constexpr UI32F SIZE_16_BIT{2}; constexpr UI32F SIZE_32_BIT{4}; constexpr UI32F SIZE_64_BIT{8}; diff --git a/src/blu_cat/gra/animation.cpp b/src/blu_cat/gra/animation.cpp index dc2c281..062fb48 100644 --- a/src/blu_cat/gra/animation.cpp +++ b/src/blu_cat/gra/animation.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 Frederico de Oliveira Linhares + * Copyright 2022-2025 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,9 @@ namespace BluCat::GRA { -Bone::Bone(glm::mat4 offset_matrix): - offset_matrix{offset_matrix} +Bone::Bone(glm::mat4 offset_matrix, UI16 parent): + offset_matrix{offset_matrix}, + parent{parent} { } diff --git a/src/blu_cat/gra/animation.hpp b/src/blu_cat/gra/animation.hpp index 1275b48..11b1d0a 100644 --- a/src/blu_cat/gra/animation.hpp +++ b/src/blu_cat/gra/animation.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 Frederico de Oliveira Linhares + * Copyright 2022-2025 Frederico de Oliveira Linhares * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,15 +28,16 @@ namespace BluCat::GRA struct Bone { glm::mat4x4 offset_matrix; + UI16 parent; - Bone(glm::mat4 offset_matrix); + Bone(glm::mat4 offset_matrix, UI16 parent); }; struct BoneTransform { uint32_t bone_id; - Channel positions; Channel rotations; + Channel positions; Channel scales; }; diff --git a/src/blu_cat/gra/skeletal_mesh.cpp b/src/blu_cat/gra/skeletal_mesh.cpp index 1515dda..8e2e39f 100644 --- a/src/blu_cat/gra/skeletal_mesh.cpp +++ b/src/blu_cat/gra/skeletal_mesh.cpp @@ -86,7 +86,7 @@ load_mesh(void *obj) SKELETAL_MESH_HEADER_SIZE + header.num_vertexes * 16 * SIZE_32_BIT + header.num_indexes * SIZE_32_BIT + - header.num_bones * 16 * SIZE_32_BIT + + header.num_bones * (16 * SIZE_32_BIT + SIZE_16_BIT) + header.num_animations * (2 * SIZE_64_BIT + SIZE_32_BIT) + header.num_bone_transforms * 4 * SIZE_32_BIT + header.num_bone_positions * (3 * SIZE_32_BIT + SIZE_64_BIT) + @@ -153,7 +153,11 @@ load_mesh(void *obj) { // Load bones self->mesh->bones.reserve(header.num_bones); for(int i{0}; i < header.num_bones; i++) - self->mesh->bones.emplace_back(input.read_mat4()); + { + auto matrix{input.read_mat4()}; + auto parent{input.read_ui16()}; + self->mesh->bones.emplace_back(matrix, parent); + } } { // Load animations diff --git a/src/blu_cat/gra/skeletal_model.cpp b/src/blu_cat/gra/skeletal_model.cpp index 4b44910..726b97e 100644 --- a/src/blu_cat/gra/skeletal_model.cpp +++ b/src/blu_cat/gra/skeletal_model.cpp @@ -172,30 +172,30 @@ SkeletalModel::~SkeletalModel() void SkeletalModel::tick(float delta) { - BluCat::GRA::Animation *current_animation = - &this->skeletal_mesh->animations[this->animation_index]; + BluCat::GRA::Animation ¤t_animation = + this->skeletal_mesh->animations[this->animation_index]; { // update time this->animation_time += delta; - if(this->animation_time > current_animation->final_time) + if(this->animation_time > current_animation.final_time) { - this->animation_time -= current_animation->final_time; + this->animation_time -= current_animation.final_time; for(BluCat::GRA::BoneTransform &bone_transform: - current_animation->bone_transforms) + current_animation.bone_transforms) { - bone_transform.positions.current_index = 0; - bone_transform.rotations.current_index = 0; - bone_transform.scales.current_index = 0; + bone_transform.positions.current_index = 0; + bone_transform.rotations.current_index = 0; + bone_transform.scales.current_index = 0; } } } - for(int i{0}; i < current_animation->bone_transforms.size(); i++) + for(UI16 i{0}; i < current_animation.bone_transforms.size(); i++) { - BluCat::GRA::BoneTransform *bone_transform = - ¤t_animation->bone_transforms[i]; + BluCat::GRA::BoneTransform &bone_transform = + current_animation.bone_transforms[i]; - auto position{bone_transform->positions.interpolate( + auto position{bone_transform.positions.interpolate( this->animation_time, [](glm::vec3 frame) { @@ -208,7 +208,7 @@ SkeletalModel::tick(float delta) return glm::translate(glm::mat4(1.0f), final_position); })}; - auto rotation{bone_transform->rotations.interpolate( + auto rotation{bone_transform.rotations.interpolate( this->animation_time, [](glm::quat frame) { @@ -220,7 +220,7 @@ SkeletalModel::tick(float delta) previous_frame, next_frame, scale_factor)); })}; - auto scale{bone_transform->scales.interpolate( + auto scale{bone_transform.scales.interpolate( this->animation_time, [](glm::vec3 frame) { @@ -233,9 +233,15 @@ SkeletalModel::tick(float delta) return glm::scale(glm::mat4(1.0f), scale); })}; - this->bone_transforms[i] = - this->skeletal_mesh->bones[i].offset_matrix * - (position * rotation * scale); + auto parent{this->skeletal_mesh->bones[i].parent}; + auto node_transform{(this->skeletal_mesh->bones[i].offset_matrix * + (position * rotation * scale))}; + + if(parent == i) + this->bone_transforms[i] = node_transform; + else + this->bone_transforms[i] = + this->bone_transforms[parent] * node_transform; } } -- cgit v1.2.3