00001
00008
00009
00010
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
00054
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
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
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
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); }
00091 bool IfInside( const Volume& volume ) const;
00092 bool IfOutside( const Volume& volume ) const;
00093
00094 Vector3 GetPosition( void ) const { return mPosition; }
00095 void SetPosition( const Vector3& position ) { mPosition = position; }
00096
00097
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
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); }
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
00149 fp GetRadius( void ) const;
00150 bool IfOutside( const BoxVolume& other ) const;
00151 bool IfInside( const BoxVolume& other ) const;
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;
00159 bool IfZero( void ) const;
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
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
00204
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
00223
00224
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 }
00231
00232 #endif // ENG_VOLUME_HH