From 254f01b89dc681d638e93723df84c68f452fc057 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 8 Jan 2019 20:42:08 +0400 Subject: [PATCH 1/2] RigGeometry optimization: vector iteration is more cheap than map iteration --- components/nifosg/nifloader.cpp | 2 +- components/sceneutil/riggeometry.cpp | 26 +++++++++++++++----------- components/sceneutil/riggeometry.hpp | 9 +++++---- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index eb20b7702..431a2edd1 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1098,7 +1098,7 @@ namespace NifOsg influence.mInvBindMatrix = data->bones[i].trafo.toMatrix(); influence.mBoundSphere = osg::BoundingSpheref(data->bones[i].boundSphereCenter, data->bones[i].boundSphereRadius); - map->mMap.insert(std::make_pair(boneName, influence)); + map->mData.emplace_back(boneName, influence); } rig->setInfluenceMap(map); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index b086cf628..bf43c2e70 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -136,20 +136,21 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) typedef std::map > Vertex2BoneMap; Vertex2BoneMap vertex2BoneMap; - for (std::map::const_iterator it = mInfluenceMap->mMap.begin(); it != mInfluenceMap->mMap.end(); ++it) + mBoneSphereVector.clear(); + for (auto& influencePair : mInfluenceMap->mData) { - Bone* bone = mSkeleton->getBone(it->first); + Bone* bone = mSkeleton->getBone(influencePair.first); if (!bone) { - Log(Debug::Error) << "Error: RigGeometry did not find bone " << it->first ; + Log(Debug::Error) << "Error: RigGeometry did not find bone " << influencePair.first; continue; } - mBoneSphereMap[bone] = it->second.mBoundSphere; + mBoneSphereVector.emplace_back(bone, influencePair.second.mBoundSphere); - const BoneInfluence& bi = it->second; + const BoneInfluence& bi = influencePair.second; - const std::map& weights = it->second.mWeights; + const std::map& weights = influencePair.second.mWeights; for (std::map::const_iterator weightIt = weights.begin(); weightIt != weights.end(); ++weightIt) { std::vector& vec = vertex2BoneMap[weightIt->first]; @@ -160,11 +161,14 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) } } + Bone2VertexMap bone2VertexMap; for (Vertex2BoneMap::iterator it = vertex2BoneMap.begin(); it != vertex2BoneMap.end(); ++it) { - mBone2VertexMap[it->second].push_back(it->first); + bone2VertexMap[it->second].push_back(it->first); } + mBone2VertexVector.assign(bone2VertexMap.begin(), bone2VertexMap.end()); + return true; } @@ -201,7 +205,7 @@ void RigGeometry::cull(osg::NodeVisitor* nv) osg::Vec3Array* normalDst = static_cast(geom.getNormalArray()); osg::Vec4Array* tangentDst = static_cast(geom.getTexCoordArray(7)); - for (auto &pair : mBone2VertexMap) + for (auto &pair : mBone2VertexVector) { osg::Matrixf resultMat (0, 0, 0, 0, 0, 0, 0, 0, @@ -263,10 +267,10 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv) updateGeomToSkelMatrix(nv->getNodePath()); osg::BoundingBox box; - for (BoneSphereMap::const_iterator it = mBoneSphereMap.begin(); it != mBoneSphereMap.end(); ++it) + for (auto& boundPair : mBoneSphereVector) { - Bone* bone = it->first; - osg::BoundingSpheref bs = it->second; + Bone* bone = boundPair.first; + osg::BoundingSpheref bs = boundPair.second; if (mGeomToSkelMatrix) transformBoundingSphere(bone->mMatrixInSkeletonSpace * (*mGeomToSkelMatrix), bs); else diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 60b3edc9d..1d51dfa59 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -36,7 +36,7 @@ namespace SceneUtil struct InfluenceMap : public osg::Referenced { - std::map mMap; + std::vector> mData; }; void setInfluenceMap(osg::ref_ptr influenceMap); @@ -73,12 +73,13 @@ namespace SceneUtil typedef std::vector VertexList; typedef std::map, VertexList> Bone2VertexMap; + typedef std::vector, VertexList>> Bone2VertexVector; - Bone2VertexMap mBone2VertexMap; + Bone2VertexVector mBone2VertexVector; - typedef std::map BoneSphereMap; + typedef std::vector> BoneSphereVector; - BoneSphereMap mBoneSphereMap; + BoneSphereVector mBoneSphereVector; unsigned int mLastFrameNumber; bool mBoundsFirstFrame; From 8e6fd348d136931c8d70d091acb4426bf11ed881 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 9 Jan 2019 21:01:33 +0400 Subject: [PATCH 2/2] RigGeometry optimization: optimize geometry optimization --- components/nifosg/nifloader.cpp | 3 +-- components/sceneutil/riggeometry.cpp | 12 ++++-------- components/sceneutil/riggeometry.hpp | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 431a2edd1..29e6ff4f4 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1092,8 +1092,7 @@ namespace NifOsg const std::vector &weights = data->bones[i].weights; for(size_t j = 0;j < weights.size();j++) { - std::pair indexWeight = std::make_pair(weights[j].vertex, weights[j].weight); - influence.mWeights.insert(indexWeight); + 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); diff --git a/components/sceneutil/riggeometry.cpp b/components/sceneutil/riggeometry.cpp index bf43c2e70..4b550b69c 100644 --- a/components/sceneutil/riggeometry.cpp +++ b/components/sceneutil/riggeometry.cpp @@ -146,18 +146,14 @@ bool RigGeometry::initFromParentSkeleton(osg::NodeVisitor* nv) continue; } - mBoneSphereVector.emplace_back(bone, influencePair.second.mBoundSphere); - const BoneInfluence& bi = influencePair.second; + mBoneSphereVector.emplace_back(bone, bi.mBoundSphere); - const std::map& weights = influencePair.second.mWeights; - for (std::map::const_iterator weightIt = weights.begin(); weightIt != weights.end(); ++weightIt) + for (auto& weightPair: bi.mWeights) { - std::vector& vec = vertex2BoneMap[weightIt->first]; + std::vector& vec = vertex2BoneMap[weightPair.first]; - BoneWeight b = std::make_pair(std::make_pair(bone, bi.mInvBindMatrix), weightIt->second); - - vec.push_back(b); + vec.emplace_back(std::make_pair(bone, bi.mInvBindMatrix), weightPair.second); } } diff --git a/components/sceneutil/riggeometry.hpp b/components/sceneutil/riggeometry.hpp index 1d51dfa59..5dd05507c 100644 --- a/components/sceneutil/riggeometry.hpp +++ b/components/sceneutil/riggeometry.hpp @@ -31,7 +31,7 @@ namespace SceneUtil osg::Matrixf mInvBindMatrix; osg::BoundingSpheref mBoundSphere; // - std::map mWeights; + std::vector> mWeights; }; struct InfluenceMap : public osg::Referenced