kick
/Users/morten/Programmering/cpp/kick/src/kick/math/aabb.cpp
00001 //
00002 //  aabb.cpp
00003 //  KickCPP
00004 //
00005 //  Created by Morten Nobel-Jørgensen on 07/12/13.
00006 //  Copyright (c) 2013 Morten Nobel-Joergensen. All rights reserved.
00007 //
00008 
00009 #include "kick/math/aabb.h"
00010 
00011 using namespace glm;
00012 
00013 namespace kick {
00014     const AABB AABB::mUninitialized{};
00015     
00016     AABB::AABB(vec3 min, vec3 max)
00017     :min(min), max(max){
00018     }
00019     
00020     AABB AABB::transform(mat4 mat)  const{
00021         glm::vec4 point(1,1,1,1);
00022         AABB res;
00023         float aabbIn[6] = {min.x, min.y, min.z, max.x, max.y, max.z};
00024         
00025         for (int i = 0; i < 2; i++) {
00026             for (int j = 0; j < 2; j++) {
00027                 for (int k = 0; k < 2; k++) {
00028                     point.x = aabbIn[i * 3];
00029                     point.y = aabbIn[j * 3 + 1];
00030                     point.z = aabbIn[k * 3 + 2];
00031 
00032                     res.addPoint(vec3(mat * point));
00033                 }
00034             }
00035         }
00036         return res;
00037     }
00038     
00039     void AABB::addPoint(glm::vec3 point){
00040         min = glm::min(min, point);
00041         max = glm::max(max, point);
00042     }
00043     
00044     vec3 AABB::center() const{
00045         return (min + max) * 0.5f;
00046     }
00047     
00048     vec3 AABB::diagonal() const{
00049         return max-min;
00050     }
00051     
00052     bool AABB::operator==(const AABB &other) const {
00053         return min == other.min && max == other.max;
00054     }
00055     
00056     bool AABB::operator!=(const AABB &other) const {
00057         return min != other.min || max != other.max;
00058     }
00059     
00060     void AABB::operator=(const AABB &other){
00061         min = other.min;
00062         max = other.max;
00063     }
00064     
00065     bool AABB::uninitialized(){
00066         return *this == mUninitialized;
00067     }
00068     
00069     bool AABB::empty(){
00070         return min == max;
00071     }
00072     
00073     void AABB::clear(){
00074         *this = mUninitialized;
00075     }
00076 
00077 
00078     bool AABB::intersect(const Ray &r, float &tNear, float &tFar, int &nearAxis, int &farAxis){
00079         // http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm
00080         tNear = -std::numeric_limits<float>::infinity( ) ;
00081         tFar = std::numeric_limits<float>::infinity( ) ;
00082 
00083         for (int i=0;i<3;i++){
00084             if (r.direction()[i]==0){
00085                 // the ray is parallel to the X planes
00086                 // origin Xo is not between the slabs ( Xo < Xl or Xo > Xh) then return false
00087                 if (r.origin()[i] < min[i] || r.origin()[i] > max[i]){
00088                     return false;
00089                 }
00090             } else {
00091                 float reciprocal = 1.0f / r.direction()[i];
00092                 // if the ray is not parallel to the plane then
00093                 // compute the intersection distance of the planes
00094                 float t1 = (min[i]-r.origin()[i])*reciprocal;
00095                 float t2 = (max[i]-r.origin()[i])*reciprocal;
00096                 if (t1 > t2){
00097                     // swap since T1 intersection with near plane
00098                     float tmp = t1;
00099                     t1 = t2;
00100                     t2 = tmp;
00101                 }
00102                 if (t1 > tNear){
00103                     tNear = t1; /* want largest Tnear */
00104                     nearAxis = i;
00105                 }
00106                 if (t2 < tFar){
00107                     tFar = t2; /* want largest Tnear */
00108                     farAxis = i;
00109                 }
00110                 if (tNear > tFar){
00111                     return false; /*  box is missed */
00112                 }
00113                 if (tFar < 0){
00114                     return false; /* box is behind ray return false end */
00115                 }
00116             }
00117         }
00118         return true;
00119 
00120     }
00121 
00122     bool AABB::contains(glm::vec3 point) {
00123         for (int i=0;i<3;i++){
00124             if (min[i]>point[i] || point[i] > max[i]){
00125                 return false;
00126             }
00127         }
00128         return true;
00129     }
00130 
00131     bool AABB::intersect(const AABB &box) {
00132         for (int i=0;i<3;i++){
00133             if (min[i]>box.max[i] || max[i]<box.min[i]){
00134                 return false;
00135             }
00136         }
00137         return true;
00138     }
00139 }
 All Classes Functions Variables