Rename ChipmunkPhysics2D and JoltPhysics3D to Physics[2D|3D]
This commit is contained in:
212
include/Nazara/Physics2D/Collider2D.hpp
Normal file
212
include/Nazara/Physics2D/Collider2D.hpp
Normal file
@@ -0,0 +1,212 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_COLLIDER2D_HPP
|
||||
#define NAZARA_PHYSICS2D_COLLIDER2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/ObjectLibrary.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <Nazara/Physics2D/Enums.hpp>
|
||||
#include <NazaraUtils/FunctionRef.hpp>
|
||||
#include <NazaraUtils/Signal.hpp>
|
||||
#include <NazaraUtils/SparsePtr.hpp>
|
||||
#include <vector>
|
||||
|
||||
struct cpBody;
|
||||
struct cpShape;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RigidBody2D;
|
||||
|
||||
class NAZARA_PHYSICS2D_API Collider2D
|
||||
{
|
||||
friend RigidBody2D;
|
||||
friend class CompoundCollider2D; //< See CompoundCollider2D::CreateShapes
|
||||
|
||||
public:
|
||||
inline Collider2D();
|
||||
Collider2D(const Collider2D&) = delete;
|
||||
Collider2D(Collider2D&&) = delete;
|
||||
virtual ~Collider2D();
|
||||
|
||||
virtual Vector2f ComputeCenterOfMass() const = 0;
|
||||
virtual float ComputeMomentOfInertia(float mass) const = 0;
|
||||
|
||||
virtual void ForEachPolygon(const FunctionRef<void(const Vector2f* vertices, std::size_t vertexCount)>& callback) const;
|
||||
|
||||
inline UInt32 GetCategoryMask() const;
|
||||
inline UInt32 GetCollisionGroup() const;
|
||||
inline unsigned int GetCollisionId() const;
|
||||
inline UInt32 GetCollisionMask() const;
|
||||
inline float GetElasticity() const;
|
||||
inline float GetFriction() const;
|
||||
inline Vector2f GetSurfaceVelocity() const;
|
||||
|
||||
virtual ColliderType2D GetType() const = 0;
|
||||
|
||||
inline bool IsTrigger() const;
|
||||
|
||||
inline void SetCategoryMask(UInt32 categoryMask);
|
||||
inline void SetCollisionGroup(UInt32 groupId);
|
||||
inline void SetCollisionId(unsigned int typeId);
|
||||
inline void SetCollisionMask(UInt32 mask);
|
||||
inline void SetElasticity(float elasticity);
|
||||
inline void SetFriction(float friction);
|
||||
inline void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
|
||||
inline void SetTrigger(bool trigger);
|
||||
|
||||
Collider2D& operator=(const Collider2D&) = delete;
|
||||
Collider2D& operator=(Collider2D&&) = delete;
|
||||
|
||||
// Signals:
|
||||
NazaraSignal(OnColliderRelease, const Collider2D* /*collider*/);
|
||||
|
||||
protected:
|
||||
virtual std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const = 0;
|
||||
|
||||
UInt32 m_categoryMask;
|
||||
UInt32 m_collisionGroup;
|
||||
UInt32 m_collisionMask;
|
||||
Vector2f m_surfaceVelocity;
|
||||
bool m_trigger;
|
||||
float m_elasticity;
|
||||
float m_friction;
|
||||
unsigned int m_collisionId;
|
||||
|
||||
private:
|
||||
virtual std::size_t GenerateShapes(cpBody* body, std::vector<cpShape*>* shapes) const;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API BoxCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
BoxCollider2D(const Vector2f& size, float radius = 0.f);
|
||||
BoxCollider2D(const Rectf& rect, float radius = 0.f);
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline float GetRadius() const;
|
||||
inline const Rectf& GetRect() const;
|
||||
inline Vector2f GetSize() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
|
||||
Rectf m_rect;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API CircleCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
CircleCollider2D(float radius, const Vector2f& offset = Vector2f::Zero());
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline const Vector2f& GetOffset() const;
|
||||
inline float GetRadius() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
|
||||
Vector2f m_offset;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API CompoundCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
CompoundCollider2D(std::vector<std::shared_ptr<Collider2D>> geoms);
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline bool DoesOverrideCollisionProperties() const;
|
||||
|
||||
inline const std::vector<std::shared_ptr<Collider2D>>& GetGeoms() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
inline void OverridesCollisionProperties(bool shouldOverride);
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
std::size_t GenerateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
|
||||
std::vector<std::shared_ptr<Collider2D>> m_geoms;
|
||||
bool m_doesOverrideCollisionProperties;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API ConvexCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
ConvexCollider2D(SparsePtr<const Vector2f> vertices, std::size_t vertexCount, float radius = 0.f);
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
ColliderType2D GetType() const override;
|
||||
inline const std::vector<Vector2d>& GetVertices() const;
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
|
||||
std::vector<Vector2d> m_vertices;
|
||||
float m_radius;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API NullCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
NullCollider2D() = default;
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
};
|
||||
|
||||
class NAZARA_PHYSICS2D_API SegmentCollider2D : public Collider2D
|
||||
{
|
||||
public:
|
||||
inline SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness = 1.f);
|
||||
inline SegmentCollider2D(const Vector2f& first, const Vector2f& firstNeighbor, const Vector2f& second, const Vector2f& secondNeighbor, float thickness = 1.f);
|
||||
|
||||
Nz::Vector2f ComputeCenterOfMass() const override;
|
||||
float ComputeMomentOfInertia(float mass) const override;
|
||||
|
||||
inline const Vector2f& GetFirstPoint() const;
|
||||
inline const Vector2f& GetFirstPointNeighbor() const;
|
||||
inline float GetLength() const;
|
||||
inline const Vector2f& GetSecondPoint() const;
|
||||
inline const Vector2f& GetSecondPointNeighbor() const;
|
||||
inline float GetThickness() const;
|
||||
ColliderType2D GetType() const override;
|
||||
|
||||
private:
|
||||
std::size_t CreateShapes(cpBody* body, std::vector<cpShape*>* shapes) const override;
|
||||
|
||||
Vector2f m_first;
|
||||
Vector2f m_firstNeighbor;
|
||||
Vector2f m_second;
|
||||
Vector2f m_secondNeighbor;
|
||||
float m_thickness;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/Collider2D.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_COLLIDER2D_HPP
|
||||
196
include/Nazara/Physics2D/Collider2D.inl
Normal file
196
include/Nazara/Physics2D/Collider2D.inl
Normal file
@@ -0,0 +1,196 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <memory>
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline Collider2D::Collider2D() :
|
||||
m_categoryMask(0xFFFFFFFF),
|
||||
m_collisionGroup(0),
|
||||
m_collisionMask(0xFFFFFFFF),
|
||||
m_surfaceVelocity(Vector2f::Zero()),
|
||||
m_trigger(false),
|
||||
m_elasticity(0.f),
|
||||
m_friction(0.f),
|
||||
m_collisionId(0)
|
||||
{
|
||||
}
|
||||
|
||||
inline UInt32 Collider2D::GetCategoryMask() const
|
||||
{
|
||||
return m_categoryMask;
|
||||
}
|
||||
|
||||
inline UInt32 Collider2D::GetCollisionGroup() const
|
||||
{
|
||||
return m_collisionGroup;
|
||||
}
|
||||
|
||||
inline unsigned int Collider2D::GetCollisionId() const
|
||||
{
|
||||
return m_collisionId;
|
||||
}
|
||||
|
||||
inline UInt32 Collider2D::GetCollisionMask() const
|
||||
{
|
||||
return m_collisionMask;
|
||||
}
|
||||
|
||||
inline float Collider2D::GetElasticity() const
|
||||
{
|
||||
return m_elasticity;
|
||||
}
|
||||
|
||||
inline float Collider2D::GetFriction() const
|
||||
{
|
||||
return m_friction;
|
||||
}
|
||||
|
||||
inline Vector2f Collider2D::GetSurfaceVelocity() const
|
||||
{
|
||||
return m_surfaceVelocity;
|
||||
}
|
||||
|
||||
inline bool Collider2D::IsTrigger() const
|
||||
{
|
||||
return m_trigger;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetCategoryMask(UInt32 categoryMask)
|
||||
{
|
||||
m_categoryMask = categoryMask;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetCollisionGroup(UInt32 groupId)
|
||||
{
|
||||
m_collisionGroup = groupId;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetCollisionId(unsigned int typeId)
|
||||
{
|
||||
m_collisionId = typeId;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetCollisionMask(UInt32 mask)
|
||||
{
|
||||
m_collisionMask = mask;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetElasticity(float elasticity)
|
||||
{
|
||||
m_elasticity = elasticity;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetFriction(float friction)
|
||||
{
|
||||
m_friction = friction;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetSurfaceVelocity(const Vector2f& surfaceVelocity)
|
||||
{
|
||||
m_surfaceVelocity = surfaceVelocity;
|
||||
}
|
||||
|
||||
inline void Collider2D::SetTrigger(bool trigger)
|
||||
{
|
||||
m_trigger = trigger;
|
||||
}
|
||||
|
||||
inline float BoxCollider2D::GetRadius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
inline const Rectf& BoxCollider2D::GetRect() const
|
||||
{
|
||||
return m_rect;
|
||||
}
|
||||
|
||||
inline Vector2f BoxCollider2D::GetSize() const
|
||||
{
|
||||
return m_rect.GetLengths();
|
||||
}
|
||||
|
||||
|
||||
inline const Vector2f& CircleCollider2D::GetOffset() const
|
||||
{
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
inline float CircleCollider2D::GetRadius() const
|
||||
{
|
||||
return m_radius;
|
||||
}
|
||||
|
||||
|
||||
inline bool Nz::CompoundCollider2D::DoesOverrideCollisionProperties() const
|
||||
{
|
||||
return m_doesOverrideCollisionProperties;
|
||||
}
|
||||
|
||||
inline const std::vector<std::shared_ptr<Collider2D>>& CompoundCollider2D::GetGeoms() const
|
||||
{
|
||||
return m_geoms;
|
||||
}
|
||||
|
||||
inline void Nz::CompoundCollider2D::OverridesCollisionProperties(bool shouldOverride)
|
||||
{
|
||||
m_doesOverrideCollisionProperties = shouldOverride;
|
||||
}
|
||||
|
||||
|
||||
inline const std::vector<Vector2d>& ConvexCollider2D::GetVertices() const
|
||||
{
|
||||
return m_vertices;
|
||||
}
|
||||
|
||||
|
||||
SegmentCollider2D::SegmentCollider2D(const Vector2f& first, const Vector2f& second, float thickness) :
|
||||
SegmentCollider2D(first, first, second, second, thickness)
|
||||
{
|
||||
}
|
||||
|
||||
inline SegmentCollider2D::SegmentCollider2D(const Vector2f& first, const Vector2f& firstNeighbor, const Vector2f& second, const Vector2f& secondNeighbor, float thickness) :
|
||||
m_first(first),
|
||||
m_firstNeighbor(firstNeighbor),
|
||||
m_second(second),
|
||||
m_secondNeighbor(secondNeighbor),
|
||||
m_thickness(thickness)
|
||||
{
|
||||
}
|
||||
|
||||
inline const Vector2f& SegmentCollider2D::GetFirstPoint() const
|
||||
{
|
||||
return m_first;
|
||||
}
|
||||
|
||||
inline const Vector2f& SegmentCollider2D::GetFirstPointNeighbor() const
|
||||
{
|
||||
return m_firstNeighbor;
|
||||
}
|
||||
|
||||
inline float SegmentCollider2D::GetLength() const
|
||||
{
|
||||
return m_first.Distance(m_second);
|
||||
}
|
||||
|
||||
inline const Vector2f& SegmentCollider2D::GetSecondPoint() const
|
||||
{
|
||||
return m_second;
|
||||
}
|
||||
|
||||
inline const Vector2f& SegmentCollider2D::GetSecondPointNeighbor() const
|
||||
{
|
||||
return m_secondNeighbor;
|
||||
}
|
||||
|
||||
inline float SegmentCollider2D::GetThickness() const
|
||||
{
|
||||
return m_thickness;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
34
include/Nazara/Physics2D/Components.hpp
Normal file
34
include/Nazara/Physics2D/Components.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// this file was automatically generated and should not be edited
|
||||
|
||||
/*
|
||||
Nazara Engine - Physics2D module
|
||||
|
||||
Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||
#define NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||
|
||||
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_COMPONENTS_HPP
|
||||
40
include/Nazara/Physics2D/Components/RigidBody2DComponent.hpp
Normal file
40
include/Nazara/Physics2D/Components/RigidBody2DComponent.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||
#define NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||
#include <variant>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_PHYSICS2D_API RigidBody2DComponent : public RigidBody2D
|
||||
{
|
||||
friend class Physics2DSystem;
|
||||
|
||||
public:
|
||||
inline RigidBody2DComponent(const RigidBody2D::DynamicSettings& settings);
|
||||
inline RigidBody2DComponent(const RigidBody2D::StaticSettings& settings);
|
||||
RigidBody2DComponent(const RigidBody2DComponent&) = delete;
|
||||
RigidBody2DComponent(RigidBody2DComponent&&) noexcept = default;
|
||||
~RigidBody2DComponent() = default;
|
||||
|
||||
RigidBody2DComponent& operator=(const RigidBody2DComponent&) = delete;
|
||||
RigidBody2DComponent& operator=(RigidBody2DComponent&&) noexcept = default;
|
||||
|
||||
private:
|
||||
inline void Construct(PhysWorld2D& world);
|
||||
|
||||
using Setting = std::variant<RigidBody2D::DynamicSettings, RigidBody2D::StaticSettings>;
|
||||
std::unique_ptr<Setting> m_settings;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/Components/RigidBody2DComponent.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_COMPONENTS_RIGIDBODY2DCOMPONENT_HPP
|
||||
30
include/Nazara/Physics2D/Components/RigidBody2DComponent.inl
Normal file
30
include/Nazara/Physics2D/Components/RigidBody2DComponent.inl
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline RigidBody2DComponent::RigidBody2DComponent(const RigidBody2D::DynamicSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline RigidBody2DComponent::RigidBody2DComponent(const RigidBody2D::StaticSettings& settings)
|
||||
{
|
||||
m_settings = std::make_unique<Setting>(settings);
|
||||
}
|
||||
|
||||
inline void RigidBody2DComponent::Construct(PhysWorld2D& world)
|
||||
{
|
||||
assert(m_settings);
|
||||
std::visit([&](auto&& arg)
|
||||
{
|
||||
Create(world, arg);
|
||||
}, *m_settings);
|
||||
m_settings.reset();
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
48
include/Nazara/Physics2D/Config.hpp
Normal file
48
include/Nazara/Physics2D/Config.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Nazara Engine - Physics2D module
|
||||
|
||||
Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_CONFIG_HPP
|
||||
#define NAZARA_PHYSICS2D_CONFIG_HPP
|
||||
|
||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||
|
||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||
#define NAZARA_PHYSICS2D_SAFE 1
|
||||
|
||||
/// Vérification des valeurs et types de certaines constantes
|
||||
#include <Nazara/Physics2D/ConfigCheck.hpp>
|
||||
|
||||
#if defined(NAZARA_STATIC)
|
||||
#define NAZARA_PHYSICS2D_API
|
||||
#else
|
||||
#ifdef NAZARA_PHYSICS2D_BUILD
|
||||
#define NAZARA_PHYSICS2D_API NAZARA_EXPORT
|
||||
#else
|
||||
#define NAZARA_PHYSICS2D_API NAZARA_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_CONFIG_HPP
|
||||
19
include/Nazara/Physics2D/ConfigCheck.hpp
Normal file
19
include/Nazara/Physics2D/ConfigCheck.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_CONFIGCHECK_HPP
|
||||
#define NAZARA_PHYSICS2D_CONFIGCHECK_HPP
|
||||
|
||||
/// This file is used to check the constant values defined in Config.hpp
|
||||
|
||||
#include <type_traits>
|
||||
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
|
||||
|
||||
// config checks
|
||||
|
||||
#undef NazaraCheckTypeAndVal
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_CONFIGCHECK_HPP
|
||||
5
include/Nazara/Physics2D/Debug.hpp
Normal file
5
include/Nazara/Physics2D/Debug.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// no header guards
|
||||
5
include/Nazara/Physics2D/DebugOff.hpp
Normal file
5
include/Nazara/Physics2D/DebugOff.hpp
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
// no header guards
|
||||
25
include/Nazara/Physics2D/Enums.hpp
Normal file
25
include/Nazara/Physics2D/Enums.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_ENUMS_HPP
|
||||
#define NAZARA_PHYSICS2D_ENUMS_HPP
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
enum class ColliderType2D
|
||||
{
|
||||
Box,
|
||||
Compound,
|
||||
Convex,
|
||||
Circle,
|
||||
Null,
|
||||
Segment,
|
||||
|
||||
Max = Segment
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_ENUMS_HPP
|
||||
61
include/Nazara/Physics2D/PhysArbiter2D.hpp
Normal file
61
include/Nazara/Physics2D/PhysArbiter2D.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_PHYSARBITER2D_HPP
|
||||
#define NAZARA_PHYSICS2D_PHYSARBITER2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <NazaraUtils/MovablePtr.hpp>
|
||||
|
||||
struct cpArbiter;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class RigidBody2D;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysArbiter2D
|
||||
{
|
||||
public:
|
||||
inline PhysArbiter2D(cpArbiter* arbiter);
|
||||
PhysArbiter2D(const PhysArbiter2D&) = delete;
|
||||
PhysArbiter2D(PhysArbiter2D&&) = default;
|
||||
~PhysArbiter2D() = default;
|
||||
|
||||
float ComputeTotalKinematicEnergy() const;
|
||||
Nz::Vector2f ComputeTotalImpulse() const;
|
||||
|
||||
std::pair<RigidBody2D*, RigidBody2D*> GetBodies() const;
|
||||
|
||||
std::size_t GetContactCount() const;
|
||||
float GetContactDepth(std::size_t i) const;
|
||||
Vector2f GetContactPointA(std::size_t i) const;
|
||||
Vector2f GetContactPointB(std::size_t i) const;
|
||||
|
||||
float GetElasticity() const;
|
||||
float GetFriction() const;
|
||||
Vector2f GetNormal() const;
|
||||
Vector2f GetSurfaceVelocity() const;
|
||||
|
||||
bool IsFirstContact() const;
|
||||
bool IsRemoval() const;
|
||||
|
||||
void SetElasticity(float elasticity);
|
||||
void SetFriction(float friction);
|
||||
void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
|
||||
|
||||
PhysArbiter2D& operator=(const PhysArbiter2D&) = delete;
|
||||
PhysArbiter2D& operator=(PhysArbiter2D&&) = default;
|
||||
|
||||
private:
|
||||
MovablePtr<cpArbiter> m_arbiter;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/PhysArbiter2D.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_PHYSARBITER2D_HPP
|
||||
16
include/Nazara/Physics2D/PhysArbiter2D.inl
Normal file
16
include/Nazara/Physics2D/PhysArbiter2D.inl
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <memory>
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline PhysArbiter2D::PhysArbiter2D(cpArbiter* arbiter) :
|
||||
m_arbiter(arbiter)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
238
include/Nazara/Physics2D/PhysConstraint2D.hpp
Normal file
238
include/Nazara/Physics2D/PhysConstraint2D.hpp
Normal file
@@ -0,0 +1,238 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_PHYSCONSTRAINT2D_HPP
|
||||
#define NAZARA_PHYSICS2D_PHYSCONSTRAINT2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/HandledObject.hpp>
|
||||
#include <Nazara/Core/ObjectHandle.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <Nazara/Physics2D/PhysWorld2D.hpp>
|
||||
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||
#include <NazaraUtils/MovablePtr.hpp>
|
||||
|
||||
struct cpConstraint;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class PhysConstraint2D;
|
||||
|
||||
using PhysConstraint2DHandle = ObjectHandle<PhysConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysConstraint2D : public HandledObject<PhysConstraint2D>
|
||||
{
|
||||
public:
|
||||
PhysConstraint2D(const PhysConstraint2D&) = delete;
|
||||
PhysConstraint2D(PhysConstraint2D&& constraint) noexcept;
|
||||
virtual ~PhysConstraint2D();
|
||||
|
||||
void EnableBodyCollision(bool enable);
|
||||
|
||||
RigidBody2D& GetBodyA();
|
||||
const RigidBody2D& GetBodyA() const;
|
||||
RigidBody2D& GetBodyB();
|
||||
const RigidBody2D& GetBodyB() const;
|
||||
float GetErrorBias() const;
|
||||
float GetLastImpulse() const;
|
||||
float GetMaxBias() const;
|
||||
float GetMaxForce() const;
|
||||
PhysWorld2D& GetWorld();
|
||||
const PhysWorld2D& GetWorld() const;
|
||||
|
||||
bool IsBodyCollisionEnabled() const;
|
||||
bool IsSingleBody() const;
|
||||
|
||||
void SetErrorBias(float bias);
|
||||
void SetMaxBias(float bias);
|
||||
void SetMaxForce(float force);
|
||||
|
||||
PhysConstraint2D& operator=(const PhysConstraint2D&) = delete;
|
||||
PhysConstraint2D& operator=(PhysConstraint2D&& constraint) noexcept;
|
||||
|
||||
protected:
|
||||
PhysConstraint2D(PhysWorld2D* world, cpConstraint* constraint);
|
||||
|
||||
MovablePtr<cpConstraint> m_constraint;
|
||||
|
||||
private:
|
||||
void Destroy();
|
||||
};
|
||||
|
||||
class PhysDampedSpringConstraint2D;
|
||||
|
||||
using PhysDampedSpringConstraint2DHandle = ObjectHandle<PhysDampedSpringConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysDampedSpringConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysDampedSpringConstraint2D(RigidBody2D& first, RigidBody2D& second, const Vector2f& firstAnchor, const Vector2f& secondAnchor, float restLength, float stiffness, float damping);
|
||||
~PhysDampedSpringConstraint2D() = default;
|
||||
|
||||
float GetDamping() const;
|
||||
Vector2f GetFirstAnchor() const;
|
||||
float GetRestLength() const;
|
||||
Vector2f GetSecondAnchor() const;
|
||||
float GetStiffness() const;
|
||||
|
||||
void SetDamping(float newDamping);
|
||||
void SetFirstAnchor(const Vector2f& firstAnchor);
|
||||
void SetRestLength(float newLength);
|
||||
void SetSecondAnchor(const Vector2f& firstAnchor);
|
||||
void SetStiffness(float newStiffness);
|
||||
};
|
||||
|
||||
class PhysDampedRotarySpringConstraint2D;
|
||||
|
||||
using PhysDampedRotarySpringConstraint2DHandle = ObjectHandle<PhysDampedRotarySpringConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysDampedRotarySpringConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysDampedRotarySpringConstraint2D(RigidBody2D& first, RigidBody2D& second, const RadianAnglef& restAngle, float stiffness, float damping);
|
||||
~PhysDampedRotarySpringConstraint2D() = default;
|
||||
|
||||
float GetDamping() const;
|
||||
RadianAnglef GetRestAngle() const;
|
||||
float GetStiffness() const;
|
||||
|
||||
void SetDamping(float newDamping);
|
||||
void SetRestAngle(const RadianAnglef& newAngle);
|
||||
void SetStiffness(float newStiffness);
|
||||
};
|
||||
|
||||
class PhysGearConstraint2D;
|
||||
|
||||
using PhysGearConstraint2DHandle = ObjectHandle<PhysGearConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysGearConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysGearConstraint2D(RigidBody2D& first, RigidBody2D& second, float phase, float ratio);
|
||||
~PhysGearConstraint2D() = default;
|
||||
|
||||
float GetPhase() const;
|
||||
float GetRatio() const;
|
||||
|
||||
void SetPhase(float phase);
|
||||
void SetRatio(float ratio);
|
||||
};
|
||||
|
||||
class PhysMotorConstraint2D;
|
||||
|
||||
using PhysMotorConstraint2DHandle = ObjectHandle<PhysMotorConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysMotorConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysMotorConstraint2D(RigidBody2D& first, RigidBody2D& second, float rate);
|
||||
~PhysMotorConstraint2D() = default;
|
||||
|
||||
float GetRate() const;
|
||||
void SetRate(float rate);
|
||||
};
|
||||
|
||||
class PhysPinConstraint2D;
|
||||
|
||||
using PhysPinConstraint2DHandle = ObjectHandle<PhysPinConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysPinConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysPinConstraint2D(RigidBody2D& body, const Vector2f& anchor);
|
||||
PhysPinConstraint2D(RigidBody2D& first, RigidBody2D& second, const Vector2f& firstAnchor, const Vector2f& secondAnchor);
|
||||
~PhysPinConstraint2D() = default;
|
||||
|
||||
float GetDistance() const;
|
||||
Vector2f GetFirstAnchor() const;
|
||||
Vector2f GetSecondAnchor() const;
|
||||
|
||||
void SetDistance(float newDistance);
|
||||
void SetFirstAnchor(const Vector2f& firstAnchor);
|
||||
void SetSecondAnchor(const Vector2f& firstAnchor);
|
||||
};
|
||||
|
||||
class PhysPivotConstraint2D;
|
||||
|
||||
using PhysPivotConstraint2DHandle = ObjectHandle<PhysPivotConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysPivotConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysPivotConstraint2D(RigidBody2D& body, const Vector2f& anchor);
|
||||
PhysPivotConstraint2D(RigidBody2D& first, RigidBody2D& second, const Vector2f& anchor);
|
||||
PhysPivotConstraint2D(RigidBody2D& first, RigidBody2D& second, const Vector2f& firstAnchor, const Vector2f& secondAnchor);
|
||||
~PhysPivotConstraint2D() = default;
|
||||
|
||||
Vector2f GetFirstAnchor() const;
|
||||
Vector2f GetSecondAnchor() const;
|
||||
|
||||
void SetFirstAnchor(const Vector2f& firstAnchor);
|
||||
void SetSecondAnchor(const Vector2f& firstAnchor);
|
||||
};
|
||||
|
||||
class PhysRatchetConstraint2D;
|
||||
|
||||
using PhysRatchetConstraint2DHandle = ObjectHandle<PhysRatchetConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysRatchetConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysRatchetConstraint2D(RigidBody2D& first, RigidBody2D& second, float phase, float ratchet);
|
||||
~PhysRatchetConstraint2D() = default;
|
||||
|
||||
RadianAnglef GetAngle() const;
|
||||
float GetPhase() const;
|
||||
float GetRatchet() const;
|
||||
|
||||
void SetAngle(const RadianAnglef& angle);
|
||||
void SetPhase(float phase);
|
||||
void SetRatchet(float ratchet);
|
||||
};
|
||||
|
||||
class PhysRotaryLimitConstraint2D;
|
||||
|
||||
using PhysRotaryLimitConstraint2DHandle = ObjectHandle<PhysRotaryLimitConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysRotaryLimitConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysRotaryLimitConstraint2D(RigidBody2D& first, RigidBody2D& second, const RadianAnglef& minAngle, const RadianAnglef& maxAngle);
|
||||
~PhysRotaryLimitConstraint2D() = default;
|
||||
|
||||
RadianAnglef GetMaxAngle() const;
|
||||
RadianAnglef GetMinAngle() const;
|
||||
|
||||
void SetMaxAngle(const RadianAnglef& maxAngle);
|
||||
void SetMinAngle(const RadianAnglef& minAngle);
|
||||
};
|
||||
|
||||
class PhysSlideConstraint2D;
|
||||
|
||||
using PhysSlideConstraint2DHandle = ObjectHandle<PhysSlideConstraint2D>;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysSlideConstraint2D : public PhysConstraint2D
|
||||
{
|
||||
public:
|
||||
PhysSlideConstraint2D(RigidBody2D& first, RigidBody2D& second, const Vector2f& firstAnchor, const Vector2f& secondAnchor, float min, float max);
|
||||
~PhysSlideConstraint2D() = default;
|
||||
|
||||
Vector2f GetFirstAnchor() const;
|
||||
float GetMaxDistance() const;
|
||||
float GetMinDistance() const;
|
||||
Vector2f GetSecondAnchor() const;
|
||||
|
||||
void SetFirstAnchor(const Vector2f& firstAnchor);
|
||||
void SetMaxDistance(float newMaxDistance);
|
||||
void SetMinDistance(float newMinDistance);
|
||||
void SetSecondAnchor(const Vector2f& firstAnchor);
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/PhysConstraint2D.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_PHYSCONSTRAINT2D_HPP
|
||||
12
include/Nazara/Physics2D/PhysConstraint2D.inl
Normal file
12
include/Nazara/Physics2D/PhysConstraint2D.inl
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <memory>
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
163
include/Nazara/Physics2D/PhysWorld2D.hpp
Normal file
163
include/Nazara/Physics2D/PhysWorld2D.hpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_PHYSWORLD2D_HPP
|
||||
#define NAZARA_PHYSICS2D_PHYSWORLD2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/Vector2.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <Nazara/Physics2D/RigidBody2D.hpp>
|
||||
#include <NazaraUtils/Bitset.hpp>
|
||||
#include <NazaraUtils/FunctionRef.hpp>
|
||||
#include <NazaraUtils/Signal.hpp>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct cpCollisionHandler;
|
||||
struct cpSpace;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class PhysArbiter2D;
|
||||
|
||||
class NAZARA_PHYSICS2D_API PhysWorld2D
|
||||
{
|
||||
friend RigidBody2D;
|
||||
|
||||
using ContactEndCallback = std::function<void(PhysWorld2D& world, PhysArbiter2D& arbiter, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactPreSolveCallback = std::function<bool(PhysWorld2D& world, PhysArbiter2D& arbiter, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactPostSolveCallback = std::function<void(PhysWorld2D& world, PhysArbiter2D& arbiter, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
using ContactStartCallback = std::function<bool(PhysWorld2D& world, PhysArbiter2D& arbiter, RigidBody2D& bodyA, RigidBody2D& bodyB, void* userdata)>;
|
||||
|
||||
using DebugDrawCircleCallback = std::function<void(const Vector2f& origin, const RadianAnglef& rotation, float radius, const Color& outlineColor, const Color& fillColor, void* userdata)>;
|
||||
using DebugDrawDotCallback = std::function<void(const Vector2f& origin, float radius, const Color& color, void* userdata)>;
|
||||
using DebugDrawPolygonCallback = std::function<void(const Vector2f* vertices, std::size_t vertexCount, float radius, const Color& outlineColor, const Color& fillColor, void* userdata)>;
|
||||
using DebugDrawSegmentCallback = std::function<void(const Vector2f& first, const Vector2f& second, const Color& color, void* userdata)>;
|
||||
using DebugDrawTickSegmentCallback = std::function<void(const Vector2f& first, const Vector2f& second, float thickness, const Color& outlineColor, const Color& fillColor, void* userdata)>;
|
||||
using DebugDrawGetColorCallback = std::function<Color(RigidBody2D& body, std::size_t shapeIndex, void* userdata)>;
|
||||
|
||||
public:
|
||||
struct ContactCallbacks;
|
||||
struct DebugDrawOptions;
|
||||
struct NearestQueryResult;
|
||||
struct RaycastHit;
|
||||
|
||||
PhysWorld2D();
|
||||
PhysWorld2D(const PhysWorld2D&) = delete;
|
||||
PhysWorld2D(PhysWorld2D&&) = delete;
|
||||
~PhysWorld2D();
|
||||
|
||||
void DebugDraw(const DebugDrawOptions& options, bool drawShapes = true, bool drawConstraints = true, bool drawCollisions = true) const;
|
||||
|
||||
float GetDamping() const;
|
||||
Vector2f GetGravity() const;
|
||||
cpSpace* GetHandle() const;
|
||||
std::size_t GetIterationCount() const;
|
||||
std::size_t GetMaxStepCount() const;
|
||||
Time GetStepSize() const;
|
||||
|
||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RigidBody2D** nearestBody = nullptr);
|
||||
bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, NearestQueryResult* result);
|
||||
|
||||
void RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(const RaycastHit&)>& callback);
|
||||
bool RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
|
||||
bool RaycastQueryFirst(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
|
||||
|
||||
void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(RigidBody2D*)>& callback);
|
||||
void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RigidBody2D*>* bodies);
|
||||
|
||||
void RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks);
|
||||
void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks);
|
||||
|
||||
void SetDamping(float dampingValue);
|
||||
void SetGravity(const Vector2f& gravity);
|
||||
void SetIterationCount(std::size_t iterationCount);
|
||||
void SetMaxStepCount(std::size_t maxStepCount);
|
||||
void SetSleepTime(Time sleepTime);
|
||||
void SetStepSize(Time stepSize);
|
||||
|
||||
void Step(Time timestep);
|
||||
|
||||
void UseSpatialHash(float cellSize, std::size_t entityCount);
|
||||
|
||||
PhysWorld2D& operator=(const PhysWorld2D&) = delete;
|
||||
PhysWorld2D& operator=(PhysWorld2D&&) = delete;
|
||||
|
||||
struct ContactCallbacks
|
||||
{
|
||||
ContactEndCallback endCallback = nullptr;
|
||||
ContactPostSolveCallback postSolveCallback = nullptr;
|
||||
ContactPreSolveCallback preSolveCallback = nullptr;
|
||||
ContactStartCallback startCallback = nullptr;
|
||||
void* userdata = nullptr;
|
||||
};
|
||||
|
||||
struct DebugDrawOptions
|
||||
{
|
||||
Color constraintColor = Color::Blue();
|
||||
Color collisionPointColor = Color::Green();
|
||||
Color shapeOutlineColor = Color::Red();
|
||||
|
||||
DebugDrawCircleCallback circleCallback;
|
||||
DebugDrawGetColorCallback colorCallback;
|
||||
DebugDrawDotCallback dotCallback;
|
||||
DebugDrawPolygonCallback polygonCallback;
|
||||
DebugDrawSegmentCallback segmentCallback;
|
||||
DebugDrawTickSegmentCallback thickSegmentCallback;
|
||||
|
||||
void* userdata = nullptr;
|
||||
};
|
||||
|
||||
struct NearestQueryResult
|
||||
{
|
||||
RigidBody2D* nearestBody;
|
||||
Vector2f closestPoint;
|
||||
Vector2f fraction;
|
||||
float distance;
|
||||
};
|
||||
|
||||
struct RaycastHit
|
||||
{
|
||||
RigidBody2D* nearestBody;
|
||||
Vector2f hitPos;
|
||||
Vector2f hitNormal;
|
||||
float fraction;
|
||||
};
|
||||
|
||||
NazaraSignal(OnPhysWorld2DPreStep, const PhysWorld2D* /*physWorld*/, float /*invStepCount*/);
|
||||
NazaraSignal(OnPhysWorld2DPostStep, const PhysWorld2D* /*physWorld*/, float /*invStepCount*/);
|
||||
|
||||
private:
|
||||
using PostStep = std::function<void(RigidBody2D* body)>;
|
||||
|
||||
static constexpr std::size_t FreeBodyIdGrowRate = 256;
|
||||
|
||||
void DeferBodyAction(RigidBody2D& rigidBody, PostStep&& func);
|
||||
void InitCallbacks(cpCollisionHandler* handler, ContactCallbacks callbacks);
|
||||
inline UInt32 RegisterBody(RigidBody2D& rigidBody);
|
||||
inline void UnregisterBody(UInt32 bodyIndex);
|
||||
inline void UpdateBodyPointer(RigidBody2D& rigidBody);
|
||||
|
||||
std::size_t m_maxStepCount;
|
||||
std::unordered_map<cpCollisionHandler*, std::unique_ptr<ContactCallbacks>> m_callbacks;
|
||||
std::unordered_map<UInt32, std::vector<PostStep>> m_rigidBodyPostSteps;
|
||||
std::vector<RigidBody2D*> m_bodies;
|
||||
cpSpace* m_handle;
|
||||
Bitset<UInt64> m_freeBodyIndices;
|
||||
Time m_stepSize;
|
||||
Time m_timestepAccumulator;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/PhysWorld2D.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_PHYSWORLD2D_HPP
|
||||
47
include/Nazara/Physics2D/PhysWorld2D.inl
Normal file
47
include/Nazara/Physics2D/PhysWorld2D.inl
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <cassert>
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline UInt32 PhysWorld2D::RegisterBody(RigidBody2D& rigidBody)
|
||||
{
|
||||
std::size_t bodyIndex = m_freeBodyIndices.FindFirst();
|
||||
if (bodyIndex == m_freeBodyIndices.npos)
|
||||
{
|
||||
bodyIndex = m_freeBodyIndices.GetSize();
|
||||
m_freeBodyIndices.Resize(bodyIndex + FreeBodyIdGrowRate, true);
|
||||
m_bodies.resize(m_freeBodyIndices.GetSize());
|
||||
}
|
||||
|
||||
assert(m_freeBodyIndices.Test(bodyIndex));
|
||||
m_freeBodyIndices.Set(bodyIndex, false);
|
||||
|
||||
assert(!m_bodies[bodyIndex]);
|
||||
m_bodies[bodyIndex] = &rigidBody;
|
||||
|
||||
return SafeCast<UInt32>(bodyIndex);
|
||||
}
|
||||
|
||||
inline void PhysWorld2D::UnregisterBody(UInt32 bodyIndex)
|
||||
{
|
||||
assert(!m_freeBodyIndices.Test(bodyIndex));
|
||||
m_freeBodyIndices.Set(bodyIndex, true);
|
||||
assert(m_bodies[bodyIndex]);
|
||||
m_bodies[bodyIndex] = nullptr;
|
||||
|
||||
m_rigidBodyPostSteps.erase(bodyIndex);
|
||||
}
|
||||
|
||||
inline void PhysWorld2D::UpdateBodyPointer(RigidBody2D& rigidBody)
|
||||
{
|
||||
UInt32 bodyIndex = rigidBody.GetBodyIndex();
|
||||
assert(m_bodies[bodyIndex]);
|
||||
m_bodies[bodyIndex] = &rigidBody;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
33
include/Nazara/Physics2D/Physics2D.hpp
Normal file
33
include/Nazara/Physics2D/Physics2D.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_HPP
|
||||
#define NAZARA_PHYSICS2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Core.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_PHYSICS2D_API Physics2D : public ModuleBase<Physics2D>
|
||||
{
|
||||
friend ModuleBase;
|
||||
|
||||
public:
|
||||
using Dependencies = TypeList<Core>;
|
||||
|
||||
struct Config {};
|
||||
|
||||
Physics2D(Config /*config*/);
|
||||
~Physics2D() = default;
|
||||
|
||||
private:
|
||||
static Physics2D* s_instance;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_HPP
|
||||
180
include/Nazara/Physics2D/RigidBody2D.hpp
Normal file
180
include/Nazara/Physics2D/RigidBody2D.hpp
Normal file
@@ -0,0 +1,180 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_RIGIDBODY2D_HPP
|
||||
#define NAZARA_PHYSICS2D_RIGIDBODY2D_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Enums.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/Rect.hpp>
|
||||
#include <Nazara/Physics2D/Collider2D.hpp>
|
||||
#include <Nazara/Physics2D/Config.hpp>
|
||||
#include <NazaraUtils/Signal.hpp>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
struct cpBody;
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class PhysArbiter2D;
|
||||
class PhysWorld2D;
|
||||
|
||||
class NAZARA_PHYSICS2D_API RigidBody2D
|
||||
{
|
||||
public:
|
||||
struct DynamicSettings;
|
||||
struct StaticSettings;
|
||||
|
||||
using VelocityFunc = std::function<void(RigidBody2D& body2D, const Vector2f& gravity, float damping, float deltaTime)>;
|
||||
|
||||
inline RigidBody2D(PhysWorld2D& world, const DynamicSettings& settings);
|
||||
inline RigidBody2D(PhysWorld2D& world, const StaticSettings& settings);
|
||||
RigidBody2D(const RigidBody2D& object);
|
||||
RigidBody2D(RigidBody2D&& object) noexcept;
|
||||
inline ~RigidBody2D();
|
||||
|
||||
inline void AddForce(const Vector2f& force, CoordSys coordSys = CoordSys::Global);
|
||||
void AddForce(const Vector2f& force, const Vector2f& point, 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);
|
||||
|
||||
bool ClosestPointQuery(const Vector2f& position, Vector2f* closestPoint = nullptr, float* closestDistance = nullptr) const;
|
||||
|
||||
void EnableSimulation(bool simulation);
|
||||
|
||||
void ForEachArbiter(const FunctionRef<void(PhysArbiter2D& /*arbiter*/)>& callback);
|
||||
void ForceSleep();
|
||||
|
||||
Rectf GetAABB() const;
|
||||
RadianAnglef GetAngularVelocity() const;
|
||||
inline UInt32 GetBodyIndex() const;
|
||||
float GetElasticity(std::size_t shapeIndex = 0) const;
|
||||
float GetFriction(std::size_t shapeIndex = 0) const;
|
||||
inline const std::shared_ptr<Collider2D>& 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;
|
||||
inline std::size_t GetShapeIndex(cpShape* shape) const;
|
||||
Vector2f GetSurfaceVelocity(std::size_t shapeIndex = 0) const;
|
||||
Vector2f GetVelocity() const;
|
||||
inline const VelocityFunc& GetVelocityFunction() const;
|
||||
inline PhysWorld2D* GetWorld() const;
|
||||
|
||||
inline bool IsKinematic() const;
|
||||
inline bool IsSimulationEnabled() const;
|
||||
bool IsSleeping() const;
|
||||
inline bool IsStatic() const;
|
||||
|
||||
void ResetVelocityFunction();
|
||||
|
||||
void SetAngularVelocity(const RadianAnglef& angularVelocity);
|
||||
void SetElasticity(float elasticity);
|
||||
void SetElasticity(std::size_t shapeIndex, float elasticity);
|
||||
void SetFriction(float friction);
|
||||
void SetFriction(std::size_t shapeIndex, float friction);
|
||||
void SetGeom(std::shared_ptr<Collider2D> geom, bool recomputeMoment = true, bool recomputeMassCenter = true);
|
||||
void SetMass(float mass, bool recomputeMoment = true);
|
||||
void SetMassCenter(const Vector2f& center, CoordSys coordSys = CoordSys::Local);
|
||||
void SetMomentOfInertia(float moment);
|
||||
void SetPosition(const Vector2f& position);
|
||||
void SetPositionOffset(const Vector2f& offset);
|
||||
void SetRotation(const RadianAnglef& rotation);
|
||||
void SetSurfaceVelocity(const Vector2f& surfaceVelocity);
|
||||
void SetSurfaceVelocity(std::size_t shapeIndex, const Vector2f& surfaceVelocity);
|
||||
void SetStatic(bool setStaticBody = true);
|
||||
void SetVelocity(const Vector2f& velocity);
|
||||
void SetVelocityFunction(VelocityFunc velocityFunc);
|
||||
|
||||
void TeleportTo(const Vector2f& position, const RadianAnglef& rotation);
|
||||
|
||||
RadianAnglef ToLocal(const RadianAnglef& worldRotation);
|
||||
Vector2f ToLocal(const Vector2f& worldPosition);
|
||||
RadianAnglef ToWorld(const RadianAnglef& localRotation);
|
||||
Vector2f ToWorld(const Vector2f& localPosition);
|
||||
|
||||
void UpdateVelocity(const Vector2f& gravity, float damping, float deltaTime);
|
||||
|
||||
void Wakeup();
|
||||
|
||||
RigidBody2D& operator=(const RigidBody2D& object);
|
||||
RigidBody2D& operator=(RigidBody2D&& object) noexcept;
|
||||
|
||||
static constexpr UInt32 InvalidBodyIndex = std::numeric_limits<UInt32>::max();
|
||||
static constexpr std::size_t InvalidShapeIndex = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct CommonSettings
|
||||
{
|
||||
std::shared_ptr<Collider2D> geom;
|
||||
RadianAnglef rotation = RadianAnglef::Zero();
|
||||
Vector2f position = Vector2f::Zero();
|
||||
bool initiallySleeping = false;
|
||||
bool isSimulationEnabled = true;
|
||||
};
|
||||
|
||||
struct DynamicSettings : CommonSettings
|
||||
{
|
||||
DynamicSettings() = default;
|
||||
DynamicSettings(std::shared_ptr<Collider2D> 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<Collider2D> collider)
|
||||
{
|
||||
geom = std::move(collider);
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
RigidBody2D() = default;
|
||||
void Create(PhysWorld2D& world, const DynamicSettings& settings);
|
||||
void Create(PhysWorld2D& world, const StaticSettings& settings);
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
void DestroyBody();
|
||||
void RegisterToSpace();
|
||||
void UnregisterFromSpace();
|
||||
|
||||
static void CopyBodyData(cpBody* from, cpBody* to);
|
||||
static void CopyShapeData(cpShape* from, cpShape* to);
|
||||
|
||||
std::vector<cpShape*> m_shapes;
|
||||
std::shared_ptr<Collider2D> m_geom;
|
||||
MovablePtr<cpBody> m_handle;
|
||||
MovablePtr<PhysWorld2D> m_world;
|
||||
UInt32 m_bodyIndex;
|
||||
Vector2f m_positionOffset;
|
||||
VelocityFunc m_velocityFunc;
|
||||
bool m_isRegistered;
|
||||
bool m_isSimulationEnabled;
|
||||
bool m_isStatic;
|
||||
float m_gravityFactor;
|
||||
float m_mass;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/RigidBody2D.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_RIGIDBODY2D_HPP
|
||||
99
include/Nazara/Physics2D/RigidBody2D.inl
Normal file
99
include/Nazara/Physics2D/RigidBody2D.inl
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline RigidBody2D::RigidBody2D(PhysWorld2D& world, const DynamicSettings& settings)
|
||||
{
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline RigidBody2D::RigidBody2D(PhysWorld2D& world, const StaticSettings& settings)
|
||||
{
|
||||
Create(world, settings);
|
||||
}
|
||||
|
||||
inline RigidBody2D::~RigidBody2D()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
inline void RigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
|
||||
{
|
||||
return AddForce(force, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline void RigidBody2D::AddImpulse(const Vector2f& impulse, CoordSys coordSys)
|
||||
{
|
||||
return AddImpulse(impulse, GetMassCenter(coordSys), coordSys);
|
||||
}
|
||||
|
||||
inline UInt32 RigidBody2D::GetBodyIndex() const
|
||||
{
|
||||
return m_bodyIndex;
|
||||
}
|
||||
|
||||
inline const std::shared_ptr<Collider2D>& RigidBody2D::GetGeom() const
|
||||
{
|
||||
return m_geom;
|
||||
}
|
||||
|
||||
inline cpBody* RigidBody2D::GetHandle() const
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
inline float RigidBody2D::GetMass() const
|
||||
{
|
||||
return m_mass;
|
||||
}
|
||||
|
||||
inline const Vector2f& RigidBody2D::GetPositionOffset() const
|
||||
{
|
||||
return m_positionOffset;
|
||||
}
|
||||
|
||||
inline std::size_t RigidBody2D::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 RigidBody2D::GetShapeCount() const
|
||||
{
|
||||
return m_shapes.size();
|
||||
}
|
||||
|
||||
inline const RigidBody2D::VelocityFunc& RigidBody2D::GetVelocityFunction() const
|
||||
{
|
||||
return m_velocityFunc;
|
||||
}
|
||||
|
||||
inline PhysWorld2D* RigidBody2D::GetWorld() const
|
||||
{
|
||||
return m_world;
|
||||
}
|
||||
|
||||
inline bool RigidBody2D::IsKinematic() const
|
||||
{
|
||||
return m_mass <= 0.f;
|
||||
}
|
||||
|
||||
inline bool RigidBody2D::IsSimulationEnabled() const
|
||||
{
|
||||
return m_isSimulationEnabled;
|
||||
}
|
||||
|
||||
inline bool RigidBody2D::IsStatic() const
|
||||
{
|
||||
return m_isStatic;
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
34
include/Nazara/Physics2D/Systems.hpp
Normal file
34
include/Nazara/Physics2D/Systems.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
// this file was automatically generated and should not be edited
|
||||
|
||||
/*
|
||||
Nazara Engine - Physics2D module
|
||||
|
||||
Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||
#define NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||
|
||||
#include <Nazara/Physics2D/Systems/Physics2DSystem.hpp>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_SYSTEMS_HPP
|
||||
96
include/Nazara/Physics2D/Systems/Physics2DSystem.hpp
Normal file
96
include/Nazara/Physics2D/Systems/Physics2DSystem.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||
#define NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||
|
||||
#include <NazaraUtils/Prerequisites.hpp>
|
||||
#include <Nazara/Core/Time.hpp>
|
||||
#include <Nazara/Physics2D/PhysWorld2D.hpp>
|
||||
#include <Nazara/Physics2D/Components/RigidBody2DComponent.hpp>
|
||||
#include <NazaraUtils/TypeList.hpp>
|
||||
#include <entt/entt.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
class NAZARA_PHYSICS2D_API Physics2DSystem
|
||||
{
|
||||
using ContactEndCallback = std::function<void(PhysWorld2D& world, PhysArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
|
||||
using ContactPostSolveCallback = std::function<void(PhysWorld2D& world, PhysArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
|
||||
using ContactPreSolveCallback = std::function<bool(PhysWorld2D& world, PhysArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
|
||||
using ContactStartCallback = std::function<bool(PhysWorld2D& world, PhysArbiter2D& arbiter, entt::handle entityA, entt::handle entityB, void* userdata)>;
|
||||
|
||||
public:
|
||||
static constexpr Int64 ExecutionOrder = 0;
|
||||
using Components = TypeList<RigidBody2DComponent, class NodeComponent>;
|
||||
|
||||
struct ContactCallbacks;
|
||||
struct NearestQueryResult;
|
||||
struct RaycastHit;
|
||||
|
||||
Physics2DSystem(entt::registry& registry);
|
||||
Physics2DSystem(const Physics2DSystem&) = delete;
|
||||
Physics2DSystem(Physics2DSystem&&) = delete;
|
||||
~Physics2DSystem();
|
||||
|
||||
inline PhysWorld2D& GetPhysWorld();
|
||||
inline const PhysWorld2D& GetPhysWorld() const;
|
||||
inline entt::handle GetRigidBodyEntity(UInt32 bodyIndex) const;
|
||||
|
||||
inline bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, entt::handle* nearestEntity = nullptr);
|
||||
inline bool NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, NearestQueryResult* result);
|
||||
|
||||
inline void RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(const RaycastHit&)>& callback);
|
||||
inline bool RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RaycastHit>* hitInfos);
|
||||
inline bool RaycastQueryFirst(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RaycastHit* hitInfo = nullptr);
|
||||
|
||||
inline void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(entt::handle)>& callback);
|
||||
inline void RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<entt::handle>* bodies);
|
||||
|
||||
inline void RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks);
|
||||
inline void RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks);
|
||||
|
||||
void Update(Time elapsedTime);
|
||||
|
||||
Physics2DSystem& operator=(const Physics2DSystem&) = delete;
|
||||
Physics2DSystem& operator=(Physics2DSystem&&) = delete;
|
||||
|
||||
struct ContactCallbacks
|
||||
{
|
||||
ContactEndCallback endCallback = nullptr;
|
||||
ContactPostSolveCallback postSolveCallback = nullptr;
|
||||
ContactPreSolveCallback preSolveCallback = nullptr;
|
||||
ContactStartCallback startCallback = nullptr;
|
||||
void* userdata = nullptr;
|
||||
};
|
||||
|
||||
struct NearestQueryResult : PhysWorld2D::NearestQueryResult
|
||||
{
|
||||
entt::handle nearestEntity;
|
||||
};
|
||||
|
||||
struct RaycastHit : PhysWorld2D::RaycastHit
|
||||
{
|
||||
entt::handle nearestEntity;
|
||||
};
|
||||
|
||||
private:
|
||||
void OnBodyConstruct(entt::registry& registry, entt::entity entity);
|
||||
void OnBodyDestruct(entt::registry& registry, entt::entity entity);
|
||||
PhysWorld2D::ContactCallbacks SetupContactCallbacks(ContactCallbacks callbacks);
|
||||
|
||||
std::vector<entt::entity> m_bodyIndicesToEntity;
|
||||
entt::registry& m_registry;
|
||||
entt::observer m_physicsConstructObserver;
|
||||
entt::scoped_connection m_bodyConstructConnection;
|
||||
entt::scoped_connection m_bodyDestructConnection;
|
||||
PhysWorld2D m_physWorld;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/Systems/Physics2DSystem.inl>
|
||||
|
||||
#endif // NAZARA_PHYSICS2D_SYSTEMS_PHYSICS2DSYSTEM_HPP
|
||||
130
include/Nazara/Physics2D/Systems/Physics2DSystem.inl
Normal file
130
include/Nazara/Physics2D/Systems/Physics2DSystem.inl
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright (C) 2024 Jérôme "SirLynix" Leclercq (lynix680@gmail.com)
|
||||
// This file is part of the "Nazara Engine - Physics2D module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Physics2D/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
inline PhysWorld2D& Physics2DSystem::GetPhysWorld()
|
||||
{
|
||||
return m_physWorld;
|
||||
}
|
||||
|
||||
inline const PhysWorld2D& Physics2DSystem::GetPhysWorld() const
|
||||
{
|
||||
return m_physWorld;
|
||||
}
|
||||
|
||||
inline entt::handle Physics2DSystem::GetRigidBodyEntity(UInt32 bodyIndex) const
|
||||
{
|
||||
return entt::handle(m_registry, m_bodyIndicesToEntity[bodyIndex]);
|
||||
}
|
||||
|
||||
inline bool Physics2DSystem::NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, entt::handle* nearestEntity)
|
||||
{
|
||||
RigidBody2D* nearestBody;
|
||||
if (!m_physWorld.NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, &nearestBody))
|
||||
return false;
|
||||
|
||||
if (nearestEntity)
|
||||
{
|
||||
if (nearestBody)
|
||||
*nearestEntity = GetRigidBodyEntity(nearestBody->GetBodyIndex());
|
||||
else
|
||||
*nearestEntity = {};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool Physics2DSystem::NearestBodyQuery(const Vector2f& from, float maxDistance, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, NearestQueryResult* result)
|
||||
{
|
||||
if (!m_physWorld.NearestBodyQuery(from, maxDistance, collisionGroup, categoryMask, collisionMask, result))
|
||||
return false;
|
||||
|
||||
if (result)
|
||||
{
|
||||
if (result->nearestBody)
|
||||
result->nearestEntity = GetRigidBodyEntity(result->nearestBody->GetBodyIndex());
|
||||
else
|
||||
result->nearestEntity = {};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Physics2DSystem::RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(const RaycastHit&)>& callback)
|
||||
{
|
||||
return m_physWorld.RaycastQuery(from, to, radius, collisionGroup, categoryMask, collisionMask, [&](const PhysWorld2D::RaycastHit& hitInfo)
|
||||
{
|
||||
RaycastHit extendedHitInfo;
|
||||
static_cast<PhysWorld2D::RaycastHit&>(extendedHitInfo) = hitInfo;
|
||||
|
||||
if (extendedHitInfo.nearestBody)
|
||||
extendedHitInfo.nearestEntity = GetRigidBodyEntity(extendedHitInfo.nearestBody->GetBodyIndex());
|
||||
|
||||
callback(extendedHitInfo);
|
||||
});
|
||||
}
|
||||
|
||||
inline bool Physics2DSystem::RaycastQuery(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<RaycastHit>* hitInfos)
|
||||
{
|
||||
NazaraAssert(hitInfos, "invalid output pointer");
|
||||
|
||||
std::size_t originalSize = hitInfos->size();
|
||||
|
||||
RaycastQuery(from, to, radius, collisionGroup, categoryMask, collisionMask, [&](const RaycastHit& hitInfo)
|
||||
{
|
||||
hitInfos->emplace_back(hitInfo);
|
||||
});
|
||||
|
||||
return hitInfos->size() != originalSize;
|
||||
}
|
||||
|
||||
inline bool Physics2DSystem::RaycastQueryFirst(const Vector2f& from, const Vector2f& to, float radius, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, RaycastHit* hitInfo)
|
||||
{
|
||||
if (!m_physWorld.RaycastQueryFirst(from, to, radius, collisionGroup, categoryMask, collisionMask, hitInfo))
|
||||
return false;
|
||||
|
||||
if (hitInfo)
|
||||
{
|
||||
if (hitInfo->nearestBody)
|
||||
hitInfo->nearestEntity = GetRigidBodyEntity(hitInfo->nearestBody->GetBodyIndex());
|
||||
else
|
||||
hitInfo->nearestEntity = {};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Physics2DSystem::RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, const FunctionRef<void(entt::handle)>& callback)
|
||||
{
|
||||
return m_physWorld.RegionQuery(boundingBox, collisionGroup, categoryMask, collisionMask, [&](RigidBody2D* body)
|
||||
{
|
||||
callback(GetRigidBodyEntity(body->GetBodyIndex()));
|
||||
});
|
||||
}
|
||||
|
||||
inline void Physics2DSystem::RegionQuery(const Rectf& boundingBox, UInt32 collisionGroup, UInt32 categoryMask, UInt32 collisionMask, std::vector<entt::handle>* bodies)
|
||||
{
|
||||
NazaraAssert(bodies, "invalid output pointer");
|
||||
|
||||
return m_physWorld.RegionQuery(boundingBox, collisionGroup, categoryMask, collisionMask, [&](RigidBody2D* body)
|
||||
{
|
||||
bodies->emplace_back(GetRigidBodyEntity(body->GetBodyIndex()));
|
||||
});
|
||||
}
|
||||
|
||||
inline void Physics2DSystem::RegisterCallbacks(unsigned int collisionId, ContactCallbacks callbacks)
|
||||
{
|
||||
return m_physWorld.RegisterCallbacks(collisionId, SetupContactCallbacks(std::move(callbacks)));
|
||||
}
|
||||
|
||||
inline void Physics2DSystem::RegisterCallbacks(unsigned int collisionIdA, unsigned int collisionIdB, ContactCallbacks callbacks)
|
||||
{
|
||||
return m_physWorld.RegisterCallbacks(collisionIdA, collisionIdB, SetupContactCallbacks(std::move(callbacks)));
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Physics2D/DebugOff.hpp>
|
||||
Reference in New Issue
Block a user