Make all physics object manage their own resources

Use smart pointer for heightfields and their members.
Move collision object addition inside of Object's ctor, as for Actors and HeightFields
pull/3041/head^2
fredzio 4 years ago
parent dc82cb61f4
commit d015f17a6c

@ -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…
Cancel
Save