From 27751db99afae9368fc29fabbe0bbedb980c3ace Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 4 May 2015 16:23:33 +0200 Subject: [PATCH] Use btScaledBvhTriangleMeshShape, bump required bullet version to 2.83 --- components/nifbullet/bulletnifloader.cpp | 4 +-- libs/openengine/bullet/physic.cpp | 32 +++++++++++++++++------- libs/openengine/bullet/physic.hpp | 3 +++ 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 93c9797b2..3207af0fe 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -123,7 +123,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) mCompoundShape = NULL; mStaticMesh = NULL; - Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(mResourceName.substr(0, mResourceName.length()-7))); + Nif::NIFFilePtr pnif (Nif::Cache::getInstance().load(mResourceName)); Nif::NIFFile & nif = *pnif.get (); if (nif.numRoots() < 1) { @@ -134,7 +134,7 @@ void ManualBulletShapeLoader::loadResource(Ogre::Resource *resource) // Have to load controlled nodes from the .kf // FIXME: the .kf has to be loaded both for rendering and physics, ideally it should be opened once and then reused mControlledNodes.clear(); - std::string kfname = mResourceName.substr(0, mResourceName.length()-7); + std::string kfname = mResourceName; Misc::StringUtils::toLower(kfname); if(kfname.size() > 4 && kfname.compare(kfname.size()-4, 4, ".nif") == 0) kfname.replace(kfname.size()-4, 4, ".kf"); diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index 013ef1003..76dbc224c 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -457,8 +457,7 @@ namespace Physic float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, Ogre::Vector3* scaledBoxTranslation, Ogre::Quaternion* boxRotation, bool raycasting, bool placeable) { - std::string sid = (boost::format("%07.3f") % scale).str(); - std::string outputstring = mesh + sid; + std::string outputstring = mesh; //get the shape from the .nif mShapeLoader->load(outputstring,"General"); @@ -477,20 +476,35 @@ namespace Physic btCollisionShape* collisionShape = raycasting ? shape->mRaycastingShape : shape->mCollisionShape; - // If this is an animated compound shape, we must duplicate it so we can animate - // multiple instances independently. - if (!raycasting && !shape->mAnimatedShapes.empty()) - collisionShape = duplicateCollisionShape(collisionShape); - if (raycasting && !shape->mAnimatedRaycastingShapes.empty()) - collisionShape = duplicateCollisionShape(collisionShape); +// TODO: check this from cmake? +#if BT_BULLET_VERSION < 283 +#error "Bullet version 2.83 or later required" +#endif - collisionShape->setLocalScaling( btVector3(scale,scale,scale)); + bool needDelete = false; + if (btBvhTriangleMeshShape* triangleShape = dynamic_cast(shape->mCollisionShape)) + { + btScaledBvhTriangleMeshShape* scaled = new btScaledBvhTriangleMeshShape(triangleShape, btVector3(scale,scale,scale)); + collisionShape = scaled; + needDelete = true; + } + else + { + // If this is an animated compound shape, we must duplicate it so we can animate + // multiple instances independently. + if (!raycasting && !shape->mAnimatedShapes.empty()) + collisionShape = duplicateCollisionShape(collisionShape); + if (raycasting && !shape->mAnimatedRaycastingShapes.empty()) + collisionShape = duplicateCollisionShape(collisionShape); + } //create the real body btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo (0,0, collisionShape); RigidBody* body = new RigidBody(CI,name); body->mPlaceable = placeable; + if (needDelete) + body->mCollisionShape.reset(collisionShape); if (!raycasting && !shape->mAnimatedShapes.empty()) { diff --git a/libs/openengine/bullet/physic.hpp b/libs/openengine/bullet/physic.hpp index 7784e8941..7b0906694 100644 --- a/libs/openengine/bullet/physic.hpp +++ b/libs/openengine/bullet/physic.hpp @@ -63,6 +63,9 @@ namespace Physic virtual ~RigidBody(); std::string mName; + // May be empty if the collision shape is a shared resource + std::auto_ptr mCollisionShape; + // Hack: placeable objects (that can be picked up by the player) have different collision behaviour. // This variable needs to be passed to BulletNifLoader. bool mPlaceable;