From 9f08dc99687eaf175ec2ff5f695dfae0decf04a3 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Thu, 8 Oct 2020 23:24:28 +0000 Subject: [PATCH] Revert "Merge branch 'skinning' into 'master'" This reverts merge request !327 --- components/nifosg/nifloader.cpp | 8 +++-- components/sceneutil/riggeometry.cpp | 35 ++++++++++++------- components/sceneutil/riggeometry.hpp | 50 ++++++---------------------- 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 4a2dac36c..61a276dc1 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1239,13 +1239,15 @@ namespace NifOsg std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->name); SceneUtil::RigGeometry::BoneInfluence influence; - const auto& weights = data->bones[i].weights; + const std::vector &weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) - influence.mWeights.push_back({weights[j].vertex, weights[j].weight}); + { + influence.mWeights.emplace_back(weights[j].vertex, weights[j].weight); + } influence.mInvBindMatrix = data->bones[i].trafo.toMatrix(); influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius); - map->mData.push_back({boneName, influence}); + map->mData.emplace_back(boneName, influence); } rig->setInfluenceMap(map); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index c6ad7e9de..b9201fdf6 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -137,13 +137,14 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) } mBoneNodesVector.clear(); - for (auto& boundPair : mBoneSphereVector->mData) + for (auto& bonePair : mBoneSphereVector->mData) { - Bone* bone = mSkeleton->getBone(boundPair.name); + const std::string& boneName = bonePair.first; + Bone* bone = mSkeleton->getBone(boneName); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << boundPair.name; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; continue; } @@ -154,11 +155,12 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) { for (auto &weight : pair.first) { - Bone* bone = mSkeleton->getBone(weight.boneName); + const std::string& boneName = weight.first.first; + Bone* bone = mSkeleton->getBone(boneName); if (!bone) { mBoneNodesVector.push_back(nullptr); - Log(Debug::Error) << "Error: RigGeometry did not find bone " << weight.boneName; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << boneName; continue; } @@ -216,7 +218,7 @@ void RigGeometry::cull(osg::NodeVisitor* nv) if (bone == nullptr) continue; - accumulateMatrix(weight.bindMatrix, bone->mMatrixInSkeletonSpace, weight.value, resultMat); + accumulateMatrix(weight.first.second, bone->mMatrixInSkeletonSpace, weight.second, resultMat); index++; } @@ -279,7 +281,7 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) continue; index++; - osg::BoundingSpheref bs = boundPair.sphere; + osg::BoundingSpheref bs = boundPair.second; if (mGeomToSkelMatrix) transformBoundingSphere(bone->mMatrixInSkeletonSpace * (*mGeomToSkelMatrix), bs); else @@ -335,21 +337,30 @@ void RigGeometry::setInfluenceMap(osg::ref_ptr influenceMap) { mInfluenceMap = influenceMap; - using Vertex2BoneMap = std::map>; + typedef std::map > Vertex2BoneMap; Vertex2BoneMap vertex2BoneMap; mBoneSphereVector = new BoneSphereVector; mBoneSphereVector->mData.reserve(mInfluenceMap->mData.size()); mBone2VertexVector = new Bone2VertexVector; - for (const BoneData& bone : mInfluenceMap->mData) + for (auto& influencePair : mInfluenceMap->mData) { - mBoneSphereVector->mData.push_back({bone.name, bone.influence.mBoundSphere}); - for (auto& weight : bone.influence.mWeights) - vertex2BoneMap[weight.vertex].push_back({bone.name, bone.influence.mInvBindMatrix, weight.value}); + const std::string& boneName = influencePair.first; + const BoneInfluence& bi = influencePair.second; + mBoneSphereVector->mData.emplace_back(boneName, bi.mBoundSphere); + + for (auto& weightPair: bi.mWeights) + { + std::vector& vec = vertex2BoneMap[weightPair.first]; + + vec.emplace_back(std::make_pair(boneName, bi.mInvBindMatrix), weightPair.second); + } } Bone2VertexMap bone2VertexMap; for (auto& vertexPair : vertex2BoneMap) + { bone2VertexMap[vertexPair.second].emplace_back(vertexPair.first); + } mBone2VertexVector->mData.reserve(bone2VertexMap.size()); mBone2VertexVector->mData.assign(bone2VertexMap.begin(), bone2VertexMap.end()); diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 5f1decf5f..801c172b3 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -25,32 +25,17 @@ namespace SceneUtil // Currently empty as this is difficult to implement. Technically we would need to compile both internal geometries in separate frames but this method is only called once. Alternatively we could compile just the static parts of the model. virtual void compileGLObjects(osg::RenderInfo& renderInfo) const {} - struct VertexWeight - { - unsigned short vertex; - float value; - }; - struct BoneInfluence { osg::Matrixf mInvBindMatrix; osg::BoundingSpheref mBoundSphere; - std::vector mWeights; - }; - - struct BoneData - { - std::string name; - BoneInfluence influence; - bool operator<(const BoneData& other) const - { - return name < other.name; - } + // + std::vector> mWeights; }; struct InfluenceMap : public osg::Referenced { - std::vector mData; + std::vector> mData; }; void setInfluenceMap(osg::ref_ptr influenceMap); @@ -94,36 +79,23 @@ namespace SceneUtil osg::ref_ptr mInfluenceMap; - struct BoneWeight - { - std::string boneName; - osg::Matrixf bindMatrix; - float value; - bool operator<(const BoneWeight& other) const - { - return boneName < other.boneName; - } - }; + typedef std::pair BoneBindMatrixPair; - using VertexList = std::vector; - using BoneWeightList = std::vector; - using Bone2VertexMap = std::map; + typedef std::pair BoneWeight; + + typedef std::vector VertexList; + + typedef std::map, VertexList> Bone2VertexMap; struct Bone2VertexVector : public osg::Referenced { - std::vector> mData; + std::vector, VertexList>> mData; }; osg::ref_ptr mBone2VertexVector; - struct BoneSphere - { - std::string name; - osg::BoundingSpheref sphere; - }; - struct BoneSphereVector : public osg::Referenced { - std::vector mData; + std::vector> mData; }; osg::ref_ptr mBoneSphereVector; std::vector mBoneNodesVector;