vee_bounding_box.h

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 
00003 /* COPYRIGHT
00004  *
00005  * This file is part of the Visual Effects Engine - VEE
00006  *
00007  * Read the "VEE-LICENSE" file for the license.
00008  *
00009  * Authors & Copyright:   
00010  *
00011  * Tommi Ilmonen, Tuukka Heikura, Marko Myllymaa and 
00012  * Janne Kontkanen 2001-2004
00013  *
00014  * Additional copyrights: Tekes 2003-2004
00015  *
00016  * firstname.lastname@hut.fi
00017  *
00018  */
00019 
00020 #ifndef VEE_BOUNDING_BOX_H
00021 #define VEE_BOUNDING_BOX_H
00022 
00023 #include <vee_vector3.h>
00024 #include <vee_matrix4.h>
00025 
00026 class VEE_BoundingBox
00027 {
00028 public:
00029   VEE_BoundingBox() {}
00030   VEE_BoundingBox(const VEE_Vector3 * lowHigh) 
00031     : m_low(*lowHigh), m_high(*lowHigh) {}
00032   VEE_BoundingBox(const VEE_Vector3 & low, const VEE_Vector3 & high) 
00033     : m_low(low), m_high(high) {}
00034   ~VEE_BoundingBox() {}
00035 
00036   void scale(float v) { m_low = m_low * v; m_high = m_high * v; }
00037   inline void scale(const VEE_Vector3 &v);
00038   void move(const VEE_Vector3 &v) { m_low += v; m_high += v; }
00039 
00040   void clear() { m_low = m_high = VEE_Vector3ZERO; }
00041   void clear(const VEE_Vector3 &v) { m_low = m_high = v; }
00042 
00043   inline void expand(const VEE_Vector3 &v);
00044   inline void expand(const VEE_Vector3 &v, float radius);
00045   inline void expand(const VEE_BoundingBox &b);
00046 
00047   VEE_Vector3 & low() { return m_low; }
00048   const VEE_Vector3 & low() const { return m_low; }
00049   VEE_Vector3 & high() { return m_high; }
00050   const VEE_Vector3 & high() const { return m_high; }
00051 
00052   void set(float lx, float ly, float lz, float hx, float hy, float hz)
00053   { m_low.make(lx, ly, lz); m_high.make(hx, hy, hz); }
00054 
00055   void set(const VEE_Vector3 &low, const VEE_Vector3 &high)
00056   { m_low = low; m_high = high; }
00057 
00058   void set(const VEE_Vector3 * begin, const VEE_Vector3 *end)
00059   { set(*begin); while(begin != end) expand(*begin++);  }
00060 
00061   void set(const VEE_Vector3 &point)
00062   { m_low = m_high = point; }
00063 
00064   void set(const VEE_Vector3 &point, float radius)
00065   { m_low = point - radius; m_high = point + radius; }
00066   
00067   inline VEE_Vector3 center() const { return (m_low + m_high) * 0.5f; }
00068   inline float centerX() const { return (m_low.x + m_high.x) * 0.5f; }
00069   inline float centerY() const { return (m_low.y + m_high.y) * 0.5f; }
00070   inline float centerZ() const { return (m_low.z + m_high.z) * 0.5f; }
00071   inline VEE_Vector3 span() const { return m_high - m_low; }
00072   inline VEE_Vector3 topCenter() const;
00073 
00074   inline bool intersects(const VEE_BoundingBox &) const;
00075   inline bool contains(const VEE_Vector3 &) const;
00076   inline bool contains(const VEE_BoundingBox &b) const;
00077   
00078   inline VEE_Vector3 clamp(const VEE_Vector3 &) const;
00079   inline float axisDistance(const VEE_Vector3 &) const;
00080   
00081 protected:
00082   VEE_Vector3 m_low, m_high;
00083 };
00084 
00085 inline void VEE_BoundingBox::expand(const VEE_Vector3 &v)
00086 {
00087   if(v[0] < m_low[0]) m_low[0] = v[0];
00088   if(v[1] < m_low[1]) m_low[1] = v[1];
00089   if(v[2] < m_low[2]) m_low[2] = v[2];
00090 
00091   if(v[0] > m_high[0]) m_high[0] = v[0];
00092   if(v[1] > m_high[1]) m_high[1] = v[1];
00093   if(v[2] > m_high[2]) m_high[2] = v[2];
00094 }
00095 
00096 inline void VEE_BoundingBox::expand(const VEE_Vector3 &v, float radius)
00097 {
00098   expand(v - VEE_Vector3(radius));
00099   expand(v + VEE_Vector3(radius));
00100 }
00101 
00102 inline void VEE_BoundingBox::expand(const VEE_BoundingBox &b)
00103 {
00104   if(b.m_low[0] < m_low[0]) m_low[0] = b.m_low[0];
00105   if(b.m_low[1] < m_low[1]) m_low[1] = b.m_low[1];
00106   if(b.m_low[2] < m_low[2]) m_low[2] = b.m_low[2];
00107 
00108   if(b.m_high[0] > m_high[0]) m_high[0] = b.m_high[0];
00109   if(b.m_high[1] > m_high[1]) m_high[1] = b.m_high[1];
00110   if(b.m_high[2] > m_high[2]) m_high[2] = b.m_high[2];
00111 }
00112 
00113 void VEE_BoundingBox::scale(const VEE_Vector3 &v)
00114 {
00115   m_low[0] *= v[0];
00116   m_low[1] *= v[1];
00117   m_low[2] *= v[2];
00118 
00119   m_high[0] *= v[0];
00120   m_high[1] *= v[1];
00121   m_high[2] *= v[2];
00122 }
00123 
00124 VEE_Vector3 VEE_BoundingBox::topCenter() const
00125 { 
00126   return VEE_Vector3((m_low.x + m_high.x) * 0.5,
00127          m_high.y,
00128          (m_low.z + m_high.z) * 0.5);
00129 }
00130 
00131 bool VEE_BoundingBox::intersects(const VEE_BoundingBox &b) const
00132 {
00133   for(int i=0; i < 3; i++) {
00134     if(b.m_high[i] < m_low[i] || b.m_low[i] > m_high[i])
00135       return false;
00136   }
00137 
00138   return true;
00139 }
00140 
00141 inline bool VEE_BoundingBox::contains(const VEE_Vector3 &v) const
00142 {
00143   return ((v[0] >= m_low[0]) && (v[0] <= m_high[0]) &&
00144     (v[1] >= m_low[1]) && (v[1] <= m_high[1]) && 
00145     (v[2] >= m_low[2]) && (v[2] <= m_high[2]));  
00146 }
00147 
00148 inline bool VEE_BoundingBox::contains(const VEE_BoundingBox &b) const
00149 {
00150   return ((b.m_low[0] >= m_low[0]) && (b.m_high[0] <= m_high[0]) &&
00151     (b.m_low[1] >= m_low[1]) && (b.m_high[1] <= m_high[1]) && 
00152     (b.m_low[2] >= m_low[2]) && (b.m_high[2] <= m_high[2]));
00153 }
00154 
00155 inline VEE_Vector3 VEE_BoundingBox::clamp(const VEE_Vector3 &v) const
00156 {
00157   int i;
00158   VEE_Vector3 r(v);
00159 
00160   for(i=0; i < 3; i++)
00161     if(r[i] < m_low[i]) r[i] = m_low[i];
00162 
00163   for(i=0; i < 3; i++)
00164     if(r[i] > m_high[i]) r[i] = m_high[i];
00165 
00166   return r;
00167 }
00168 
00169 inline float VEE_BoundingBox::axisDistance(const VEE_Vector3 &l) const
00170 {
00171   VEE_Vector3 d;
00172 
00173   for(int i = 0; i < 3; i++) {
00174     if(l[i] > m_high[i])
00175       d[i] = l[i] - m_high[i];
00176     else if(l[i] < m_low[i])
00177       d[i] = m_low[i] - l[i];
00178     else
00179       d[i] = 0.0f;
00180   }
00181 
00182   return d.maximum();
00183 }
00184 
00185 
00188 template <class M>
00189 inline VEE_BoundingBox operator * (const M &m, const VEE_BoundingBox &b)
00190 {
00191   VEE_Vector3 tmp, low = b.low(), high = b.high();
00192 
00193   VEE_BoundingBox box;
00194   box.set(m * low);
00195   
00196   for(uint x = 0; x < 2; x++) {
00197     for(uint y = 0; y < 2; y++) {
00198       for(uint z = 0; z < 2; z++) {
00199   tmp.x = x ? low.x : high.x;
00200   tmp.y = y ? low.y : high.y;
00201   tmp.z = z ? low.z : high.z;
00202 
00203   box.expand(m * tmp);
00204   
00205       }
00206     }
00207   }
00208 
00209   return box;
00210 }
00211 
00212 #endif
00213 

Generated on Mon Mar 12 21:09:00 2007 for VEE - The Visual Effects Engine by  doxygen 1.4.6