1 #ifndef __GNUC__ 2 #pragma once 3 #endif 4 #ifndef __XR_AABB_H__ 5 #define __XR_AABB_H__ 6 7 #include "xr_vector3.h" 8 #include "xr_limits.h" 9 10 namespace xray_re { 11 12 template<typename T> struct _aabb { 13 _aabb<T>& null(); 14 _aabb<T>& set(const _aabb<T>& box); 15 _aabb<T>& invalidate(); 16 _aabb<T>& extend(const _vector3<T>& p); 17 _aabb<T>& grow(T s); 18 _aabb<T>& grow(const _vector3<T>& s); 19 _aabb<T>& shrink(T s); 20 _aabb<T>& shrink(const _vector3<T>& s); 21 _aabb<T>& fix(); 22 T volume() const; 23 T size() const; 24 T width() const; 25 T height() const; 26 T depth() const; 27 void center(_vector3<T>& v) const; 28 T overlap_ratio(const _aabb<T>& box) const; 29 bool contain(const _vector3<T>& p) const; 30 bool contain(const _aabb<T>& box) const; 31 bool intersect(const _aabb<T>& box) const; 32 bool intersect_zy(const _aabb<T>& box) const; 33 _aabb<T>& merge(const _aabb<T>& box); 34 35 union { 36 struct { 37 _vector3<T> min; 38 _vector3<T> max; 39 }; 40 struct { 41 T x1, y1, z1; 42 T x2, y2, z2; 43 }; 44 }; 45 }; 46 47 typedef _aabb<float> fbox; 48 typedef _aabb<int16_t> i16box; 49 null()50template<typename T> inline _aabb<T>& _aabb<T>::null() 51 { 52 min.set(); 53 max.set(); 54 return *this; 55 } 56 set(const _aabb<T> & box)57template<typename T> inline _aabb<T>& _aabb<T>::set(const _aabb<T>& box) 58 { 59 min.set(box.min); 60 max.set(box.max); 61 return *this; 62 } 63 invalidate()64template<typename T> inline _aabb<T>& _aabb<T>::invalidate() 65 { 66 x1 = y1 = z1 = xr_numeric_limits<T>::max(); 67 x2 = y2 = z2 = xr_numeric_limits<T>::real_min(); 68 return *this; 69 } 70 extend(const _vector3<T> & p)71template<typename T> inline _aabb<T>& _aabb<T>::extend(const _vector3<T>& p) 72 { 73 min.min(p); 74 max.max(p); 75 return *this; 76 } 77 grow(const _vector3<T> & s)78template<typename T> inline _aabb<T>& _aabb<T>::grow(const _vector3<T>& s) 79 { 80 min.sub(s); 81 max.add(s); 82 return *this; 83 } 84 grow(T s)85template<typename T> inline _aabb<T>& _aabb<T>::grow(T s) 86 { 87 min.sub(s); 88 max.add(s); 89 return *this; 90 } 91 shrink(const _vector3<T> & s)92template<typename T> inline _aabb<T>& _aabb<T>::shrink(const _vector3<T>& s) 93 { 94 min.sub(s); 95 max.add(s); 96 return fix(); 97 } 98 shrink(T s)99template<typename T> inline _aabb<T>& _aabb<T>::shrink(T s) 100 { 101 min.add(s); 102 max.sub(s); 103 return fix(); 104 } 105 fix()106template<typename T> inline _aabb<T>& _aabb<T>::fix() 107 { 108 if (x2 < x1) 109 x1 = x2 = T(0.5)*(x1 + x2); 110 if (y2 < y1) 111 y1 = y2 = T(0.5)*(y1 + y2); 112 if (z2 < z1) 113 z1 = z2 = T(0.5)*(z1 + z2); 114 return *this; 115 } 116 contain(const _vector3<T> & p)117template<typename T> inline bool _aabb<T>::contain(const _vector3<T>& p) const 118 { 119 return (p.x >= min.x && p.x <= max.x) && 120 (p.y >= min.y && p.y <= max.y) && 121 (p.z >= min.z && p.z <= max.z); 122 } 123 contain(const _aabb<T> & box)124template<typename T> inline bool _aabb<T>::contain(const _aabb<T>& box) const 125 { 126 return (x1 <= box.x1 && box.x2 <= x2) && 127 (y1 <= box.y1 && box.y2 <= y2) && 128 (z1 <= box.z1 && box.z2 <= z2); 129 } 130 intersect(const _aabb<T> & box)131template<typename T> inline bool _aabb<T>::intersect(const _aabb<T>& box) const 132 { 133 if (x1 > box.x2 || x2 < box.x1) 134 return false; 135 if (y1 > box.y2 || y2 < box.y1) 136 return false; 137 if (z1 > box.z2 || z2 < box.z1) 138 return false; 139 return true; 140 } 141 intersect_zy(const _aabb<T> & box)142template<typename T> inline bool _aabb<T>::intersect_zy(const _aabb<T>& box) const 143 { 144 if (z1 > box.z2 || z2 < box.z1) 145 return false; 146 if (y1 > box.y2 || y2 < box.y1) 147 return false; 148 return true; 149 } 150 volume()151template<typename T> inline T _aabb<T>::volume() const 152 { 153 return (x2 - x1)*(y2 - y1)*(z2 - z1); 154 } 155 size()156template<typename T> inline T _aabb<T>::size() const 157 { 158 return (x2 - x1) + (y2 - y1) + (z2 - z1); 159 } 160 width()161template<typename T> inline T _aabb<T>::width() const { return x2 - x1; } height()162template<typename T> inline T _aabb<T>::height() const { return y2 - y1; } depth()163template<typename T> inline T _aabb<T>::depth() const { return z2 - z1; } 164 center(_vector3<T> & p)165template<typename T> inline void _aabb<T>::center(_vector3<T>& p) const 166 { 167 p.add(max, min).mul(T(0.5)); 168 } 169 overlap_ratio(const _aabb<T> & box)170template<typename T> inline T _aabb<T>::overlap_ratio(const _aabb<T>& box) const 171 { 172 T w = (x2 < box.x2) ? x2 : box.x2; 173 w -= (x1 < box.x1) ? box.x1 : x1; 174 if (w <= 0) 175 return 0; 176 T h = (y2 < box.z2) ? y2 : box.y2; 177 h -= (y1 < box.y1) ? box.y1 : y1; 178 if (h <= 0) 179 return 0; 180 T d = (z2 < box.z2) ? z2 : box.z2; 181 d -= (z1 < box.z1) ? box.z1 : z1; 182 if (d <= 0) 183 return 0; 184 return (w*h*d)/box.volume(); 185 } 186 merge(const _aabb<T> & box)187template<typename T> inline _aabb<T>& _aabb<T>::merge(const _aabb<T>& box) 188 { 189 if (x1 > box.x1) 190 x1 = box.x1; 191 if (y1 > box.y1) 192 y1 = box.y1; 193 if (z1 > box.z1) 194 z1 = box.z1; 195 if (x2 < box.x2) 196 x2 = box.x2; 197 if (y2 < box.y2) 198 y2 = box.y2; 199 if (z2 < box.z2) 200 z2 = box.z2; 201 return *this; 202 } 203 204 } // end of namespace xray_re 205 206 #endif 207