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

CollidersPair is now a structure that automatically orders colliders based on their pointer value

parent 393eccb0
Loading
Loading
Loading
Loading
+40 −5
Original line number Diff line number Diff line
@@ -143,7 +143,42 @@ struct Collider : com::File, utils::StoredItem
	std::size_t m_layer = 0; // by default every collider is in collision layer 0
};

using CollidersPair = std::pair<Collider const *, Collider const *>;
struct CollidersPair
{
	CollidersPair(Collider const * a = nullptr, Collider const * b = nullptr) 
		: m_collider_a(a), m_collider_b(b)
	{
		if (m_collider_a > m_collider_b)
		{
			std::swap(m_collider_a, m_collider_b);
		}
	}
	
	Collider const * collider_a() const
	{
		return m_collider_a;
	}

	Collider const * collider_b() const
	{
		return m_collider_b;
	}

	bool contains(Collider const *collider) const
	{
		ASSUMPTION(m_collider_a && m_collider_b);
		return m_collider_a == collider || m_collider_b == collider;
	}

	friend bool operator==(const CollidersPair &left, const CollidersPair &right)
	{
		return left.collider_a() == right.collider_a() && left.collider_b() == right.collider_b();
	}

	private:
		Collider const * m_collider_a;
		Collider const * m_collider_b;
};
using PotentialCollisions = std::vector<CollidersPair>;

// ###########################
@@ -290,18 +325,18 @@ struct LineSegmentCollider final : Collider

} // namespace phx::coll

template <> struct std::hash<std::pair<phx::coll::Collider const *, phx::coll::Collider const *>>
template <> struct std::hash<phx::coll::CollidersPair>
{
	std::size_t
	operator()(const std::pair<phx::coll::Collider const *, phx::coll::Collider const *> &pair) const
	operator()(const phx::coll::CollidersPair &pair) const
	{
		using boost::hash_combine;
		using boost::hash_value;

		std::size_t seed = 0;

		hash_combine(seed, hash_value(pair.first));
		hash_combine(seed, hash_value(pair.second));
		hash_combine(seed, hash_value(pair.collider_a()));
		hash_combine(seed, hash_value(pair.collider_b()));

		// Return the result.
		return seed;
+1 −1
Original line number Diff line number Diff line
@@ -526,7 +526,7 @@ void AABBTree::clear_collisions(com::Folder *world, Collider *collider)
		return;
	}

	collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider](const CollidersPair &pair) { return pair.first == collider || pair.second == collider;} ), collisions.end());
	collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider](const CollidersPair &pair) { return pair.contains(collider); } ), collisions.end());
}

bool AABBTree::update_collisions(com::Folder *world, const std::shared_ptr<AABBNode> &node)
+3 −3
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ void SweepAndPrune::update_collider(com::Folder *world, Collider *collider)
			// Remove any potential collision
			if (!min_endpoint->next[axis]->is_min)
			{
				collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider, min_endpoint, axis](const CollidersPair &pair) { return pair.first == collider && pair.second == min_endpoint->next[axis]->collider;} ), collisions.end());
				collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider, min_endpoint, axis](const CollidersPair &pair) { return pair.collider_a() == collider && pair.collider_b() == min_endpoint->next[axis]->collider;} ), collisions.end());
			}
			swap_endpoints(world, axis, min_endpoint, false);
		}
@@ -174,7 +174,7 @@ void SweepAndPrune::update_collider(com::Folder *world, Collider *collider)
			// Remove any potential collision
			if (max_endpoint->prev[axis]->is_min)
			{
				collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider, max_endpoint, axis](const CollidersPair &pair) { return pair.first == collider && pair.second == max_endpoint->prev[axis]->collider;} ), collisions.end());
				collisions.erase(std::remove_if(collisions.begin(), collisions.end(), [collider, max_endpoint, axis](const CollidersPair &pair) { return pair.collider_a() == collider && pair.collider_b() == max_endpoint->prev[axis]->collider;} ), collisions.end());
			}
			swap_endpoints(world, axis, max_endpoint, true);
		}
@@ -338,7 +338,7 @@ void SweepAndPrune::remove_collider(com::Folder *world, Collider *collider)
	endpoint_map.erase(collider);

	// Remove the collider from the list of collisions
	std::erase_if(collisions, [collider](const CollidersPair &pair) { return pair.first == collider || pair.second == collider; });
	std::erase_if(collisions, [collider](const CollidersPair &pair) { return pair.contains(collider); });
}

bool SweepAndPrune::detect(com::Folder *world, PotentialCollisions &result)
+0 −4
Original line number Diff line number Diff line
@@ -77,8 +77,6 @@ bool CollisionMatrix::should_collide(std::size_t layer_a,

bool CollisionMatrix::should_collide(Collider const * a, Collider const * b) const
{
	if (a > b) { std::swap(a,b); }
	
	if (m_overrides.contains({a,b}))
	{
		return m_overrides.at({a,b});
@@ -89,13 +87,11 @@ bool CollisionMatrix::should_collide(Collider const * a, Collider const * b) con

void CollisionMatrix::override(Collider const *a, Collider const *b, bool value)
{
	if (a > b) { std::swap(a,b); }
	m_overrides[{a,b}] = value;
}

void CollisionMatrix::remove_override(Collider const *a, Collider const *b)
{
	if (a > b) { std::swap(a,b); }
	m_overrides.erase({a, b});
}

+3 −3
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ bool CollisionSystem::detect_collisions(com::Folder *world, bool clear_cache,

	auto filtered =
	    collisions | std::views::filter([](const CollidersPair &pair)
					    { return phx::layer_system()->should_collide(pair.first, pair.second); });
					    { return phx::layer_system()->should_collide(pair.collider_a(), pair.collider_b()); });

	// Clear the collisions file
	auto collisions_file = world->find<CollisionsFile>(CollisionsFile::self_file_name());
@@ -150,8 +150,8 @@ bool CollisionSystem::detect_collisions(com::Folder *world, bool clear_cache,
		for (const auto &collision : filtered)
		{
			collisions_file->add_broad_phase_collision(collision);
			Collider const *collider_a = collision.first;
			Collider const *collider_b = collision.second;
			Collider const *collider_a = collision.collider_a();
			Collider const *collider_b = collision.collider_b();

			if (collider_a->collider_type() > collider_b->collider_type())
			{