From bdab3fa3216a5c4ee5385c7131604bfd40fb143a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 28 Sep 2014 18:02:57 +0200 Subject: [PATCH] Bullet optimization: Don't update AABBs of static objects every frame --- apps/openmw/mwworld/physicssystem.cpp | 18 +++++++++++++++--- libs/openengine/bullet/physic.cpp | 7 +++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index d5267b8cf..97ea7ca91 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -40,7 +40,7 @@ using namespace Ogre; namespace { -void animateCollisionShapes (std::map& map) +void animateCollisionShapes (std::map& map, btDynamicsWorld* dynamicsWorld) { for (std::map::iterator it = map.begin(); it != map.end(); ++it) @@ -79,6 +79,9 @@ void animateCollisionShapes (std::mapgetChildShape(shapeIt->second)->setLocalScaling(BtOgre::Convert::toBullet(bone->_getDerivedScale())); compound->updateChildTransform(shapeIt->second, trans); } + + // needed because we used btDynamicsWorld::setForceUpdateAllAabbs(false) + dynamicsWorld->updateSingleAabb(it->first); } } @@ -670,11 +673,18 @@ namespace MWWorld const Ogre::Vector3 &position = node->getPosition(); if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle)) + { body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z)); + mEngine->mDynamicsWorld->updateSingleAabb(body); + } if(OEngine::Physic::RigidBody *body = mEngine->getRigidBody(handle, true)) + { body->getWorldTransform().setOrigin(btVector3(position.x,position.y,position.z)); + mEngine->mDynamicsWorld->updateSingleAabb(body); + } + // Actors update their AABBs every frame (DISABLE_DEACTIVATION), so no need to do it manually if(OEngine::Physic::PhysicActor *physact = mEngine->getCharacter(handle)) physact->setPosition(position); } @@ -696,6 +706,7 @@ namespace MWWorld body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); else mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation); + mEngine->mDynamicsWorld->updateSingleAabb(body); } if (OEngine::Physic::RigidBody* body = mEngine->getRigidBody(handle, true)) { @@ -703,6 +714,7 @@ namespace MWWorld body->getWorldTransform().setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); else mEngine->boxAdjustExternal(handleToMesh[handle], body, node->getScale().x, node->getPosition(), rotation); + mEngine->mDynamicsWorld->updateSingleAabb(body); } } @@ -864,8 +876,8 @@ namespace MWWorld void PhysicsSystem::stepSimulation(float dt) { - animateCollisionShapes(mEngine->mAnimatedShapes); - animateCollisionShapes(mEngine->mAnimatedRaycastingShapes); + animateCollisionShapes(mEngine->mAnimatedShapes, mEngine->mDynamicsWorld); + animateCollisionShapes(mEngine->mAnimatedRaycastingShapes, mEngine->mDynamicsWorld); mEngine->stepSimulation(dt); } diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index f2be11386..d3aa714f1 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -97,6 +97,8 @@ namespace Physic (0,0, mShape.get()); mBody = new RigidBody(CI, name); mBody->mPlaceable = false; + mBody->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); + mBody->setActivationState(DISABLE_DEACTIVATION); setPosition(position); setRotation(rotation); @@ -233,6 +235,11 @@ namespace Physic // The world. mDynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); + + // Don't update AABBs of all objects every frame. Most objects in MW are static, so we don't need this. + // Should a "static" object ever be moved, we have to update its AABB manually using DynamicsWorld::updateSingleAabb. + mDynamicsWorld->setForceUpdateAllAabbs(false); + mDynamicsWorld->setGravity(btVector3(0,0,-10)); if(BulletShapeManager::getSingletonPtr() == NULL)