|
|
|
@@ -1,11 +1,130 @@
|
|
|
|
|
#include "types/vertex.h"
|
|
|
|
|
#include <cfloat>
|
|
|
|
|
#include <engine/collision.h>
|
|
|
|
|
#include <J3ML/Geometry.h>
|
|
|
|
|
#include <J3ML/Geometry/AABB.h>
|
|
|
|
|
#include <J3ML/Geometry/Triangle.h>
|
|
|
|
|
#include <type_traits>
|
|
|
|
|
#include <variant>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
bool orientedBoundingBoxCollides(const Collider &boundingBox, const Collider &boundingBox2) {
|
|
|
|
|
inline constexpr decltype(auto) getVertexArray = [](auto&& shape) {
|
|
|
|
|
if constexpr (std::is_rvalue_reference_v<decltype(shape)>) {
|
|
|
|
|
return std::move(shape.vertexArray);
|
|
|
|
|
} else {
|
|
|
|
|
return shape.vertexArray;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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 OrientedBoundingBox& lhs, const OrientedBoundingBox& rhs) const {
|
|
|
|
|
Vector3 axes[3] = {
|
|
|
|
|
Vector3(1, 0, 0),
|
|
|
|
|
Vector3(0, 1, 0),
|
|
|
|
|
Vector3(0, 0, 1)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (const auto& axis : axes) {
|
|
|
|
|
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
|
|
|
|
|
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : lhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection1Min) projection1Min = projection;
|
|
|
|
|
if (projection > projection1Max) projection1Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : rhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection2Min) projection2Min = projection;
|
|
|
|
|
if (projection > projection2Max) projection2Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (projection1Max < projection2Min || projection2Max < projection1Min)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& axis : axes) {
|
|
|
|
|
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
|
|
|
|
|
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : lhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection1Min) projection1Min = projection;
|
|
|
|
|
if (projection > projection1Max) projection1Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : rhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection2Min) projection2Min = projection;
|
|
|
|
|
if (projection > projection2Max) projection2Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (projection1Max < projection2Min || projection2Max < projection1Min)
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true; //OBBs collide.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const OrientedBoundingBox& lhs, const AxisAlignedBoundingBox& rhs) const {
|
|
|
|
|
// Not yet implemented
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const AxisAlignedBoundingBox& lhs, const OrientedBoundingBox& rhs) const {
|
|
|
|
|
return operator()(rhs, lhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const CollisionMap& lhs, const AxisAlignedBoundingBox& 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 {
|
|
|
|
|
return operator()(rhs, lhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const CollisionMap& lhs, const OrientedBoundingBox& rhs) const {
|
|
|
|
|
// Not yet implemented
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const OrientedBoundingBox& lhs, const CollisionMap& rhs) const {
|
|
|
|
|
return operator()(rhs, lhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool operator()(const CollisionMap& lhs, const CollisionMap& rhs) const {
|
|
|
|
|
// Not yet implemented
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool orientedBoundingBoxCollides(const OrientedBoundingBox &lhs, const OrientedBoundingBox &rhs) {
|
|
|
|
|
Vector3 axes[3] = {
|
|
|
|
|
Vector3(1, 0, 0),
|
|
|
|
|
Vector3(0, 1, 0),
|
|
|
|
@@ -16,14 +135,14 @@ namespace {
|
|
|
|
|
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
|
|
|
|
|
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : boundingBox.shape.vertices) {
|
|
|
|
|
for (const auto& vertex : lhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection1Min) projection1Min = projection;
|
|
|
|
|
if (projection > projection1Max) projection1Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : boundingBox2.shape.vertices) {
|
|
|
|
|
for (const auto& vertex : rhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection2Min) projection2Min = projection;
|
|
|
|
@@ -38,14 +157,14 @@ namespace {
|
|
|
|
|
float projection1Min = FLT_MAX, projection1Max = -FLT_MAX;
|
|
|
|
|
float projection2Min = FLT_MAX, projection2Max = -FLT_MAX;
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : boundingBox.shape.vertices) {
|
|
|
|
|
for (const auto& vertex : lhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection1Min) projection1Min = projection;
|
|
|
|
|
if (projection > projection1Max) projection1Max = projection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : boundingBox2.shape.vertices) {
|
|
|
|
|
for (const auto& vertex : rhs.vertexArray.vertices) {
|
|
|
|
|
Vector3 vert = {vertex.x, vertex.y, vertex.z};
|
|
|
|
|
float projection = vert.Dot(axis);
|
|
|
|
|
if (projection < projection2Min) projection2Min = projection;
|
|
|
|
@@ -59,42 +178,13 @@ namespace {
|
|
|
|
|
return true; //OBBs collide.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool axisAlignedBoundingBoxCollides(const Collider &boundingBox, const Collider &boundingBox2) {
|
|
|
|
|
Vector3 aabb1Min = {boundingBox.shape.vertices.front().x, boundingBox.shape.vertices.front().y, boundingBox.shape.vertices.front().z};
|
|
|
|
|
Vector3 aabb1Max = {boundingBox.shape.vertices.back().x, boundingBox.shape.vertices.back().y, boundingBox.shape.vertices.back().z};
|
|
|
|
|
Vector3 aabb2Min = {boundingBox2.shape.vertices.front().x, boundingBox2.shape.vertices.front().y, boundingBox2.shape.vertices.front().z};
|
|
|
|
|
Vector3 aabb2Max = {boundingBox2.shape.vertices.back().x, boundingBox2.shape.vertices.back().y, boundingBox2.shape.vertices.back().z};
|
|
|
|
|
struct ContainsVisitor {
|
|
|
|
|
Vector3 position;
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Broken
|
|
|
|
|
bool triangleVSAxisAlignedBoundingBoxCollides(const Triangle &triangle, const Collider &boundingBox) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool collisionMapVSAxisAlignedBoundingBoxCollides(const Collider &boundingBox, const Collider& collisionMap) {
|
|
|
|
|
for (auto& triangle : collisionMap.getTriangles())
|
|
|
|
|
if (triangleVSAxisAlignedBoundingBoxCollides(triangle, boundingBox))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Collider::contains(const Position& position) const {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ColliderType::AxisAlignedBoundingBox: {
|
|
|
|
|
Vector3 minimum = {shape.vertices.front().x, shape.vertices.front().y, shape.vertices.front().z};
|
|
|
|
|
Vector3 maximum = {shape.vertices.back().x, shape.vertices.back().y, shape.vertices.back().z};
|
|
|
|
|
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 &&
|
|
|
|
@@ -103,11 +193,12 @@ bool Collider::contains(const Position& position) const {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ColliderType::OrientedBoundingBox: {
|
|
|
|
|
bool operator()(const OrientedBoundingBox& obb) const {
|
|
|
|
|
const auto& vertices = obb.vertexArray.vertices;
|
|
|
|
|
Vector3 minimum = {FLT_MAX, FLT_MAX, FLT_MAX};
|
|
|
|
|
Vector3 maximum = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
|
|
|
|
|
|
|
|
|
|
for (const auto& vertex : shape.vertices) {
|
|
|
|
|
for (const auto& vertex : vertices) {
|
|
|
|
|
if (vertex.x < minimum.x) minimum.x = vertex.x;
|
|
|
|
|
if (vertex.y < minimum.y) minimum.y = vertex.y;
|
|
|
|
|
if (vertex.z < minimum.z) minimum.z = vertex.z;
|
|
|
|
@@ -124,128 +215,181 @@ bool Collider::contains(const Position& position) const {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
bool operator()(const CollisionMap& map) const {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Collider::contains(const Position& position) const {
|
|
|
|
|
return std::visit(ContainsVisitor{position}, shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Collider::collides(const Collider& other) const {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case ColliderType::AxisAlignedBoundingBox:
|
|
|
|
|
switch (other.type) {
|
|
|
|
|
case ColliderType::AxisAlignedBoundingBox:
|
|
|
|
|
return axisAlignedBoundingBoxCollides(*this, other);
|
|
|
|
|
|
|
|
|
|
case ColliderType::OrientedBoundingBox:
|
|
|
|
|
return false; // not implemented
|
|
|
|
|
|
|
|
|
|
case ColliderType::CollisionMap:
|
|
|
|
|
return collisionMapVSAxisAlignedBoundingBoxCollides(other, *this);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ColliderType::OrientedBoundingBox:
|
|
|
|
|
switch (other.type) {
|
|
|
|
|
case ColliderType::AxisAlignedBoundingBox:
|
|
|
|
|
return false; // not implemented
|
|
|
|
|
|
|
|
|
|
case ColliderType::OrientedBoundingBox:
|
|
|
|
|
return orientedBoundingBoxCollides(*this, other);
|
|
|
|
|
|
|
|
|
|
case ColliderType::CollisionMap:
|
|
|
|
|
return false; // not implemented
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ColliderType::CollisionMap:
|
|
|
|
|
switch (other.type) {
|
|
|
|
|
case ColliderType::AxisAlignedBoundingBox:
|
|
|
|
|
return collisionMapVSAxisAlignedBoundingBoxCollides(*this, other);
|
|
|
|
|
|
|
|
|
|
case ColliderType::OrientedBoundingBox:
|
|
|
|
|
return false; // not implemented
|
|
|
|
|
|
|
|
|
|
case ColliderType::CollisionMap:
|
|
|
|
|
return false; // not implemented
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
return std::visit(CollisionVisitor{}, shape, other.shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Collider::translate(const Vector3& translation) {
|
|
|
|
|
for (auto& vertex : shape.vertices) {
|
|
|
|
|
vertex += translation;
|
|
|
|
|
}
|
|
|
|
|
struct Visitor {
|
|
|
|
|
Vector3 direction;
|
|
|
|
|
|
|
|
|
|
void operator()(AxisAlignedBoundingBox& aabb) const {
|
|
|
|
|
for (auto& vertex : aabb.vertexArray.vertices) {
|
|
|
|
|
vertex += direction;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(OrientedBoundingBox& obb) const {
|
|
|
|
|
for (auto& vertex : obb.vertexArray.vertices) {
|
|
|
|
|
vertex += direction;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(CollisionMap& map) const {
|
|
|
|
|
for (auto& vertex : map.vertexArray.vertices) {
|
|
|
|
|
vertex += direction;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::visit(Visitor{translation}, shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Collider::rotate(const Vector3& rotation) {
|
|
|
|
|
if (type == ColliderType::AxisAlignedBoundingBox)
|
|
|
|
|
return; // Axis-aligned bounding box does not rotate, it is always axis-aligned
|
|
|
|
|
shape.rotate(rotation);
|
|
|
|
|
angle = rotation;
|
|
|
|
|
struct Visitor {
|
|
|
|
|
Vector3 ang;
|
|
|
|
|
|
|
|
|
|
void operator()(AxisAlignedBoundingBox&) const {
|
|
|
|
|
// AABB does not rotate, it is axis-aligned
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(OrientedBoundingBox& obb) const {
|
|
|
|
|
obb.vertexArray.rotate(ang);
|
|
|
|
|
obb.angle = ang;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(CollisionMap& map) const {
|
|
|
|
|
map.vertexArray.rotate(ang);
|
|
|
|
|
map.angle = ang;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::visit(Visitor{rotation}, shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Collider::scale(const Vector3& scale) {
|
|
|
|
|
for (auto& vertex : shape.vertices) {
|
|
|
|
|
vertex.x *= scale.x;
|
|
|
|
|
vertex.y *= scale.y;
|
|
|
|
|
vertex.z *= scale.z;
|
|
|
|
|
}
|
|
|
|
|
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()(OrientedBoundingBox& obb) const {
|
|
|
|
|
for (auto& vertex : obb.vertexArray.vertices) {
|
|
|
|
|
vertex.x *= factor.x;
|
|
|
|
|
vertex.y *= factor.y;
|
|
|
|
|
vertex.z *= factor.z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(CollisionMap& map) const {
|
|
|
|
|
for (auto& vertex : map.vertexArray.vertices) {
|
|
|
|
|
vertex.x *= factor.x;
|
|
|
|
|
vertex.y *= factor.y;
|
|
|
|
|
vertex.z *= factor.z;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::visit(Visitor{scale}, shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Collider::collides(const Triangle& triangle) const {
|
|
|
|
|
return triangleVSAxisAlignedBoundingBoxCollides(triangle, *this);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Collider::draw() {
|
|
|
|
|
if (type != ColliderType::CollisionMap) {
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
auto& vertices = shape.vertices;
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[(i + 1) % 4].x, vertices[(i + 1) % 4].y, vertices[(i + 1) % 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
glVertex3f(vertices[((i + 1) % 4) + 4].x, vertices[((i + 1) % 4) + 4].y, vertices[((i + 1) % 4) + 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (type == ColliderType::CollisionMap) {
|
|
|
|
|
shape.drawWireframe();
|
|
|
|
|
|
|
|
|
|
for (const auto& triangle : getTriangles()) {
|
|
|
|
|
Vector3 edge1 = triangle.V1 - triangle.V0;
|
|
|
|
|
Vector3 edge2 = triangle.V2 - triangle.V0;
|
|
|
|
|
Vector3 normal = Vector3::Normalize(Vector3::Cross(edge1, edge2));
|
|
|
|
|
|
|
|
|
|
Vector3 centroid = (triangle.V0 + triangle.V1 + triangle.V2) / 3.0f;
|
|
|
|
|
Vector3 normalPoint = centroid + (normal * 0.25);
|
|
|
|
|
|
|
|
|
|
glColor3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
struct DrawVisitor {
|
|
|
|
|
void operator()(const AxisAlignedBoundingBox& 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() },
|
|
|
|
|
Vertex{ aabb.MaxX(), aabb.MaxY(), aabb.MinZ() },
|
|
|
|
|
Vertex{ aabb.MinX(), aabb.MinY(), aabb.MaxZ() },
|
|
|
|
|
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);
|
|
|
|
|
glVertex3f(centroid.x, centroid.y, centroid.z);
|
|
|
|
|
glVertex3f(normalPoint.x, normalPoint.y, normalPoint.z);
|
|
|
|
|
glEnd();
|
|
|
|
|
glColor4f(1.f, 1.f, 1.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[(i + 1) % 4].x, vertices[(i + 1) % 4].y, vertices[(i + 1) % 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
glVertex3f(vertices[((i + 1) % 4) + 4].x, vertices[((i + 1) % 4) + 4].y, vertices[((i + 1) % 4) + 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(OrientedBoundingBox& obb) {
|
|
|
|
|
auto& vertices = obb.vertexArray.vertices;
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[(i + 1) % 4].x, vertices[(i + 1) % 4].y, vertices[(i + 1) % 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
glVertex3f(vertices[((i + 1) % 4) + 4].x, vertices[((i + 1) % 4) + 4].y, vertices[((i + 1) % 4) + 4].z);
|
|
|
|
|
|
|
|
|
|
glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
|
|
|
|
|
glVertex3f(vertices[i + 4].x, vertices[i + 4].y, vertices[i + 4].z);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void operator()(CollisionMap& map) const {
|
|
|
|
|
map.vertexArray.drawWireframe();
|
|
|
|
|
|
|
|
|
|
for (const auto& triangle : map.getTriangles()) {
|
|
|
|
|
Vector3 edge1 = triangle.V1 - triangle.V0;
|
|
|
|
|
Vector3 edge2 = triangle.V2 - triangle.V0;
|
|
|
|
|
Vector3 normal = Vector3::Normalize(Vector3::Cross(edge1, edge2));
|
|
|
|
|
|
|
|
|
|
Vector3 centroid = (triangle.V0 + triangle.V1 + triangle.V2) / 3.0f;
|
|
|
|
|
Vector3 normalPoint = centroid + (normal * 0.25);
|
|
|
|
|
|
|
|
|
|
glColor3f(0.0f, 1.0f, 0.0f);
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
glVertex3f(centroid.x, centroid.y, centroid.z);
|
|
|
|
|
glVertex3f(normalPoint.x, normalPoint.y, normalPoint.z);
|
|
|
|
|
glEnd();
|
|
|
|
|
glColor4f(1.f, 1.f, 1.f, 1.f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::visit(DrawVisitor{}, shape);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<Triangle> Collider::getTriangles() const {
|
|
|
|
|
std::vector<Triangle> CollisionMap::getTriangles() const {
|
|
|
|
|
std::vector<Triangle> triangles;
|
|
|
|
|
for (size_t i = 0; i < shape.indices.size(); i += 3) {
|
|
|
|
|
if (i + 2 < shape.indices.size()) {
|
|
|
|
|
for (size_t i = 0; i < vertexArray.indices.size(); i += 3) {
|
|
|
|
|
if (i + 2 < vertexArray.indices.size()) {
|
|
|
|
|
Triangle triangle;
|
|
|
|
|
triangle.V0 = shape.vertices[shape.indices[i]];
|
|
|
|
|
triangle.V1 = shape.vertices[shape.indices[i + 1]];
|
|
|
|
|
triangle.V2 = shape.vertices[shape.indices[i + 2]];
|
|
|
|
|
triangle.V0 = vertexArray.vertices[vertexArray.indices[i]];
|
|
|
|
|
triangle.V1 = vertexArray.vertices[vertexArray.indices[i + 1]];
|
|
|
|
|
triangle.V2 = vertexArray.vertices[vertexArray.indices[i + 2]];
|
|
|
|
|
triangles.push_back(triangle);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|