#ifndef OPENMW_MWPHYSICS_PROJECTILE_H #define OPENMW_MWPHYSICS_PROJECTILE_H #include #include #include #include #include "components/misc/convert.hpp" #include "ptrholder.hpp" class btCollisionObject; class btCollisionShape; class btConvexShape; class btVector3; 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; btCollisionObject* getCollisionObject() const { return mCollisionObject.get(); } bool isActive() const { return mActive.load(std::memory_order_acquire); } MWWorld::Ptr getTarget() const { assert(!mActive); return mHitTarget; } MWWorld::Ptr getCaster() const; void setCaster(MWWorld::Ptr caster); bool canTraverseWater() const; void hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal); void setValidTargets(const std::vector& targets); bool isValidTarget(const MWWorld::Ptr& target) const; std::optional getWaterHitPosition(); void setWaterHitPosition(btVector3 pos); private: std::unique_ptr mShape; btConvexShape* mConvexShape; std::unique_ptr mCollisionObject; btTransform mLocalTransform; bool mTransformUpdatePending; bool mCanCrossWaterSurface; bool mCrossedWaterSurface; std::atomic mActive; MWWorld::Ptr mCaster; MWWorld::Ptr mHitTarget; std::optional mWaterHitPosition; btVector3 mHitPosition; btVector3 mHitNormal; std::vector mValidTargets; mutable std::mutex mMutex; PhysicsSystem *mPhysics; PhysicsTaskScheduler *mTaskScheduler; Projectile(const Projectile&); Projectile& operator=(const Projectile&); }; } #endif