// Copyright (C) 2020 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics 2D module" // For conditions of distribution and use, see copyright notice in Config.hpp #pragma once #ifndef NAZARA_COLLIDER2D_HPP #define NAZARA_COLLIDER2D_HPP #include #include #include #include #include #include #include #include #include #include struct cpShape; namespace Nz { class Collider2D; class RigidBody2D; using Collider2DConstRef = ObjectRef; using Collider2DLibrary = ObjectLibrary; using Collider2DRef = ObjectRef; class NAZARA_PHYSICS2D_API Collider2D : public RefCounted { friend Collider2DLibrary; 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 std::function& 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(RigidBody2D* body, std::vector* 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(RigidBody2D* body, std::vector* shapes) const; static Collider2DLibrary::LibraryMap s_library; }; class BoxCollider2D; using BoxCollider2DConstRef = ObjectRef; using BoxCollider2DRef = ObjectRef; 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; template static BoxCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; Rectf m_rect; float m_radius; }; class CircleCollider2D; using CircleCollider2DConstRef = ObjectRef; using CircleCollider2DRef = ObjectRef; 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; template static CircleCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; Vector2f m_offset; float m_radius; }; class CompoundCollider2D; using CompoundCollider2DConstRef = ObjectRef; using CompoundCollider2DRef = ObjectRef; class NAZARA_PHYSICS2D_API CompoundCollider2D : public Collider2D { public: CompoundCollider2D(std::vector geoms); Nz::Vector2f ComputeCenterOfMass() const override; float ComputeMomentOfInertia(float mass) const override; inline bool DoesOverrideCollisionProperties() const; inline const std::vector& GetGeoms() const; ColliderType2D GetType() const override; inline void OverridesCollisionProperties(bool shouldOverride); template static CompoundCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; std::size_t GenerateShapes(RigidBody2D* body, std::vector* shapes) const override; std::vector m_geoms; bool m_doesOverrideCollisionProperties; }; class ConvexCollider2D; using ConvexCollider2DConstRef = ObjectRef; using ConvexCollider2DRef = ObjectRef; class NAZARA_PHYSICS2D_API ConvexCollider2D : public Collider2D { public: ConvexCollider2D(SparsePtr 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& GetVertices() const; template static ConvexCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; std::vector m_vertices; float m_radius; }; class NullCollider2D; using NullCollider2DConstRef = ObjectRef; using NullCollider2DRef = ObjectRef; 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; template static NullCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; }; class SegmentCollider2D; using SegmentCollider2DConstRef = ObjectRef; using SegmentCollider2DRef = ObjectRef; 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; template static SegmentCollider2DRef New(Args&&... args); private: std::size_t CreateShapes(RigidBody2D* body, std::vector* shapes) const override; Vector2f m_first; Vector2f m_firstNeighbor; Vector2f m_second; Vector2f m_secondNeighbor; float m_thickness; }; } #include #endif // NAZARA_COLLIDER2D_HPP