Support J3ML::AABB

This commit is contained in:
Mishura
2024-05-06 19:27:50 -04:00
parent e7464e963b
commit c0baa7abad
4 changed files with 23 additions and 69 deletions

View File

@@ -11,10 +11,7 @@ enum class ColliderType : uint8_t {
};
using J3ML::Geometry::Triangle;
struct AxisAlignedBoundingBox {
VertexArray vertexArray;
};
using J3ML::Geometry::AABB;
struct OrientedBoundingBox {
VertexArray vertexArray;
@@ -30,10 +27,9 @@ struct CollisionMap {
class Collider {
public:
using shape_type = std::variant<AxisAlignedBoundingBox, OrientedBoundingBox, CollisionMap>;
using shape_type = std::variant<AABB, OrientedBoundingBox, CollisionMap>;
shape_type shape;
ColliderType type;
void draw();
void translate(const Vector3& translation);

View File

@@ -26,7 +26,6 @@ Collider Sphere2::getCollider() {
//collider.angle = angle;
map.vertexArray.vertices = getGeometry()->vertices;
map.vertexArray.indices = getGeometry()->indices;
collider.type = ColliderType::CollisionMap;
collider.rotate(angle);
collider.scale(Vector3(getScale(), getScale(), getScale()));

View File

@@ -6,6 +6,7 @@
#include <J3ML/Geometry/Triangle.h>
#include <type_traits>
#include <variant>
#include <array>
namespace {
inline constexpr decltype(auto) getVertexArray = [](auto&& shape) {
@@ -17,22 +18,8 @@ namespace {
};
struct CollisionVisitor {
bool operator()(const AxisAlignedBoundingBox& lhs, const AxisAlignedBoundingBox& rhs) const {
Vector3 aabb1Min = {lhs.vertexArray.vertices.front().x, lhs.vertexArray.vertices.front().y, lhs.vertexArray.vertices.front().z};
Vector3 aabb1Max = {lhs.vertexArray.vertices.back().x, lhs.vertexArray.vertices.back().y, lhs.vertexArray.vertices.back().z};
Vector3 aabb2Min = {rhs.vertexArray.vertices.front().x, rhs.vertexArray.vertices.front().y, rhs.vertexArray.vertices.front().z};
Vector3 aabb2Max = {rhs.vertexArray.vertices.back().x, rhs.vertexArray.vertices.back().y, rhs.vertexArray.vertices.back().z};
if (aabb1Max.x < aabb2Min.x || aabb2Max.x < aabb1Min.x)
return false;
if (aabb1Max.y < aabb2Min.y || aabb2Max.y < aabb1Min.y)
return false;
if (aabb1Max.z < aabb2Min.z || aabb2Max.z < aabb1Min.z)
return false;
return true; //AABBs Collide.
bool operator()(const AABB& lhs, const AABB& rhs) const {
return lhs.Intersects(rhs);
}
bool operator()(const OrientedBoundingBox& lhs, const OrientedBoundingBox& rhs) const {
@@ -89,23 +76,23 @@ namespace {
return true; //OBBs collide.
}
bool operator()(const OrientedBoundingBox& lhs, const AxisAlignedBoundingBox& rhs) const {
bool operator()(const OrientedBoundingBox& lhs, const AABB& rhs) const {
// Not yet implemented
return false;
}
bool operator()(const AxisAlignedBoundingBox& lhs, const OrientedBoundingBox& rhs) const {
bool operator()(const AABB& lhs, const OrientedBoundingBox& rhs) const {
return operator()(rhs, lhs);
}
bool operator()(const CollisionMap& lhs, const AxisAlignedBoundingBox& rhs) const {
bool operator()(const CollisionMap& lhs, const AABB& rhs) const {
for (const auto& triangle : lhs.getTriangles())
if (false /* rhs.Intersects(triangle) */)
return true;
return false;
}
bool operator()(const AxisAlignedBoundingBox& lhs, const CollisionMap& rhs) const {
bool operator()(const AABB& lhs, const CollisionMap& rhs) const {
return operator()(rhs, lhs);
}
@@ -181,16 +168,8 @@ namespace {
struct ContainsVisitor {
Vector3 position;
bool operator()(const AxisAlignedBoundingBox& aabb) const {
const auto& vertices = aabb.vertexArray.vertices;
Vector3 minimum = {vertices.front().x, vertices.front().y, vertices.front().z};
Vector3 maximum = {vertices.back().x, vertices.back().y, vertices.back().z};
return (
position.x >= minimum.x && position.x <= maximum.x &&
position.y >= minimum.y && position.y <= maximum.y &&
position.z >= minimum.z && position.z <= maximum.z
);
bool operator()(const AABB& aabb) const {
return aabb.Contains(position);
}
bool operator()(const OrientedBoundingBox& obb) const {
@@ -208,6 +187,7 @@ namespace {
if (vertex.z > maximum.z) maximum.z = vertex.z;
}
// This looks like logic for AABB, not OBB
return (
position.x >= minimum.x && position.x <= maximum.x &&
position.y >= minimum.y && position.y <= maximum.y &&
@@ -233,10 +213,8 @@ void Collider::translate(const Vector3& translation) {
struct Visitor {
Vector3 direction;
void operator()(AxisAlignedBoundingBox& aabb) const {
for (auto& vertex : aabb.vertexArray.vertices) {
vertex += direction;
}
void operator()(AABB& aabb) const {
aabb = aabb.Translated(direction);
}
void operator()(OrientedBoundingBox& obb) const {
@@ -259,7 +237,7 @@ void Collider::rotate(const Vector3& rotation) {
struct Visitor {
Vector3 ang;
void operator()(AxisAlignedBoundingBox&) const {
void operator()(AABB&) const {
// AABB does not rotate, it is axis-aligned
return;
}
@@ -282,12 +260,8 @@ void Collider::scale(const Vector3& scale) {
struct Visitor {
Vector3 factor;
void operator()(AxisAlignedBoundingBox& aabb) const {
for (auto& vertex : aabb.vertexArray.vertices) {
vertex.x *= factor.x;
vertex.y *= factor.y;
vertex.z *= factor.z;
}
void operator()(AABB& aabb) const {
aabb = aabb.Scaled(factor);
}
void operator()(OrientedBoundingBox& obb) const {
@@ -316,8 +290,8 @@ bool Collider::collides(const Triangle& triangle) const {
void Collider::draw() {
struct DrawVisitor {
void operator()(const AxisAlignedBoundingBox& aabb) const {
/*std::array vertices = {
void operator()(const AABB& aabb) const {
std::array vertices = {
Vertex{ aabb.MinX(), aabb.MinY(), aabb.MinZ() },
Vertex{ aabb.MaxX(), aabb.MinY(), aabb.MinZ() },
Vertex{ aabb.MinX(), aabb.MaxY(), aabb.MinZ() },
@@ -326,8 +300,7 @@ void Collider::draw() {
Vertex{ aabb.MaxX(), aabb.MinY(), aabb.MaxZ() },
Vertex{ aabb.MinX(), aabb.MaxY(), aabb.MaxZ() },
Vertex{ aabb.MaxX(), aabb.MaxY(), aabb.MaxZ() },
};*/
auto& vertices = aabb.vertexArray.vertices;
};
glBegin(GL_LINES);
for (int i = 0; i < 4; ++i) {
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);

View File

@@ -2,7 +2,6 @@
#include <limits>
Collider Collider::calculateOBB(const VertexArray& vArray, const Vector3& angle) {
Collider ret;
float minX = std::numeric_limits<float>::max();
float minY = std::numeric_limits<float>::max();
float minZ = std::numeric_limits<float>::max();
@@ -26,7 +25,7 @@ Collider Collider::calculateOBB(const VertexArray& vArray, const Vector3& angle)
maxZ = vertex.z;
}
auto& output = ret.shape.emplace<OrientedBoundingBox>().vertexArray;
VertexArray output;
output.vertices.emplace_back(minX, minY, minZ);
output.vertices.emplace_back(maxX, minY, minZ);
output.vertices.emplace_back(minX, maxY, minZ);
@@ -37,12 +36,10 @@ Collider Collider::calculateOBB(const VertexArray& vArray, const Vector3& angle)
output.vertices.emplace_back(maxX, maxY, maxZ);
output.rotate(angle);
ret.type = ColliderType::OrientedBoundingBox;
return ret;
return Collider{.shape = OrientedBoundingBox{.vertexArray = std::move(output), .angle = angle}};
}
Collider Collider::calculateAABB(const VertexArray& vArray) {
Collider ret;
float minX = std::numeric_limits<float>::max();
float minY = std::numeric_limits<float>::max();
float minZ = std::numeric_limits<float>::max();
@@ -65,16 +62,5 @@ Collider Collider::calculateAABB(const VertexArray& vArray) {
if (vertex.z > maxZ)
maxZ = vertex.z;
}
auto& output = ret.shape.emplace<AxisAlignedBoundingBox>().vertexArray;
output.vertices.emplace_back(minX, minY, minZ);
output.vertices.emplace_back(maxX, minY, minZ);
output.vertices.emplace_back(minX, maxY, minZ);
output.vertices.emplace_back(maxX, maxY, minZ);
output.vertices.emplace_back(minX, minY, maxZ);
output.vertices.emplace_back(maxX, minY, maxZ);
output.vertices.emplace_back(minX, maxY, maxZ);
output.vertices.emplace_back(maxX, maxY, maxZ);
ret.type = ColliderType::AxisAlignedBoundingBox;
return ret;
return Collider{.shape = AABB{Vector3{minX, minY, minZ}, Vector3{maxX, maxY, maxZ}}};
}