diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 3b7b0d061..3b52ee934 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -58,7 +58,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic mConvexShape = static_cast(mShape.get()); - mCollisionObject.reset(new btCollisionObject); + mCollisionObject = std::make_unique(); mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); mCollisionObject->setActivationState(DISABLE_DEACTIVATION); mCollisionObject->setCollisionShape(mShape.get()); @@ -76,8 +76,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic Actor::~Actor() { - if (mCollisionObject) - mTaskScheduler->removeCollisionObject(mCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } void Actor::enableCollisionMode(bool collision) diff --git a/apps/openmw/mwphysics/heightfield.cpp b/apps/openmw/mwphysics/heightfield.cpp index e1448116b..436cdfe8f 100644 --- a/apps/openmw/mwphysics/heightfield.cpp +++ b/apps/openmw/mwphysics/heightfield.cpp @@ -1,4 +1,5 @@ #include "heightfield.hpp" +#include "mtphysics.hpp" #include @@ -42,10 +43,12 @@ namespace namespace MWPhysics { - HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject) - : mHeights(makeHeights(heights, sqrtVerts)) + HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler) + : mHoldObject(holdObject) + , mHeights(makeHeights(heights, sqrtVerts)) + , mTaskScheduler(scheduler) { - mShape = new btHeightfieldTerrainShape( + mShape = std::make_unique( sqrtVerts, sqrtVerts, getHeights(heights, mHeights), 1, @@ -60,31 +63,29 @@ namespace MWPhysics (y+0.5f) * triSize * (sqrtVerts-1), (maxH+minH)*0.5f)); - mCollisionObject = new btCollisionObject; - mCollisionObject->setCollisionShape(mShape); + mCollisionObject = std::make_unique(); + mCollisionObject->setCollisionShape(mShape.get()); mCollisionObject->setWorldTransform(transform); - - mHoldObject = holdObject; + mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_HeightMap, CollisionType_Actor|CollisionType_Projectile); } HeightField::~HeightField() { - delete mCollisionObject; - delete mShape; + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } btCollisionObject* HeightField::getCollisionObject() { - return mCollisionObject; + return mCollisionObject.get(); } const btCollisionObject* HeightField::getCollisionObject() const { - return mCollisionObject; + return mCollisionObject.get(); } const btHeightfieldTerrainShape* HeightField::getShape() const { - return mShape; + return mShape.get(); } } diff --git a/apps/openmw/mwphysics/heightfield.hpp b/apps/openmw/mwphysics/heightfield.hpp index 2ba58afff..c76f8b943 100644 --- a/apps/openmw/mwphysics/heightfield.hpp +++ b/apps/openmw/mwphysics/heightfield.hpp @@ -5,6 +5,7 @@ #include +#include #include class btCollisionObject; @@ -17,10 +18,12 @@ namespace osg namespace MWPhysics { + class PhysicsTaskScheduler; + class HeightField { public: - HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject); + HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler); ~HeightField(); btCollisionObject* getCollisionObject(); @@ -28,11 +31,13 @@ namespace MWPhysics const btHeightfieldTerrainShape* getShape() const; private: - btHeightfieldTerrainShape* mShape; - btCollisionObject* mCollisionObject; + std::unique_ptr mShape; + std::unique_ptr mCollisionObject; osg::ref_ptr mHoldObject; std::vector mHeights; + PhysicsTaskScheduler* mTaskScheduler; + void operator=(const HeightField&); HeightField(const HeightField&); }; diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index 910f7bf15..e3615989d 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -14,29 +14,29 @@ namespace MWPhysics { - Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler) + Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler) : mShapeInstance(shapeInstance) , mSolid(true) , mTaskScheduler(scheduler) { mPtr = ptr; - mCollisionObject.reset(new btCollisionObject); + mCollisionObject = std::make_unique(); mCollisionObject->setCollisionShape(shapeInstance->getCollisionShape()); mCollisionObject->setUserPointer(this); setScale(ptr.getCellRef().getScale()); setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); - const float* pos = ptr.getRefData().getPosition().pos; - setOrigin(btVector3(pos[0], pos[1], pos[2])); + setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3())); commitPositionChange(); + + mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); } Object::~Object() { - if (mCollisionObject) - mTaskScheduler->removeCollisionObject(mCollisionObject.get()); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } const Resource::BulletShapeInstance* Object::getShapeInstance() const diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index 876e35651..cae877180 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -26,7 +26,7 @@ namespace MWPhysics class Object final : public PtrHolder { public: - Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, PhysicsTaskScheduler* scheduler); + Object(const MWWorld::Ptr& ptr, osg::ref_ptr shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler); ~Object() override; const Resource::BulletShapeInstance* getShapeInstance() const; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index b50366ade..95d1ec70a 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -107,12 +107,7 @@ namespace MWPhysics if (mWaterCollisionObject) mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get()); - for (auto& heightField : mHeightFields) - { - mTaskScheduler->removeCollisionObject(heightField.second->getCollisionObject()); - delete heightField.second; - } - + mHeightFields.clear(); mObjects.clear(); mActors.clear(); mProjectiles.clear(); @@ -442,22 +437,14 @@ namespace MWPhysics void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject) { - HeightField *heightfield = new HeightField(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject); - mHeightFields[std::make_pair(x,y)] = heightfield; - - mTaskScheduler->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap, - CollisionType_Actor|CollisionType_Projectile); + mHeightFields[std::make_pair(x,y)] = std::make_unique(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject, mTaskScheduler.get()); } void PhysicsSystem::removeHeightField (int x, int y) { HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x,y)); if(heightfield != mHeightFields.end()) - { - mTaskScheduler->removeCollisionObject(heightfield->second->getCollisionObject()); - delete heightfield->second; mHeightFields.erase(heightfield); - } } const HeightField* PhysicsSystem::getHeightField(int x, int y) const @@ -465,7 +452,7 @@ namespace MWPhysics const auto heightField = mHeightFields.find(std::make_pair(x, y)); if (heightField == mHeightFields.end()) return nullptr; - return heightField->second; + return heightField->second.get(); } void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType) @@ -474,14 +461,11 @@ namespace MWPhysics if (!shapeInstance || !shapeInstance->getCollisionShape()) return; - auto obj = std::make_shared(ptr, shapeInstance, mTaskScheduler.get()); + auto obj = std::make_shared(ptr, shapeInstance, collisionType, mTaskScheduler.get()); mObjects.emplace(ptr, obj); if (obj->isAnimated()) mAnimatedObjects.insert(obj.get()); - - mTaskScheduler->addCollisionObject(obj->getCollisionObject(), collisionType, - CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); } void PhysicsSystem::remove(const MWWorld::Ptr &ptr) diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 2de8d153b..449209974 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -274,7 +274,7 @@ namespace MWPhysics using ProjectileMap = std::map>; ProjectileMap mProjectiles; - using HeightFieldMap = std::map, HeightField *>; + using HeightFieldMap = std::map, std::unique_ptr>; HeightFieldMap mHeightFields; bool mDebugDrawEnabled; diff --git a/apps/openmw/mwphysics/projectile.cpp b/apps/openmw/mwphysics/projectile.cpp index a8aaeb72a..1b9beca5f 100644 --- a/apps/openmw/mwphysics/projectile.cpp +++ b/apps/openmw/mwphysics/projectile.cpp @@ -28,7 +28,7 @@ Projectile::Projectile(int projectileId, const MWWorld::Ptr& caster, const osg:: mShape.reset(new btSphereShape(1.f)); mConvexShape = static_cast(mShape.get()); - mCollisionObject.reset(new btCollisionObject); + mCollisionObject = std::make_unique(); mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); mCollisionObject->setActivationState(DISABLE_DEACTIVATION); mCollisionObject->setCollisionShape(mShape.get()); @@ -45,12 +45,9 @@ Projectile::Projectile(int projectileId, const MWWorld::Ptr& caster, const osg:: Projectile::~Projectile() { - if (mCollisionObject) - { - if (!mActive) - mPhysics->reportCollision(mHitPosition, mHitNormal); - mTaskScheduler->removeCollisionObject(mCollisionObject.get()); - } + if (!mActive) + mPhysics->reportCollision(mHitPosition, mHitNormal); + mTaskScheduler->removeCollisionObject(mCollisionObject.get()); } void Projectile::commitPositionChange()