Commit c228b757 authored by Libor Moravčík's avatar Libor Moravčík
Browse files

Simplified collision matrix and layer system

parent a92fe901
Loading
Loading
Loading
Loading
+11 −16
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@
#define PHX_BODY_SYSTEM_HPP_INCLUDED

#include <com/system.hpp>
#include <optional>
#include <phx/coll/layer_system.hpp>
#include <phx/dyn/material.hpp>

@@ -127,53 +126,49 @@ struct BodySystem final : com::System
	dyn::RigidBodyPart *get_rigid_body_part(com::Folder *body,
						com::ContextPath const &relativepath = {});
	coll::Collider *get_collider(com::Folder *body);
	coll::Layer *get_layer(com::Folder *body);

	template <typename ColliderType, typename... Args>
		requires std::is_base_of_v<coll::Collider, ColliderType>
	ColliderType *insert_collider(com::Folder *body, coll::LayerIdentifier layer,
				      Args &&...args);
	ColliderType *insert_collider(com::Folder *body, std::size_t const layer = 0, Args &&...args);

	template <typename ColliderType, typename... Args>
		requires std::is_base_of_v<coll::Collider, ColliderType>
	ColliderType *insert_collider(com::Folder *body, Args &&...args);

	coll::Collider *insert_collider(com::Folder *body, coll::Collider *collider,
					std::optional<coll::LayerIdentifier> layer = std::nullopt,
					com::ContextPath const &subfolders = {});
	com::Link *insert_layer(com::Folder *body, coll::LayerIdentifier layer,
					std::size_t const layer = 0,
					com::ContextPath const &subfolders = {});

	coll::BoxCollider *
	insert_box_collider(com::Folder *body, vec3 const &half_extents,
			    std::optional<coll::LayerIdentifier> layer = std::nullopt,
			    std::size_t const layer = 0,
			    com::ContextPath const &subfolders = {});
	coll::SphereCollider *
	insert_sphere_collider(com::Folder *body, scalar radius,
			       std::optional<coll::LayerIdentifier> layer = std::nullopt,
			       std::size_t const layer = 0,
			       com::ContextPath const &subfolders = {});
	coll::CylinderCollider *
	insert_cylinder_collider(com::Folder *body, scalar radius, scalar height,
				 std::optional<coll::LayerIdentifier> layer = std::nullopt,
				 std::size_t const layer = 0,
				 com::ContextPath const &subfolders = {});

	coll::ConeCollider *
	insert_cone_collider(com::Folder *body, scalar radius, scalar height,
			     std::optional<coll::LayerIdentifier> layer = std::nullopt,
			     std::size_t const layer = 0,
			     com::ContextPath const &subfolders = {});
	coll::CapsuleCollider *
	insert_capsule_collider(com::Folder *body, scalar radius, scalar height,
				std::optional<coll::LayerIdentifier> layer = std::nullopt,
				std::size_t const layer = 0,
				com::ContextPath const &subfolders = {});
	coll::ConvexHullCollider *
	insert_convex_hull_collider(com::Folder *body, std::vector<vec3> const &vertices,
				    std::vector<std::array<size_t, 3>> const &faces,
				    std::optional<coll::LayerIdentifier> layer = std::nullopt,
				    std::size_t const layer = 0,
				    com::ContextPath const &subfolders = {});
	coll::ConvexHullCollider *
	insert_convex_hull_collider(com::Folder *body, std::vector<vec3> const &vertices,
				    std::vector<uint32_t> const &indices,
				    std::optional<coll::LayerIdentifier> layer = std::nullopt,
				    std::size_t const layer = 0,
				    com::ContextPath const &subfolders = {});

      private:
@@ -202,11 +197,11 @@ struct BodySystem final : com::System

template <typename ColliderType, typename... Args>
	requires std::is_base_of_v<coll::Collider, ColliderType>
ColliderType *BodySystem::insert_collider(com::Folder *body, coll::LayerIdentifier layer,
ColliderType *BodySystem::insert_collider(com::Folder *body, std::size_t layer,
					  Args &&...args)
{
	auto *collider = body->push_back<ColliderType>(std::forward<Args>(args)...);
	insert_layer(body, layer_system()->get_layer(layer));
	collider->set_collision_layer(layer);
	return collider;
}

+3 −2
Original line number Diff line number Diff line
@@ -19,8 +19,6 @@ struct Sphere;
namespace phx::coll
{

struct Layer;

enum class ColliderType
{
	Sphere,
@@ -50,6 +48,8 @@ struct Collider : com::File, utils::StoredItem
	void on_erase(ContextItem *subject) override;

	com::Folder *body_root() const;
	std::size_t const & collision_layer() const;
	inline void set_collision_layer(std::size_t const layer) { m_layer = layer; }
	Layer *layer() const;

	// Setters
@@ -141,6 +141,7 @@ struct Collider : com::File, utils::StoredItem
	AABB m_aabbfat;
	vec3 m_aabbfatten_margin = zero<vec3>();
	geometry::Shape *m_shape = nullptr;
	std::size_t m_layer = 0; // by default every collider is in collision layer 0
};

using CollidersPair = std::pair<Collider const *, Collider const *>;
+21 −40
Original line number Diff line number Diff line
#ifndef PHX_COLL_COLLISION_MATRIX_HPP_INCLUDED
#define PHX_COLL_COLLISION_MATRIX_HPP_INCLUDED

#include <boost/numeric/ublas/symmetric.hpp>
#include <com/context.hpp>
#include <utils/unordered_pair.hpp>

#include <phx/coll/collision_info.hpp>
#include <phx/coll/layer.hpp>

#include <phx/coll/collider.hpp>
#include <phx/coll/layer_system.hpp>

namespace phx::coll
{
using boost::numeric::ublas::symmetric_matrix;

struct LayerSystem;
struct Layer;

struct CollisionMatrix final : public com::File
{
@@ -23,54 +17,41 @@ struct CollisionMatrix final : public com::File
	{
		return "collision_matrix";
	}
	const size_t DEFAULT_MATRIX_SIZE = 16;
	
	static const std::size_t MATRIX_SIZE = LayerSystem::NUMBER_OF_LAYERS * (LayerSystem::NUMBER_OF_LAYERS + 1 ) / 2;
	
	// Constructors
	explicit CollisionMatrix() : com::File(self_file_name()), m_matrix(DEFAULT_MATRIX_SIZE) {}
	explicit CollisionMatrix() : com::File(self_file_name()) {}
	~CollisionMatrix() override = default;

	// Adding and removing layers
	void add_layer(const LayerIdentifier &layer, bool default_value = true);
	void remove_layer(const LayerIdentifier &layer);

	// Setting
	void set_collision(const LayerIdentifier &layer_a, const LayerIdentifier &layer_b,
			   bool value);
	void set_collision(const LayerIdentifier &layer_a,
			   const std::vector<LayerIdentifier> &layers, bool value);
	void set_all_collisions(const LayerIdentifier &layer_a, bool value);
	void set_collision(std::size_t layer_a, std::size_t layer_b, bool value);
	void set_collision(std::size_t layer, const std::vector<std::size_t> &layers, bool value);
	void set_all_collisions(std::size_t layer, bool value);

	// Enabling
	void enable_collision(const LayerIdentifier &layer_a, const LayerIdentifier &layer_b);
	void enable_collision(const LayerIdentifier &layer_a,
			      const std::vector<LayerIdentifier> &layers);
	void enable_all_collisions(const LayerIdentifier &layer_a);
	void enable_collision(std::size_t layer_a, std::size_t layer_b);
	void enable_collision(std::size_t layer, const std::vector<std::size_t> &layers);
	void enable_all_collisions(std::size_t layer);

	// Disabling
	void disable_collision(const LayerIdentifier &layer_a, const LayerIdentifier &layer_b);
	void disable_collision(const LayerIdentifier &layer_a,
			       const std::vector<LayerIdentifier> &layers);
	void disable_all_collisions(const LayerIdentifier &layer_a);

	// Specific collider inclusion and exclusion
	void override_colliders(CollidersPair const &pair, bool value);
	void remove_override(CollidersPair const &pair);
	void clear_overrides();
	void disable_collision(std::size_t layer_a, std::size_t layer_b);
	void disable_collision(std::size_t layer, const std::vector<std::size_t> &layers);
	void disable_all_collisions(std::size_t layer);

	// Querying
	bool should_collide(const LayerIdentifier &layer_a, const LayerIdentifier &layer_b) const;
	bool should_collide(std::size_t layer_a, std::size_t layer_b) const;
	bool should_collide(CollidersPair const &pair) const;
	void print(std::ostream &out = std::cout, std::size_t n = LayerSystem::NUMBER_OF_LAYERS);

      protected:
	void initialize() override;

      private:
	symmetric_matrix<bool> m_matrix;
	std::unordered_map<CollidersPair, bool> m_overrides;

	void resize_matrix(size_t desired_size);
	void add_row(size_t row, bool default_value);
	void remove_row(size_t row);
        void set_matrix_element(std::size_t i, std::size_t j, bool value);
	bool get_matrix_element(std::size_t i, std::size_t j) const;
	int matrix_index(std::size_t i, std::size_t j) const;
	std::array<bool, MATRIX_SIZE> m_matrix{};
};
} // namespace phx::coll

+1 −1
Original line number Diff line number Diff line
@@ -59,7 +59,7 @@ struct CollisionSystem final : com::System

	bool raycast(com::Folder *world, geometry::Ray const &ray, RayCastResult &result,
		     RayCastAlgorithm algorithm = RayCastAlgorithm::VCLIP,
		     std::optional<std::unordered_set<LayerIdentifier>> layers = std::nullopt);
		     std::unordered_set<std::size_t> layers = {});
		     
	bool raycast(const geometry::Ray &ray, ConvexHullCollider *collider, RayCastResult &result,
		     RayCastAlgorithm algorithm = RayCastAlgorithm::VCLIP) const;

phx/include/phx/coll/layer.hpp

deleted100644 → 0
+0 −46
Original line number Diff line number Diff line
#ifndef PHX_COLL_LAYER_HPP_INCLUDED
#define PHX_COLL_LAYER_HPP_INCLUDED

#include <com/context.hpp>
#include <variant>

namespace phx::coll
{
struct Layer;

using LayerIdentifier = std::variant<size_t, std::string, Layer *>; // id, name, layer pointer

struct Layer final : public com::File
{
	// Constants
	static inline std::string self_file_name()
	{
		return "layer";
	}

	// Constructors
	explicit Layer(const size_t id, std::string const &name) : com::File(name), m_id(id) {}
	~Layer() override = default;

	Layer(const Layer &other) = default;

	// Getters
	size_t id() const
	{
		return m_id;
	}

	// Methods
	bool should_collide(const LayerIdentifier &other);

	File *clone() const override
	{
		return new Layer(*this);
	}

      private:
	size_t m_id;
};
} // namespace phx::collisions

#endif // AGE_PHX_LAYER_HPP_INCLUDED
Loading