inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_box3f 00005 #define inlib_box3f 00006 00007 #include "vec3f" 00008 #include "mnmx" 00009 00010 #include <cfloat> // FLT_MAX 00011 #include <ostream> 00012 00013 namespace inlib { 00014 00015 class box3f { 00016 public: 00017 box3f(){ 00018 make_empty(); 00019 } 00020 virtual ~box3f() {} 00021 public: 00022 box3f(const box3f& a_from) 00023 :m_min(a_from.m_min) 00024 ,m_max(a_from.m_max) 00025 {} 00026 box3f& operator=(const box3f& a_from){ 00027 m_min = a_from.m_min; 00028 m_max = a_from.m_max; 00029 return *this; 00030 } 00031 public: 00032 bool center(vec3f& a_center) const { 00033 if(is_empty()) { 00034 a_center.set_value(0,0,0); //?? 00035 return false; 00036 } 00037 a_center.set_value((m_max[0] + m_min[0]) * 0.5f, 00038 (m_max[1] + m_min[1]) * 0.5f, 00039 (m_max[2] + m_min[2]) * 0.5f); 00040 return true; 00041 } 00042 00043 bool set_bounds(const vec3f& a_mn,const vec3f& a_mx){ 00044 if( a_mn[0]>a_mx[0] || 00045 a_mn[1]>a_mx[1] || 00046 a_mn[2]>a_mx[2]) return false; 00047 m_min = a_mn; 00048 m_max = a_mx; 00049 return true; 00050 } 00051 bool set_bounds(float a_mn_x,float a_mn_y,float a_mn_z, 00052 float a_mx_x,float a_mx_y,float a_mx_z){ 00053 if( a_mn_x>a_mx_x || 00054 a_mn_y>a_mx_y || 00055 a_mn_z>a_mx_z ) return false; 00056 m_min.set_value(a_mn_x,a_mn_y,a_mn_z); 00057 m_max.set_value(a_mx_x,a_mx_y,a_mx_z); 00058 return true; 00059 } 00060 void make_empty(){ 00061 m_min.set_value(FLT_MAX, FLT_MAX, FLT_MAX); 00062 m_max.set_value(-FLT_MAX, -FLT_MAX, -FLT_MAX); 00063 } 00064 bool get_size(float& a_dx,float& a_dy,float& a_dz) const { 00065 if(is_empty()) { 00066 a_dx = 0; 00067 a_dy = 0; 00068 a_dz = 0; 00069 return false; 00070 } 00071 a_dx = m_max[0] - m_min[0]; 00072 a_dy = m_max[1] - m_min[1]; 00073 a_dz = m_max[2] - m_min[2]; 00074 return true; 00075 } 00076 bool is_empty() const { 00077 return m_max[0] < m_min[0]; 00078 } 00079 const vec3f& mn() const {return m_min;} 00080 const vec3f& mx() const {return m_max;} 00081 00082 void extend_by(const vec3f& a_point) { 00083 // Extend the boundaries of the box by the given point, i.e. make the 00084 // point fit inside the box if it isn't already so. 00085 if(is_empty()) { 00086 set_bounds(a_point,a_point); 00087 } else { 00088 m_min.set_value(inlib::mn<float>(a_point[0],m_min[0]), 00089 inlib::mn<float>(a_point[1],m_min[1]), 00090 inlib::mn<float>(a_point[2],m_min[2])); 00091 m_max.set_value(inlib::mx<float>(a_point[0],m_max[0]), 00092 inlib::mx<float>(a_point[1],m_max[1]), 00093 inlib::mx<float>(a_point[2],m_max[2])); 00094 } 00095 } 00096 00097 void extend_by(float a_x,float a_y,float a_z) { 00098 // Extend the boundaries of the box by the given point, i.e. make the 00099 // point fit inside the box if it isn't already so. 00100 if(is_empty()) { 00101 set_bounds(a_x,a_y,a_z,a_x,a_y,a_z); 00102 } else { 00103 m_min.set_value(inlib::mn<float>(a_x,m_min[0]), 00104 inlib::mn<float>(a_y,m_min[1]), 00105 inlib::mn<float>(a_z,m_min[2])); 00106 m_max.set_value(inlib::mx<float>(a_x,m_max[0]), 00107 inlib::mx<float>(a_y,m_max[1]), 00108 inlib::mx<float>(a_z,m_max[2])); 00109 } 00110 } 00111 00112 //NOTE : print is a Python keyword. 00113 void dump(std::ostream& a_out) { 00114 float dx,dy,dz; 00115 if(!get_size(dx,dy,dz)) { 00116 a_out << "box is empty." << std::endl; 00117 } else { 00118 a_out << " size " << dx << " " << dy << " " << dz << std::endl; 00119 } 00120 a_out << " min " << m_min[0] << " " << m_min[1] << " " << m_min[2] << std::endl; 00121 a_out << " max " << m_max[0] << " " << m_max[1] << " " << m_max[2] << std::endl; 00122 vec3f c; 00123 center(c); 00124 a_out << " center " << c[0] << " " << c[1] << " " << c[2] << std::endl; 00125 } 00126 00127 private: 00128 vec3f m_min; 00129 vec3f m_max; 00130 }; 00131 00132 } 00133 00134 #endif