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