From 138ea0e0c7c66f714b938e3846974070daafd8b4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Jun 2014 10:45:07 +0000 Subject: [PATCH] From Pjotr Svetachov, "For a scene with a lot of animated agents I did some small optimizations to reduce cpu overhead: 1) Avoid a load-hit-store in UpdateBone. b->getMatrixInBoneSpace() returns the same matrix that was just stored with b->setMatrix() 2) Avoid calling element->isIdentity() for the whole transform stack (can be expensive is element is a matrix) 3) Make the key frame interpolator use binary search instead of a linear one. This is very noticeable in scenes where some geometry has long repeating animations that start at the same time, you will see the update time grow then reset and grow again." git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14294 16af8721-9629-0410-8352-f15c8da7e697 --- include/osgAnimation/Interpolator | 28 ++++++++++++--------------- src/osgAnimation/StackedTransform.cpp | 8 ++++---- src/osgAnimation/UpdateBone.cpp | 4 ++-- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/include/osgAnimation/Interpolator b/include/osgAnimation/Interpolator index 1190e3aa4..28c9b789f 100644 --- a/include/osgAnimation/Interpolator +++ b/include/osgAnimation/Interpolator @@ -33,33 +33,29 @@ namespace osgAnimation typedef TYPE UsingType; public: - mutable int _lastKeyAccess; + TemplateInterpolatorBase() {} - TemplateInterpolatorBase() : _lastKeyAccess(-1) {} - - void reset() { _lastKeyAccess = -1; } int getKeyIndexFromTime(const TemplateKeyframeContainer& keys, double time) const { - // todo use a cache int key_size = keys.size(); if (!key_size) { osg::notify(osg::WARN) << "TemplateInterpolatorBase::getKeyIndexFromTime the container is empty, impossible to get key index from time" << std::endl;; return -1; } const TemplateKeyframe* keysVector = &keys.front(); - for (int i = 0; i < key_size-1; i++) - { - double time0 = keysVector[i].getTime(); - double time1 = keysVector[i+1].getTime(); - - if ( time >= time0 && time < time1 ) - { - _lastKeyAccess = i; - return i; + int k = 0; + int l = key_size; + int mid = key_size/2; + while(mid != k){ + double time1 = keysVector[mid].getTime(); + if(time1 < time){ + k = mid; + } else { + l = mid; } + mid = (l+k)/2; } - osg::notify(osg::WARN) << time << " first key " << keysVector[0].getTime() << " last key " << keysVector[key_size-1].getTime() << std::endl; - return -1; + return k; } }; diff --git a/src/osgAnimation/StackedTransform.cpp b/src/osgAnimation/StackedTransform.cpp index 91ac2d842..a56b35f1a 100644 --- a/src/osgAnimation/StackedTransform.cpp +++ b/src/osgAnimation/StackedTransform.cpp @@ -32,7 +32,7 @@ StackedTransform::StackedTransform(const StackedTransform& rhs, const osg::CopyO void StackedTransform::update(float t) { - int dirty = 0; + bool dirty = false; for (StackedTransform::iterator it = begin(); it != end(); ++it) { StackedTransformElement* element = it->get(); @@ -40,9 +40,9 @@ void StackedTransform::update(float t) continue; // update and check if there are changes element->update(t); - if (element->isIdentity()) - continue; - dirty++; + if (!dirty && !element->isIdentity()){ + dirty = true; + } } if (!dirty) diff --git a/src/osgAnimation/UpdateBone.cpp b/src/osgAnimation/UpdateBone.cpp index cbc50ba3a..eb892a076 100644 --- a/src/osgAnimation/UpdateBone.cpp +++ b/src/osgAnimation/UpdateBone.cpp @@ -46,9 +46,9 @@ void UpdateBone::operator()(osg::Node* node, osg::NodeVisitor* nv) Bone* parent = b->getBoneParent(); if (parent) - b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace() * parent->getMatrixInSkeletonSpace()); + b->setMatrixInSkeletonSpace(matrix * parent->getMatrixInSkeletonSpace()); else - b->setMatrixInSkeletonSpace(b->getMatrixInBoneSpace()); + b->setMatrixInSkeletonSpace(matrix); } traverse(node,nv); }