mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-05 06:40:09 +00:00
Merge branch 'raii' into 'master'
Make all physics object manage their own resources. See merge request OpenMW/openmw!527
This commit is contained in:
commit
6863c5a68f
@ -58,7 +58,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
|
||||
|
||||
mConvexShape = static_cast<btConvexShape*>(mShape.get());
|
||||
|
||||
mCollisionObject.reset(new btCollisionObject);
|
||||
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||
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)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "heightfield.hpp"
|
||||
#include "mtphysics.hpp"
|
||||
|
||||
#include <osg/Object>
|
||||
|
||||
@ -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<btHeightfieldTerrainShape>(
|
||||
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<btCollisionObject>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <LinearMath/btScalar.h>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
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<btHeightfieldTerrainShape> mShape;
|
||||
std::unique_ptr<btCollisionObject> mCollisionObject;
|
||||
osg::ref_ptr<const osg::Object> mHoldObject;
|
||||
std::vector<btScalar> mHeights;
|
||||
|
||||
PhysicsTaskScheduler* mTaskScheduler;
|
||||
|
||||
void operator=(const HeightField&);
|
||||
HeightField(const HeightField&);
|
||||
};
|
||||
|
@ -14,29 +14,29 @@
|
||||
|
||||
namespace MWPhysics
|
||||
{
|
||||
Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, PhysicsTaskScheduler* scheduler)
|
||||
Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler)
|
||||
: mShapeInstance(shapeInstance)
|
||||
, mSolid(true)
|
||||
, mTaskScheduler(scheduler)
|
||||
{
|
||||
mPtr = ptr;
|
||||
|
||||
mCollisionObject.reset(new btCollisionObject);
|
||||
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||
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
|
||||
|
@ -26,7 +26,7 @@ namespace MWPhysics
|
||||
class Object final : public PtrHolder
|
||||
{
|
||||
public:
|
||||
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, PhysicsTaskScheduler* scheduler);
|
||||
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, int collisionType, PhysicsTaskScheduler* scheduler);
|
||||
~Object() override;
|
||||
|
||||
const Resource::BulletShapeInstance* getShapeInstance() const;
|
||||
|
@ -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<HeightField>(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<Object>(ptr, shapeInstance, mTaskScheduler.get());
|
||||
auto obj = std::make_shared<Object>(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)
|
||||
|
@ -274,7 +274,7 @@ namespace MWPhysics
|
||||
using ProjectileMap = std::map<int, std::shared_ptr<Projectile>>;
|
||||
ProjectileMap mProjectiles;
|
||||
|
||||
using HeightFieldMap = std::map<std::pair<int, int>, HeightField *>;
|
||||
using HeightFieldMap = std::map<std::pair<int, int>, std::unique_ptr<HeightField>>;
|
||||
HeightFieldMap mHeightFields;
|
||||
|
||||
bool mDebugDrawEnabled;
|
||||
|
@ -28,7 +28,7 @@ Projectile::Projectile(int projectileId, const MWWorld::Ptr& caster, const osg::
|
||||
mShape.reset(new btSphereShape(1.f));
|
||||
mConvexShape = static_cast<btConvexShape*>(mShape.get());
|
||||
|
||||
mCollisionObject.reset(new btCollisionObject);
|
||||
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user