mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +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
8 changed files with 39 additions and 53 deletions
|
@ -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…
Reference in a new issue