eng_volume.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 #ifndef ENG_VOLUME_HH
00014 #define ENG_VOLUME_HH 1
00015 
00016 namespace eng {
00017 
00018 class SphereVolume;
00019 class BoxVolume;
00020 
00047 class Volume : public Shared
00048 {
00049 public:
00050                             Volume( void ) { }
00051     virtual                 ~Volume() { }
00052 
00053 // Abstract methods:
00054 // Space-neutral Vector3 is used, not WorldVertex nor LocalVertex.
00055     virtual SphereVolume    ToSphereVolume( void ) const = 0;
00056     virtual BoxVolume       ToBoxVolume( void ) const = 0;
00057     virtual bool            IfInside( const Vector3& v ) const = 0;
00058     virtual bool            IfInside( const Volume& volume ) const = 0;  
00059     virtual bool            IfOutside( const Volume& volume ) const = 0;  
00060     virtual Vector3         GetPosition( void ) const = 0;
00061     virtual void            SetPosition( const Vector3& position ) = 0;
00062 
00063 // Virtual default methods:
00064     virtual bool IfOutside( const Vector3& v ) const
00065     {
00066         return not IfInside(v);
00067     }
00068 
00070     virtual bool IfIntersecting( const Volume& volume ) const
00071     {
00072         // Logical, inefficient, infrequent.
00073         return (not IfInside(volume)) && (not IfOutside(volume));
00074     }
00075 };
00076 
00080 class SphereVolume : public Volume
00081 {
00082 public:
00083                     SphereVolume( const Vector3& position, const fp radius );
00084                     ~SphereVolume();
00085 
00086 // Implement abstract methods:
00087     SphereVolume    ToSphereVolume( void ) const { return *this; }
00088     BoxVolume       ToBoxVolume( void ) const;
00089     bool            IfInside( const Vector3& v ) const;
00090     bool            IfOutside( const Vector3& v ) const { return not IfInside(v); }  // fix compile
00091     bool            IfInside( const Volume& volume ) const;
00092     bool            IfOutside( const Volume& volume ) const;
00093   //bool            IfIntersecting( const Volume& volume ) const;  // default
00094     Vector3         GetPosition( void ) const { return mPosition; }
00095     void            SetPosition( const Vector3& position ) { mPosition = position; }
00096 
00097 // Specific methods:
00098     bool            IfInside( const SphereVolume& volume ) const;
00099     bool            IfOutside( const SphereVolume& volume ) const;
00100     fp              GetRadius( void ) const { return mRadius; }
00101     void            Grow( const Vector3& v );
00102     friend bool inline operator==( const SphereVolume& a, const SphereVolume& b )
00103     {
00104         return (a.mPosition == b.mPosition) && (a.mRadius == b.mRadius);
00105     }
00106     friend bool inline operator!=( const SphereVolume& a, const SphereVolume& b )
00107     {
00108         return not (a == b);
00109     }
00110 #if DEBUG
00111 bool Check( void ) const;
00112 #endif
00113 
00114 private:
00115     Vector3     mPosition;
00116     fp          mRadius;
00117 };
00118 
00119 ostream& operator<<( ostream& strm, const SphereVolume& sphereVolume );
00120 
00129 class BoxVolume : public Volume
00130 {
00131 public:
00132                     BoxVolume( void );
00133                     BoxVolume( const Vector3& minimum, const Vector3& maximum );
00134                     BoxVolume( const SphereVolume& sphereVolume );
00135                     ~BoxVolume();
00136 
00137 // Implement abstract methods:
00138     SphereVolume    ToSphereVolume( void ) const;
00139     BoxVolume       ToBoxVolume( void ) const { return BoxVolume(*this); }
00140     bool            IfInside( const Vector3& v ) const;
00141     bool            IfOutside( const Vector3& v ) const { return not IfInside(v); }  // fix compile
00142     bool            IfInside( const Volume& volume ) const;
00143     bool            IfOutside( const Volume& volume ) const;
00144     bool            IfIntersecting( const Volume& volume ) const;
00145     Vector3         GetPosition( void ) const;
00146     void            SetPosition( const Vector3& position );
00147 
00148 // Specific methods:
00149     fp              GetRadius( void ) const;
00150     bool            IfOutside( const BoxVolume& other ) const;
00151     bool            IfInside( const BoxVolume& other ) const;  // BoxVolume arg
00152     bool            IfIntersecting( const BoxVolume& other ) const;
00153     void            Set( const Vector3& v1, const Vector3& v2 );
00154     void            Grow( const Vector3& v );
00155     void            Grow( const BoxVolume& other );
00156     Vector3         GetCenter( void ) const;
00157     Vector3         GetMidOffset( void ) const;
00158     bool            IfEmpty( void ) const;  // if volume is empty
00159     bool            IfZero( void ) const;   // if equals (0,0,0,0,0,0)
00160     bool            IfCube( void ) const;
00161     friend bool inline operator==( const BoxVolume& a, const BoxVolume& b )
00162     {
00163         return (a.mMin == b.mMin)
00164             && (a.mMax == b.mMax);
00165     }
00166     friend bool inline operator!=( const BoxVolume& a, const BoxVolume& b )
00167     {
00168         return not (a == b);
00169     }
00170 
00171 #if DEBUG
00172 bool Check( void ) const;
00173 #endif
00174 
00175 public:
00176     Vector3     mMin;
00177     Vector3     mMax;
00178 };
00179 
00180 ostream& operator<<( ostream& strm, const BoxVolume& boxVolume );
00181 
00187 class BSPVolume : private Volume
00188 {
00189 #if 0 // FUTURE
00190 public:
00191                     BSPVolume( SharedPtr<BSP> bsp );
00192                     ~BSPVolume();
00193 
00194 // Implement abstract methods:
00195     SphereVolume    ToSphereVolume( void ) const;
00196     BoxVolume       ToBoxVolume( void ) const;
00197     bool            IfInside( const Vector3& v ) const;
00198     bool            IfInside( const Volume& volume ) const;
00199     bool            IfOutside( const Volume& volume ) const;
00200     Vector3         GetPosition( void ) const;
00201     void            SetPosition( const Vector3& position );
00202 
00203 // Cloning a BSPVolume will be cheap since root is a SharedPtr.
00204 // All that's needed is to translate position to make it per-Object.
00205 
00206 private:
00207     Vector3         mPosition;
00208     SharedPtr<Node>     mRoot;
00209 #endif // FUTURE
00210 };
00211 
00215 
00219 INLINE fp
00220 ApproxRadiusOfBox( const fp x_width, const fp y_width, const fp z_width )
00221 {
00222     // (w/2,w/2,w/2) defines a corner of an expanded box (relative to center).
00223     // (1,1,1) = sqrt(1+1+1) = 1.732051.
00224     // approxRadius = maxWidth * 1.732051.
00225 
00226     const fp maxWidth = Max( x_width, Max(y_width,z_width) );
00227     return maxWidth * 0.5 * eng::defs::BOX_WIDTH_TO_RADIUS_SCALE;
00228 }
00229 
00230 } // namespace eng
00231 
00232 #endif // ENG_VOLUME_HH
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:09 2007