# 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-2009 Torus Knot Software Ltd
    00008
    00009 Permission is hereby granted, free of charge, to any person obtaining a copy
    00010 of this software and associated documentation files (the "Software"), to deal
    00011 in the Software without restriction, including without limitation the rights
    00012 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    00013 copies of the Software, and to permit persons to whom the Software is
    00014 furnished to do so, subject to the following conditions:
    00015
    00016 The above copyright notice and this permission notice shall be included in
    00017 all copies or substantial portions of the Software.
    00018
    00019 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    00020 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00021 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    00022 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00023 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    00024 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    00025 THE SOFTWARE.
    00026 -----------------------------------------------------------------------------
    00027 */
    00028 #ifndef __Math_H__
    00029 #define __Math_H__
    00030
    00031 #include "OgrePrerequisites.h"
    00032
    00033 namespace Ogre
    00034 {
    00046     class Radian
    00047     {
    00048         Real mRad;
    00049
    00050     public:
    00051         explicit Radian ( Real r=0 ) : mRad(r) {}
    00052         Radian ( const Degree& d );
    00053         Radian& operator = ( const Real& f ) { mRad = f; return *this; }
    00054         Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
    00055         Radian& operator = ( const Degree& d );
    00056
    00057         Real valueDegrees() const; // see bottom of this file
    00058         Real valueRadians() const { return mRad; }
    00059         Real valueAngleUnits() const;
    00060
    00061         const Radian& operator + () const { return *this; }
    00062         Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
    00063         Radian operator + ( const Degree& d ) const;
    00064         Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
    00065         Radian& operator += ( const Degree& d );
    00066         Radian operator - () const { return Radian(-mRad); }
    00067         Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
    00068         Radian operator - ( const Degree& d ) const;
    00069         Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
    00070         Radian& operator -= ( const Degree& d );
    00071         Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
    00072         Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
    00073         Radian& operator *= ( Real f ) { mRad *= f; return *this; }
    00074         Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
    00075         Radian& operator /= ( Real f ) { mRad /= f; return *this; }
    00076
    00077         bool operator <  ( const Radian& r ) const { return mRad <  r.mRad; }
    00078         bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; }
    00079         bool operator == ( const Radian& r ) const { return mRad == r.mRad; }
    00080         bool operator != ( const Radian& r ) const { return mRad != r.mRad; }
    00081         bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; }
    00082         bool operator >  ( const Radian& r ) const { return mRad >  r.mRad; }
    00083
    00084         inline _OgreExport friend std::ostream& operator <<
    00085             ( std::ostream& o, const Radian& v )
    00086         {
    00087             o << "Radian(" << v.valueRadians() << ")";
    00088             return o;
    00089         }
    00090     };
    00091
    00097     class Degree
    00098     {
    00099         Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
    00100
    00101     public:
    00102         explicit Degree ( Real d=0 ) : mDeg(d) {}
    00103         Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
    00104         Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
    00105         Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
    00106         Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
    00107
    00108         Real valueDegrees() const { return mDeg; }
    00109         Real valueRadians() const; // see bottom of this file
    00110         Real valueAngleUnits() const;
    00111
    00112         const Degree& operator + () const { return *this; }
    00113         Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
    00114         Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
    00115         Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
    00116         Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
    00117         Degree operator - () const { return Degree(-mDeg); }
    00118         Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
    00119         Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
    00120         Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
    00121         Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
    00122         Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
    00123         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
    00124         Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
    00125         Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
    00126         Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
    00127
    00128         bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
    00129         bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
    00130         bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
    00131         bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
    00132         bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
    00133         bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
    00134
    00135         inline _OgreExport friend std::ostream& operator <<
    00136             ( std::ostream& o, const Degree& v )
    00137         {
    00138             o << "Degree(" << v.valueDegrees() << ")";
    00139             return o;
    00140         }
    00141     };
    00142
    00149     class Angle
    00150     {
    00151         Real mAngle;
    00152     public:
    00153         explicit Angle ( Real angle ) : mAngle(angle) {}
    00154         operator Radian() const;
    00155         operator Degree() const;
    00156     };
    00157
    00158     // these functions could not be defined within the class definition of class
    00159     // Radian because they required class Degree to be defined
    00160     inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
    00161     }
    00162     inline Radian& Radian::operator = ( const Degree& d ) {
    00163         mRad = d.valueRadians(); return *this;
    00164     }
    00165     inline Radian Radian::operator + ( const Degree& d ) const {
    00166         return Radian ( mRad + d.valueRadians() );
    00167     }
    00168     inline Radian& Radian::operator += ( const Degree& d ) {
    00169         mRad += d.valueRadians();
    00170         return *this;
    00171     }
    00172     inline Radian Radian::operator - ( const Degree& d ) const {
    00173         return Radian ( mRad - d.valueRadians() );
    00174     }
    00175     inline Radian& Radian::operator -= ( const Degree& d ) {
    00176         mRad -= d.valueRadians();
    00177         return *this;
    00178     }
    00179
    00190     class _OgreExport Math
    00191     {
    00192    public:
    00198        enum AngleUnit
    00199        {
    00200            AU_DEGREE,
    00201            AU_RADIAN
    00202        };
    00203
    00204     protected:
    00205        // angle units used by the api
    00206        static AngleUnit msAngleUnit;
    00207
    00209         static int mTrigTableSize;
    00210
    00212         static Real mTrigTableFactor;
    00213         static Real* mSinTable;
    00214         static Real* mTanTable;
    00215
    00218         void buildTrigTables();
    00219
    00220         static Real SinTable (Real fValue);
    00221         static Real TanTable (Real fValue);
    00222     public:
    00228         Math(unsigned int trigTableSize = 4096);
    00229
    00232         ~Math();
    00233
    00234         static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
    00235         static inline int ICeil (float fValue) { return int(ceil(fValue)); }
    00236         static inline int IFloor (float fValue) { return int(floor(fValue)); }
    00237         static int ISign (int iValue);
    00238
    00239         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
    00240         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
    00241         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
    00242         static Radian ACos (Real fValue);
    00243         static Radian ASin (Real fValue);
    00244         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
    00245         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
    00246         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
    00247         static inline bool isNaN(Real f)
    00248         {
    00249             // std::isnan() is C99, not supported by all compilers
    00250             // However NaN always fails this next test, no other number does.
    00251             return f != f;
    00252         }
    00253
    00261         static inline Real Cos (const Radian& fValue, bool useTables = false) {
    00262             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
    00263         }
    00271         static inline Real Cos (Real fValue, bool useTables = false) {
    00272             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
    00273         }
    00274
    00275         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
    00276
    00277         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
    00278
    00279         static inline Real Log (Real fValue) { return Real(log(fValue)); }
    00280
    00282         static const Real LOG2;
    00283
    00284         static inline Real Log2 (Real fValue) { return Real(log(fValue)/LOG2); }
    00285
    00286         static inline Real LogN (Real base, Real fValue) { return Real(log(fValue)/log(base)); }
    00287
    00288         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
    00289
    00290         static Real Sign (Real fValue);
    00291         static inline Radian Sign ( const Radian& rValue )
    00292         {
    00293             return Radian(Sign(rValue.valueRadians()));
    00294         }
    00295         static inline Degree Sign ( const Degree& dValue )
    00296         {
    00297             return Degree(Sign(dValue.valueDegrees()));
    00298         }
    00299
    00307         static inline Real Sin (const Radian& fValue, bool useTables = false) {
    00308             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
    00309         }
    00317         static inline Real Sin (Real fValue, bool useTables = false) {
    00318             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
    00319         }
    00320
    00321         static inline Real Sqr (Real fValue) { return fValue*fValue; }
    00322
    00323         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
    00324
    00325         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
    00326
    00327         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
    00328
    00332         static Real InvSqrt(Real fValue);
    00333
    00334         static Real UnitRandom ();  // in [0,1]
    00335
    00336         static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
    00337
    00338         static Real SymmetricRandom ();  // in [-1,1]
    00339
    00347         static inline Real Tan (const Radian& fValue, bool useTables = false) {
    00348             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
    00349         }
    00357         static inline Real Tan (Real fValue, bool useTables = false) {
    00358             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
    00359         }
    00360
    00361         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
    00362         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
    00363
    00370        static void setAngleUnit(AngleUnit unit);
    00372        static AngleUnit getAngleUnit(void);
    00373
    00375        static Real AngleUnitsToRadians(Real units);
    00377        static Real RadiansToAngleUnits(Real radians);
    00379        static Real AngleUnitsToDegrees(Real units);
    00381        static Real DegreesToAngleUnits(Real degrees);
    00382
    00404         static bool pointInTri2D(const Vector2& p, const Vector2& a,
    00405             const Vector2& b, const Vector2& c);
    00406
    00431         static bool pointInTri3D(const Vector3& p, const Vector3& a,
    00432             const Vector3& b, const Vector3& c, const Vector3& normal);
    00434         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
    00435
    00437         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
    00438             bool discardInside = true);
    00439
    00441         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box);
    00442
    00465         static bool intersects(const Ray& ray, const AxisAlignedBox& box,
    00466             Real* d1, Real* d2);
    00467
    00492         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00493             const Vector3& b, const Vector3& c, const Vector3& normal,
    00494             bool positiveSide = true, bool negativeSide = true);
    00495
    00516         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00517             const Vector3& b, const Vector3& c,
    00518             bool positiveSide = true, bool negativeSide = true);
    00519
    00521         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
    00522
    00524         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
    00525
    00531         static std::pair<bool, Real> intersects(
    00532             const Ray& ray, const vector<Plane>::type& planeList,
    00533             bool normalIsOutside);
    00539         static std::pair<bool, Real> intersects(
    00540             const Ray& ray, const list<Plane>::type& planeList,
    00541             bool normalIsOutside);
    00542
    00546         static bool intersects(const Sphere& sphere, const Plane& plane);
    00547
    00550         static bool RealEqual(Real a, Real b,
    00551             Real tolerance = std::numeric_limits<Real>::epsilon());
    00552
    00554         static Vector3 calculateTangentSpaceVector(
    00555             const Vector3& position1, const Vector3& position2, const Vector3& position3,
    00556             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
    00557
    00559         static Matrix4 buildReflectionMatrix(const Plane& p);
    00561         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00563         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00565         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00567         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00568
    00572         static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
    00573
    00575         template <typename T>
    00576         static T Clamp(T val, T minval, T maxval)
    00577         {
    00578             assert (minval < maxval && "Invalid clamp range");
    00579             return std::max(std::min(val, maxval), minval);
    00580         }
    00581
    00582         static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation,
    00583             const Matrix4* reflectMatrix = 0);
    00584
    00586         static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);
    00587
    00588
    00589
    00590         static const Real POS_INFINITY;
    00591         static const Real NEG_INFINITY;
    00592         static const Real PI;
    00593         static const Real TWO_PI;
    00594         static const Real HALF_PI;
    00595         static const Real fDeg2Rad;
    00596         static const Real fRad2Deg;
    00597
    00598     };
    00599
    00600     // these functions must be defined down here, because they rely on the
    00601     // angle unit conversion functions in class Math:
    00602
    00603     inline Real Radian::valueDegrees() const
    00604     {
    00605         return Math::RadiansToDegrees ( mRad );
    00606     }
    00607
    00608     inline Real Radian::valueAngleUnits() const
    00609     {
    00610         return Math::RadiansToAngleUnits ( mRad );
    00611     }
    00612
    00613     inline Real Degree::valueRadians() const
    00614     {
    00615         return Math::DegreesToRadians ( mDeg );
    00616     }
    00617
    00618     inline Real Degree::valueAngleUnits() const
    00619     {
    00620         return Math::DegreesToAngleUnits ( mDeg );
    00621     }
    00622
    00623     inline Angle::operator Radian() const
    00624     {
    00625         return Radian(Math::AngleUnitsToRadians(mAngle));
    00626     }
    00627
    00628     inline Angle::operator Degree() const
    00629     {
    00630         return Degree(Math::AngleUnitsToDegrees(mAngle));
    00631     }
    00632
    00633     inline Radian operator * ( Real a, const Radian& b )
    00634     {
    00635         return Radian ( a * b.valueRadians() );
    00636     }
    00637
    00638     inline Radian operator / ( Real a, const Radian& b )
    00639     {
    00640         return Radian ( a / b.valueRadians() );
    00641     }
    00642
    00643     inline Degree operator * ( Real a, const Degree& b )
    00644     {
    00645         return Degree ( a * b.valueDegrees() );
    00646     }
    00647
    00648     inline Degree operator / ( Real a, const Degree& b )
    00649     {
    00650         return Degree ( a / b.valueDegrees() );
    00651     }
    00655 }
    00656 #endif

Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:52