# OgreMath.h

Go to the documentation of this file.

    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 __Math_H__
    00026 #define __Math_H__
    00027
    00028 #include "OgrePrerequisites.h"
    00029
    00030 namespace Ogre
    00031 {
    00037     class Radian
    00038     {
    00039         Real mRad;
    00040
    00041     public:
    00042         explicit Radian ( Real r=0 ) : mRad(r) {}
    00043         Radian ( const Degree& d );
    00044         const Radian& operator = ( const Real& f ) { mRad = f; return *this; }
    00045         const Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
    00046         const Radian& operator = ( const Degree& d );
    00047
    00048         Real valueDegrees() const; // see bottom of this file
    00049         Real valueRadians() const { return mRad; }
    00050         Real valueAngleUnits() const;
    00051
    00052         Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
    00053         Radian operator + ( const Degree& d ) const;
    00054         Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
    00055         Radian& operator += ( const Degree& d );
    00056         Radian operator - () { return Radian(-mRad); }
    00057         Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
    00058         Radian operator - ( const Degree& d ) const;
    00059         Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
    00060         Radian& operator -= ( const Degree& d );
    00061         Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
    00062         Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
    00063         Radian& operator *= ( Real f ) { mRad *= f; return *this; }
    00064         Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
    00065         Radian& operator /= ( Real f ) { mRad /= f; return *this; }
    00066
    00067         bool operator <  ( const Radian& r ) const { return mRad <  r.mRad; }
    00068         bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; }
    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     };
    00074
    00080     class Degree
    00081     {
    00082         Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
    00083
    00084     public:
    00085         explicit Degree ( Real d=0 ) : mDeg(d) {}
    00086         Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
    00087         const Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
    00088         const Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
    00089         const Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
    00090
    00091         Real valueDegrees() const { return mDeg; }
    00092         Real valueRadians() const; // see bottom of this file
    00093         Real valueAngleUnits() const;
    00094
    00095         Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
    00096         Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
    00097         Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
    00098         Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
    00099         Degree operator - () { return Degree(-mDeg); }
    00100         Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
    00101         Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
    00102         Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
    00103         Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
    00104         Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
    00105         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
    00106         Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
    00107         Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
    00108         Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
    00109
    00110         bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
    00111         bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
    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     };
    00117
    00124     class Angle
    00125     {
    00126         Real mAngle;
    00127     public:
    00128         explicit Angle ( Real angle ) : mAngle(angle) {}
    00129         operator Radian();
    00130         operator Degree();
    00131     };
    00132
    00133     // these functions could not be defined within the class definition of class
    00134     // Radian because they required class Degree to be defined
    00135     inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
    00136     }
    00137     inline const Radian& Radian::operator = ( const Degree& d ) {
    00138         mRad = d.valueRadians(); return *this;
    00139     }
    00140     inline Radian Radian::operator + ( const Degree& d ) const {
    00141         return Radian ( mRad + d.valueRadians() );
    00142     }
    00143     inline Radian& Radian::operator += ( const Degree& d ) {
    00144         mRad += d.valueRadians();
    00145         return *this;
    00146     }
    00147     inline Radian Radian::operator - ( const Degree& d ) const {
    00148         return Radian ( mRad - d.valueRadians() );
    00149     }
    00150     inline Radian& Radian::operator -= ( const Degree& d ) {
    00151         mRad -= d.valueRadians();
    00152         return *this;
    00153     }
    00154
    00165     class _OgreExport Math
    00166     {
    00167    public:
    00173        enum AngleUnit
    00174        {
    00175            AU_DEGREE,
    00176            AU_RADIAN
    00177        };
    00178
    00179     protected:
    00180        // angle units used by the api
    00181        static AngleUnit msAngleUnit;
    00182
    00184         static int mTrigTableSize;
    00185
    00187         static Real mTrigTableFactor;
    00188         static Real* mSinTable;
    00189         static Real* mTanTable;
    00190
    00193         void buildTrigTables();
    00194
    00195         static Real SinTable (Real fValue);
    00196         static Real TanTable (Real fValue);
    00197     public:
    00203         Math(unsigned int trigTableSize = 4096);
    00204
    00207         ~Math();
    00208
    00209         static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
    00210         static inline int ICeil (float fValue) { return int(ceil(fValue)); }
    00211         static inline int IFloor (float fValue) { return int(floor(fValue)); }
    00212         static int ISign (int iValue);
    00213
    00214         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
    00215         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
    00216         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
    00217         static Radian ACos (Real fValue);
    00218         static Radian ASin (Real fValue);
    00219         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
    00220         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
    00221         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
    00222
    00230         static inline Real Cos (const Radian& fValue, bool useTables = false) {
    00231             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
    00232         }
    00240         static inline Real Cos (Real fValue, bool useTables = false) {
    00241             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
    00242         }
    00243
    00244         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
    00245
    00246         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
    00247
    00248         static inline Real Log (Real fValue) { return Real(log(fValue)); }
    00249
    00250         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
    00251
    00252         static Real Sign (Real fValue);
    00253         static inline Radian Sign ( const Radian& rValue )
    00254         {
    00255             return Radian(Sign(rValue.valueRadians()));
    00256         }
    00257         static inline Degree Sign ( const Degree& dValue )
    00258         {
    00259             return Degree(Sign(dValue.valueDegrees()));
    00260         }
    00261
    00269         static inline Real Sin (const Radian& fValue, bool useTables = false) {
    00270             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
    00271         }
    00279         static inline Real Sin (Real fValue, bool useTables = false) {
    00280             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
    00281         }
    00282
    00283         static inline Real Sqr (Real fValue) { return fValue*fValue; }
    00284
    00285         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
    00286
    00287         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
    00288
    00289         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
    00290
    00294         static Real InvSqrt(Real fValue);
    00295
    00296         static Real UnitRandom ();  // in [0,1]
    00297
    00298         static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
    00299
    00300         static Real SymmetricRandom ();  // in [-1,1]
    00301
    00309         static inline Real Tan (const Radian& fValue, bool useTables = false) {
    00310             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
    00311         }
    00319         static inline Real Tan (Real fValue, bool useTables = false) {
    00320             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
    00321         }
    00322
    00323         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
    00324         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
    00325
    00332        static void setAngleUnit(AngleUnit unit);
    00334        static AngleUnit getAngleUnit(void);
    00335
    00337        static Real AngleUnitsToRadians(Real units);
    00339        static Real RadiansToAngleUnits(Real radians);
    00341        static Real AngleUnitsToDegrees(Real units);
    00343        static Real DegreesToAngleUnits(Real degrees);
    00344
    00374         static bool pointInTri2D( Real px, Real pz, Real ax, Real az, Real bx, Real bz, Real cx, Real cz );
    00375
    00377         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
    00378
    00380         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
    00381             bool discardInside = true);
    00382
    00384         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& sphere);
    00385
    00387         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
    00388
    00390         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
    00391
    00397         static std::pair<bool, Real> intersects(
    00398             const Ray& ray, const std::vector<Plane>& planeList,
    00399             bool normalIsOutside);
    00405         static std::pair<bool, Real> intersects(
    00406             const Ray& ray, const std::list<Plane>& planeList,
    00407             bool normalIsOutside);
    00408
    00412         static bool intersects(const Sphere& sphere, const Plane& plane);
    00413
    00416         static bool RealEqual(Real a, Real b,
    00417             Real tolerance = std::numeric_limits<Real>::epsilon());
    00418
    00420         static Vector3 calculateTangentSpaceVector(
    00421             const Vector3& position1, const Vector3& position2, const Vector3& position3,
    00422             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
    00423
    00425         static Matrix4 buildReflectionMatrix(const Plane& p);
    00427         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00429         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00431         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00433         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00434
    00435         static const Real POS_INFINITY;
    00436         static const Real NEG_INFINITY;
    00437         static const Real PI;
    00438         static const Real TWO_PI;
    00439         static const Real HALF_PI;
    00440         static const Real fDeg2Rad;
    00441         static const Real fRad2Deg;
    00442
    00443     };
    00444
    00445     // these functions must be defined down here, because they rely on the
    00446     // angle unit conversion functions in class Math:
    00447
    00448     inline Real Radian::valueDegrees() const
    00449     {
    00450         return Math::RadiansToDegrees ( mRad );
    00451     }
    00452
    00453     inline Real Radian::valueAngleUnits() const
    00454     {
    00455         return Math::RadiansToAngleUnits ( mRad );
    00456     }
    00457
    00458     inline Real Degree::valueRadians() const
    00459     {
    00460         return Math::DegreesToRadians ( mDeg );
    00461     }
    00462
    00463     inline Real Degree::valueAngleUnits() const
    00464     {
    00465         return Math::DegreesToAngleUnits ( mDeg );
    00466     }
    00467
    00468     inline Angle::operator Radian()
    00469     {
    00470         return Radian(Math::AngleUnitsToRadians(mAngle));
    00471     }
    00472
    00473     inline Angle::operator Degree()
    00474     {
    00475         return Degree(Math::AngleUnitsToDegrees(mAngle));
    00476     }
    00477
    00478     inline Radian operator * ( Real a, const Radian& b )
    00479     {
    00480         return Radian ( a * b.valueRadians() );
    00481     }
    00482
    00483     inline Radian operator / ( Real a, const Radian& b )
    00484     {
    00485         return Radian ( a / b.valueRadians() );
    00486     }
    00487
    00488     inline Degree operator * ( Real a, const Degree& b )
    00489     {
    00490         return Degree ( a * b.valueDegrees() );
    00491     }
    00492
    00493     inline Degree operator / ( Real a, const Degree& b )
    00494     {
    00495         return Degree ( a / b.valueDegrees() );
    00496     }
    00497
    00498 }
    00499 #endif

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Feb 12 12:59:47 2006