mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 13:49:56 +00:00
32108adc31
- enchanted arrow explode upon hit the water plane - non enchanted arrow disappear (or more accurately, they hit nothingness) - enchanted arrow shot underwater explode immediately - non enchanted arrow disappear immediately Also, solve a bug that occured previously and could theoritically still happens where we use the last tested collision position for instead of the last registered hit: Use the hit position as saved inside Projectile::hit() instead of the last position saved inside the callback. If a projectile collides with several objects (bottom of the sea and water surface for instance), the last collision tested won't necessarily be the impact position as we have no control over the order in which the tests are performed.
112 lines
2.4 KiB
C++
112 lines
2.4 KiB
C++
#ifndef OPENMW_MWPHYSICS_PROJECTILE_H
|
|
#define OPENMW_MWPHYSICS_PROJECTILE_H
|
|
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <mutex>
|
|
|
|
#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, 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);
|
|
|
|
void setHitWater()
|
|
{
|
|
mHitWater = true;
|
|
}
|
|
|
|
bool getHitWater() const
|
|
{
|
|
return mHitWater;
|
|
}
|
|
|
|
void hit(MWWorld::Ptr target, btVector3 pos, btVector3 normal);
|
|
|
|
void setValidTargets(const std::vector<MWWorld::Ptr>& targets);
|
|
bool isValidTarget(const MWWorld::Ptr& target) const;
|
|
|
|
btVector3 getHitPosition() const
|
|
{
|
|
return mHitPosition;
|
|
}
|
|
|
|
private:
|
|
|
|
std::unique_ptr<btCollisionShape> mShape;
|
|
btConvexShape* mConvexShape;
|
|
|
|
std::unique_ptr<btCollisionObject> mCollisionObject;
|
|
bool mTransformUpdatePending;
|
|
bool mHitWater;
|
|
std::atomic<bool> mActive;
|
|
MWWorld::Ptr mCaster;
|
|
MWWorld::Ptr mHitTarget;
|
|
osg::Vec3f mPosition;
|
|
btVector3 mHitPosition;
|
|
btVector3 mHitNormal;
|
|
|
|
std::vector<MWWorld::Ptr> mValidTargets;
|
|
|
|
mutable std::mutex mMutex;
|
|
|
|
PhysicsSystem *mPhysics;
|
|
PhysicsTaskScheduler *mTaskScheduler;
|
|
|
|
Projectile(const Projectile&);
|
|
Projectile& operator=(const Projectile&);
|
|
};
|
|
|
|
}
|
|
|
|
|
|
#endif
|