|
|
@@ -32,51 +32,10 @@ OTHER DEALINGS IN THE SOFTWARE.
|
|
|
#include "Frustum.h"
|
|
|
#include "MathUtils.h"
|
|
|
#include "Types.h"
|
|
|
-#include "Circle.h"
|
|
|
-#include "Rect.h"
|
|
|
#include "AABB.h"
|
|
|
|
|
|
namespace crown
|
|
|
{
|
|
|
-
|
|
|
-/// Intersection test utils.
|
|
|
-/// Table of Intersection tests (3d)
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | | Ray | Plane | Sphere | AABB | Frustum |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | Ray | No | Yes | Yes | No | No |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | Plane | - | Yes (1) | Yes (+) | No | No |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | Sphere | - | - | Yes (+) | No | Yes |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | AABB | - | - | - | Yes (+) | Yes |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-/// | Frustum | - | - | - | - | No |
|
|
|
-/// +----------+----------+----------+----------+----------+----------+
|
|
|
-//
|
|
|
-/// Notes:
|
|
|
-/// (1): Intersection of three planes
|
|
|
-/// (-): Static intersection only
|
|
|
-/// (+): Static/Dynamic intersection
|
|
|
-/// Table of Intersection tests (2d)
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | | Circle | Rect | O Rect | Segment | Ray 2d |
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | Circle | Yes (p-) | No | No | No | No |
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | Rect | - | Yes | No | No | No | <- Axis Aligned Rect
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | O Rect | - | - | No | No | No | <- Oriented Rect
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | Segment | - | - | - | No | No |
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// | Ray 2d | - | - | - | - | No |
|
|
|
-/// +---------------+----------+-------------+-------------+----------+----------+
|
|
|
-/// Notes:
|
|
|
-/// (p): Penetration vector
|
|
|
-/// (-): Static intersection only
|
|
|
-/// (+): Static/Dynamic intersection
|
|
|
class Intersection
|
|
|
{
|
|
|
public:
|
|
|
@@ -98,11 +57,6 @@ public:
|
|
|
static bool test_frustum_sphere(const Frustum& f, const Sphere& s);
|
|
|
static bool test_frustum_box(const Frustum& f, const AABB& box);
|
|
|
|
|
|
- static bool test_circle_circle(const Circle& c1, const Circle& c2, Vector2& penetration);
|
|
|
- static bool test_dynamic_circle_circle(const Circle& c1, const Vector2& d1, const Circle& c2, const Vector2& d2, float& it);
|
|
|
- static bool test_rect_rect(const Rect& r1, const Rect& r2, Vector2& penetration);
|
|
|
- static bool test_circle_rect(const Circle& c1, const Rect& r2, Vector2& penetration);
|
|
|
-
|
|
|
private:
|
|
|
|
|
|
// Disable construction
|
|
|
@@ -485,204 +439,4 @@ inline bool Intersection::test_frustum_box(const Frustum& f, const AABB& b)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-inline bool Intersection::test_circle_circle(const Circle& c1, const Circle& c2, Vector2& penetration)
|
|
|
-{
|
|
|
- Vector2 distance = c1.center() - c2.center();
|
|
|
- float distanceLen2 = vector2::squared_length(distance);
|
|
|
- float radiusSum = c1.radius() + c2.radius();
|
|
|
- if (distanceLen2 > radiusSum*radiusSum)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (distanceLen2 < 0.001)
|
|
|
- {
|
|
|
- penetration = Vector2(c1.radius(), 0.0);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- distanceLen2 = math::sqrt(distanceLen2);
|
|
|
- penetration = distance * ((radiusSum - distanceLen2) / distanceLen2);
|
|
|
- }
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-inline bool Intersection::test_dynamic_circle_circle(const Circle& c1, const Vector2& d1, const Circle& c2, const Vector2& d2, float& it)
|
|
|
-{
|
|
|
- // c1 == static circle
|
|
|
- // c2 == moving circle
|
|
|
- Vector2 d = d2 - d1;
|
|
|
- vector2::normalize(d);
|
|
|
-
|
|
|
- const Vector2& cs = c1.center();
|
|
|
- const Vector2& cm = c2.center();
|
|
|
-
|
|
|
- Vector2 e = cs - cm;
|
|
|
- float r = c1.radius() + c2.radius();
|
|
|
-
|
|
|
- // If ||e|| < r, int32_tersection occurs at t = 0
|
|
|
- if (vector2::length(e) < r)
|
|
|
- {
|
|
|
- it = 0.0;
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- // it == Intersection Time
|
|
|
- float ed = vector2::dot(e, d);
|
|
|
- float squared = (ed * ed) + (r * r) - vector2::dot(e, e);
|
|
|
-
|
|
|
- // If the value inside the square root is neg, then no int32_tersection
|
|
|
- if (squared < 0.0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- float t = ed - math::sqrt(squared);
|
|
|
- float l = vector2::length(d2 - d1);
|
|
|
-
|
|
|
- // If t < 0 || t > l, then non int32_tersection in the considered period of time
|
|
|
- if (t < 0.0 || t > l)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- it = t / l;
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-inline bool Intersection::test_rect_rect(const Rect& r1, const Rect& r2, Vector2& penetration)
|
|
|
-{
|
|
|
- //x
|
|
|
- float min1MinusMax2 = r1.min().x - r2.max().x;
|
|
|
- float min2MinusMax1 = r2.min().x - r1.max().x;
|
|
|
-
|
|
|
- if (min1MinusMax2 > min2MinusMax1)
|
|
|
- {
|
|
|
- if (min1MinusMax2 > 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- penetration.x = -min1MinusMax2;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (min2MinusMax1 > 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- penetration.x = min2MinusMax1;
|
|
|
- }
|
|
|
-
|
|
|
- //y
|
|
|
- min1MinusMax2 = r1.min().y - r2.max().y;
|
|
|
- min2MinusMax1 = r2.min().y - r1.max().y;
|
|
|
-
|
|
|
- if (min1MinusMax2 > min2MinusMax1)
|
|
|
- {
|
|
|
- if (min1MinusMax2 > 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- penetration.y = -min1MinusMax2;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if (min2MinusMax1 > 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- penetration.y = min2MinusMax1;
|
|
|
- }
|
|
|
-
|
|
|
- if (math::abs(penetration.x) < math::abs(penetration.y))
|
|
|
- {
|
|
|
- penetration.y = 0.0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- penetration.x = 0.0;
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-//-----------------------------------------------------------------------------
|
|
|
-inline bool Intersection::test_circle_rect(const Circle& c1, const Rect& r2, Vector2& penetration)
|
|
|
-{
|
|
|
- bool circleIsAtRight;
|
|
|
- if (c1.center().x > (r2.min().x + r2.max().x) / 2)
|
|
|
- {
|
|
|
- penetration.x = (c1.center().x - c1.radius()) - r2.max().x;
|
|
|
- circleIsAtRight = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- penetration.x = r2.min().x - (c1.center().x + c1.radius());
|
|
|
- circleIsAtRight = false;
|
|
|
- }
|
|
|
-
|
|
|
- bool circleIsAtTop;
|
|
|
- if (c1.center().y > (r2.min().y + r2.max().y) / 2)
|
|
|
- {
|
|
|
- penetration.y = (c1.center().y - c1.radius()) - r2.max().y;
|
|
|
- circleIsAtTop = true;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- penetration.y = r2.min().y - (c1.center().y + c1.radius());
|
|
|
- circleIsAtTop = false;
|
|
|
- }
|
|
|
-
|
|
|
- if (penetration.x < -c1.radius() || penetration.y < -c1.radius())
|
|
|
- {
|
|
|
- if (penetration.y > 0 || penetration.x > 0)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (penetration.x > penetration.y)
|
|
|
- {
|
|
|
- penetration.y = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- penetration.x = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- //else if (penetration.y < -c1.radius())
|
|
|
- //{
|
|
|
- // if (penetration.x > 0)
|
|
|
- // {
|
|
|
- // return false;
|
|
|
- // }
|
|
|
- // penetration.y = 0;
|
|
|
- //}
|
|
|
- else
|
|
|
- {
|
|
|
- penetration += Vector2(c1.radius(), c1.radius());
|
|
|
- float len = math::sqrt(vector2::squared_length(penetration));
|
|
|
- if (len > c1.radius())
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- //The - is to point32_t outwards
|
|
|
- penetration *= - (c1.radius() - len) / len;
|
|
|
- }
|
|
|
-
|
|
|
- if (circleIsAtRight)
|
|
|
- {
|
|
|
- penetration.x *= -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (circleIsAtTop)
|
|
|
- {
|
|
|
- penetration.y *= -1;
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
} // namespace crown
|
|
|
-
|