mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 02:45:32 +00:00
Projectile to projectile collision
This commit is contained in:
parent
66fe3b0d38
commit
7e85235220
6 changed files with 41 additions and 23 deletions
|
@ -30,9 +30,7 @@ namespace MWPhysics
|
||||||
return btScalar(1);
|
return btScalar(1);
|
||||||
PtrHolder* targetHolder = static_cast<PtrHolder*>(mMe->getUserPointer());
|
PtrHolder* targetHolder = static_cast<PtrHolder*>(mMe->getUserPointer());
|
||||||
const MWWorld::Ptr target = targetHolder->getPtr();
|
const MWWorld::Ptr target = targetHolder->getPtr();
|
||||||
|
projectileHolder->hit(target, convexResult.m_hitPointLocal, convexResult.m_hitNormalLocal);
|
||||||
osg::Vec3f pos = Misc::Convert::makeOsgVec3f(convexResult.m_hitPointLocal);
|
|
||||||
projectileHolder->hit(target, pos);
|
|
||||||
return btScalar(1);
|
return btScalar(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
#include "closestnotmerayresultcallback.hpp"
|
#include "closestnotmerayresultcallback.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||||
|
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
|
||||||
|
#include "actor.hpp"
|
||||||
|
#include "collisiontype.hpp"
|
||||||
#include "projectile.hpp"
|
#include "projectile.hpp"
|
||||||
#include "ptrholder.hpp"
|
#include "ptrholder.hpp"
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
ClosestNotMeRayResultCallback::ClosestNotMeRayResultCallback(const btCollisionObject* me, const std::vector<const btCollisionObject*>& targets, const btVector3& from, const btVector3& to, int projId)
|
ClosestNotMeRayResultCallback::ClosestNotMeRayResultCallback(const btCollisionObject* me, std::vector<const btCollisionObject*> targets, const btVector3& from, const btVector3& to, Projectile* proj)
|
||||||
: btCollisionWorld::ClosestRayResultCallback(from, to)
|
: btCollisionWorld::ClosestRayResultCallback(from, to)
|
||||||
, mMe(me), mTargets(targets), mProjectileId(projId)
|
, mMe(me), mTargets(std::move(targets)), mProjectile(proj)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,20 +28,27 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
if ((std::find(mTargets.begin(), mTargets.end(), rayResult.m_collisionObject) == mTargets.end()))
|
if ((std::find(mTargets.begin(), mTargets.end(), rayResult.m_collisionObject) == mTargets.end()))
|
||||||
{
|
{
|
||||||
PtrHolder* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
auto* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
||||||
if (holder && !holder->getPtr().isEmpty() && holder->getPtr().getClass().isActor())
|
if (holder && !holder->getPtr().isEmpty() && holder->getPtr().getClass().isActor())
|
||||||
return 1.f;
|
return 1.f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mProjectileId >= 0)
|
btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||||
|
if (mProjectile)
|
||||||
{
|
{
|
||||||
PtrHolder* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
auto* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
||||||
Projectile* projectile = dynamic_cast<Projectile*>(holder);
|
if (auto* target = dynamic_cast<Actor*>(holder))
|
||||||
if (projectile && projectile->getProjectileId() == mProjectileId)
|
{
|
||||||
return 1.f;
|
mProjectile->hit(target->getPtr(), m_hitPointWorld, m_hitNormalWorld);
|
||||||
|
}
|
||||||
|
else if (auto* target = dynamic_cast<Projectile*>(holder))
|
||||||
|
{
|
||||||
|
target->hit(mProjectile->getPtr(), m_hitPointWorld, m_hitNormalWorld);
|
||||||
|
mProjectile->hit(target->getPtr(), m_hitPointWorld, m_hitNormalWorld);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
return rayResult.m_hitFraction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,18 @@ class btCollisionObject;
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
|
class Projectile;
|
||||||
|
|
||||||
class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClosestNotMeRayResultCallback(const btCollisionObject* me, const std::vector<const btCollisionObject*>& targets, const btVector3& from, const btVector3& to, int projId=-1);
|
ClosestNotMeRayResultCallback(const btCollisionObject* me, std::vector<const btCollisionObject*> targets, const btVector3& from, const btVector3& to, Projectile* proj=nullptr);
|
||||||
|
|
||||||
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) override;
|
btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) override;
|
||||||
private:
|
private:
|
||||||
const btCollisionObject* mMe;
|
const btCollisionObject* mMe;
|
||||||
const std::vector<const btCollisionObject*> mTargets;
|
const std::vector<const btCollisionObject*> mTargets;
|
||||||
const int mProjectileId;
|
Projectile* mProjectile;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -288,7 +288,7 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClosestNotMeRayResultCallback resultCallback(me, targetCollisionObjects, btFrom, btTo, projId);
|
ClosestNotMeRayResultCallback resultCallback(me, targetCollisionObjects, btFrom, btTo, getProjectile(projId));
|
||||||
resultCallback.m_collisionFilterGroup = group;
|
resultCallback.m_collisionFilterGroup = group;
|
||||||
resultCallback.m_collisionFilterMask = mask;
|
resultCallback.m_collisionFilterMask = mask;
|
||||||
|
|
||||||
|
@ -664,7 +664,7 @@ namespace MWPhysics
|
||||||
int PhysicsSystem::addProjectile (const osg::Vec3f& position)
|
int PhysicsSystem::addProjectile (const osg::Vec3f& position)
|
||||||
{
|
{
|
||||||
mProjectileId++;
|
mProjectileId++;
|
||||||
auto projectile = std::make_shared<Projectile>(mProjectileId, position, mTaskScheduler.get());
|
auto projectile = std::make_shared<Projectile>(mProjectileId, position, mTaskScheduler.get(), this);
|
||||||
mProjectiles.emplace(mProjectileId, std::move(projectile));
|
mProjectiles.emplace(mProjectileId, std::move(projectile));
|
||||||
|
|
||||||
return mProjectileId;
|
return mProjectileId;
|
||||||
|
|
|
@ -18,8 +18,9 @@
|
||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTaskScheduler* scheduler)
|
Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem)
|
||||||
: mActive(true)
|
: mActive(true)
|
||||||
|
, mPhysics(physicssystem)
|
||||||
, mTaskScheduler(scheduler)
|
, mTaskScheduler(scheduler)
|
||||||
, mProjectileId(projectileId)
|
, mProjectileId(projectileId)
|
||||||
{
|
{
|
||||||
|
@ -35,7 +36,7 @@ Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTask
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
|
|
||||||
const int collisionMask = CollisionType_World | CollisionType_HeightMap |
|
const int collisionMask = CollisionType_World | CollisionType_HeightMap |
|
||||||
CollisionType_Actor | CollisionType_Door | CollisionType_Water;
|
CollisionType_Actor | CollisionType_Door | CollisionType_Water | CollisionType_Projectile;
|
||||||
mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Projectile, collisionMask);
|
mTaskScheduler->addCollisionObject(mCollisionObject.get(), CollisionType_Projectile, collisionMask);
|
||||||
|
|
||||||
commitPositionChange();
|
commitPositionChange();
|
||||||
|
@ -44,7 +45,11 @@ Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTask
|
||||||
Projectile::~Projectile()
|
Projectile::~Projectile()
|
||||||
{
|
{
|
||||||
if (mCollisionObject)
|
if (mCollisionObject)
|
||||||
|
{
|
||||||
|
if (!mActive)
|
||||||
|
mPhysics->reportCollision(mHitPosition, mHitNormal);
|
||||||
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Projectile::commitPositionChange()
|
void Projectile::commitPositionChange()
|
||||||
|
@ -64,13 +69,14 @@ void Projectile::setPosition(const osg::Vec3f &position)
|
||||||
mTransformUpdatePending = true;
|
mTransformUpdatePending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Projectile::hit(MWWorld::Ptr target, osg::Vec3f pos)
|
void Projectile::hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal)
|
||||||
{
|
{
|
||||||
if (!mActive.load(std::memory_order_acquire))
|
if (!mActive.load(std::memory_order_acquire))
|
||||||
return;
|
return;
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||||
mHitTarget = target;
|
mHitTarget = target;
|
||||||
mHitPosition = pos;
|
mHitPosition = pos;
|
||||||
|
mHitNormal = normal;
|
||||||
mActive.store(false, std::memory_order_release);
|
mActive.store(false, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <components/misc/convert.hpp>
|
#include "components/misc/convert.hpp"
|
||||||
|
|
||||||
#include "ptrholder.hpp"
|
#include "ptrholder.hpp"
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ namespace MWPhysics
|
||||||
class Projectile final : public PtrHolder
|
class Projectile final : public PtrHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Projectile(const int projectileId, const osg::Vec3f& position, PhysicsTaskScheduler* scheduler);
|
Projectile(const int projectileId, const osg::Vec3f& position, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem);
|
||||||
~Projectile() override;
|
~Projectile() override;
|
||||||
|
|
||||||
btConvexShape* getConvexShape() const { return mConvexShape; }
|
btConvexShape* getConvexShape() const { return mConvexShape; }
|
||||||
|
@ -68,7 +68,7 @@ namespace MWPhysics
|
||||||
return Misc::Convert::toOsg(mHitPosition);
|
return Misc::Convert::toOsg(mHitPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hit(MWWorld::Ptr target, osg::Vec3f pos);
|
void hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal);
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -81,12 +81,14 @@ namespace MWPhysics
|
||||||
bool mTransformUpdatePending;
|
bool mTransformUpdatePending;
|
||||||
std::atomic<bool> mActive;
|
std::atomic<bool> mActive;
|
||||||
MWWorld::Ptr mHitTarget;
|
MWWorld::Ptr mHitTarget;
|
||||||
osg::Vec3f mHitPosition;
|
btVector3 mHitPosition;
|
||||||
|
btVector3 mHitNormal;
|
||||||
|
|
||||||
mutable std::mutex mPositionMutex;
|
mutable std::mutex mPositionMutex;
|
||||||
|
|
||||||
osg::Vec3f mPosition;
|
osg::Vec3f mPosition;
|
||||||
|
|
||||||
|
PhysicsSystem *mPhysics;
|
||||||
PhysicsTaskScheduler *mTaskScheduler;
|
PhysicsTaskScheduler *mTaskScheduler;
|
||||||
|
|
||||||
Projectile(const Projectile&);
|
Projectile(const Projectile&);
|
||||||
|
|
Loading…
Reference in a new issue