ChipmunkPhysics2D: Rework RigidBody2D
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <NazaraUtils/FunctionRef.hpp>
|
||||
#include <NazaraUtils/Signal.hpp>
|
||||
#include <NazaraUtils/SparsePtr.hpp>
|
||||
#include <vector>
|
||||
@@ -38,7 +39,7 @@ namespace Nz
|
||||
virtual Vector2f ComputeCenterOfMass() const = 0;
|
||||
virtual float ComputeMomentOfInertia(float mass) const = 0;
|
||||
|
||||
virtual void ForEachPolygon(const std::function<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
virtual void ForEachPolygon(const FunctionRef<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
|
||||
inline UInt32 GetCategoryMask() const;
|
||||
inline UInt32 GetCollisionGroup() const;
|
||||
|
||||
@@ -27,17 +27,20 @@ namespace Nz
|
||||
class NAZARA_CHIPMUNKPHYSICS2D_API ChipmunkRigidBody2D
|
||||
{
|
||||
public:
|
||||
struct DynamicSettings;
|
||||
struct StaticSettings;
|
||||
|
||||
using VelocityFunc = std::function<void(ChipmunkRigidBody2D& body2D, const Vector2f& gravity, float damping, float deltaTime)>;
|
||||
|
||||
ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass);
|
||||
ChipmunkRigidBody2D(ChipmunkPhysWorld2D* world, float mass, std::shared_ptr<ChipmunkCollider2D> geom);
|
||||
inline ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const DynamicSettings& settings);
|
||||
inline ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const StaticSettings& settings);
|
||||
ChipmunkRigidBody2D(const ChipmunkRigidBody2D& object);
|
||||
ChipmunkRigidBody2D(ChipmunkRigidBody2D&& object) noexcept;
|
||||
~ChipmunkRigidBody2D();
|
||||
inline ~ChipmunkRigidBody2D();
|
||||
|
||||
void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys::Global);
|
||||
inline void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys::Global);
|
||||
void AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys = CoordSys::Global);
|
||||
void AddImpulse(const Vector2f& impulse, CoordSys coordSys = CoordSys::Global);
|
||||
inline void AddImpulse(const Vector2f& impulse, CoordSys coordSys = CoordSys::Global);
|
||||
void AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys = CoordSys::Global);
|
||||
void AddTorque(const RadianAnglef& torque);
|
||||
|
||||
@@ -45,40 +48,36 @@ namespace Nz
|
||||
|
||||
void EnableSimulation(bool simulation);
|
||||
|
||||
void ForEachArbiter(std::function<void(ChipmunkArbiter2D& /*arbiter*/)> callback);
|
||||
void ForEachArbiter(const FunctionRef<void(ChipmunkArbiter2D& /*arbiter*/)>& callback);
|
||||
void ForceSleep();
|
||||
|
||||
Rectf GetAABB() const;
|
||||
inline float GetAngularDamping() const;
|
||||
RadianAnglef GetAngularVelocity() const;
|
||||
NAZARA_DEPRECATED("Name error, please use GetMassCenter")
|
||||
inline Vector2f GetCenterOfGravity(CoordSys coordSys = CoordSys::Local) const;
|
||||
float GetElasticity(std::size_t shapeIndex = 0) const;
|
||||
float GetFriction(std::size_t shapeIndex = 0) const;
|
||||
const std::shared_ptr<ChipmunkCollider2D>& GetGeom() const;
|
||||
cpBody* GetHandle() const;
|
||||
float GetMass() const;
|
||||
inline const std::shared_ptr<ChipmunkCollider2D>& GetGeom() const;
|
||||
inline cpBody* GetHandle() const;
|
||||
inline float GetMass() const;
|
||||
Vector2f GetMassCenter(CoordSys coordSys = CoordSys::Local) const;
|
||||
float GetMomentOfInertia() const;
|
||||
Vector2f GetPosition() const;
|
||||
inline const Vector2f& GetPositionOffset() const;
|
||||
RadianAnglef GetRotation() const;
|
||||
inline std::size_t GetShapeCount() const;
|
||||
std::size_t GetShapeIndex(cpShape* shape) const;
|
||||
inline std::size_t GetShapeIndex(cpShape* shape) const;
|
||||
Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
|
||||
void* GetUserdata() const;
|
||||
inline void* GetUserdata() const;
|
||||
Vector2f GetVelocity() const;
|
||||
const VelocityFunc& GetVelocityFunction() const;
|
||||
ChipmunkPhysWorld2D* GetWorld() const;
|
||||
inline const VelocityFunc& GetVelocityFunction() const;
|
||||
inline ChipmunkPhysWorld2D* GetWorld() const;
|
||||
|
||||
bool IsKinematic() const;
|
||||
bool IsSimulationEnabled() const;
|
||||
inline bool IsKinematic() const;
|
||||
inline bool IsSimulationEnabled() const;
|
||||
bool IsSleeping() const;
|
||||
bool IsStatic() const;
|
||||
inline bool IsStatic() const;
|
||||
|
||||
void ResetVelocityFunction();
|
||||
|
||||
inline void SetAngularDamping(float angularDamping);
|
||||
void SetAngularVelocity(const RadianAnglef& angularVelocity);
|
||||
void SetElasticity(float elasticity);
|
||||
void SetElasticity(std::size_t shapeIndex, float elasticity);
|
||||
@@ -94,7 +93,7 @@ namespace Nz
|
||||
void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
|
||||
void SetSurfaceVelocity(std::size_t shapeIndex, const Vector2f& surfaceVelocity);
|
||||
void SetStatic(bool setStaticBody = true);
|
||||
void SetUserdata(void* ud);
|
||||
inline void SetUserdata(void* ud);
|
||||
void SetVelocity(const Vector2f& velocity);
|
||||
void SetVelocityFunction(VelocityFunc velocityFunc);
|
||||
|
||||
@@ -112,24 +111,59 @@ namespace Nz
|
||||
|
||||
static constexpr std::size_t InvalidShapeIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct CommonSettings
|
||||
{
|
||||
std::shared_ptr<ChipmunkCollider2D> geom;
|
||||
RadianAnglef rotation = RadianAnglef::Zero();
|
||||
Vector2f position = Vector2f::Zero();
|
||||
bool initiallySleeping = false;
|
||||
bool isSimulationEnabled = true;
|
||||
};
|
||||
|
||||
struct DynamicSettings : CommonSettings
|
||||
{
|
||||
DynamicSettings() = default;
|
||||
DynamicSettings(std::shared_ptr<ChipmunkCollider2D> collider, float mass_) :
|
||||
mass(mass_)
|
||||
{
|
||||
geom = std::move(collider);
|
||||
}
|
||||
|
||||
RadianAnglef angularVelocity = RadianAnglef::Zero();
|
||||
Vector2f linearVelocity = Vector2f::Zero();
|
||||
float gravityFactor = 1.f;
|
||||
float mass = 1.f;
|
||||
};
|
||||
|
||||
struct StaticSettings : CommonSettings
|
||||
{
|
||||
StaticSettings() = default;
|
||||
StaticSettings(std::shared_ptr<ChipmunkCollider2D> collider)
|
||||
{
|
||||
geom = std::move(collider);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
ChipmunkRigidBody2D() = default;
|
||||
void Create(ChipmunkPhysWorld2D& world, const DynamicSettings& settings);
|
||||
void Create(ChipmunkPhysWorld2D& world, const StaticSettings& settings);
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
cpBody* Create(float mass = 1.f, float moment = 1.f);
|
||||
void RegisterToSpace();
|
||||
void UnregisterFromSpace();
|
||||
|
||||
static void CopyBodyData(cpBody* from, cpBody* to);
|
||||
static void CopyShapeData(cpShape* from, cpShape* to);
|
||||
|
||||
Vector2f m_positionOffset;
|
||||
VelocityFunc m_velocityFunc;
|
||||
std::vector<cpShape*> m_shapes;
|
||||
std::shared_ptr<ChipmunkCollider2D> m_geom;
|
||||
cpBody* m_handle;
|
||||
void* m_userData;
|
||||
ChipmunkPhysWorld2D* m_world;
|
||||
MovablePtr<cpBody> m_handle;
|
||||
MovablePtr<ChipmunkPhysWorld2D> m_world;
|
||||
MovablePtr<void> m_userData;
|
||||
Vector2f m_positionOffset;
|
||||
VelocityFunc m_velocityFunc;
|
||||
bool m_isRegistered;
|
||||
bool m_isSimulationEnabled;
|
||||
bool m_isStatic;
|
||||
|
||||
@@ -6,14 +6,46 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline float ChipmunkRigidBody2D::GetAngularDamping() const
|
||||
inline ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const DynamicSettings& settings)
|
||||
{
|
||||
return GetMomentOfInertia();
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline Vector2f ChipmunkRigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
|
||||
inline ChipmunkRigidBody2D::ChipmunkRigidBody2D(ChipmunkPhysWorld2D& world, const StaticSettings& settings)
|
||||
{
|
||||
return GetMassCenter(coordSys);
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline ChipmunkRigidBody2D::~ChipmunkRigidBody2D()
|
||||
{
|
||||
OnRigidBody2DRelease(this);
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
|
||||
{
|
||||
return AddForce(force, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys)
|
||||
{
|
||||
return AddImpulse(impulse, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<ChipmunkCollider2D>& ChipmunkRigidBody2D::GetGeom() const
|
||||
{
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
inline cpBody* ChipmunkRigidBody2D::GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
inline float ChipmunkRigidBody2D::GetMass() const
|
||||
{
|
||||
return m_mass;
|
||||
}
|
||||
|
||||
inline const Vector2f& ChipmunkRigidBody2D::GetPositionOffset() const
|
||||
@@ -21,14 +53,53 @@ namespace Nz
|
||||
return m_positionOffset;
|
||||
}
|
||||
|
||||
inline std::size_t ChipmunkRigidBody2D::GetShapeIndex(cpShape* shape) const
|
||||
{
|
||||
auto it = std::find(m_shapes.begin(), m_shapes.end(), shape);
|
||||
if (it == m_shapes.end())
|
||||
return InvalidShapeIndex;
|
||||
|
||||
return std::distance(m_shapes.begin(), it);
|
||||
}
|
||||
|
||||
inline std::size_t ChipmunkRigidBody2D::GetShapeCount() const
|
||||
{
|
||||
return m_shapes.size();
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::SetAngularDamping(float angularDamping)
|
||||
inline void* ChipmunkRigidBody2D::GetUserdata() const
|
||||
{
|
||||
SetMomentOfInertia(angularDamping);
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
inline const ChipmunkRigidBody2D::VelocityFunc& ChipmunkRigidBody2D::GetVelocityFunction() const
|
||||
{
|
||||
return m_velocityFunc;
|
||||
}
|
||||
|
||||
inline ChipmunkPhysWorld2D* ChipmunkRigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsKinematic() const
|
||||
{
|
||||
return m_mass <= 0.f;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsSimulationEnabled() const
|
||||
{
|
||||
return m_isSimulationEnabled;
|
||||
}
|
||||
|
||||
inline bool ChipmunkRigidBody2D::IsStatic() const
|
||||
{
|
||||
return m_isStatic;
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2D::SetUserdata(void* ud)
|
||||
{
|
||||
m_userData = ud;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/ChipmunkPhysics2D/ChipmunkRigidBody2D.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
@@ -17,13 +18,20 @@ namespace Nz
|
||||
friend class ChipmunkPhysics2DSystem;
|
||||
|
||||
public:
|
||||
using ChipmunkRigidBody2D::ChipmunkRigidBody2D;
|
||||
inline ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::DynamicSettings& settings);
|
||||
inline ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::StaticSettings& settings);
|
||||
ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2DComponent&) = default;
|
||||
ChipmunkRigidBody2DComponent(ChipmunkRigidBody2DComponent&&) noexcept = default;
|
||||
~ChipmunkRigidBody2DComponent() = default;
|
||||
|
||||
ChipmunkRigidBody2DComponent& operator=(const ChipmunkRigidBody2DComponent&) = default;
|
||||
ChipmunkRigidBody2DComponent& operator=(ChipmunkRigidBody2DComponent&&) noexcept = default;
|
||||
|
||||
private:
|
||||
inline void Construct(ChipmunkPhysWorld2D& world);
|
||||
|
||||
using Setting = std::variant<ChipmunkRigidBody2D::DynamicSettings, ChipmunkRigidBody2D::StaticSettings>;
|
||||
std::unique_ptr<Setting> m_settings;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,25 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline ChipmunkRigidBody2DComponent::ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::DynamicSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline ChipmunkRigidBody2DComponent::ChipmunkRigidBody2DComponent(const ChipmunkRigidBody2D::StaticSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline void ChipmunkRigidBody2DComponent::Construct(ChipmunkPhysWorld2D& world)
|
||||
{
|
||||
assert(m_settings);
|
||||
std::visit([&](auto&& arg)
|
||||
{
|
||||
Create(world, arg);
|
||||
}, *m_settings);
|
||||
m_settings.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/ChipmunkPhysics2D/DebugOff.hpp>
|
||||
|
||||
@@ -27,8 +27,6 @@ namespace Nz
|
||||
ChipmunkPhysics2DSystem(ChipmunkPhysics2DSystem&&) = delete;
|
||||
~ChipmunkPhysics2DSystem();
|
||||
|
||||
template<typename... Args> ChipmunkRigidBody2DComponent CreateRigidBody(Args&&... args);
|
||||
|
||||
inline ChipmunkPhysWorld2D& GetPhysWorld();
|
||||
inline const ChipmunkPhysWorld2D& GetPhysWorld() const;
|
||||
|
||||
@@ -38,9 +36,11 @@ namespace Nz
|
||||
ChipmunkPhysics2DSystem& operator=(ChipmunkPhysics2DSystem&&) = delete;
|
||||
|
||||
private:
|
||||
void OnBodyConstruct(entt::registry& registry, entt::entity entity);
|
||||
|
||||
entt::registry& m_registry;
|
||||
entt::observer m_physicsConstructObserver;
|
||||
entt::scoped_connection m_constructConnection;
|
||||
entt::scoped_connection m_bodyConstructConnection;
|
||||
ChipmunkPhysWorld2D m_physWorld;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,12 +6,6 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename... Args>
|
||||
ChipmunkRigidBody2DComponent ChipmunkPhysics2DSystem::CreateRigidBody(Args&&... args)
|
||||
{
|
||||
return ChipmunkRigidBody2DComponent(&m_physWorld, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline ChipmunkPhysWorld2D& ChipmunkPhysics2DSystem::GetPhysWorld()
|
||||
{
|
||||
return m_physWorld;
|
||||
|
||||
Reference in New Issue
Block a user