space-game001/src/BoneAnimatedModel.h
2026-04-16 17:48:23 +03:00

100 lines
2.4 KiB
C++

#pragma once
#include "render/Renderer.h"
#include <unordered_map>
namespace ZL
{
constexpr int MAX_BONE_COUNT = 6;
constexpr int MAX_GPU_BONES = 64;
struct Bone
{
Vector3f boneStartWorld;
float boneLength;
Matrix4f boneMatrixWorld;
int parent;
std::vector<int> children;
};
struct BoneWeight
{
int boneIndex = -1;
float weight = 0;
};
struct AnimationKeyFrame
{
int frame;
std::vector<Bone> bones;
};
struct Animation
{
std::vector<AnimationKeyFrame> keyFrames;
};
struct GpuBoneData {
std::vector<Vector4f> boneIndices0; // bone indices 0-3 per vertex (as float)
std::vector<Vector2f> boneIndices1; // bone indices 4-5 per vertex
std::vector<Vector4f> boneWeights0; // bone weights 0-3 per vertex
std::vector<Vector2f> boneWeights1; // bone weights 4-5 per vertex
bool prepared = false;
void PrepareGpuSkinningData(const std::vector<std::array<BoneWeight, MAX_BONE_COUNT>>& verticesBoneWeight);
};
struct BoneSystem
{
VertexDataStruct mesh;
VertexDataStruct startMesh;
std::vector<std::array<BoneWeight, MAX_BONE_COUNT>> verticesBoneWeight;
Matrix4f armatureMatrix;
std::vector<Bone> startBones;
std::vector<Bone> currentBones;
std::vector<Animation> animations;
int startingFrame = 0;
void LoadFromFile(const std::string& fileName, const std::string& ZIPFileName = "");
void LoadFromBinaryFile(const std::string& fileName, const std::string& ZIPFileName = "");
void Interpolate(int frame);
// GPU skinning: compute skinning matrices without modifying the mesh
//void ComputeSkinningMatrices(int frame, std::vector<Matrix4f>& outMatrices) const;
};
struct GpuSkinningShaderData {
GpuBoneData gpuBoneData;
// GPU skinning data (lazily initialized)
VertexRenderStruct bindPoseMutable;
std::shared_ptr<VBOHolder> boneIndices0VBO;
std::shared_ptr<VBOHolder> boneIndices1VBO;
std::shared_ptr<VBOHolder> boneWeights0VBO;
std::shared_ptr<VBOHolder> boneWeights1VBO;
bool gpuSkinningPrepared = false;
std::vector<Eigen::Matrix4f> skinningMatrices;
void prepareGpuSkinningVBOs(BoneSystem& model);
void RenderVBO(Renderer& renderer);
void ComputeSkinningMatrices(const std::vector<Bone>& startBones, const std::vector<AnimationKeyFrame>& keyFrames, int frame);
};
struct BoneAnimationData {
BoneSystem model;
float currentFrame = 0.f;
int lastFrame = -1;
int totalFrames = 1;
GpuSkinningShaderData gpuSkinningShaderData;
};
};