|
Blender
V2.59
|
00001 /* 00002 * $Id: SG_BBox.cpp 35175 2011-02-25 13:39:04Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * The Original Code is: all of this file. 00024 * 00025 * Contributor(s): none yet. 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * Bounding Box 00029 */ 00030 00036 #include <math.h> 00037 00038 #include "SG_BBox.h" 00039 #include "SG_Node.h" 00040 00041 SG_BBox::SG_BBox() : 00042 m_min(0., 0., 0.), 00043 m_max(0., 0., 0.) 00044 { 00045 } 00046 00047 SG_BBox::SG_BBox(const MT_Point3 &min, const MT_Point3 &max) : 00048 m_min(min), 00049 m_max(max) 00050 { 00051 } 00052 00053 SG_BBox::SG_BBox(const SG_BBox &other, const MT_Transform &world) : 00054 m_min(world(other.m_min)), 00055 m_max(world(other.m_max)) 00056 { 00057 *this += world(MT_Point3(m_min[0], m_min[1], m_max[2])); 00058 *this += world(MT_Point3(m_min[0], m_max[1], m_min[2])); 00059 *this += world(MT_Point3(m_min[0], m_max[1], m_max[2])); 00060 *this += world(MT_Point3(m_max[0], m_min[1], m_min[2])); 00061 *this += world(MT_Point3(m_max[0], m_min[1], m_max[2])); 00062 *this += world(MT_Point3(m_max[0], m_max[1], m_min[2])); 00063 } 00064 00065 SG_BBox::SG_BBox(const SG_BBox &other) : 00066 m_min(other.m_min), 00067 m_max(other.m_max) 00068 { 00069 } 00070 00071 SG_BBox::~ SG_BBox() 00072 { 00073 } 00074 00075 SG_BBox& SG_BBox::operator +=(const MT_Point3 &point) 00076 { 00077 if (point[0] < m_min[0]) 00078 m_min[0] = point[0]; 00079 else if (point[0] > m_max[0]) 00080 m_max[0] = point[0]; 00081 00082 if (point[1] < m_min[1]) 00083 m_min[1] = point[1]; 00084 else if (point[1] > m_max[1]) 00085 m_max[1] = point[1]; 00086 00087 if (point[2] < m_min[2]) 00088 m_min[2] = point[2]; 00089 else if (point[2] > m_max[2]) 00090 m_max[2] = point[2]; 00091 00092 return *this; 00093 } 00094 00095 SG_BBox& SG_BBox::operator += (const SG_BBox &bbox) 00096 { 00097 *this += bbox.m_min; 00098 *this += bbox.m_max; 00099 00100 return *this; 00101 } 00102 00103 SG_BBox SG_BBox::operator +(const SG_BBox &bbox2) const 00104 { 00105 SG_BBox ret = *this; 00106 ret += bbox2; 00107 return ret; 00108 } 00109 00110 MT_Scalar SG_BBox::volume() const 00111 { 00112 MT_Vector3 size = m_max - m_min; 00113 return size[0]*size[1]*size[2]; 00114 } 00115 #if 0 00116 void SG_BBox::translate(const MT_Vector3& dx) 00117 { 00118 m_min += dx; 00119 m_max += dx; 00120 } 00121 00122 void SG_BBox::scale(const MT_Vector3& size, const MT_Point3& point) 00123 { 00124 MT_Vector3 center = (m_max - m_min)/2. + point; 00125 m_max = (m_max - center)*size; 00126 m_min = (m_min - center)*size; 00127 } 00128 #endif 00129 00130 SG_BBox SG_BBox::transform(const MT_Transform &world) const 00131 { 00132 SG_BBox bbox(world(m_min), world(m_max)); 00133 bbox += world(MT_Point3(m_min[0], m_min[1], m_max[2])); 00134 bbox += world(MT_Point3(m_min[0], m_max[1], m_min[2])); 00135 bbox += world(MT_Point3(m_min[0], m_max[1], m_max[2])); 00136 bbox += world(MT_Point3(m_max[0], m_min[1], m_min[2])); 00137 bbox += world(MT_Point3(m_max[0], m_min[1], m_max[2])); 00138 bbox += world(MT_Point3(m_max[0], m_max[1], m_min[2])); 00139 return bbox; 00140 } 00141 00142 bool SG_BBox::inside(const MT_Point3 &point) const 00143 { 00144 return point[0] >= m_min[0] && point[0] <= m_max[0] && 00145 point[1] >= m_min[1] && point[1] <= m_max[1] && 00146 point[2] >= m_min[2] && point[2] <= m_max[2]; 00147 } 00148 00149 bool SG_BBox::inside(const SG_BBox& other) const 00150 { 00151 return inside(other.m_min) && inside(other.m_max); 00152 } 00153 00154 bool SG_BBox::intersects(const SG_BBox& other) const 00155 { 00156 return inside(other.m_min) != inside(other.m_max); 00157 } 00158 00159 bool SG_BBox::outside(const SG_BBox& other) const 00160 { 00161 return !inside(other.m_min) && !inside(other.m_max); 00162 } 00163 00164 SG_BBox::intersect SG_BBox::test(const SG_BBox& other) const 00165 { 00166 bool point1(inside(other.m_min)), point2(inside(other.m_max)); 00167 00168 return point1?(point2?INSIDE:INTERSECT):(point2?INTERSECT:OUTSIDE); 00169 } 00170 00171 void SG_BBox::get(MT_Point3 *box, const MT_Transform &world) const 00172 { 00173 *box++ = world(m_min); 00174 *box++ = world(MT_Point3(m_min[0], m_min[1], m_max[2])); 00175 *box++ = world(MT_Point3(m_min[0], m_max[1], m_min[2])); 00176 *box++ = world(MT_Point3(m_min[0], m_max[1], m_max[2])); 00177 *box++ = world(MT_Point3(m_max[0], m_min[1], m_min[2])); 00178 *box++ = world(MT_Point3(m_max[0], m_min[1], m_max[2])); 00179 *box++ = world(MT_Point3(m_max[0], m_max[1], m_min[2])); 00180 *box++ = world(m_max); 00181 } 00182 00183 void SG_BBox::getaa(MT_Point3 *box, const MT_Transform &world) const 00184 { 00185 const MT_Point3 min(world(m_min)), max(world(m_max)); 00186 *box++ = min; 00187 *box++ = MT_Point3(min[0], min[1], max[2]); 00188 *box++ = MT_Point3(min[0], max[1], min[2]); 00189 *box++ = MT_Point3(min[0], max[1], max[2]); 00190 *box++ = MT_Point3(max[0], min[1], min[2]); 00191 *box++ = MT_Point3(max[0], min[1], max[2]); 00192 *box++ = MT_Point3(max[0], max[1], min[2]); 00193 *box++ = max; 00194 } 00195 00196 void SG_BBox::getmm(MT_Point3 *box, const MT_Transform &world) const 00197 { 00198 const MT_Point3 min(world(m_min)), max(world(m_max)); 00199 *box++ = min; 00200 *box++ = max; 00201 } 00202 00203 void SG_BBox::split(SG_BBox &left, SG_BBox &right) const 00204 { 00205 MT_Scalar sizex = m_max[0] - m_min[0]; 00206 MT_Scalar sizey = m_max[1] - m_min[1]; 00207 MT_Scalar sizez = m_max[2] - m_min[2]; 00208 if (sizex < sizey) 00209 { 00210 if (sizey > sizez) 00211 { 00212 left.m_min = m_min; 00213 left.m_max[0] = m_max[0]; 00214 left.m_max[1] = m_min[1] + sizey/2.0; 00215 left.m_max[2] = m_max[2]; 00216 00217 right.m_min[0] = m_min[0]; 00218 right.m_min[1] = m_min[1] + sizey/2.0; 00219 right.m_min[2] = m_min[2]; 00220 right.m_max = m_max; 00221 std::cout << "splity" << std::endl; 00222 } else { 00223 left.m_min = m_min; 00224 left.m_max[0] = m_max[0]; 00225 left.m_max[1] = m_max[1]; 00226 left.m_max[2] = m_min[2] + sizez/2.0; 00227 00228 right.m_min[0] = m_min[0]; 00229 right.m_min[1] = m_min[1]; 00230 right.m_min[2] = m_min[2] + sizez/2.0; 00231 right.m_max = m_max; 00232 std::cout << "splitz" << std::endl; 00233 } 00234 } else { 00235 if (sizex > sizez) 00236 { 00237 left.m_min = m_min; 00238 left.m_max[0] = m_min[0] + sizex/2.0; 00239 left.m_max[1] = m_max[1]; 00240 left.m_max[2] = m_max[2]; 00241 00242 right.m_min[0] = m_min[0] + sizex/2.0; 00243 right.m_min[1] = m_min[1]; 00244 right.m_min[2] = m_min[2]; 00245 right.m_max = m_max; 00246 std::cout << "splitx" << std::endl; 00247 } else { 00248 left.m_min = m_min; 00249 left.m_max[0] = m_max[0]; 00250 left.m_max[1] = m_max[1]; 00251 left.m_max[2] = m_min[2] + sizez/2.0; 00252 00253 right.m_min[0] = m_min[0]; 00254 right.m_min[1] = m_min[1]; 00255 right.m_min[2] = m_min[2] + sizez/2.0; 00256 right.m_max = m_max; 00257 std::cout << "splitz" << std::endl; 00258 } 00259 } 00260 00261 //std::cout << "Left: " << left.m_min << " -> " << left.m_max << " Right: " << right.m_min << " -> " << right.m_max << std::endl; 00262 }