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

Improved determinism, fixed box vs box algorithm, removed contact id, caching...

Improved determinism, fixed box vs box algorithm, removed contact id, caching is now done by identifying close world position
parent e7cfeb25
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -46,9 +46,11 @@ struct CollisionInfo
		return m_contacts;
	}

	inline void add_contact(Contact const &contact)
	inline void add_contact(vec3 const &point_on_a_ws, vec3 const &point_on_b_ws, vec3 const &point_on_a_ls, vec3 const &point_on_b_ls, vec3 const &normal_on_a_ws, scalar signed_distance)
	{
		m_contacts.push_back(contact);
		Contact contact(point_on_a_ws, point_on_b_ws, point_on_a_ls, point_on_b_ls, normal_on_a_ws, signed_distance);
		contact.set_colliders(m_collider_a, m_collider_b);
		m_contacts.emplace_back(contact);
	}

	inline void set_features(std::pair<geometry::Feature *, geometry::Feature *> const &features)
+6 −5
Original line number Diff line number Diff line
@@ -13,8 +13,9 @@
namespace phx::dyn
{
	struct ContactManifold;
	typedef utils::unordered_pair<com::Folder *> bodies_pair_t;
	typedef std::unordered_map<bodies_pair_t, ContactManifold> bodies_contact_manifold_t;
	typedef std::pair<std::size_t, std::size_t> bodies_pair_t;
	typedef std::vector<ContactManifold> contact_manifolds_t;
	typedef std::unordered_map<bodies_pair_t, std::size_t> bodies_pair_to_manifold_t;
}

namespace phx::coll
@@ -51,11 +52,11 @@ struct CollisionSystem final : com::System
	    com::Folder *world, bool clear_cache = false,
	    BroadDetector::Algorithm broad_detector = BroadDetector::Algorithm::AABB_TREE,
	    NarrowDetector::Algorithm narrow_detector = NarrowDetector::Algorithm::GJK, 
	    dyn::bodies_contact_manifold_t *manifolds = nullptr);
	    dyn::bodies_pair_to_manifold_t *bodies_pair_to_manifold = nullptr, dyn::contact_manifolds_t *manifolds = nullptr);

	bool detect_collisions(com::Folder *world, dyn::bodies_contact_manifold_t *manifolds)
	bool detect_collisions(com::Folder *world, dyn::bodies_pair_to_manifold_t *bodies_pair_to_manifold, dyn::contact_manifolds_t *manifolds)
	{
		return detect_collisions(world, false, BroadDetector::Algorithm::BRUTE, NarrowDetector::Algorithm::GJK, manifolds);
		return detect_collisions(world, false, BroadDetector::Algorithm::BRUTE, NarrowDetector::Algorithm::GJK, bodies_pair_to_manifold, manifolds);
	}

	PotentialCollisions broadphase_collisions(com::Folder *world) const;
+16 −25
Original line number Diff line number Diff line
@@ -15,16 +15,22 @@ struct Contact
	bool m_is_new_contact = true;
	Contact() {}

	Contact(ContactID const &id, vec3 const &point_on_a_ws, vec3 const &point_on_b_ws,
	Contact(vec3 const &point_on_a_ws, vec3 const &point_on_b_ws,
		vec3 const &point_on_a_ls, vec3 const &point_on_b_ls, vec3 const &normal_on_a_ws,
		scalar signed_distance) 
	    : m_id(id), m_point_on_a_ws(point_on_a_ws), m_point_on_b_ws(point_on_b_ws),
	    : m_point_on_a_ws(point_on_a_ws), m_point_on_b_ws(point_on_b_ws),
	      m_point_on_a_ls(point_on_a_ls), m_point_on_b_ls(point_on_b_ls),
	      m_normal_on_a_ws(normal_on_a_ws), m_signed_distance(signed_distance)
	{
	
	}

	inline void set_colliders(const Collider *collider_a, const Collider *collider_b)
	{
		m_collider_a = collider_a;
		m_collider_b = collider_b;
	}

	inline void set_point_on_a_ws(vec3 const &point_on_a)
	{
		m_point_on_a_ws = point_on_a;
@@ -35,11 +41,6 @@ struct Contact
		m_point_on_b_ws = point_on_b;
	}

	inline ContactID const &id() const
	{
		return m_id;
	}

	inline vec3 const &point_on_a_ws() const
	{
		return m_point_on_a_ws;
@@ -77,12 +78,12 @@ struct Contact
	
	inline Collider const *collider_a() const
	{
		return m_id.collider_a();
		return m_collider_a;
	}

	inline Collider const *collider_b() const
	{
		return m_id.collider_b();
		return m_collider_b;
	}

	inline void set_constraint_ids(constraint_id_t id, constraint_id_t f0, constraint_id_t f1)
@@ -115,7 +116,7 @@ struct Contact
		bool eq = collider_a() == other.collider_a() && collider_b() == other.collider_b();		
		if (!eq) { return false;}
		
		eq = equal(len2(point_on_a_ws() - other.point_on_a_ws()), 0.0f, 0.25f) && equal(len2(point_on_b_ws() - other.point_on_b_ws()), 0.0f, 0.25f);
		eq = equal(len2(point_on_a_ws() - other.point_on_a_ws()), 0.0f, 0.025f) && equal(len2(point_on_b_ws() - other.point_on_b_ws()), 0.0f, 0.025f);
		return eq;
	}

@@ -126,7 +127,7 @@ struct Contact

	friend std::ostream &operator<<(std::ostream &os, const Contact &contact)
	{
		os << "- ID: " << std::endl << contact.id() << std::endl;
		// os << "- ID: " << std::endl << contact.id() << std::endl;
		os << "- point_on_a_ws: " << contact.point_on_a_ws() << std::endl;
		os << "- point_on_b_ws: " << contact.point_on_b_ws() << std::endl;
		os << "- point_on_a_ls: " << contact.point_on_a_ls() << std::endl;
@@ -144,13 +145,14 @@ struct Contact
      private:
	inline void swap()
	{
		m_id.swap();
		std::swap(m_collider_a, m_collider_b);
		std::swap(m_point_on_a_ls, m_point_on_b_ls);
		std::swap(m_point_on_a_ws, m_point_on_b_ws);
		m_normal_on_a_ws = -m_normal_on_a_ws;
	}

	ContactID m_id;
	Collider const *m_collider_a = nullptr;
	Collider const *m_collider_b = nullptr;
	vec3 m_point_on_a_ws;
	vec3 m_point_on_b_ws;
	vec3 m_point_on_a_ls;
@@ -165,16 +167,5 @@ struct Contact
};
} // namespace phx::coll

namespace std
{
// Hash of ContactID
template <> struct hash<phx::coll::Contact>
{
	std::size_t operator()(const phx::coll::Contact &contact) const noexcept
	{
		return std::hash<phx::coll::ContactID>()(contact.id());
	}
};
} // namespace std

#endif
 No newline at end of file
+126 −126
Original line number Diff line number Diff line
@@ -5,131 +5,131 @@
#include <math/geometry.hpp>
#include <phx/coll/collider.hpp>

namespace phx::coll
{
struct ContactID
{
	friend struct Contact;
	ContactID()
	    : ContactID(nullptr, nullptr, geometry::FeatureType::None, geometry::FeatureType::None,
			0, 0)
	{
	}

	ContactID(Collider const *collider_a, Collider const *collider_b,
		  geometry::FeatureType feature_type_a, geometry::FeatureType feature_type_b,
		  size_t feature_id_a, size_t feature_id_b)
	    : m_collider_a(collider_a), m_collider_b(collider_b), m_feature_type_a(feature_type_a),
	      m_feature_type_b(feature_type_b), m_feature_id_a(feature_id_a),
	      m_feature_id_b(feature_id_b)

	{
	}

	bool is_valid() const
	{
		return m_collider_a != nullptr && m_collider_b != nullptr &&
		       m_feature_type_a != geometry::FeatureType::None &&
		       m_feature_type_b != geometry::FeatureType::None;
	}

	// Operators
	bool operator==(const ContactID &other) const
	{
		return m_collider_a == other.m_collider_a && m_collider_b == other.m_collider_b &&
		       m_feature_type_a == other.m_feature_type_a &&
		       m_feature_type_b == other.m_feature_type_b &&
		       m_feature_id_a == other.m_feature_id_a &&
		       m_feature_id_b == other.m_feature_id_b;
	}

	bool operator!=(const ContactID &other) const
	{
		return !(*this == other);
	}

	Collider const *collider_a() const
	{
		return m_collider_a;
	}

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

	geometry::FeatureType feature_type_a() const
	{
		return m_feature_type_a;
	}

	geometry::FeatureType feature_type_b() const
	{
		return m_feature_type_b;
	}

	size_t feature_id_a() const
	{
		return m_feature_id_a;
	}

	size_t feature_id_b() const
	{
		return m_feature_id_b;
	}

	friend std::ostream &operator<<(std::ostream &os, const ContactID &id)
	{
		os << "- feature_type_a: " << id.feature_type_a() << std::endl;
		os << "- feature_type_b: " << id.feature_type_b() << std::endl;
		os << "- feature_id_a: " << id.feature_id_a() << std::endl;
		os << "- feature_id_b: " << id.feature_id_b() << std::endl;
		os << "- collider_a: " << (uintptr_t)id.collider_a() << std::endl;
		os << "- collider_b: " << (uintptr_t)id.collider_b() << std::endl;
		return os;
	}

      private:
	void swap()
	{
		std::swap(m_collider_a, m_collider_b);
		std::swap(m_feature_type_a, m_feature_type_b);
		std::swap(m_feature_id_a, m_feature_id_b);
	}

	Collider const *m_collider_a;
	Collider const *m_collider_b;

	geometry::FeatureType m_feature_type_a;
	geometry::FeatureType m_feature_type_b;
	size_t m_feature_id_a;
	size_t m_feature_id_b;
};
} // namespace phx

namespace std
{
// Hash of ContactID
template <> struct hash<phx::coll::ContactID>
{
	std::size_t operator()(const phx::coll::ContactID &id) const noexcept
	{
		using boost::hash_combine;
		using boost::hash_value;

		std::size_t seed = 0;

		hash_combine(seed, hash_value(id.feature_id_a()));
		hash_combine(seed, hash_value(id.feature_id_b()));
		hash_combine(seed, hash_value(id.feature_type_a()));
		hash_combine(seed, hash_value(id.feature_type_b()));
		hash_combine(seed, hash_value(id.collider_a()));
		hash_combine(seed, hash_value(id.collider_b()));

		// Return the result.
		return seed;
	}
};
} // namespace std
// namespace phx::coll
// {
// struct ContactID
// {
// 	friend struct Contact;
// 	ContactID()
// 	    : ContactID(nullptr, nullptr, geometry::FeatureType::None, geometry::FeatureType::None,
// 			0, 0)
// 	{
// 	}

// 	ContactID(Collider const *collider_a, Collider const *collider_b,
// 		  geometry::FeatureType feature_type_a, geometry::FeatureType feature_type_b,
// 		  size_t feature_id_a, size_t feature_id_b)
// 	    : m_collider_a(collider_a), m_collider_b(collider_b), m_feature_type_a(feature_type_a),
// 	      m_feature_type_b(feature_type_b), m_feature_id_a(feature_id_a),
// 	      m_feature_id_b(feature_id_b)

// 	{
// 	}

// 	bool is_valid() const
// 	{
// 		return m_collider_a != nullptr && m_collider_b != nullptr &&
// 		       m_feature_type_a != geometry::FeatureType::None &&
// 		       m_feature_type_b != geometry::FeatureType::None;
// 	}

// 	// Operators
// 	bool operator==(const ContactID &other) const
// 	{
// 		return m_collider_a == other.m_collider_a && m_collider_b == other.m_collider_b &&
// 		       m_feature_type_a == other.m_feature_type_a &&
// 		       m_feature_type_b == other.m_feature_type_b &&
// 		       m_feature_id_a == other.m_feature_id_a &&
// 		       m_feature_id_b == other.m_feature_id_b;
// 	}

// 	bool operator!=(const ContactID &other) const
// 	{
// 		return !(*this == other);
// 	}

// 	Collider const *collider_a() const
// 	{
// 		return m_collider_a;
// 	}

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

// 	geometry::FeatureType feature_type_a() const
// 	{
// 		return m_feature_type_a;
// 	}

// 	geometry::FeatureType feature_type_b() const
// 	{
// 		return m_feature_type_b;
// 	}

// 	size_t feature_id_a() const
// 	{
// 		return m_feature_id_a;
// 	}

// 	size_t feature_id_b() const
// 	{
// 		return m_feature_id_b;
// 	}

// 	friend std::ostream &operator<<(std::ostream &os, const ContactID &id)
// 	{
// 		os << "- feature_type_a: " << id.feature_type_a() << std::endl;
// 		os << "- feature_type_b: " << id.feature_type_b() << std::endl;
// 		os << "- feature_id_a: " << id.feature_id_a() << std::endl;
// 		os << "- feature_id_b: " << id.feature_id_b() << std::endl;
// 		os << "- collider_a: " << (uintptr_t)id.collider_a() << std::endl;
// 		os << "- collider_b: " << (uintptr_t)id.collider_b() << std::endl;
// 		return os;
// 	}

//       private:
// 	void swap()
// 	{
// 		std::swap(m_collider_a, m_collider_b);
// 		std::swap(m_feature_type_a, m_feature_type_b);
// 		std::swap(m_feature_id_a, m_feature_id_b);
// 	}

// 	Collider const *m_collider_a;
// 	Collider const *m_collider_b;

// 	geometry::FeatureType m_feature_type_a;
// 	geometry::FeatureType m_feature_type_b;
// 	size_t m_feature_id_a;
// 	size_t m_feature_id_b;
// };
// } // namespace phx

// namespace std
// {
// // Hash of ContactID
// template <> struct hash<phx::coll::ContactID>
// {
// 	std::size_t operator()(const phx::coll::ContactID &id) const noexcept
// 	{
// 		using boost::hash_combine;
// 		using boost::hash_value;

// 		std::size_t seed = 0;

// 		hash_combine(seed, hash_value(id.feature_id_a()));
// 		hash_combine(seed, hash_value(id.feature_id_b()));
// 		hash_combine(seed, hash_value(id.feature_type_a()));
// 		hash_combine(seed, hash_value(id.feature_type_b()));
// 		hash_combine(seed, hash_value(id.collider_a()));
// 		hash_combine(seed, hash_value(id.collider_b()));

// 		// Return the result.
// 		return seed;
// 	}
// };
// } // namespace std

#endif // AGE_PHX_COLLISION_ID_HPP_INCLUDED
+0 −5
Original line number Diff line number Diff line
@@ -54,11 +54,6 @@ template <typename CacheType> struct NarrowDetectorCached : NarrowDetector
	// Methods
	inline bool detect(Collider const *collider_a, Collider const *collider_b, CollisionInfo &info) override final
	{
		if (collider_a > collider_b)
		{
			std::swap(collider_a, collider_b);
		}

		reset();
		
		std::optional<CacheType> cache = m_cache.get(collider_a, collider_b);
Loading