Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

MathUnit.h

00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright (c) 2000-2005 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #ifndef __MATHUNIT_H__
00026 #define __MATHUNIT_H__
00027 
00028 
00029 #include "Peonstdafx.h"
00030 
00031 
00032 namespace peon
00033 {
00039         class Radian
00040         {
00041                 Real mRad;
00042 
00043         public:
00044                 explicit Radian ( Real r=0 ) : mRad(r) {}
00045                 Radian ( const Degree& d );
00046                 const Radian& operator = ( const Real& f ) { mRad = f; return *this; }
00047                 const Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
00048                 const Radian& operator = ( const Degree& d );
00049 
00050                 Real valueDegrees() const; // see bottom of this file
00051                 Real valueRadians() const { return mRad; }
00052                 Real valueAngleUnits() const;
00053 
00054                 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
00055                 Radian operator + ( const Degree& d ) const;
00056                 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
00057                 Radian& operator += ( const Degree& d );
00058                 Radian operator - () { return Radian(-mRad); }
00059                 Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
00060                 Radian operator - ( const Degree& d ) const;
00061                 Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
00062                 Radian& operator -= ( const Degree& d );
00063                 Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
00064         Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
00065                 Radian& operator *= ( Real f ) { mRad *= f; return *this; }
00066                 Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
00067                 Radian& operator /= ( Real f ) { mRad /= f; return *this; }
00068 
00069                 bool operator <  ( const Radian& r ) const { return mRad <  r.mRad; }
00070                 bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; }
00071                 bool operator == ( const Radian& r ) const { return mRad == r.mRad; }
00072                 bool operator != ( const Radian& r ) const { return mRad != r.mRad; }
00073                 bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; }
00074                 bool operator >  ( const Radian& r ) const { return mRad >  r.mRad; }
00075         };
00076 
00082         class Degree
00083         {
00084                 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
00085 
00086         public:
00087                 explicit Degree ( Real d=0 ) : mDeg(d) {}
00088                 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
00089                 const Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
00090                 const Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
00091                 const Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
00092 
00093                 Real valueDegrees() const { return mDeg; }
00094                 Real valueRadians() const; // see bottom of this file
00095                 Real valueAngleUnits() const;
00096 
00097                 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
00098                 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
00099                 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
00100                 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
00101                 Degree operator - () { return Degree(-mDeg); }
00102                 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
00103                 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
00104                 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
00105                 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
00106                 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
00107         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
00108                 Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
00109                 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
00110                 Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
00111 
00112                 bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
00113                 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
00114                 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
00115                 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
00116                 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
00117                 bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
00118         };
00119 
00126         class Angle
00127         {
00128                 Real mAngle;
00129         public:
00130                 explicit Angle ( Real angle ) : mAngle(angle) {}
00131                 operator Radian();
00132                 operator Degree();
00133         };
00134 
00135         // these functions could not be defined within the class definition of class
00136         // Radian because they required class Degree to be defined
00137         inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
00138         }
00139         inline const Radian& Radian::operator = ( const Degree& d ) {
00140                 mRad = d.valueRadians(); return *this;
00141         }
00142         inline Radian Radian::operator + ( const Degree& d ) const {
00143                 return Radian ( mRad + d.valueRadians() );
00144         }
00145         inline Radian& Radian::operator += ( const Degree& d ) {
00146                 mRad += d.valueRadians();
00147                 return *this;
00148         }
00149         inline Radian Radian::operator - ( const Degree& d ) const {
00150                 return Radian ( mRad - d.valueRadians() );
00151         }
00152         inline Radian& Radian::operator -= ( const Degree& d ) {
00153                 mRad -= d.valueRadians();
00154                 return *this;
00155         }
00156 
00167     class _PeonExport MathUnit
00168     {
00169    public:
00175        enum AngleUnit
00176        {
00177            AU_DEGREE,
00178            AU_RADIAN
00179        };
00180 
00181     protected:
00182        // angle units used by the api
00183        static AngleUnit msAngleUnit;
00184 
00186         static int mTrigTableSize;
00187 
00189         static Real mTrigTableFactor;
00190         static Real* mSinTable;
00191         static Real* mTanTable;
00192 
00195         void buildTrigTables();
00196 
00197                 static Real SinTable (Real fValue);
00198                 static Real TanTable (Real fValue);
00199     public:
00205         MathUnit(unsigned int trigTableSize = 4096);
00206 
00209         ~MathUnit();
00210 
00211                 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
00212                 static inline int ICeil (float fValue) { return int(ceil(fValue)); }
00213                 static inline int IFloor (float fValue) { return int(floor(fValue)); }
00214         static int ISign (int iValue);
00215 
00216                 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
00217                 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
00218                 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
00219                 static Radian ACos (Real fValue);
00220                 static Radian ASin (Real fValue);
00221                 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
00222                 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
00223                 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
00224 
00232         static inline Real Cos (const Radian& fValue, bool useTables = false) {
00233                         return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
00234                 }
00242         static inline Real Cos (Real fValue, bool useTables = false) {
00243                         return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
00244                 }
00245 
00246                 static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
00247 
00248                 static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
00249 
00250                 static inline Real Log (Real fValue) { return Real(log(fValue)); }
00251 
00252                 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
00253 
00254         static Real Sign (Real fValue);
00255                 static inline Radian Sign ( const Radian& rValue )
00256                 {
00257                         return Radian(Sign(rValue.valueRadians()));
00258                 }
00259                 static inline Degree Sign ( const Degree& dValue )
00260                 {
00261                         return Degree(Sign(dValue.valueDegrees()));
00262                 }
00263 
00271         static inline Real Sin (const Radian& fValue, bool useTables = false) {
00272                         return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
00273                 }
00281         static inline Real Sin (Real fValue, bool useTables = false) {
00282                         return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
00283                 }
00284 
00285                 static inline Real Sqr (Real fValue) { return fValue*fValue; }
00286 
00287                 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
00288 
00289         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
00290 
00291         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
00292 
00296                 static Real InvSqrt(Real fValue);
00297 
00298         static Real UnitRandom ();  // in [0,1]
00299 
00300         static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
00301 
00302         static Real SymmetricRandom ();  // in [-1,1]
00303 
00311                 static inline Real Tan (const Radian& fValue, bool useTables = false) {
00312                         return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
00313                 }
00321                 static inline Real Tan (Real fValue, bool useTables = false) {
00322                         return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
00323                 }
00324 
00325                 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
00326         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
00327 
00334        static void setAngleUnit(AngleUnit unit);
00336        static AngleUnit getAngleUnit(void);
00337 
00339        static Real AngleUnitsToRadians(Real units);
00341        static Real RadiansToAngleUnits(Real radians);
00343        static Real AngleUnitsToDegrees(Real units);
00345        static Real DegreesToAngleUnits(Real degrees);
00346 
00376         static bool pointInTri2D( Real px, Real pz, Real ax, Real az, Real bx, Real bz, Real cx, Real cz );
00377 
00379         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
00380 
00382         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 
00383             bool discardInside = true);
00384         
00386         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& sphere);
00387 
00389         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
00390 
00392         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
00393 
00399         static std::pair<bool, Real> intersects(
00400             const Ray& ray, const std::vector<Plane>& planeList, 
00401             bool normalIsOutside);
00407         static std::pair<bool, Real> intersects(
00408             const Ray& ray, const std::list<Plane>& planeList, 
00409             bool normalIsOutside);
00410 
00414         static bool intersects(const Sphere& sphere, const Plane& plane);
00415 
00418         static bool RealEqual(Real a, Real b,
00419             Real tolerance = std::numeric_limits<Real>::epsilon());
00420 
00422         static Vector3 calculateTangentSpaceVector(
00423             const Vector3& position1, const Vector3& position2, const Vector3& position3,
00424             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
00425 
00427         static Matrix44 buildReflectionMatrix(const Plane& p);
00429         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00431         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00433         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00435         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00436 
00437         static const Real POS_INFINITY;
00438         static const Real NEG_INFINITY;
00439         static const Real PI;
00440         static const Real TWO_PI;
00441         static const Real HALF_PI;
00442                 static const Real fDeg2Rad;
00443                 static const Real fRad2Deg;
00444 
00445     };
00446 
00447         // these functions must be defined down here, because they rely on the
00448         // angle unit conversion functions in class MathUnit:
00449 
00450         inline Real Radian::valueDegrees() const
00451         {
00452                 return MathUnit::RadiansToDegrees ( mRad );
00453         }
00454 
00455         inline Real Radian::valueAngleUnits() const
00456         {
00457                 return MathUnit::RadiansToAngleUnits ( mRad );
00458         }
00459 
00460         inline Real Degree::valueRadians() const
00461         {
00462                 return MathUnit::DegreesToRadians ( mDeg );
00463         }
00464 
00465         inline Real Degree::valueAngleUnits() const
00466         {
00467                 return MathUnit::DegreesToAngleUnits ( mDeg );
00468         }
00469 
00470         inline Angle::operator Radian()
00471         {
00472                 return Radian(MathUnit::AngleUnitsToRadians(mAngle));
00473         }
00474 
00475         inline Angle::operator Degree()
00476         {
00477                 return Degree(MathUnit::AngleUnitsToDegrees(mAngle));
00478         }
00479 
00480         inline Radian operator * ( Real a, const Radian& b )
00481         {
00482                 return Radian ( a * b.valueRadians() );
00483         }
00484 
00485         inline Radian operator / ( Real a, const Radian& b )
00486         {
00487                 return Radian ( a / b.valueRadians() );
00488         }
00489 
00490         inline Degree operator * ( Real a, const Degree& b )
00491         {
00492                 return Degree ( a * b.valueDegrees() );
00493         }
00494 
00495         inline Degree operator / ( Real a, const Degree& b )
00496         {
00497                 return Degree ( a / b.valueDegrees() );
00498         }
00499 
00500 }
00501 
00502 #endif

Generated on Wed Nov 9 09:37:05 2005 for Peon by  doxygen 1.4.3