mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-06 00:40:04 +00:00
0bce6c09e1
- 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.
108 lines
2.4 KiB
C++
108 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;
|
|
|
|
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;
|
|
}
|
|
|
|
void setHitWater()
|
|
{
|
|
mHitWater = true;
|
|
}
|
|
|
|
bool getHitWater() const
|
|
{
|
|
return mHitWater;
|
|
}
|
|
|
|
void hit(const btCollisionObject* target, btVector3 pos, btVector3 normal);
|
|
|
|
void setValidTargets(const std::vector<MWWorld::Ptr>& targets);
|
|
bool isValidTarget(const btCollisionObject* target) const;
|
|
|
|
btVector3 getHitPosition() const
|
|
{
|
|
return mHitPosition;
|
|
}
|
|
|
|
private:
|
|
|
|
std::unique_ptr<btCollisionShape> mShape;
|
|
btConvexShape* mConvexShape;
|
|
|
|
bool mTransformUpdatePending;
|
|
bool mHitWater;
|
|
std::atomic<bool> mActive;
|
|
MWWorld::Ptr mCaster;
|
|
const btCollisionObject* mCasterColObj;
|
|
const btCollisionObject* mHitTarget;
|
|
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
|