Add epsilon tunable to collision checks. Add line-point collision check logic
This commit is contained in:
parent
478b82582b
commit
fd282607ae
@ -21,12 +21,14 @@
|
||||
|
||||
namespace egn{
|
||||
|
||||
static constexpr float default_collision_epsilon = 1.0e-10f;
|
||||
|
||||
class collidable_visitor;
|
||||
|
||||
class collidable_iface
|
||||
{
|
||||
public:
|
||||
virtual bool check_collision(const collidable_iface& c)const = 0;
|
||||
virtual bool check_collision(const collidable_iface& c, float epsilon)const = 0;
|
||||
virtual void accept_visitor(collidable_visitor& v)const = 0;
|
||||
};
|
||||
|
||||
@ -34,7 +36,7 @@ namespace egn{
|
||||
class collidable : public collidable_iface
|
||||
{
|
||||
public:
|
||||
bool check_collision(const collidable_iface& c)const override final;
|
||||
bool check_collision(const collidable_iface& c, float epsilon = default_collision_epsilon)const override final;
|
||||
private:
|
||||
void accept_visitor(collidable_visitor& v)const override final;
|
||||
};
|
||||
@ -61,9 +63,10 @@ namespace egn{
|
||||
{
|
||||
private:
|
||||
const T& m_l;
|
||||
float m_epsilon;
|
||||
bool m_result = false;
|
||||
public:
|
||||
constexpr explicit collision_visitor(const T& l);
|
||||
constexpr explicit collision_visitor(const T& l, float epsilon);
|
||||
void visit(const aabb& a)override;
|
||||
void visit(const aabs& a)override;
|
||||
void visit(const line& a)override;
|
||||
@ -72,38 +75,37 @@ namespace egn{
|
||||
constexpr bool result()const;
|
||||
};
|
||||
|
||||
|
||||
bool check_collision(const collidable_iface& l, const collidable_iface& r);
|
||||
bool check_collision(const aabb& l, const aabb& r);
|
||||
bool check_collision(const aabb& l, const aabs& r);
|
||||
bool check_collision(const aabb& l, const line& r);
|
||||
bool check_collision(const aabb& l, const plane& r);
|
||||
bool check_collision(const aabb& l, const point& r);
|
||||
bool check_collision(const aabs& l, const aabs& r);
|
||||
bool check_collision(const aabs& l, const aabb& r);
|
||||
bool check_collision(const aabs& l, const line& r);
|
||||
bool check_collision(const aabs& l, const plane& r);
|
||||
bool check_collision(const aabs& l, const point& r);
|
||||
bool check_collision(const line& l, const line& r);
|
||||
bool check_collision(const line& l, const aabb& r);
|
||||
bool check_collision(const line& l, const aabs& r);
|
||||
bool check_collision(const line& l, const plane& r);
|
||||
bool check_collision(const line& l, const point& r);
|
||||
bool check_collision(const plane& l, const plane& r);
|
||||
bool check_collision(const plane& l, const aabb& r);
|
||||
bool check_collision(const plane& l, const aabs& r);
|
||||
bool check_collision(const plane& l, const line& r);
|
||||
bool check_collision(const plane& l, const point& r);
|
||||
bool check_collision(const point& l, const point& r);
|
||||
bool check_collision(const point& l, const aabb& r);
|
||||
bool check_collision(const point& l, const aabs& r);
|
||||
bool check_collision(const point& l, const line& r);
|
||||
bool check_collision(const point& l, const plane& r);
|
||||
bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabb& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabb& l, const aabs& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabb& l, const line& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabb& l, const plane& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabb& l, const point& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabs& l, const aabs& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabs& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabs& l, const line& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabs& l, const plane& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const aabs& l, const point& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const line& l, const line& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const line& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const line& l, const aabs& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const line& l, const plane& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const line& l, const point& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const plane& l, const plane& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const plane& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const plane& l, const aabs& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const plane& l, const line& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const plane& l, const point& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const point& l, const point& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const point& l, const aabb& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const point& l, const aabs& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const point& l, const line& r, float epsilon = default_collision_epsilon);
|
||||
bool check_collision(const point& l, const plane& r, float epsilon = default_collision_epsilon);
|
||||
|
||||
|
||||
template<typename Derived>
|
||||
bool collidable<Derived>::check_collision(const collidable_iface& c)const{
|
||||
collision_visitor<Derived> vis(static_cast<const Derived&>(*this));
|
||||
bool collidable<Derived>::check_collision(const collidable_iface& c, float epsilon)const{
|
||||
collision_visitor<Derived> vis(static_cast<const Derived&>(*this), epsilon);
|
||||
c.accept_visitor(vis);
|
||||
return vis.result();
|
||||
}
|
||||
@ -113,27 +115,28 @@ namespace egn{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr collision_visitor<T>::collision_visitor(const T& l):
|
||||
m_l(l){}
|
||||
constexpr collision_visitor<T>::collision_visitor(const T& l, float epsilon):
|
||||
m_l(l),
|
||||
m_epsilon(epsilon){}
|
||||
template<typename T>
|
||||
void collision_visitor<T>::visit(const aabb& a){
|
||||
m_result = check_collision(m_l, a);
|
||||
m_result = check_collision(m_l, a, m_epsilon);
|
||||
}
|
||||
template<typename T>
|
||||
void collision_visitor<T>::visit(const aabs& a){
|
||||
m_result = check_collision(m_l, a);
|
||||
m_result = check_collision(m_l, a, m_epsilon);
|
||||
}
|
||||
template<typename T>
|
||||
void collision_visitor<T>::visit(const line& a){
|
||||
m_result = check_collision(m_l, a);
|
||||
m_result = check_collision(m_l, a, m_epsilon);
|
||||
}
|
||||
template<typename T>
|
||||
void collision_visitor<T>::visit(const plane& a){
|
||||
m_result = check_collision(m_l, a);
|
||||
m_result = check_collision(m_l, a, m_epsilon);
|
||||
}
|
||||
template<typename T>
|
||||
void collision_visitor<T>::visit(const point& a){
|
||||
m_result = check_collision(m_l, a);
|
||||
m_result = check_collision(m_l, a, m_epsilon);
|
||||
}
|
||||
template<typename T>
|
||||
constexpr bool collision_visitor<T>::result()const{
|
||||
|
||||
@ -243,6 +243,13 @@ namespace math{
|
||||
template<typename T, typename U, size_t C, size_t R>
|
||||
constexpr auto operator-(const matrix<T,R,C>& left);
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
constexpr auto abs(const matrix_base<T,R,C>& left);
|
||||
template<typename T, typename U, typename V, size_t R, size_t C>
|
||||
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
|
||||
template<typename T, typename U, typename V, size_t R, size_t C>
|
||||
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon);
|
||||
|
||||
//Arithmetic assignment operators
|
||||
template<typename T, typename U, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right);
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
#define REXY_MAT_TPP
|
||||
|
||||
#include <cstdlib> //size_t
|
||||
#include <cmath> //sin, cos
|
||||
#include <cmath> //sin, cos, abs
|
||||
#include <type_traits> //decay_t, declval
|
||||
#include "detail/matrix.hpp"
|
||||
#include "quat.hpp"
|
||||
@ -343,7 +343,26 @@ namespace math{
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
template<typename T, size_t R, size_t C>
|
||||
constexpr auto abs(const matrix_base<T,R,C>& left){
|
||||
matrix<T,R,C> res(no_initialize);
|
||||
for(size_t i = 0; i < left.size(); ++i){
|
||||
res.get(i) = std::abs(left.get(i));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
template<typename T, typename U, typename V, size_t R, size_t C>
|
||||
constexpr bool fuzzy_eq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
|
||||
for(size_t i = 0;i < left.size();++i){
|
||||
if(std::abs(left.get(i) - right.get(i)) > epsilon)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template<typename T, typename U, typename V, size_t R, size_t C>
|
||||
constexpr bool fuzzy_neq(const matrix_base<T,R,C>& left, const matrix_base<U,R,C>& right, const V& epsilon){
|
||||
return !fuzzy_eq(left, right, epsilon);
|
||||
}
|
||||
|
||||
template<typename T, typename U, size_t R>
|
||||
constexpr decltype(auto) operator*=(matrix<T,R,R>& left, const matrix<U,R,R>& right){
|
||||
|
||||
@ -21,111 +21,133 @@
|
||||
|
||||
namespace egn{
|
||||
|
||||
bool check_collision(const collidable_iface& l, const collidable_iface& r){
|
||||
return l.check_collision(r);
|
||||
bool check_collision(const collidable_iface& l, const collidable_iface& r, float epsilon){
|
||||
return l.check_collision(r, epsilon);
|
||||
}
|
||||
bool check_collision(const aabb& l, const aabb& r){
|
||||
bool check_collision(const aabb& l, const aabb& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabb& l, const aabs& r){
|
||||
bool check_collision(const aabb& l, const aabs& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabb& l, const line& r){
|
||||
bool check_collision(const aabb& l, const line& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabb& l, const plane& r){
|
||||
bool check_collision(const aabb& l, const plane& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabb& l, const point& r){
|
||||
bool check_collision(const aabb& l, const point& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabs& l, const aabs& r){
|
||||
bool check_collision(const aabs& l, const aabs& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabs& l, const aabb& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const aabs& l, const aabb& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const aabs& l, const line& r){
|
||||
bool check_collision(const aabs& l, const line& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabs& l, const plane& r){
|
||||
bool check_collision(const aabs& l, const plane& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const aabs& l, const point& r){
|
||||
bool check_collision(const aabs& l, const point& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const line& l, const line& r){
|
||||
bool check_collision(const line& l, const line& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const line& l, const aabs& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const line& l, const aabs& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const line& l, const aabb& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const line& l, const aabb& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const line& l, const plane& r){
|
||||
bool check_collision(const line& l, const plane& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const line& l, const point& r){
|
||||
bool check_collision(const line& l, const point& r, float epsilon){
|
||||
math::vec3<float> ab = (l.point2 - l.point1);
|
||||
math::vec3<float> ac = (r - l.point1);
|
||||
|
||||
//check if the point and line are colinear
|
||||
if(math::fuzzy_neq(math::cross(ab, ac), math::vec3<float>(math::zero_initialize), epsilon))
|
||||
return false;
|
||||
|
||||
//check if the point is between the endpoints of the line segment
|
||||
float value = (ab * ac) / (ab * ab);
|
||||
if(value >= (0.0f - epsilon) && value <= (1.0f + epsilon))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const plane& l, const plane& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const plane& l, const plane& r){
|
||||
bool check_collision(const plane& l, const aabb& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const aabs& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const line& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const point& r, float epsilon){
|
||||
(void)l;
|
||||
(void)r;
|
||||
(void)epsilon;
|
||||
return false;
|
||||
}
|
||||
bool check_collision(const plane& l, const aabb& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const point& l, const point& r, float epsilon){
|
||||
return math::fuzzy_eq(l, r, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const aabs& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const point& l, const aabb& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const line& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const point& l, const aabs& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const plane& l, const point& r){
|
||||
(void)l;
|
||||
(void)r;
|
||||
return false;
|
||||
bool check_collision(const point& l, const line& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
bool check_collision(const point& l, const point& r){
|
||||
return (l == r);
|
||||
}
|
||||
bool check_collision(const point& l, const aabb& r){
|
||||
return check_collision(r, l);
|
||||
}
|
||||
bool check_collision(const point& l, const aabs& r){
|
||||
return check_collision(r, l);
|
||||
}
|
||||
bool check_collision(const point& l, const line& r){
|
||||
return check_collision(r, l);
|
||||
}
|
||||
bool check_collision(const point& l, const plane& r){
|
||||
return check_collision(r, l);
|
||||
bool check_collision(const point& l, const plane& r, float epsilon){
|
||||
return check_collision(r, l, epsilon);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user