mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-10 01:36:26 +02:00
117 lines
3.1 KiB
C++
Executable file
117 lines
3.1 KiB
C++
Executable file
//
|
|
// AABox.h - Axis Aligned Boxes
|
|
// hifi
|
|
//
|
|
// Added by Brad Hefta-Gaub on 04/11/13.
|
|
// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards
|
|
//
|
|
// Simple axis aligned box class.
|
|
//
|
|
|
|
#include "SharedUtil.h"
|
|
|
|
#include "AABox.h"
|
|
|
|
|
|
void AABox::scale(float scale) {
|
|
_corner = _corner*scale;
|
|
_size = _size*scale;
|
|
}
|
|
|
|
|
|
void AABox::setBox(const glm::vec3& corner, const glm::vec3& size) {
|
|
_corner = corner;
|
|
_size = size;
|
|
|
|
// In the event that the caller gave us negative sizes, fix things up to be reasonable
|
|
if (_size.x < 0.0) {
|
|
_size.x = -size.x;
|
|
_corner.x -= _size.x;
|
|
}
|
|
if (_size.y < 0.0) {
|
|
_size.y = -size.y;
|
|
_corner.y -= _size.y;
|
|
}
|
|
if (_size.z < 0.0) {
|
|
_size.z = -size.z;
|
|
_corner.z -= _size.z;
|
|
}
|
|
}
|
|
|
|
glm::vec3 AABox::getVertexP(const glm::vec3 &normal) const {
|
|
glm::vec3 res = _corner;
|
|
if (normal.x > 0)
|
|
res.x += _size.x;
|
|
|
|
if (normal.y > 0)
|
|
res.y += _size.y;
|
|
|
|
if (normal.z > 0)
|
|
res.z += _size.z;
|
|
|
|
return(res);
|
|
}
|
|
|
|
|
|
|
|
glm::vec3 AABox::getVertexN(const glm::vec3 &normal) const {
|
|
glm::vec3 res = _corner;
|
|
|
|
if (normal.x < 0)
|
|
res.x += _size.x;
|
|
|
|
if (normal.y < 0)
|
|
res.y += _size.y;
|
|
|
|
if (normal.z < 0)
|
|
res.z += _size.z;
|
|
|
|
return(res);
|
|
}
|
|
|
|
// determines whether a value is within the extents
|
|
static bool isWithin(float value, float corner, float size) {
|
|
return value >= corner && value <= corner + size;
|
|
}
|
|
|
|
bool AABox::contains(const glm::vec3& point) const {
|
|
return isWithin(point.x, _corner.x, _size.x) &&
|
|
isWithin(point.y, _corner.y, _size.y) &&
|
|
isWithin(point.z, _corner.z, _size.z);
|
|
}
|
|
|
|
// finds the intersection between the closer plane in one direction
|
|
static bool findIntersection(float origin, float direction, float corner, float size, float* t) {
|
|
if (direction > EPSILON) {
|
|
*t = (corner - origin) / direction;
|
|
return true;
|
|
|
|
} else if (direction < -EPSILON) {
|
|
*t = (corner + size - origin) / direction;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool AABox::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float* t) const {
|
|
// handle the trivial case where the box contains the origin
|
|
if (contains(origin)) {
|
|
*t = 0;
|
|
return true;
|
|
}
|
|
// check each direction
|
|
float nt;
|
|
if (findIntersection(origin.x, direction.x, _corner.x, _size.x, &nt) && nt >= 0 &&
|
|
isWithin(origin.y + nt*direction.y, _corner.y, _size.y) &&
|
|
isWithin(origin.z + nt*direction.z, _corner.z, _size.z) ||
|
|
findIntersection(origin.y, direction.y, _corner.y, _size.y, &nt) && nt >= 0 &&
|
|
isWithin(origin.x + nt*direction.x, _corner.x, _size.x) &&
|
|
isWithin(origin.z + nt*direction.z, _corner.z, _size.z) ||
|
|
findIntersection(origin.z, direction.z, _corner.z, _size.z, &nt) && nt >= 0 &&
|
|
isWithin(origin.y + nt*direction.y, _corner.y, _size.y) &&
|
|
isWithin(origin.x + nt*direction.x, _corner.x, _size.x)) {
|
|
*t = nt;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|