#include "bulletshape.hpp" #include #include #include #include #include #include namespace Resource { BulletShape::BulletShape() : mCollisionShape(nullptr) , mAvoidCollisionShape(nullptr) { } BulletShape::BulletShape(const BulletShape ©, const osg::CopyOp ©op) : mCollisionShape(duplicateCollisionShape(copy.mCollisionShape)) , mAvoidCollisionShape(duplicateCollisionShape(copy.mAvoidCollisionShape)) , mCollisionBox(copy.mCollisionBox) , mAnimatedShapes(copy.mAnimatedShapes) { } BulletShape::~BulletShape() { deleteShape(mAvoidCollisionShape); deleteShape(mCollisionShape); } void BulletShape::deleteShape(btCollisionShape* shape) { if(shape!=nullptr) { if(shape->isCompound()) { btCompoundShape* ms = static_cast(shape); int a = ms->getNumChildShapes(); for(int i=0; i getChildShape(i)); } delete shape; } } btCollisionShape* BulletShape::duplicateCollisionShape(const btCollisionShape *shape) const { if(shape->isCompound()) { const btCompoundShape *comp = static_cast(shape); btCompoundShape *newShape = new btCompoundShape; int numShapes = comp->getNumChildShapes(); for(int i = 0;i < numShapes;++i) { btCollisionShape *child = duplicateCollisionShape(comp->getChildShape(i)); btTransform trans = comp->getChildTransform(i); newShape->addChildShape(trans, child); } return newShape; } if(const btBvhTriangleMeshShape* trishape = dynamic_cast(shape)) { btScaledBvhTriangleMeshShape* newShape = new btScaledBvhTriangleMeshShape(const_cast(trishape), btVector3(1.f, 1.f, 1.f)); return newShape; } if (const btBoxShape* boxshape = dynamic_cast(shape)) { return new btBoxShape(*boxshape); } if (shape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE) return new btHeightfieldTerrainShape(static_cast(*shape)); throw std::logic_error(std::string("Unhandled Bullet shape duplication: ")+shape->getName()); } btCollisionShape *BulletShape::getCollisionShape() const { return mCollisionShape; } btCollisionShape *BulletShape::getAvoidCollisionShape() const { return mAvoidCollisionShape; } void BulletShape::setLocalScaling(const btVector3& scale) { mCollisionShape->setLocalScaling(scale); if (mAvoidCollisionShape) mAvoidCollisionShape->setLocalScaling(scale); } osg::ref_ptr BulletShape::makeInstance() const { osg::ref_ptr instance (new BulletShapeInstance(this)); return instance; } BulletShapeInstance::BulletShapeInstance(osg::ref_ptr source) : BulletShape() , mSource(source) { mCollisionBox = source->mCollisionBox; mAnimatedShapes = source->mAnimatedShapes; if (source->mCollisionShape) mCollisionShape = duplicateCollisionShape(source->mCollisionShape); if (source->mAvoidCollisionShape) mAvoidCollisionShape = duplicateCollisionShape(source->mAvoidCollisionShape); } }