mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-30 12:32:36 +00:00
07fa1803f7
collision handling and castRay() to avoid calling getPtr(). It is a step forward removing the mutex inside of PtrHolder. Do the same for DeepestNotMeContactTestResultCallback. It is used only for not-ranged combat for now, but do it anyway for parity with all other callback. This way, once the PtrHolder mutex is gone one will not have to worry about wether it is safe to use the callback in a specific context. To avoid use-after-free with projectile / projectile collision, defer deletion of projectile. Since instead of storing a copy of target Ptr we have a pointer to its collision object, we can't delete projectiles until after we finished iterating over the loops.
101 lines
2.4 KiB
C++
101 lines
2.4 KiB
C++
#ifndef OPENMW_MWPHYSICS_PROJECTILE_H
|
|
#define OPENMW_MWPHYSICS_PROJECTILE_H
|
|
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <optional>
|
|
|
|
#include <LinearMath/btVector3.h>
|
|
|
|
#include "ptrholder.hpp"
|
|
|
|
class btCollisionObject;
|
|
class btCollisionShape;
|
|
class btConvexShape;
|
|
|
|
namespace osg
|
|
{
|
|
class Vec3f;
|
|
}
|
|
|
|
namespace Resource
|
|
{
|
|
class BulletShape;
|
|
}
|
|
|
|
namespace MWPhysics
|
|
{
|
|
class PhysicsTaskScheduler;
|
|
class PhysicsSystem;
|
|
|
|
class Projectile final : public PtrHolder
|
|
{
|
|
public:
|
|
Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, bool canCrossWaterSurface, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem);
|
|
~Projectile() override;
|
|
|
|
btConvexShape* getConvexShape() const { return mConvexShape; }
|
|
|
|
void commitPositionChange();
|
|
|
|
void setPosition(const osg::Vec3f& position);
|
|
osg::Vec3f getPosition() const;
|
|
|
|
bool isActive() const
|
|
{
|
|
return mActive.load(std::memory_order_acquire);
|
|
}
|
|
|
|
MWWorld::Ptr getTarget() const;
|
|
|
|
MWWorld::Ptr getCaster() const;
|
|
void setCaster(const MWWorld::Ptr& caster);
|
|
const btCollisionObject* getCasterCollisionObject() const
|
|
{
|
|
return mCasterColObj;
|
|
}
|
|
|
|
bool canTraverseWater() const;
|
|
|
|
void hit(const btCollisionObject* target, btVector3 pos, btVector3 normal);
|
|
|
|
void setValidTargets(const std::vector<MWWorld::Ptr>& targets);
|
|
bool isValidTarget(const btCollisionObject* target) const;
|
|
|
|
std::optional<btVector3> getWaterHitPosition();
|
|
void setWaterHitPosition(btVector3 pos);
|
|
|
|
private:
|
|
|
|
std::unique_ptr<btCollisionShape> mShape;
|
|
btConvexShape* mConvexShape;
|
|
|
|
bool mTransformUpdatePending;
|
|
bool mCanCrossWaterSurface;
|
|
bool mCrossedWaterSurface;
|
|
std::atomic<bool> mActive;
|
|
MWWorld::Ptr mCaster;
|
|
const btCollisionObject* mCasterColObj;
|
|
const btCollisionObject* mHitTarget;
|
|
std::optional<btVector3> mWaterHitPosition;
|
|
osg::Vec3f mPosition;
|
|
btVector3 mHitPosition;
|
|
btVector3 mHitNormal;
|
|
|
|
std::vector<const btCollisionObject*> mValidTargets;
|
|
|
|
mutable std::mutex mMutex;
|
|
|
|
PhysicsSystem *mPhysics;
|
|
PhysicsTaskScheduler *mTaskScheduler;
|
|
|
|
Projectile(const Projectile&);
|
|
Projectile& operator=(const Projectile&);
|
|
};
|
|
|
|
}
|
|
|
|
|
|
#endif
|