# 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-2006 Torus Knot Software Ltd
    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 You may alternatively use this source under the terms of a specific version of
    00025 the OGRE Unrestricted License provided you have obtained such a license from
    00026 Torus Knot Software Ltd.
    00027 -----------------------------------------------------------------------------
    00028 */
    00029 #ifndef __Math_H__
    00030 #define __Math_H__
    00031
    00032 #include "OgrePrerequisites.h"
    00033
    00034 namespace Ogre
    00035 {
    00041     class Radian
    00042     {
    00043         Real mRad;
    00044
    00045     public:
    00046         explicit Radian ( Real r=0 ) : mRad(r) {}
    00047         Radian ( const Degree& d );
    00048         Radian& operator = ( const Real& f ) { mRad = f; return *this; }
    00049         Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
    00050         Radian& operator = ( const Degree& d );
    00051
    00052         Real valueDegrees() const; // see bottom of this file
    00053         Real valueRadians() const { return mRad; }
    00054         Real valueAngleUnits() const;
    00055
    00056         const Radian& operator + () const { return *this; }
    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 - () const { return Radian(-mRad); }
    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 * ( Real f ) const { return Radian ( mRad * f ); }
    00067         Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
    00068         Radian& operator *= ( Real f ) { mRad *= f; return *this; }
    00069         Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
    00070         Radian& operator /= ( Real f ) { mRad /= f; return *this; }
    00071
    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         bool operator != ( const Radian& r ) const { return mRad != r.mRad; }
    00076         bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; }
    00077         bool operator >  ( const Radian& r ) const { return mRad >  r.mRad; }
    00078
    00079         inline _OgreExport friend std::ostream& operator <<
    00080             ( std::ostream& o, const Radian& v )
    00081         {
    00082             o << "Radian(" << v.valueRadians() << ")";
    00083             return o;
    00084         }
    00085     };
    00086
    00092     class Degree
    00093     {
    00094         Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
    00095
    00096     public:
    00097         explicit Degree ( Real d=0 ) : mDeg(d) {}
    00098         Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
    00099         Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
    00100         Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
    00101         Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
    00102
    00103         Real valueDegrees() const { return mDeg; }
    00104         Real valueRadians() const; // see bottom of this file
    00105         Real valueAngleUnits() const;
    00106
    00107         const Degree& operator + () const { return *this; }
    00108         Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
    00109         Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
    00110         Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
    00111         Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
    00112         Degree operator - () const { return Degree(-mDeg); }
    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 * ( Real f ) const { return Degree ( mDeg * f ); }
    00118         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
    00119         Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
    00120         Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
    00121         Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
    00122
    00123         bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
    00124         bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
    00125         bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
    00126         bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
    00127         bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
    00128         bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
    00129
    00130         inline _OgreExport friend std::ostream& operator <<
    00131             ( std::ostream& o, const Degree& v )
    00132         {
    00133             o << "Degree(" << v.valueDegrees() << ")";
    00134             return o;
    00135         }
    00136     };
    00137
    00144     class Angle
    00145     {
    00146         Real mAngle;
    00147     public:
    00148         explicit Angle ( Real angle ) : mAngle(angle) {}
    00149         operator Radian() const;
    00150         operator Degree() const;
    00151     };
    00152
    00153     // these functions could not be defined within the class definition of class
    00154     // Radian because they required class Degree to be defined
    00155     inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
    00156     }
    00157     inline Radian& Radian::operator = ( const Degree& d ) {
    00158         mRad = d.valueRadians(); return *this;
    00159     }
    00160     inline Radian Radian::operator + ( const Degree& d ) const {
    00161         return Radian ( mRad + d.valueRadians() );
    00162     }
    00163     inline Radian& Radian::operator += ( const Degree& d ) {
    00164         mRad += d.valueRadians();
    00165         return *this;
    00166     }
    00167     inline Radian Radian::operator - ( const Degree& d ) const {
    00168         return Radian ( mRad - d.valueRadians() );
    00169     }
    00170     inline Radian& Radian::operator -= ( const Degree& d ) {
    00171         mRad -= d.valueRadians();
    00172         return *this;
    00173     }
    00174
    00185     class _OgreExport Math
    00186     {
    00187    public:
    00193        enum AngleUnit
    00194        {
    00195            AU_DEGREE,
    00196            AU_RADIAN
    00197        };
    00198
    00199     protected:
    00200        // angle units used by the api
    00201        static AngleUnit msAngleUnit;
    00202
    00204         static int mTrigTableSize;
    00205
    00207         static Real mTrigTableFactor;
    00208         static Real* mSinTable;
    00209         static Real* mTanTable;
    00210
    00213         void buildTrigTables();
    00214
    00215         static Real SinTable (Real fValue);
    00216         static Real TanTable (Real fValue);
    00217     public:
    00223         Math(unsigned int trigTableSize = 4096);
    00224
    00227         ~Math();
    00228
    00229         static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
    00230         static inline int ICeil (float fValue) { return int(ceil(fValue)); }
    00231         static inline int IFloor (float fValue) { return int(floor(fValue)); }
    00232         static int ISign (int iValue);
    00233
    00234         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
    00235         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
    00236         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
    00237         static Radian ACos (Real fValue);
    00238         static Radian ASin (Real fValue);
    00239         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
    00240         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
    00241         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
    00242
    00250         static inline Real Cos (const Radian& fValue, bool useTables = false) {
    00251             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
    00252         }
    00260         static inline Real Cos (Real fValue, bool useTables = false) {
    00261             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
    00262         }
    00263
    00264         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
    00265
    00266         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
    00267
    00268         static inline Real Log (Real fValue) { return Real(log(fValue)); }
    00269
    00270         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
    00271
    00272         static Real Sign (Real fValue);
    00273         static inline Radian Sign ( const Radian& rValue )
    00274         {
    00275             return Radian(Sign(rValue.valueRadians()));
    00276         }
    00277         static inline Degree Sign ( const Degree& dValue )
    00278         {
    00279             return Degree(Sign(dValue.valueDegrees()));
    00280         }
    00281
    00289         static inline Real Sin (const Radian& fValue, bool useTables = false) {
    00290             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
    00291         }
    00299         static inline Real Sin (Real fValue, bool useTables = false) {
    00300             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
    00301         }
    00302
    00303         static inline Real Sqr (Real fValue) { return fValue*fValue; }
    00304
    00305         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
    00306
    00307         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
    00308
    00309         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
    00310
    00314         static Real InvSqrt(Real fValue);
    00315
    00316         static Real UnitRandom ();  // in [0,1]
    00317
    00318         static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
    00319
    00320         static Real SymmetricRandom ();  // in [-1,1]
    00321
    00329         static inline Real Tan (const Radian& fValue, bool useTables = false) {
    00330             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
    00331         }
    00339         static inline Real Tan (Real fValue, bool useTables = false) {
    00340             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
    00341         }
    00342
    00343         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
    00344         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
    00345
    00352        static void setAngleUnit(AngleUnit unit);
    00354        static AngleUnit getAngleUnit(void);
    00355
    00357        static Real AngleUnitsToRadians(Real units);
    00359        static Real RadiansToAngleUnits(Real radians);
    00361        static Real AngleUnitsToDegrees(Real units);
    00363        static Real DegreesToAngleUnits(Real degrees);
    00364
    00386         static bool pointInTri2D(const Vector2& p, const Vector2& a,
    00387             const Vector2& b, const Vector2& c);
    00388
    00413         static bool pointInTri3D(const Vector3& p, const Vector3& a,
    00414             const Vector3& b, const Vector3& c, const Vector3& normal);
    00416         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
    00417
    00419         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
    00420             bool discardInside = true);
    00421
    00423         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box);
    00424
    00447         static bool intersects(const Ray& ray, const AxisAlignedBox& box,
    00448             Real* d1, Real* d2);
    00449
    00474         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00475             const Vector3& b, const Vector3& c, const Vector3& normal,
    00476             bool positiveSide = true, bool negativeSide = true);
    00477
    00498         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00499             const Vector3& b, const Vector3& c,
    00500             bool positiveSide = true, bool negativeSide = true);
    00501
    00503         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
    00504
    00506         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
    00507
    00513         static std::pair<bool, Real> intersects(
    00514             const Ray& ray, const std::vector<Plane>& planeList,
    00515             bool normalIsOutside);
    00521         static std::pair<bool, Real> intersects(
    00522             const Ray& ray, const std::list<Plane>& planeList,
    00523             bool normalIsOutside);
    00524
    00528         static bool intersects(const Sphere& sphere, const Plane& plane);
    00529
    00532         static bool RealEqual(Real a, Real b,
    00533             Real tolerance = std::numeric_limits<Real>::epsilon());
    00534
    00536         static Vector3 calculateTangentSpaceVector(
    00537             const Vector3& position1, const Vector3& position2, const Vector3& position3,
    00538             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
    00539
    00541         static Matrix4 buildReflectionMatrix(const Plane& p);
    00543         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00545         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00547         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00549         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00550
    00554         static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
    00555
    00557         template <typename T>
    00558         static T Clamp(T val, T minval, T maxval)
    00559         {
    00560             assert (minval < maxval && "Invalid clamp range");
    00561             return std::max(std::min(val, maxval), minval);
    00562         }
    00563
    00564         static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation,
    00565             const Matrix4* reflectMatrix = 0);
    00566
    00568         static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);
    00569
    00570
    00571
    00572         static const Real POS_INFINITY;
    00573         static const Real NEG_INFINITY;
    00574         static const Real PI;
    00575         static const Real TWO_PI;
    00576         static const Real HALF_PI;
    00577         static const Real fDeg2Rad;
    00578         static const Real fRad2Deg;
    00579
    00580     };
    00581
    00582     // these functions must be defined down here, because they rely on the
    00583     // angle unit conversion functions in class Math:
    00584
    00585     inline Real Radian::valueDegrees() const
    00586     {
    00587         return Math::RadiansToDegrees ( mRad );
    00588     }
    00589
    00590     inline Real Radian::valueAngleUnits() const
    00591     {
    00592         return Math::RadiansToAngleUnits ( mRad );
    00593     }
    00594
    00595     inline Real Degree::valueRadians() const
    00596     {
    00597         return Math::DegreesToRadians ( mDeg );
    00598     }
    00599
    00600     inline Real Degree::valueAngleUnits() const
    00601     {
    00602         return Math::DegreesToAngleUnits ( mDeg );
    00603     }
    00604
    00605     inline Angle::operator Radian() const
    00606     {
    00607         return Radian(Math::AngleUnitsToRadians(mAngle));
    00608     }
    00609
    00610     inline Angle::operator Degree() const
    00611     {
    00612         return Degree(Math::AngleUnitsToDegrees(mAngle));
    00613     }
    00614
    00615     inline Radian operator * ( Real a, const Radian& b )
    00616     {
    00617         return Radian ( a * b.valueRadians() );
    00618     }
    00619
    00620     inline Radian operator / ( Real a, const Radian& b )
    00621     {
    00622         return Radian ( a / b.valueRadians() );
    00623     }
    00624
    00625     inline Degree operator * ( Real a, const Degree& b )
    00626     {
    00627         return Degree ( a * b.valueDegrees() );
    00628     }
    00629
    00630     inline Degree operator / ( Real a, const Degree& b )
    00631     {
    00632         return Degree ( a / b.valueDegrees() );
    00633     }
    00634
    00635 }
    00636 #endif

Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Dec 27 17:31:06 2009