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