Add AABBvAABB interesection & add AABB scale
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include <J3ML/LinearAlgebra.h>
|
||||
#include <J3ML/Geometry/Common.h>
|
||||
#include <J3ML/Geometry/Shape.h>
|
||||
@@ -179,6 +181,8 @@ namespace J3ML::Geometry
|
||||
|
||||
void Translate(const Vector3& offset);
|
||||
AABB Translated(const Vector3& offset) const;
|
||||
void Scale(const Vector3& scale);
|
||||
AABB Scaled(const Vector3& scale) const;
|
||||
AABB TransformAABB(const Matrix3x3& transform);
|
||||
AABB TransformAABB(const Matrix4x4& transform);
|
||||
AABB TransformAABB(const Quaternion& transform);
|
||||
@@ -230,6 +234,7 @@ namespace J3ML::Geometry
|
||||
bool Intersects(const Polygon& polygon) const;
|
||||
bool Intersects(const Frustum& frustum) const;
|
||||
bool Intersects(const Polyhedron& polyhedron) const;
|
||||
bool Intersects(const AABB& aabb) const;
|
||||
|
||||
/** For reference documentation on the Sphere-AABB intersection test, see Christer Ericson's Real-Time Collision Detection, p. 165. [groupSyntax]
|
||||
@param sphere The first parameter of this function specifies the other object to test against.
|
||||
@@ -270,9 +275,9 @@ namespace J3ML::Geometry
|
||||
}
|
||||
|
||||
/// Finds the set intersection of this and the given AABB.
|
||||
/** @return This function returns the AABB that is contained in both this and the given AABB.
|
||||
/** @return This function returns an intersection that is contained in both this and the given AABB if there is one.
|
||||
@todo Add Intersection(OBB/Polyhedron). */
|
||||
AABB Intersection(const AABB& rhs) const;
|
||||
std::optional<AABB> Intersection(const AABB& rhs) const;
|
||||
|
||||
|
||||
/// Sets this AABB to enclose the given set of points.
|
||||
|
@@ -454,6 +454,51 @@ namespace J3ML::Geometry {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AABB::Intersects(const AABB& aabb) const {
|
||||
return Intersection(aabb).has_value();
|
||||
}
|
||||
|
||||
std::optional<AABB> AABB::Intersection(const AABB& rhs) const {
|
||||
// Here we do SAT, except that due to both objects being AABBs, they are "already projected" onto the same axis
|
||||
constexpr auto test = [](float a, float b, float c, float d) -> std::optional<Vector2> {
|
||||
// Overlap Test
|
||||
// Points go:
|
||||
// +-------------+
|
||||
// +-----|-----+ |
|
||||
// | 1 | | 2 |
|
||||
// | +-----|-------+
|
||||
// +-----------+
|
||||
//
|
||||
// A-----C-----B-------D
|
||||
//
|
||||
// IF A < C AND B > C ( Overlap in order object 1 -> object 2)
|
||||
// IF C < A AND D > A ( Overlap in order object 2 -> object 1)
|
||||
if (a < c && b > c) {
|
||||
return Vector2{c, b};
|
||||
}
|
||||
if (c < a && d > a) {
|
||||
return Vector2{a, d};
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
// This is SAT, so we need all axes to collide
|
||||
std::optional<Vector2> xCollision = test(MinX(), MaxX(), rhs.MinX(), rhs.MaxX());
|
||||
if (!xCollision.has_value()) return std::nullopt;
|
||||
|
||||
std::optional<Vector2> yCollision = test(MinY(), MaxY(), rhs.MinY(), rhs.MaxY());
|
||||
if (!yCollision.has_value()) return std::nullopt;
|
||||
|
||||
std::optional<Vector2> zCollision = test(MinZ(), MaxZ(), rhs.MinZ(), rhs.MaxZ());
|
||||
if (!zCollision.has_value()) return std::nullopt;
|
||||
|
||||
// At this point all 3 optionals have a value ; x of each is the "min" value, y of each is the "max" value
|
||||
return AABB{
|
||||
Vector3{xCollision->x, yCollision->x, zCollision->x},
|
||||
Vector3{xCollision->y, yCollision->y, zCollision->y}
|
||||
};
|
||||
}
|
||||
|
||||
bool AABB::IntersectLineAABB_CPP(const Vector3 &linePos, const Vector3 &lineDir, float &tNear, float &tFar) const
|
||||
{
|
||||
assert(lineDir.IsNormalized());
|
||||
@@ -552,6 +597,22 @@ namespace J3ML::Geometry {
|
||||
return AABB(minPoint+offset, maxPoint+offset);
|
||||
}
|
||||
|
||||
void AABB::Scale(const Vector3 &scale) {
|
||||
minPoint.x *= scale.x;
|
||||
minPoint.y *= scale.y;
|
||||
minPoint.z *= scale.z;
|
||||
maxPoint.x *= scale.x;
|
||||
maxPoint.y *= scale.y;
|
||||
maxPoint.z *= scale.z;
|
||||
}
|
||||
|
||||
AABB AABB::Scaled(const Vector3 &scale) const {
|
||||
return AABB(
|
||||
Vector3(minPoint.x*scale.y, minPoint.y*scale.y, minPoint.z*scale.z),
|
||||
Vector3(maxPoint.x*scale.y, maxPoint.y*scale.y, maxPoint.z*scale.z)
|
||||
);
|
||||
}
|
||||
|
||||
AABB AABB::TransformAABB(const Matrix3x3 &transform) {
|
||||
// TODO: assert(transform.IsColOrthogonal());
|
||||
// TODO: assert(transform.HasUniformScale());
|
||||
|
Reference in New Issue
Block a user