100 lines
2.4 KiB
C++
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;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}; |