overte-HifiExperiments/libraries/voxels/src/AABox.cpp
2013-05-03 20:12:46 -07:00

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;
}