00001 /* 00002 SagaEngine library 00003 Copyright (c) 2002-2006 Skalden Studio AS 00004 00005 This software is provided 'as-is', without any express or implied 00006 warranty. In no event will the authors be held liable for any 00007 damages arising from the use of this software. 00008 00009 Permission is granted to distribute the library under the terms of the 00010 Q Public License version 1.0. Be sure to read and understand the license 00011 before using the library. It should be included here, or you may read it 00012 at http://www.trolltech.com/products/qt/licenses/licensing/qpl 00013 00014 The original version of this library can be located at: 00015 http://www.sagaengine.com/ 00016 00017 Rune Myrland 00018 rune@skalden.com 00019 */ 00020 00021 00022 #ifndef util_bounds_BoundingBox_hpp 00023 #define util_bounds_BoundingBox_hpp 00024 00025 #include "../type/util_type.hpp" 00026 #include "../vecmath/Point3.hpp" 00027 #include "util/error/Log.hpp" 00028 00029 00030 namespace se_core { 00031 class _SeCoreExport BoundingBox { 00032 public: 00033 BoundingBox() : minX_(0), minY_(0), minZ_(0), maxX_(0), maxY_(0), maxZ_(0) {} 00034 00035 BoundingBox(const Point3& p, coor_t radius) 00036 : minX_(p.x_ - radius), minY_(p.y_ - radius), minZ_(p.z_ - radius) 00037 , maxX_(p.x_ + radius), maxY_(p.y_ + radius), maxZ_(p.z_ + radius) { 00038 } 00039 00040 BoundingBox(const Point3& p, coor_t radius, coor_t height) 00041 : minX_(p.x_ - radius), minY_(p.y_), minZ_(p.z_ - radius) 00042 , maxX_(p.x_ + radius), maxY_(p.y_ + height), maxZ_(p.z_ + radius) { 00043 } 00044 00045 BoundingBox(const Point3& p, const BoundingBox& b) 00046 : minX_(p.x_ + b.minX_), minY_(p.y_ + b.minY_), minZ_(p.z_ + b.minZ_) 00047 , maxX_(p.x_ + b.maxX_), maxY_(p.y_ + b.maxY_), maxZ_(p.z_ + b.maxZ_) { 00048 } 00049 00050 void reset() { 00051 minX_ = minY_ = minZ_ = 0; 00052 maxX_ = maxY_ = maxZ_ = 0; 00053 } 00054 00055 inline void setMin(coor_t x, coor_t y, coor_t z) { 00056 minX_ = x; 00057 minY_ = y; 00058 minZ_ = z; 00059 } 00060 00061 00062 inline void setMax(coor_t x, coor_t y, coor_t z) { 00063 maxX_ = x; 00064 maxY_ = y; 00065 maxZ_ = z; 00066 } 00067 00068 00069 bool isNull() const { 00070 return (minX_ == maxX_ && minY_ == maxY_ && minZ_ == maxZ_); 00071 } 00072 00073 00074 void merge(BoundingBox &b) { 00075 /* 00076 if(isNull()) { 00077 *this = b; 00078 return; 00079 } 00080 */ 00081 00082 if(b.minX_ < minX_) minX_ = b.minX_; 00083 if(b.minY_ < minY_) minY_ = b.minY_; 00084 if(b.minZ_ < minZ_) minZ_ = b.minZ_; 00085 00086 if(b.maxX_ > maxX_) maxX_ = b.maxX_; 00087 if(b.maxY_ > maxY_) maxY_ = b.maxY_; 00088 if(b.maxZ_ > maxZ_) maxZ_ = b.maxZ_; 00089 } 00090 00091 00092 bool hasInside(coor_t x, coor_t y, coor_t z) const { 00093 return (x >= minX_ && x < maxX_ 00094 && y >= minY_ && y < maxY_ 00095 && z >= minZ_ && z < maxZ_); 00096 } 00097 00098 00099 bool hasInside(const Point3& p) const { 00100 return (p.x_ >= minX_ && p.x_ < maxX_ 00101 && p.y_ >= minY_ && p.y_ < maxY_ 00102 && p.z_ >= minZ_ && p.z_ < maxZ_); 00103 } 00104 00105 bool isTouching(const Point3& p) const { 00106 return (p.x_ >= minX_ && p.x_ <= maxX_ 00107 && p.y_ >= minY_ && p.y_ <= maxY_ 00108 && p.z_ >= minZ_ && p.z_ <= maxZ_); 00109 } 00110 00111 00112 bool isTouching(const Point3& p, coor_t epsilon) const { 00113 return (p.x_ >= minX_ - epsilon && p.x_ <= maxX_ + epsilon 00114 && p.y_ >= minY_ - epsilon && p.y_ <= maxY_ + epsilon 00115 && p.z_ >= minZ_ - epsilon && p.z_ <= maxZ_ + epsilon); 00116 } 00117 00118 00119 00120 bool isTouchingXZ(const Point3& p) const { 00121 return (p.x_ >= minX_ && p.x_ <= maxX_ 00122 && p.z_ >= minZ_ && p.z_ <= maxZ_); 00123 } 00124 00125 00126 bool hasInside(const Point3& offset, const Point3& p) const { 00127 return (p.x_ >= offset.x_ + minX_ && p.x_ < offset.x_ + maxX_ 00128 && p.y_ >= offset.y_ + minY_ && p.y_ < offset.y_ + maxY_ 00129 && p.z_ >= offset.z_ + minZ_ && p.z_ < offset.z_ + maxZ_); 00130 } 00131 00132 00133 void center(Point3& out) const { 00134 out.x_ = CoorT::half(minX_ + maxX_); 00135 out.y_ = CoorT::half(minY_ + maxY_); 00136 out.z_ = CoorT::half(minZ_ + maxZ_); 00137 } 00138 00139 00140 bool isTouching(const BoundingBox& b) const { 00141 if(b.maxX_ < minX_ 00142 || b.minX_ > maxX_ 00143 || maxX_ < b.minX_ 00144 || minX_ > b.maxX_) 00145 return false; 00146 00147 if(b.maxY_ < minY_ 00148 || b.minY_ > maxY_ 00149 || maxY_ < b.minY_ 00150 || minY_ > b.maxY_) 00151 return false; 00152 00153 if(b.maxZ_ < minZ_ 00154 || b.minZ_ > maxZ_ 00155 || maxZ_ < b.minZ_ 00156 || minZ_ > b.maxZ_) 00157 return false; 00158 return true; 00159 } 00160 00161 coor_t radius() const { 00162 return (maxX_ - minX_ > maxZ_ - minZ_) ? CoorT::half(maxX_ - minX_) : CoorT::half(maxZ_ - minZ_); 00163 } 00164 00165 coor_t smallRadius() const { 00166 return (maxX_ - minX_ < maxZ_ - minZ_) ? CoorT::half(maxX_ - minX_) : CoorT::half(maxZ_ - minZ_); 00167 } 00168 00169 coor_t minX_, minY_, minZ_; 00170 coor_t maxX_, maxY_, maxZ_; 00171 }; 00172 00173 se_err::Log& operator<< (se_err::Log& log, const BoundingBox& b); 00174 00175 } 00176 00177 #endif
Home Page | SagaEngine trunk (updated nightly) reference generated Sun Dec 2 20:06:12 2007 by Doxygen version 1.3.9.1.