1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-17 01:10:10 +00:00
OpenMW/apps/openmw/mwphysics/projectile.cpp

89 lines
2.6 KiB
C++
Raw Normal View History

#include <memory>
#include <BulletCollision/CollisionShapes/btSphereShape.h>
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
#include <LinearMath/btVector3.h>
#include <components/debug/debuglog.hpp>
#include <components/misc/convert.hpp>
#include <components/resource/bulletshape.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include "../mwworld/class.hpp"
#include "collisiontype.hpp"
#include "mtphysics.hpp"
#include "projectile.hpp"
namespace MWPhysics
{
2020-10-31 13:01:14 +00:00
Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem)
: mActive(true)
2020-10-31 13:01:14 +00:00
, mPhysics(physicssystem)
, mTaskScheduler(scheduler)
, mProjectileId(projectileId)
{
mShape.reset(new btSphereShape(1.f));
mConvexShape = static_cast<btConvexShape*>(mShape.get());
mCollisionObject.reset(new btCollisionObject);
mCollisionObject->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
mCollisionObject->setActivationState(DISABLE_DEACTIVATION);
mCollisionObject->setCollisionShape(mShape.get());
mCollisionObject->setUserPointer(this);
setPosition(position);
const int collisionMask = CollisionType_World | CollisionType_HeightMap |
2020-10-31 13:01:14 +00:00
CollisionType_Actor | CollisionType_Door | CollisionType_Water | CollisionType_Projectile;
mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Projectile, collisionMask);
commitPositionChange();
}
Projectile::~Projectile()
{
if (mCollisionObject)
2020-10-31 13:01:14 +00:00
{
if (!mActive)
mPhysics->reportCollision(mHitPosition, mHitNormal);
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
2020-10-31 13:01:14 +00:00
}
}
void Projectile::commitPositionChange()
{
std::unique_lock<std::mutex> lock(mPositionMutex);
if (mTransformUpdatePending)
{
mCollisionObject->setWorldTransform(mLocalTransform);
mTransformUpdatePending = false;
}
}
void Projectile::setPosition(const osg::Vec3f &position)
{
std::unique_lock<std::mutex> lock(mPositionMutex);
mLocalTransform.setOrigin(Misc::Convert::toBullet(position));
mTransformUpdatePending = true;
}
2020-10-31 13:01:14 +00:00
void Projectile::hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal)
{
if (!mActive.load(std::memory_order_acquire))
return;
std::unique_lock<std::mutex> lock(mPositionMutex);
mHitTarget = target;
mHitPosition = pos;
2020-10-31 13:01:14 +00:00
mHitNormal = normal;
mActive.store(false, std::memory_order_release);
}
void Projectile::activate()
{
assert(!mActive);
mActive.store(true, std::memory_order_release);
}
}