Disable skinning updates for actors beyond the AI processing distance

c++11
scrawl 10 years ago
parent 48a6d7c1a0
commit 83c6ba97c0

@ -1085,12 +1085,15 @@ namespace MWMechanics
// AI and magic effects update // AI and magic effects update
for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter) for(PtrActorMap::iterator iter(mActors.begin()); iter != mActors.end(); ++iter)
{ {
bool inProcessingRange = Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
<= sqrProcessingDistance;
iter->second->getCharacterController()->setActive(inProcessingRange);
if (!iter->first.getClass().getCreatureStats(iter->first).isDead()) if (!iter->first.getClass().getCreatureStats(iter->first).isDead())
{ {
updateActor(iter->first, duration); updateActor(iter->first, duration);
if (MWBase::Environment::get().getMechanicsManager()->isAIActive() && if (MWBase::Environment::get().getMechanicsManager()->isAIActive() && inProcessingRange)
Ogre::Vector3(player.getRefData().getPosition().pos).squaredDistance(Ogre::Vector3(iter->first.getRefData().getPosition().pos))
<= sqrProcessingDistance)
{ {
if (timerUpdateAITargets == 0) if (timerUpdateAITargets == 0)
{ {

@ -1898,6 +1898,11 @@ bool CharacterController::isKnockedOut() const
return mHitState == CharState_KnockOut; return mHitState == CharState_KnockOut;
} }
void CharacterController::setActive(bool active)
{
mAnimation->setActive(active);
}
void CharacterController::setHeadTrackTarget(const MWWorld::Ptr &target) void CharacterController::setHeadTrackTarget(const MWWorld::Ptr &target)
{ {
mHeadTrackTarget = target; mHeadTrackTarget = target;

@ -228,6 +228,9 @@ public:
bool isReadyToBlock() const; bool isReadyToBlock() const;
bool isKnockedOut() const; bool isKnockedOut() const;
/// @see Animation::setActive
void setActive(bool active);
/// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr. /// Make this character turn its head towards \a target. To turn off head tracking, pass an empty Ptr.
void setHeadTrackTarget(const MWWorld::Ptr& target); void setHeadTrackTarget(const MWWorld::Ptr& target);
}; };

@ -214,6 +214,14 @@ namespace MWRender
mInsert->removeChild(mObjectRoot); mInsert->removeChild(mObjectRoot);
} }
void Animation::setActive(bool active)
{
if (SceneUtil::Skeleton* skel = dynamic_cast<SceneUtil::Skeleton*>(mObjectRoot.get()))
{
skel->setActive(active);
}
}
void Animation::updatePtr(const MWWorld::Ptr &ptr) void Animation::updatePtr(const MWWorld::Ptr &ptr)
{ {
mPtr = ptr; mPtr = ptr;

@ -242,6 +242,10 @@ public:
Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem); Animation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem);
virtual ~Animation(); virtual ~Animation();
/// Set active flag on the object skeleton, if one exists.
/// @see SceneUtil::Skeleton::setActive
void setActive(bool active);
osg::Group* getOrCreateObjectRoot(); osg::Group* getOrCreateObjectRoot();
osg::Group* getObjectRoot(); osg::Group* getObjectRoot();

@ -58,6 +58,8 @@ public:
}; };
RigGeometry::RigGeometry() RigGeometry::RigGeometry()
: mFirstFrame(true)
, mBoundsFirstFrame(true)
{ {
setCullCallback(new UpdateRigGeometry); setCullCallback(new UpdateRigGeometry);
setUpdateCallback(new UpdateRigBounds); setUpdateCallback(new UpdateRigBounds);
@ -67,6 +69,8 @@ RigGeometry::RigGeometry()
RigGeometry::RigGeometry(const RigGeometry &copy, const osg::CopyOp &copyop) RigGeometry::RigGeometry(const RigGeometry &copy, const osg::CopyOp &copyop)
: osg::Geometry(copy, copyop) : osg::Geometry(copy, copyop)
, mInfluenceMap(copy.mInfluenceMap) , mInfluenceMap(copy.mInfluenceMap)
, mFirstFrame(copy.mFirstFrame)
, mBoundsFirstFrame(copy.mBoundsFirstFrame)
{ {
setSourceGeometry(copy.mSourceGeometry); setSourceGeometry(copy.mSourceGeometry);
} }
@ -199,6 +203,10 @@ void RigGeometry::update(osg::NodeVisitor* nv)
return; return;
} }
if (!mSkeleton->getActive() && !mFirstFrame)
return;
mFirstFrame = false;
mSkeleton->updateBoneMatrices(nv); mSkeleton->updateBoneMatrices(nv);
osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv); osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv);
@ -247,6 +255,10 @@ void RigGeometry::updateBounds(osg::NodeVisitor *nv)
return; return;
} }
if (!mSkeleton->getActive() && !mBoundsFirstFrame)
return;
mBoundsFirstFrame = false;
mSkeleton->updateBoneMatrices(nv); mSkeleton->updateBoneMatrices(nv);
osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv); osg::Matrixf geomToSkel = getGeomToSkelMatrix(nv);

@ -64,6 +64,9 @@ namespace SceneUtil
BoneSphereMap mBoneSphereMap; BoneSphereMap mBoneSphereMap;
bool mFirstFrame;
bool mBoundsFirstFrame;
bool initFromParentSkeleton(osg::NodeVisitor* nv); bool initFromParentSkeleton(osg::NodeVisitor* nv);
osg::Matrixf getGeomToSkelMatrix(osg::NodeVisitor* nv); osg::Matrixf getGeomToSkelMatrix(osg::NodeVisitor* nv);

@ -35,6 +35,7 @@ Skeleton::Skeleton()
: mBoneCacheInit(false) : mBoneCacheInit(false)
, mNeedToUpdateBoneMatrices(true) , mNeedToUpdateBoneMatrices(true)
, mLastFrameNumber(0) , mLastFrameNumber(0)
, mActive(true)
{ {
} }
@ -44,12 +45,11 @@ Skeleton::Skeleton(const Skeleton &copy, const osg::CopyOp &copyop)
, mBoneCacheInit(false) , mBoneCacheInit(false)
, mNeedToUpdateBoneMatrices(true) , mNeedToUpdateBoneMatrices(true)
, mLastFrameNumber(0) , mLastFrameNumber(0)
, mActive(copy.mActive)
{ {
} }
Bone* Skeleton::getBone(const std::string &name) Bone* Skeleton::getBone(const std::string &name)
{ {
if (!mBoneCacheInit) if (!mBoneCacheInit)
@ -123,6 +123,16 @@ void Skeleton::updateBoneMatrices(osg::NodeVisitor* nv)
} }
} }
void Skeleton::setActive(bool active)
{
mActive = active;
}
bool Skeleton::getActive() const
{
return mActive;
}
Bone::Bone() Bone::Bone()
: mNode(NULL) : mNode(NULL)
{ {

@ -47,6 +47,12 @@ namespace SceneUtil
/// Request an update of bone matrices. May be a no-op if already updated in this frame. /// Request an update of bone matrices. May be a no-op if already updated in this frame.
void updateBoneMatrices(osg::NodeVisitor* nv); void updateBoneMatrices(osg::NodeVisitor* nv);
/// Set the skinning active flag. Inactive skeletons will not have their child rigs updated.
/// You should set this flag to false if you know that bones are not currently moving.
void setActive(bool active);
bool getActive() const;
private: private:
// The root bone is not a "real" bone, it has no corresponding node in the scene graph. // The root bone is not a "real" bone, it has no corresponding node in the scene graph.
// As far as the scene graph goes we support multiple root bones. // As far as the scene graph goes we support multiple root bones.
@ -58,6 +64,8 @@ namespace SceneUtil
bool mNeedToUpdateBoneMatrices; bool mNeedToUpdateBoneMatrices;
bool mActive;
unsigned int mLastFrameNumber; unsigned int mLastFrameNumber;
}; };

Loading…
Cancel
Save