Minor refactoring
This commit is contained in:
parent
71346b4227
commit
d47cfd1b6b
@ -196,35 +196,18 @@ namespace ZL
|
||||
}
|
||||
else
|
||||
{
|
||||
/*std::cout << "-Processing bone: " << boneName << ", parent: " << boneParent << " " << "sizeof:" << boneParent.size() << " " << strlen("None") <<
|
||||
int(boneParent[0])<<","<<
|
||||
int(boneParent[1]) << ","<<
|
||||
int(boneParent[2]) << ","<<
|
||||
int(boneParent[3]) << ","<<
|
||||
int(boneParent[4]) << "," <<
|
||||
int(boneParent[5]) << ","
|
||||
<< std::endl;*/
|
||||
bones[i].parent = getIndexByValue(boneParent, boneNames);
|
||||
}
|
||||
|
||||
for (int j = 0; j < boneChildren[boneName].size(); j++)
|
||||
{
|
||||
//std::cout << "Enumerating bones:" << j << " " << boneName << " " << boneChildren[boneName][j] << std::endl;
|
||||
|
||||
bones[i].children.push_back(getIndexByValue(boneChildren[boneName][j], boneNames));
|
||||
}
|
||||
|
||||
/*if (boneName == "Bone.020")
|
||||
{
|
||||
std::cout << i << std::endl;
|
||||
}*/
|
||||
}
|
||||
|
||||
startBones = bones;
|
||||
currentBones = bones;
|
||||
|
||||
///std::cout << "Hello!" << std::endl;
|
||||
|
||||
std::getline(f, tempLine); //vertice count
|
||||
int numberVertices;
|
||||
|
||||
@ -258,8 +241,6 @@ namespace ZL
|
||||
|
||||
//==== process uv and normals begin
|
||||
|
||||
//std::cout << "Hello x1" << std::endl;
|
||||
|
||||
std::getline(f, tempLine); //===UV Coordinates:
|
||||
|
||||
std::getline(f, tempLine); //triangle count
|
||||
@ -319,19 +300,10 @@ namespace ZL
|
||||
|
||||
uvCoords[i][j] = Vector2f{ floatValues[0],floatValues[1] };
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//std::cout << "Hello eee" << std::endl;
|
||||
|
||||
std::getline(f, tempLine); //===Normals:
|
||||
|
||||
|
||||
std::vector<Vector3f> normals;
|
||||
|
||||
normals.resize(numberVertices);
|
||||
@ -436,8 +408,6 @@ namespace ZL
|
||||
std::getline(f, tempLine);//=== Animation Keyframes ===
|
||||
std::getline(f, tempLine);//=== Bone Transforms per Keyframe ===
|
||||
|
||||
|
||||
|
||||
std::getline(f, tempLine);
|
||||
int numberKeyFrames;
|
||||
|
||||
@ -466,11 +436,6 @@ namespace ZL
|
||||
throw std::runtime_error("No number found in the input string.");
|
||||
}
|
||||
|
||||
/*if (i == 0)
|
||||
{
|
||||
startingFrame = numberFrame;
|
||||
}*/
|
||||
|
||||
animations[0].keyFrames[i].frame = numberFrame;
|
||||
|
||||
animations[0].keyFrames[i].bones.resize(numberBones);
|
||||
@ -479,7 +444,7 @@ namespace ZL
|
||||
{
|
||||
std::getline(f, tempLine);
|
||||
std::string boneName = tempLine.substr(8);
|
||||
//std::cout << "Processing keyframe " << i << ", bone: " << j << " " << boneName << std::endl;
|
||||
|
||||
int boneNumber = getIndexByValue(boneName, boneNames);
|
||||
animations[0].keyFrames[i].bones[boneNumber] = startBones[boneNumber];
|
||||
|
||||
@ -516,7 +481,6 @@ namespace ZL
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[0 + 2 * 4] = floatValues[2];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[0 + 3 * 4] = floatValues[3];
|
||||
|
||||
|
||||
std::getline(f, tempLine);
|
||||
b = tempLine.cbegin();
|
||||
e = tempLine.cend();
|
||||
@ -544,8 +508,6 @@ namespace ZL
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[2 + 1 * 4] = floatValues[1];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[2 + 2 * 4] = floatValues[2];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[2 + 3 * 4] = floatValues[3];
|
||||
|
||||
|
||||
std::getline(f, tempLine);
|
||||
b = tempLine.cbegin();
|
||||
e = tempLine.cend();
|
||||
@ -560,8 +522,6 @@ namespace ZL
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[3 + 2 * 4] = floatValues[2];
|
||||
animations[0].keyFrames[i].bones[boneNumber].boneMatrixWorld.data()[3 + 3 * 4] = floatValues[3];
|
||||
|
||||
//std::getline(f, tempLine);// ignore last matrix line
|
||||
|
||||
//=============== Matrix end ==================
|
||||
|
||||
}
|
||||
@ -587,6 +547,14 @@ namespace ZL
|
||||
}
|
||||
|
||||
startMesh = mesh;
|
||||
|
||||
|
||||
if (startBones.size() > MAX_GPU_BONES)
|
||||
{
|
||||
std::cout << "Warning: model has " << startBones.size()
|
||||
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
|
||||
//throw std::runtime_error("Too many bones for GPU skinning");
|
||||
}
|
||||
}
|
||||
|
||||
void BoneSystem::LoadFromBinaryFile(const std::string& fileName, const std::string& ZIPFileName)
|
||||
@ -747,49 +715,57 @@ namespace ZL
|
||||
}
|
||||
|
||||
startMesh = mesh;
|
||||
}
|
||||
|
||||
void BoneSystem::PrepareGpuSkinningData()
|
||||
{
|
||||
size_t vertexCount = verticesBoneWeight.size();
|
||||
gpuBoneData.boneIndices0.resize(vertexCount);
|
||||
gpuBoneData.boneIndices1.resize(vertexCount);
|
||||
gpuBoneData.boneWeights0.resize(vertexCount);
|
||||
gpuBoneData.boneWeights1.resize(vertexCount);
|
||||
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
{
|
||||
gpuBoneData.boneIndices0[i] = Vector4f(
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][0].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][1].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][2].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][3].boneIndex))
|
||||
);
|
||||
gpuBoneData.boneIndices1[i] = Vector2f(
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][4].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][5].boneIndex))
|
||||
);
|
||||
gpuBoneData.boneWeights0[i] = Vector4f(
|
||||
verticesBoneWeight[i][0].weight,
|
||||
verticesBoneWeight[i][1].weight,
|
||||
verticesBoneWeight[i][2].weight,
|
||||
verticesBoneWeight[i][3].weight
|
||||
);
|
||||
gpuBoneData.boneWeights1[i] = Vector2f(
|
||||
verticesBoneWeight[i][4].weight,
|
||||
verticesBoneWeight[i][5].weight
|
||||
);
|
||||
}
|
||||
|
||||
gpuBoneData.prepared = true;
|
||||
|
||||
if (startBones.size() > MAX_GPU_BONES)
|
||||
{
|
||||
std::cout << "Warning: model has " << startBones.size()
|
||||
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
|
||||
//throw std::runtime_error("Too many bones for GPU skinning");
|
||||
}
|
||||
}
|
||||
|
||||
void GpuBoneData::PrepareGpuSkinningData(const std::vector<std::array<BoneWeight, MAX_BONE_COUNT>>& verticesBoneWeight)
|
||||
{
|
||||
size_t vertexCount = verticesBoneWeight.size();
|
||||
boneIndices0.resize(vertexCount);
|
||||
boneIndices1.resize(vertexCount);
|
||||
boneWeights0.resize(vertexCount);
|
||||
boneWeights1.resize(vertexCount);
|
||||
|
||||
for (size_t i = 0; i < vertexCount; i++)
|
||||
{
|
||||
boneIndices0[i] = Vector4f(
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][0].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][1].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][2].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][3].boneIndex))
|
||||
);
|
||||
boneIndices1[i] = Vector2f(
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][4].boneIndex)),
|
||||
static_cast<float>(max(0, verticesBoneWeight[i][5].boneIndex))
|
||||
);
|
||||
boneWeights0[i] = Vector4f(
|
||||
verticesBoneWeight[i][0].weight,
|
||||
verticesBoneWeight[i][1].weight,
|
||||
verticesBoneWeight[i][2].weight,
|
||||
verticesBoneWeight[i][3].weight
|
||||
);
|
||||
boneWeights1[i] = Vector2f(
|
||||
verticesBoneWeight[i][4].weight,
|
||||
verticesBoneWeight[i][5].weight
|
||||
);
|
||||
}
|
||||
|
||||
prepared = true;
|
||||
|
||||
/*
|
||||
if (startBones.size() > MAX_GPU_BONES)
|
||||
{
|
||||
std::cout << "Warning: model has " << startBones.size()
|
||||
<< " bones, exceeding GPU skinning limit of " << MAX_GPU_BONES << std::endl;
|
||||
}*/
|
||||
}
|
||||
|
||||
void BoneSystem::ComputeSkinningMatrices(int frame, std::vector<Matrix4f>& outMatrices) const
|
||||
{
|
||||
int startingKeyFrame = -1;
|
||||
|
||||
@ -42,6 +42,7 @@ namespace ZL
|
||||
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
|
||||
@ -65,12 +66,26 @@ namespace ZL
|
||||
|
||||
void Interpolate(int frame);
|
||||
|
||||
// GPU skinning: prepare per-vertex bone data for VBO upload
|
||||
void PrepareGpuSkinningData();
|
||||
// GPU skinning: compute skinning matrices without modifying the mesh
|
||||
void ComputeSkinningMatrices(int frame, std::vector<Matrix4f>& outMatrices) const;
|
||||
};
|
||||
|
||||
struct BoneAnimationData {
|
||||
BoneSystem model;
|
||||
float currentFrame = 0.f;
|
||||
int lastFrame = -1;
|
||||
int totalFrames = 1;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -291,24 +291,24 @@ void Character::draw(Renderer& renderer) {
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.modelMutable.AssignFrom(anim.model.mesh);
|
||||
anim.modelMutable.RefreshVBO();
|
||||
modelMutable.AssignFrom(anim.model.mesh);
|
||||
modelMutable.RefreshVBO();
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(anim.modelMutable);
|
||||
renderer.DrawVertexRenderStruct(modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
renderer.shaderManager.PopShader();
|
||||
}
|
||||
|
||||
void Character::prepareGpuSkinningVBOs(AnimationData& anim) {
|
||||
void Character::prepareGpuSkinningVBOs(BoneAnimationData& anim) {
|
||||
if (anim.gpuSkinningPrepared)
|
||||
{
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
anim.model.PrepareGpuSkinningData();
|
||||
anim.model.gpuBoneData.PrepareGpuSkinningData(anim.model.verticesBoneWeight);
|
||||
|
||||
// Upload bind-pose mesh (static, done once)
|
||||
anim.bindPoseMutable.AssignFrom(anim.model.startMesh);
|
||||
@ -443,9 +443,9 @@ void Character::drawShadowDepthCpu(Renderer& renderer) {
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.modelMutable.AssignFrom(anim.model.mesh);
|
||||
anim.modelMutable.RefreshVBO();
|
||||
renderer.DrawVertexRenderStruct(anim.modelMutable);
|
||||
modelMutable.AssignFrom(anim.model.mesh);
|
||||
modelMutable.RefreshVBO();
|
||||
renderer.DrawVertexRenderStruct(modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
}
|
||||
@ -550,10 +550,10 @@ void Character::drawCpuWithShadow(Renderer& renderer, const Eigen::Matrix4f& lig
|
||||
renderer.RotateMatrix(modelCorrectionRotation.toRotationMatrix());
|
||||
|
||||
auto& anim = it->second;
|
||||
anim.modelMutable.AssignFrom(anim.model.mesh);
|
||||
anim.modelMutable.RefreshVBO();
|
||||
modelMutable.AssignFrom(anim.model.mesh);
|
||||
modelMutable.RefreshVBO();
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getTexID());
|
||||
renderer.DrawVertexRenderStruct(anim.modelMutable);
|
||||
renderer.DrawVertexRenderStruct(modelMutable);
|
||||
|
||||
renderer.PopMatrix();
|
||||
renderer.PopProjectionMatrix();
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
|
||||
void loadAnimation(AnimationState state, const std::string& filename, const std::string& zipFile = "");
|
||||
void loadBinaryAnimation(AnimationState state, const std::string& filename, const std::string& zipFile = "");
|
||||
// void setTexture(std::shared_ptr<Texture> texture);
|
||||
|
||||
void setTexture(std::shared_ptr<Texture> texture) {
|
||||
this->texture = texture;
|
||||
}
|
||||
@ -38,6 +38,7 @@ public:
|
||||
// From Python you can chain further commands (walk, wait, trigger others).
|
||||
void setTarget(const Eigen::Vector3f& target,
|
||||
std::function<void()> onArrived = nullptr);
|
||||
|
||||
void setPathPlanner(PathPlanner planner);
|
||||
void draw(Renderer& renderer);
|
||||
void drawShadowDepth(Renderer& renderer);
|
||||
@ -70,29 +71,15 @@ public:
|
||||
Character* attackTarget = nullptr;
|
||||
bool isPlayer = false;
|
||||
bool useGpuSkinning = true;
|
||||
//bool useGpuSkinning = false;
|
||||
|
||||
float interactionRadius = 0.0f;
|
||||
|
||||
|
||||
private:
|
||||
struct AnimationData {
|
||||
BoneSystem model;
|
||||
|
||||
std::map<AnimationState, BoneAnimationData> animations;
|
||||
VertexRenderStruct modelMutable;
|
||||
float currentFrame = 0.f;
|
||||
int lastFrame = -1;
|
||||
int totalFrames = 1;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
std::map<AnimationState, AnimationData> animations;
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
Eigen::Vector3f walkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
|
||||
@ -111,7 +98,7 @@ private:
|
||||
AnimationState resolveActiveState() const;
|
||||
|
||||
// GPU skinning: prepare per-animation VBOs (called lazily on first draw)
|
||||
void prepareGpuSkinningVBOs(AnimationData& anim);
|
||||
void prepareGpuSkinningVBOs(BoneAnimationData& anim);
|
||||
// GPU skinning: draw using shader-based skinning
|
||||
void drawGpuSkinning(Renderer& renderer);
|
||||
// Shadow: draw into depth map (no texture, no projection push)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user