mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-06 00:40:04 +00:00
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
This commit is contained in:
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());
|
mConvexShape = static_cast<btConvexShape*>(mShape.get());
|
||||||
|
|
||||||
mCollisionObject.reset(new btCollisionObject);
|
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||||
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
|
mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
|
||||||
mCollisionObject->setCollisionShape(mShape.get());
|
mCollisionObject->setCollisionShape(mShape.get());
|
||||||
@ -76,7 +76,6 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
|
|||||||
|
|
||||||
Actor::~Actor()
|
Actor::~Actor()
|
||||||
{
|
{
|
||||||
if (mCollisionObject)
|
|
||||||
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "heightfield.hpp"
|
#include "heightfield.hpp"
|
||||||
|
#include "mtphysics.hpp"
|
||||||
|
|
||||||
#include <osg/Object>
|
#include <osg/Object>
|
||||||
|
|
||||||
@ -42,10 +43,12 @@ namespace
|
|||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler)
|
||||||
: mHeights(makeHeights(heights, sqrtVerts))
|
: mHoldObject(holdObject)
|
||||||
|
, mHeights(makeHeights(heights, sqrtVerts))
|
||||||
|
, mTaskScheduler(scheduler)
|
||||||
{
|
{
|
||||||
mShape = new btHeightfieldTerrainShape(
|
mShape = std::make_unique<btHeightfieldTerrainShape>(
|
||||||
sqrtVerts, sqrtVerts,
|
sqrtVerts, sqrtVerts,
|
||||||
getHeights(heights, mHeights),
|
getHeights(heights, mHeights),
|
||||||
1,
|
1,
|
||||||
@ -60,31 +63,29 @@ namespace MWPhysics
|
|||||||
(y+0.5f) * triSize * (sqrtVerts-1),
|
(y+0.5f) * triSize * (sqrtVerts-1),
|
||||||
(maxH+minH)*0.5f));
|
(maxH+minH)*0.5f));
|
||||||
|
|
||||||
mCollisionObject = new btCollisionObject;
|
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||||
mCollisionObject->setCollisionShape(mShape);
|
mCollisionObject->setCollisionShape(mShape.get());
|
||||||
mCollisionObject->setWorldTransform(transform);
|
mCollisionObject->setWorldTransform(transform);
|
||||||
|
mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_HeightMap, CollisionType_Actor|CollisionType_Projectile);
|
||||||
mHoldObject = holdObject;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HeightField::~HeightField()
|
HeightField::~HeightField()
|
||||||
{
|
{
|
||||||
delete mCollisionObject;
|
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||||
delete mShape;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btCollisionObject* HeightField::getCollisionObject()
|
btCollisionObject* HeightField::getCollisionObject()
|
||||||
{
|
{
|
||||||
return mCollisionObject;
|
return mCollisionObject.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const btCollisionObject* HeightField::getCollisionObject() const
|
const btCollisionObject* HeightField::getCollisionObject() const
|
||||||
{
|
{
|
||||||
return mCollisionObject;
|
return mCollisionObject.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const btHeightfieldTerrainShape* HeightField::getShape() const
|
const btHeightfieldTerrainShape* HeightField::getShape() const
|
||||||
{
|
{
|
||||||
return mShape;
|
return mShape.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <LinearMath/btScalar.h>
|
#include <LinearMath/btScalar.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class btCollisionObject;
|
class btCollisionObject;
|
||||||
@ -17,10 +18,12 @@ namespace osg
|
|||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
|
class PhysicsTaskScheduler;
|
||||||
|
|
||||||
class HeightField
|
class HeightField
|
||||||
{
|
{
|
||||||
public:
|
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();
|
~HeightField();
|
||||||
|
|
||||||
btCollisionObject* getCollisionObject();
|
btCollisionObject* getCollisionObject();
|
||||||
@ -28,11 +31,13 @@ namespace MWPhysics
|
|||||||
const btHeightfieldTerrainShape* getShape() const;
|
const btHeightfieldTerrainShape* getShape() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
btHeightfieldTerrainShape* mShape;
|
std::unique_ptr<btHeightfieldTerrainShape> mShape;
|
||||||
btCollisionObject* mCollisionObject;
|
std::unique_ptr<btCollisionObject> mCollisionObject;
|
||||||
osg::ref_ptr<const osg::Object> mHoldObject;
|
osg::ref_ptr<const osg::Object> mHoldObject;
|
||||||
std::vector<btScalar> mHeights;
|
std::vector<btScalar> mHeights;
|
||||||
|
|
||||||
|
PhysicsTaskScheduler* mTaskScheduler;
|
||||||
|
|
||||||
void operator=(const HeightField&);
|
void operator=(const HeightField&);
|
||||||
HeightField(const HeightField&);
|
HeightField(const HeightField&);
|
||||||
};
|
};
|
||||||
|
@ -14,28 +14,28 @@
|
|||||||
|
|
||||||
namespace MWPhysics
|
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)
|
: mShapeInstance(shapeInstance)
|
||||||
, mSolid(true)
|
, mSolid(true)
|
||||||
, mTaskScheduler(scheduler)
|
, mTaskScheduler(scheduler)
|
||||||
{
|
{
|
||||||
mPtr = ptr;
|
mPtr = ptr;
|
||||||
|
|
||||||
mCollisionObject.reset(new btCollisionObject);
|
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||||
mCollisionObject->setCollisionShape(shapeInstance->getCollisionShape());
|
mCollisionObject->setCollisionShape(shapeInstance->getCollisionShape());
|
||||||
|
|
||||||
mCollisionObject->setUserPointer(this);
|
mCollisionObject->setUserPointer(this);
|
||||||
|
|
||||||
setScale(ptr.getCellRef().getScale());
|
setScale(ptr.getCellRef().getScale());
|
||||||
setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude()));
|
setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude()));
|
||||||
const float* pos = ptr.getRefData().getPosition().pos;
|
setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3()));
|
||||||
setOrigin(btVector3(pos[0], pos[1], pos[2]));
|
|
||||||
commitPositionChange();
|
commitPositionChange();
|
||||||
|
|
||||||
|
mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::~Object()
|
Object::~Object()
|
||||||
{
|
{
|
||||||
if (mCollisionObject)
|
|
||||||
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ namespace MWPhysics
|
|||||||
class Object final : public PtrHolder
|
class Object final : public PtrHolder
|
||||||
{
|
{
|
||||||
public:
|
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;
|
~Object() override;
|
||||||
|
|
||||||
const Resource::BulletShapeInstance* getShapeInstance() const;
|
const Resource::BulletShapeInstance* getShapeInstance() const;
|
||||||
|
@ -107,12 +107,7 @@ namespace MWPhysics
|
|||||||
if (mWaterCollisionObject)
|
if (mWaterCollisionObject)
|
||||||
mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get());
|
mTaskScheduler->removeCollisionObject(mWaterCollisionObject.get());
|
||||||
|
|
||||||
for (auto& heightField : mHeightFields)
|
mHeightFields.clear();
|
||||||
{
|
|
||||||
mTaskScheduler->removeCollisionObject(heightField.second->getCollisionObject());
|
|
||||||
delete heightField.second;
|
|
||||||
}
|
|
||||||
|
|
||||||
mObjects.clear();
|
mObjects.clear();
|
||||||
mActors.clear();
|
mActors.clear();
|
||||||
mProjectiles.clear();
|
mProjectiles.clear();
|
||||||
@ -442,30 +437,22 @@ namespace MWPhysics
|
|||||||
|
|
||||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
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)] = std::make_unique<HeightField>(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject, mTaskScheduler.get());
|
||||||
mHeightFields[std::make_pair(x,y)] = heightfield;
|
|
||||||
|
|
||||||
mTaskScheduler->addCollisionObject(heightfield->getCollisionObject(), CollisionType_HeightMap,
|
|
||||||
CollisionType_Actor|CollisionType_Projectile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::removeHeightField (int x, int y)
|
void PhysicsSystem::removeHeightField (int x, int y)
|
||||||
{
|
{
|
||||||
HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x,y));
|
HeightFieldMap::iterator heightfield = mHeightFields.find(std::make_pair(x,y));
|
||||||
if(heightfield != mHeightFields.end())
|
if(heightfield != mHeightFields.end())
|
||||||
{
|
|
||||||
mTaskScheduler->removeCollisionObject(heightfield->second->getCollisionObject());
|
|
||||||
delete heightfield->second;
|
|
||||||
mHeightFields.erase(heightfield);
|
mHeightFields.erase(heightfield);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const HeightField* PhysicsSystem::getHeightField(int x, int y) const
|
const HeightField* PhysicsSystem::getHeightField(int x, int y) const
|
||||||
{
|
{
|
||||||
const auto heightField = mHeightFields.find(std::make_pair(x, y));
|
const auto heightField = mHeightFields.find(std::make_pair(x, y));
|
||||||
if (heightField == mHeightFields.end())
|
if (heightField == mHeightFields.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return heightField->second;
|
return heightField->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType)
|
void PhysicsSystem::addObject (const MWWorld::Ptr& ptr, const std::string& mesh, int collisionType)
|
||||||
@ -474,14 +461,11 @@ namespace MWPhysics
|
|||||||
if (!shapeInstance || !shapeInstance->getCollisionShape())
|
if (!shapeInstance || !shapeInstance->getCollisionShape())
|
||||||
return;
|
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);
|
mObjects.emplace(ptr, obj);
|
||||||
|
|
||||||
if (obj->isAnimated())
|
if (obj->isAnimated())
|
||||||
mAnimatedObjects.insert(obj.get());
|
mAnimatedObjects.insert(obj.get());
|
||||||
|
|
||||||
mTaskScheduler->addCollisionObject(obj->getCollisionObject(), collisionType,
|
|
||||||
CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::remove(const MWWorld::Ptr &ptr)
|
void PhysicsSystem::remove(const MWWorld::Ptr &ptr)
|
||||||
|
@ -274,7 +274,7 @@ namespace MWPhysics
|
|||||||
using ProjectileMap = std::map<int, std::shared_ptr<Projectile>>;
|
using ProjectileMap = std::map<int, std::shared_ptr<Projectile>>;
|
||||||
ProjectileMap mProjectiles;
|
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;
|
HeightFieldMap mHeightFields;
|
||||||
|
|
||||||
bool mDebugDrawEnabled;
|
bool mDebugDrawEnabled;
|
||||||
|
@ -28,7 +28,7 @@ Projectile::Projectile(int projectileId, const MWWorld::Ptr& caster, const osg::
|
|||||||
mShape.reset(new btSphereShape(1.f));
|
mShape.reset(new btSphereShape(1.f));
|
||||||
mConvexShape = static_cast<btConvexShape*>(mShape.get());
|
mConvexShape = static_cast<btConvexShape*>(mShape.get());
|
||||||
|
|
||||||
mCollisionObject.reset(new btCollisionObject);
|
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||||
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
|
||||||
mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
|
mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
|
||||||
mCollisionObject->setCollisionShape(mShape.get());
|
mCollisionObject->setCollisionShape(mShape.get());
|
||||||
@ -44,14 +44,11 @@ Projectile::Projectile(int projectileId, const MWWorld::Ptr& caster, const osg::
|
|||||||
}
|
}
|
||||||
|
|
||||||
Projectile::~Projectile()
|
Projectile::~Projectile()
|
||||||
{
|
|
||||||
if (mCollisionObject)
|
|
||||||
{
|
{
|
||||||
if (!mActive)
|
if (!mActive)
|
||||||
mPhysics->reportCollision(mHitPosition, mHitNormal);
|
mPhysics->reportCollision(mHitPosition, mHitNormal);
|
||||||
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Projectile::commitPositionChange()
|
void Projectile::commitPositionChange()
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user