Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
4.1 kB · 109 lines
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110#include "bulletshape.hpp"
#include <stdexcept>#include <string>
#include <BulletCollision/CollisionShapes/btBoxShape.h>#include <BulletCollision/CollisionShapes/btCompoundShape.h>#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>#include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
namespace Resource{ namespace { CollisionShapePtr duplicateCollisionShape(const btCollisionShape* shape) { if (shape == nullptr) return nullptr;
if (shape->isCompound()) { const btCompoundShape* comp = static_cast<const btCompoundShape*>(shape); std::unique_ptr<btCompoundShape, DeleteCollisionShape> newShape(new btCompoundShape);
for (int i = 0, n = comp->getNumChildShapes(); i < n; ++i) { auto child = duplicateCollisionShape(comp->getChildShape(i)); const btTransform& trans = comp->getChildTransform(i); newShape->addChildShape(trans, child.release()); }
return newShape; }
if (shape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { const btScaledBvhTriangleMeshShape* trishape = static_cast<const btScaledBvhTriangleMeshShape*>(shape); return CollisionShapePtr(new btScaledBvhTriangleMeshShape( const_cast<btBvhTriangleMeshShape*>(trishape->getChildShape()), trishape->getLocalScaling())); }
if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { const btBvhTriangleMeshShape* trishape = static_cast<const btBvhTriangleMeshShape*>(shape); return CollisionShapePtr(new btScaledBvhTriangleMeshShape( const_cast<btBvhTriangleMeshShape*>(trishape), btVector3(1.f, 1.f, 1.f))); }
if (shape->getShapeType() == BOX_SHAPE_PROXYTYPE) { const btBoxShape* boxshape = static_cast<const btBoxShape*>(shape); return CollisionShapePtr(new btBoxShape(*boxshape)); }
if (shape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE) return CollisionShapePtr( new btHeightfieldTerrainShape(static_cast<const btHeightfieldTerrainShape&>(*shape)));
throw std::logic_error(std::string("Unhandled Bullet shape duplication: ") + shape->getName()); }
void deleteShape(btCollisionShape* shape) { if (shape->isCompound()) { btCompoundShape* compound = static_cast<btCompoundShape*>(shape); for (int i = 0, n = compound->getNumChildShapes(); i < n; i++) if (btCollisionShape* child = compound->getChildShape(i)) deleteShape(child); }
delete shape; } }
void DeleteCollisionShape::operator()(btCollisionShape* shape) const { deleteShape(shape); }
BulletShape::BulletShape(const BulletShape& other) : mCollisionShape(duplicateCollisionShape(other.mCollisionShape.get())) , mAvoidCollisionShape(duplicateCollisionShape(other.mAvoidCollisionShape.get())) , mCollisionBox(other.mCollisionBox) , mAnimatedShapes(other.mAnimatedShapes) , mFileName(other.mFileName) , mFileHash(other.mFileHash) , mVisualCollisionType(other.mVisualCollisionType) { }
void BulletShape::setLocalScaling(const btVector3& scale) { mCollisionShape->setLocalScaling(scale); if (mAvoidCollisionShape) mAvoidCollisionShape->setLocalScaling(scale); }
std::shared_ptr<BulletShapeInstance> makeInstance(std::shared_ptr<const BulletShape> source) { return std::make_shared<BulletShapeInstance>(std::move(source)); }
BulletShapeInstance::BulletShapeInstance(std::shared_ptr<const BulletShape> source) : BulletShape(*source) , mSource(std::move(source)) { }}