diff --git a/src/BoneAnimatedModel.cpp b/src/BoneAnimatedModel.cpp index 710cf03..3c03541 100644 --- a/src/BoneAnimatedModel.cpp +++ b/src/BoneAnimatedModel.cpp @@ -757,13 +757,6 @@ namespace ZL } 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& outMatrices) const @@ -897,13 +890,6 @@ namespace ZL } - /*std::cout << "m=" << skinningMatrixForEachBone[5] << std::endl; - - std::cout << "Start Mesh data " << std::endl; - std::cout << startMesh.PositionData[0] << std::endl; - std::cout << startMesh.PositionData[10] << std::endl; - std::cout << startMesh.PositionData[100] << std::endl; - */ for (int i = 0; i < mesh.PositionData.size(); i++) { Vector4f originalPos = { @@ -926,30 +912,10 @@ namespace ZL } vMoved = true; finalPos = finalPos + (skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex] * originalPos) * verticesBoneWeight[i][j].weight; - - /*if (i == 100) - { - std::cout << "bone index=" << verticesBoneWeight[i][j].boneIndex << std::endl; - std::cout << "weight=" << verticesBoneWeight[i][j].weight << std::endl; - std::cout << "skinning matrix=" << skinningMatrixForEachBone[verticesBoneWeight[i][j].boneIndex] << std::endl; - std::cout << "original pos=" << originalPos.transpose() << std::endl; - std::cout << "final pos=" << finalPos.transpose() << std::endl; - std::cout << "-----------------" << std::endl; - }*/ + } } - /*if (i == 100) - { - std::cout << originalPos << std::endl; - std::cout << finalPos << std::endl; - }*/ - - /*if (abs(finalPos(0) - originalPos(0)) > 1 || abs(finalPos(1) - originalPos(1)) > 1 || abs(finalPos(2) - originalPos(2)) > 1) - { - - }*/ - if (!vMoved) { finalPos = originalPos; @@ -962,5 +928,41 @@ namespace ZL } + void BoneAnimationData::prepareGpuSkinningVBOs() { + if (gpuSkinningPrepared) + { + return; + } + + model.gpuBoneData.PrepareGpuSkinningData(model.verticesBoneWeight); + + // Upload bind-pose mesh (static, done once) + bindPoseMutable.AssignFrom(model.startMesh); + + auto& gpu = model.gpuBoneData; + + boneIndices0VBO = std::make_shared(); + glBindBuffer(GL_ARRAY_BUFFER, boneIndices0VBO->getBuffer()); + glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices0.size() * sizeof(Eigen::Vector4f), + gpu.boneIndices0.data(), GL_STATIC_DRAW); + + boneIndices1VBO = std::make_shared(); + glBindBuffer(GL_ARRAY_BUFFER, boneIndices1VBO->getBuffer()); + glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices1.size() * sizeof(Eigen::Vector2f), + gpu.boneIndices1.data(), GL_STATIC_DRAW); + + boneWeights0VBO = std::make_shared(); + glBindBuffer(GL_ARRAY_BUFFER, boneWeights0VBO->getBuffer()); + glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights0.size() * sizeof(Eigen::Vector4f), + gpu.boneWeights0.data(), GL_STATIC_DRAW); + + boneWeights1VBO = std::make_shared(); + glBindBuffer(GL_ARRAY_BUFFER, boneWeights1VBO->getBuffer()); + glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights1.size() * sizeof(Eigen::Vector2f), + gpu.boneWeights1.data(), GL_STATIC_DRAW); + + gpuSkinningPrepared = true; + } + } \ No newline at end of file diff --git a/src/BoneAnimatedModel.h b/src/BoneAnimatedModel.h index 7442e19..5540851 100644 --- a/src/BoneAnimatedModel.h +++ b/src/BoneAnimatedModel.h @@ -84,6 +84,8 @@ namespace ZL std::shared_ptr boneWeights1VBO; bool gpuSkinningPrepared = false; std::vector skinningMatrices; + + void prepareGpuSkinningVBOs(); }; diff --git a/src/Character.cpp b/src/Character.cpp index 999037d..d4e1ff2 100644 --- a/src/Character.cpp +++ b/src/Character.cpp @@ -301,43 +301,6 @@ void Character::draw(Renderer& renderer) { renderer.shaderManager.PopShader(); } -void Character::prepareGpuSkinningVBOs(BoneAnimationData& anim) { - if (anim.gpuSkinningPrepared) - { - - return; - } - - anim.model.gpuBoneData.PrepareGpuSkinningData(anim.model.verticesBoneWeight); - - // Upload bind-pose mesh (static, done once) - anim.bindPoseMutable.AssignFrom(anim.model.startMesh); - - auto& gpu = anim.model.gpuBoneData; - - anim.boneIndices0VBO = std::make_shared(); - glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices0VBO->getBuffer()); - glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices0.size() * sizeof(Eigen::Vector4f), - gpu.boneIndices0.data(), GL_STATIC_DRAW); - - anim.boneIndices1VBO = std::make_shared(); - glBindBuffer(GL_ARRAY_BUFFER, anim.boneIndices1VBO->getBuffer()); - glBufferData(GL_ARRAY_BUFFER, gpu.boneIndices1.size() * sizeof(Eigen::Vector2f), - gpu.boneIndices1.data(), GL_STATIC_DRAW); - - anim.boneWeights0VBO = std::make_shared(); - glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights0VBO->getBuffer()); - glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights0.size() * sizeof(Eigen::Vector4f), - gpu.boneWeights0.data(), GL_STATIC_DRAW); - - anim.boneWeights1VBO = std::make_shared(); - glBindBuffer(GL_ARRAY_BUFFER, anim.boneWeights1VBO->getBuffer()); - glBufferData(GL_ARRAY_BUFFER, gpu.boneWeights1.size() * sizeof(Eigen::Vector2f), - gpu.boneWeights1.data(), GL_STATIC_DRAW); - - anim.gpuSkinningPrepared = true; -} - void Character::drawGpuSkinning(Renderer& renderer) { AnimationState drawState = resolveActiveState(); auto it = animations.find(drawState); @@ -347,7 +310,7 @@ void Character::drawGpuSkinning(Renderer& renderer) { } auto& anim = it->second; - prepareGpuSkinningVBOs(anim); + anim.prepareGpuSkinningVBOs(); if (anim.skinningMatrices.empty()) { @@ -456,7 +419,7 @@ void Character::drawShadowDepthGpuSkinning(Renderer& renderer) { if (it == animations.end()) return; auto& anim = it->second; - prepareGpuSkinningVBOs(anim); + anim.prepareGpuSkinningVBOs(); if (anim.skinningMatrices.empty()) { if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty()) return; anim.model.ComputeSkinningMatrices( @@ -566,7 +529,8 @@ void Character::drawGpuSkinningWithShadow(Renderer& renderer, const Eigen::Matri if (it == animations.end() || !texture) return; auto& anim = it->second; - prepareGpuSkinningVBOs(anim); + anim.prepareGpuSkinningVBOs(); + if (anim.skinningMatrices.empty()) { if (anim.model.animations.empty() || anim.model.animations[0].keyFrames.empty()) return; anim.model.ComputeSkinningMatrices( diff --git a/src/Character.h b/src/Character.h index e3d1a49..cd290f0 100644 --- a/src/Character.h +++ b/src/Character.h @@ -97,8 +97,6 @@ private: // if the requested state has no loaded animation. AnimationState resolveActiveState() const; - // GPU skinning: prepare per-animation VBOs (called lazily on first draw) - 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)