mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-31 23:15:41 +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);
|
||||
PtrHolder* targetHolder = static_cast<PtrHolder*>(mMe->getUserPointer());
|
||||
const MWWorld::Ptr target = targetHolder->getPtr();
|
||||
|
||||
osg::Vec3f pos = Misc::Convert::makeOsgVec3f(convexResult.m_hitPointLocal);
|
||||
projectileHolder->hit(target, pos);
|
||||
projectileHolder->hit(target, convexResult.m_hitPointLocal, convexResult.m_hitNormalLocal);
|
||||
return btScalar(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
#include "closestnotmerayresultcallback.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionObject.h>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
|
||||
#include "actor.hpp"
|
||||
#include "collisiontype.hpp"
|
||||
#include "projectile.hpp"
|
||||
#include "ptrholder.hpp"
|
||||
|
||||
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)
|
||||
, 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()))
|
||||
{
|
||||
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())
|
||||
return 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
if (mProjectileId >= 0)
|
||||
btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||
if (mProjectile)
|
||||
{
|
||||
PtrHolder* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
||||
Projectile* projectile = dynamic_cast<Projectile*>(holder);
|
||||
if (projectile && projectile->getProjectileId() == mProjectileId)
|
||||
return 1.f;
|
||||
auto* holder = static_cast<PtrHolder*>(rayResult.m_collisionObject->getUserPointer());
|
||||
if (auto* target = dynamic_cast<Actor*>(holder))
|
||||
{
|
||||
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
|
||||
{
|
||||
class Projectile;
|
||||
|
||||
class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
||||
{
|
||||
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;
|
||||
private:
|
||||
const btCollisionObject* mMe;
|
||||
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_collisionFilterMask = mask;
|
||||
|
||||
|
@ -664,7 +664,7 @@ namespace MWPhysics
|
|||
int PhysicsSystem::addProjectile (const osg::Vec3f& position)
|
||||
{
|
||||
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));
|
||||
|
||||
return mProjectileId;
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
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)
|
||||
, mPhysics(physicssystem)
|
||||
, mTaskScheduler(scheduler)
|
||||
, mProjectileId(projectileId)
|
||||
{
|
||||
|
@ -35,7 +36,7 @@ Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTask
|
|||
setPosition(position);
|
||||
|
||||
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);
|
||||
|
||||
commitPositionChange();
|
||||
|
@ -44,7 +45,11 @@ Projectile::Projectile(int projectileId, const osg::Vec3f& position, PhysicsTask
|
|||
Projectile::~Projectile()
|
||||
{
|
||||
if (mCollisionObject)
|
||||
{
|
||||
if (!mActive)
|
||||
mPhysics->reportCollision(mHitPosition, mHitNormal);
|
||||
mTaskScheduler->removeCollisionObject(mCollisionObject.get());
|
||||
}
|
||||
}
|
||||
|
||||
void Projectile::commitPositionChange()
|
||||
|
@ -64,13 +69,14 @@ void Projectile::setPosition(const osg::Vec3f &position)
|
|||
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))
|
||||
return;
|
||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
||||
mHitTarget = target;
|
||||
mHitPosition = pos;
|
||||
mHitNormal = normal;
|
||||
mActive.store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <components/misc/convert.hpp>
|
||||
#include "components/misc/convert.hpp"
|
||||
|
||||
#include "ptrholder.hpp"
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace MWPhysics
|
|||
class Projectile final : public PtrHolder
|
||||
{
|
||||
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;
|
||||
|
||||
btConvexShape* getConvexShape() const { return mConvexShape; }
|
||||
|
@ -68,7 +68,7 @@ namespace MWPhysics
|
|||
return Misc::Convert::toOsg(mHitPosition);
|
||||
}
|
||||
|
||||
void hit(MWWorld::Ptr target, osg::Vec3f pos);
|
||||
void hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal);
|
||||
void activate();
|
||||
|
||||
private:
|
||||
|
@ -81,12 +81,14 @@ namespace MWPhysics
|
|||
bool mTransformUpdatePending;
|
||||
std::atomic<bool> mActive;
|
||||
MWWorld::Ptr mHitTarget;
|
||||
osg::Vec3f mHitPosition;
|
||||
btVector3 mHitPosition;
|
||||
btVector3 mHitNormal;
|
||||
|
||||
mutable std::mutex mPositionMutex;
|
||||
|
||||
osg::Vec3f mPosition;
|
||||
|
||||
PhysicsSystem *mPhysics;
|
||||
PhysicsTaskScheduler *mTaskScheduler;
|
||||
|
||||
Projectile(const Projectile&);
|
||||
|
|
Loading…
Reference in a new issue