Sirikata
|
00001 /* Sirikata Utilities -- Math Library 00002 * BoundingBox.hpp 00003 * 00004 * Copyright (c) 2009, Daniel Reiter Horn 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 #ifndef _SIRIKATA_BOUNDING_BOX_HPP 00033 #define _SIRIKATA_BOUNDING_BOX_HPP 00034 00035 #define BBOX_CONTAINS_EPSILON 0.0005 00036 00037 namespace Sirikata { 00038 template <typename real> class BoundingBox { 00039 Vector3<real> mMin; 00040 Vector3f mAcross; 00041 public: 00042 BoundingBox() {} 00043 static BoundingBox<real> null() { 00044 return BoundingBox<real>(Vector3<real>(0,0,0),0); 00045 } 00046 00047 BoundingBox(const Vector3<real>¢er, float radius){ 00048 mMin=center-Vector3<real>(radius,radius,radius); 00049 mAcross=Vector3f(2.0f*radius,2.0f*radius,2.0f*radius); 00050 } 00051 template <typename flt> BoundingBox(const BoundingBox<flt>&input) { 00052 mMin=Vector3<real>(input.min()); 00053 mAcross=input.across(); 00054 } 00055 BoundingBox(const Vector3<real>&imin,const Vector3<real>&imax){ 00056 mMin=imin; 00057 Vector3<real> tmp(imax-imin); 00058 mAcross.x=(float)tmp.x; 00059 mAcross.y=(float)tmp.y; 00060 mAcross.z=(float)tmp.z; 00061 } 00062 00063 const Vector3<real> &min()const{ 00064 return mMin; 00065 } 00066 const Vector3f& across() const { 00067 return mAcross; 00068 } 00069 const Vector3f& diag() const { 00070 return mAcross; 00071 } 00072 const Vector3f& extents() const { 00073 return mAcross; 00074 } 00075 Vector3<real> max() const { 00076 return mMin+Vector3<real>(mAcross); 00077 } 00078 Vector3<real> center() const { 00079 return mMin+Vector3<real>(mAcross * 0.5f); 00080 } 00081 BoundingSphere<real> toBoundingSphere() const{ 00082 Vector3<real> center=this->center(); 00083 float maxlen=(this->max()-this->center()).lengthSquared(); 00084 float minlen=(this->min()-this->center()).lengthSquared(); 00085 float radius=std::sqrt(minlen<maxlen?maxlen:minlen); 00086 return BoundingSphere<real>(center,radius); 00087 } 00088 00089 BoundingBox<real> merge(const BoundingBox<real>&other) { 00090 return BoundingBox<real>(min().min(other.min()), 00091 max().max(other.max())); 00092 } 00093 BoundingBox merge(const Vector3<real>&other) { 00094 return BoundingBox(min().min(other), 00095 max().max(other)); 00096 } 00097 00098 BoundingBox& mergeIn(const BoundingBox<real>& other) { 00099 Vector3<real> mmax = max().max(other.max()); 00100 Vector3<real> mmin= min().min(other.min()); 00101 mMin = mmin; 00102 mAcross = Vector3f(mmax - mmin); 00103 return *this; 00104 } 00105 00106 BoundingBox& mergeIn(const Vector3<real>& other) { 00107 Vector3<real> mmin=min().min(other); 00108 Vector3<real> mmax = max().max(other); 00109 mMin=mmin; 00110 mAcross = Vector3f(mmax - mmin); 00111 return *this; 00112 } 00113 00121 bool contains(const Vector3<real>& point, real eps = BBOX_CONTAINS_EPSILON) const { 00122 Vector3<real> mmax = max(); 00123 Vector3<real> mmin = min(); 00124 for(int i = 0; i < Vector3<real>::size; i++) { 00125 if ( (point[i] - mmin[i] < -eps) || 00126 (mmax[i] - point[i] < -eps) ) 00127 return false; 00128 } 00129 return true; 00130 } 00131 00132 00133 bool degenerate() const { 00134 for(int i = 0; i < Vector3<real>::size; i++) 00135 if (mAcross[i] <= 0) return true; 00136 return false; 00137 } 00138 00139 real volume() const { 00140 if (degenerate()) return 0.0; 00141 real vol = 1; 00142 for(int i = 0; i < Vector3<real>::size; i++) 00143 vol *= mAcross[i]; 00144 return vol; 00145 } 00146 00147 Vector3<real> clamp(const Vector3<real>& v) const { 00148 return v.max(min()).min(max()); 00149 } 00150 00151 bool intersects(const BoundingBox& bbox2) const { 00152 BoundingBox bbox = BoundingBox(min().max(bbox2.min()), 00153 max().min(bbox2.max())); 00154 00155 if (bbox.min().x < bbox.max().x && 00156 bbox.min().y < bbox.max().y && 00157 bbox.min().z < bbox.max().z) 00158 { 00159 return true; 00160 } 00161 00162 return false; 00163 } 00164 00165 bool operator==(const BoundingBox& rhs) const{ 00166 return (mMin == rhs.mMin && mAcross == rhs.mAcross); 00167 } 00168 bool operator!=(const BoundingBox& rhs) const{ 00169 return (mMin != rhs.mMin || mAcross != rhs.mAcross); 00170 } 00171 00172 }; 00173 00174 template<typename scalar> 00175 inline std::ostream& operator <<(std::ostream& os, const BoundingBox<scalar> &rhs) { 00176 os << '<' << rhs.min() << ',' << rhs.max() << '>'; 00177 return os; 00178 } 00179 00180 template<typename scalar> 00181 inline std::istream& operator >>(std::istream& is, BoundingBox<scalar> &rhs) { 00182 // FIXME this should be more robust. It currently relies on the exact format provided by operator << 00183 char dummy; 00184 Vector3<scalar> minval, maxval; 00185 is >> dummy >> minval >> dummy >> maxval >> dummy; 00186 rhs = BoundingBox<scalar>(minval, maxval); 00187 return is; 00188 } 00189 00190 00191 } 00192 #endif