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-2012 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
    00243         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
    00244
    00249         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
    00250
    00255         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
    00256
    00261         static Radian ACos (Real fValue);
    00262
    00267         static Radian ASin (Real fValue);
    00268
    00273         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
    00274
    00281         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
    00282
    00289         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
    00290         static inline bool isNaN(Real f)
    00291         {
    00292             // std::isnan() is C99, not supported by all compilers
    00293             // However NaN always fails this next test, no other number does.
    00294             return f != f;
    00295         }
    00296
    00304         static inline Real Cos (const Radian& fValue, bool useTables = false) {
    00305             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
    00306         }
    00314         static inline Real Cos (Real fValue, bool useTables = false) {
    00315             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
    00316         }
    00317
    00318         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
    00319
    00326         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
    00327
    00328         static inline Real Log (Real fValue) { return Real(log(fValue)); }
    00329
    00331         static const Real LOG2;
    00332
    00333         static inline Real Log2 (Real fValue) { return Real(log(fValue)/LOG2); }
    00334
    00335         static inline Real LogN (Real base, Real fValue) { return Real(log(fValue)/log(base)); }
    00336
    00337         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
    00338
    00339         static Real Sign (Real fValue);
    00340         static inline Radian Sign ( const Radian& rValue )
    00341         {
    00342             return Radian(Sign(rValue.valueRadians()));
    00343         }
    00344         static inline Degree Sign ( const Degree& dValue )
    00345         {
    00346             return Degree(Sign(dValue.valueDegrees()));
    00347         }
    00348
    00356         static inline Real Sin (const Radian& fValue, bool useTables = false) {
    00357             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
    00358         }
    00366         static inline Real Sin (Real fValue, bool useTables = false) {
    00367             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
    00368         }
    00369
    00374         static inline Real Sqr (Real fValue) { return fValue*fValue; }
    00375
    00380         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
    00381
    00388         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
    00389
    00396         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
    00397
    00403         static Real InvSqrt (Real fValue);
    00404
    00409         static Real UnitRandom ();
    00410
    00419         static Real RangeRandom (Real fLow, Real fHigh);
    00420
    00425         static Real SymmetricRandom ();
    00426
    00434         static inline Real Tan (const Radian& fValue, bool useTables = false) {
    00435             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
    00436         }
    00444         static inline Real Tan (Real fValue, bool useTables = false) {
    00445             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
    00446         }
    00447
    00448         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
    00449         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
    00450
    00457        static void setAngleUnit(AngleUnit unit);
    00459        static AngleUnit getAngleUnit(void);
    00460
    00462        static Real AngleUnitsToRadians(Real units);
    00464        static Real RadiansToAngleUnits(Real radians);
    00466        static Real AngleUnitsToDegrees(Real units);
    00468        static Real DegreesToAngleUnits(Real degrees);
    00469
    00491         static bool pointInTri2D(const Vector2& p, const Vector2& a,
    00492             const Vector2& b, const Vector2& c);
    00493
    00518         static bool pointInTri3D(const Vector3& p, const Vector3& a,
    00519             const Vector3& b, const Vector3& c, const Vector3& normal);
    00521         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
    00522
    00524         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
    00525             bool discardInside = true);
    00526
    00528         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box);
    00529
    00552         static bool intersects(const Ray& ray, const AxisAlignedBox& box,
    00553             Real* d1, Real* d2);
    00554
    00579         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00580             const Vector3& b, const Vector3& c, const Vector3& normal,
    00581             bool positiveSide = true, bool negativeSide = true);
    00582
    00603         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00604             const Vector3& b, const Vector3& c,
    00605             bool positiveSide = true, bool negativeSide = true);
    00606
    00608         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
    00609
    00611         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
    00612
    00618         static std::pair<bool, Real> intersects(
    00619             const Ray& ray, const vector<Plane>::type& planeList,
    00620             bool normalIsOutside);
    00626         static std::pair<bool, Real> intersects(
    00627             const Ray& ray, const list<Plane>::type& planeList,
    00628             bool normalIsOutside);
    00629
    00633         static bool intersects(const Sphere& sphere, const Plane& plane);
    00634
    00637         static bool RealEqual(Real a, Real b,
    00638             Real tolerance = std::numeric_limits<Real>::epsilon());
    00639
    00641         static Vector3 calculateTangentSpaceVector(
    00642             const Vector3& position1, const Vector3& position2, const Vector3& position3,
    00643             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
    00644
    00646         static Matrix4 buildReflectionMatrix(const Plane& p);
    00648         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00650         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00652         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00654         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00655
    00659         static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
    00660
    00662         template <typename T>
    00663         static T Clamp(T val, T minval, T maxval)
    00664         {
    00665             assert (minval <= maxval && "Invalid clamp range");
    00666             return std::max(std::min(val, maxval), minval);
    00667         }
    00668
    00669         static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation,
    00670             const Matrix4* reflectMatrix = 0);
    00671
    00673         static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);
    00674
    00675
    00676
    00677         static const Real POS_INFINITY;
    00678         static const Real NEG_INFINITY;
    00679         static const Real PI;
    00680         static const Real TWO_PI;
    00681         static const Real HALF_PI;
    00682         static const Real fDeg2Rad;
    00683         static const Real fRad2Deg;
    00684
    00685     };
    00686
    00687     // these functions must be defined down here, because they rely on the
    00688     // angle unit conversion functions in class Math:
    00689
    00690     inline Real Radian::valueDegrees() const
    00691     {
    00692         return Math::RadiansToDegrees ( mRad );
    00693     }
    00694
    00695     inline Real Radian::valueAngleUnits() const
    00696     {
    00697         return Math::RadiansToAngleUnits ( mRad );
    00698     }
    00699
    00700     inline Real Degree::valueRadians() const
    00701     {
    00702         return Math::DegreesToRadians ( mDeg );
    00703     }
    00704
    00705     inline Real Degree::valueAngleUnits() const
    00706     {
    00707         return Math::DegreesToAngleUnits ( mDeg );
    00708     }
    00709
    00710     inline Angle::operator Radian() const
    00711     {
    00712         return Radian(Math::AngleUnitsToRadians(mAngle));
    00713     }
    00714
    00715     inline Angle::operator Degree() const
    00716     {
    00717         return Degree(Math::AngleUnitsToDegrees(mAngle));
    00718     }
    00719
    00720     inline Radian operator * ( Real a, const Radian& b )
    00721     {
    00722         return Radian ( a * b.valueRadians() );
    00723     }
    00724
    00725     inline Radian operator / ( Real a, const Radian& b )
    00726     {
    00727         return Radian ( a / b.valueRadians() );
    00728     }
    00729
    00730     inline Degree operator * ( Real a, const Degree& b )
    00731     {
    00732         return Degree ( a * b.valueDegrees() );
    00733     }
    00734
    00735     inline Degree operator / ( Real a, const Degree& b )
    00736     {
    00737         return Degree ( a / b.valueDegrees() );
    00738     }
    00742 }
    00743 #endif

Copyright © 2012 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sun Sep 2 2012 07:27:22