# 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
    00085     class Degree
    00086     {
    00087         Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
    00088
    00089     public:
    00090         explicit Degree ( Real d=0 ) : mDeg(d) {}
    00091         Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
    00092         Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
    00093         Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
    00094         Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
    00095
    00096         Real valueDegrees() const { return mDeg; }
    00097         Real valueRadians() const; // see bottom of this file
    00098         Real valueAngleUnits() const;
    00099
    00100         const Degree& operator + () const { return *this; }
    00101         Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
    00102         Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
    00103         Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
    00104         Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
    00105         Degree operator - () const { return Degree(-mDeg); }
    00106         Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
    00107         Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
    00108         Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
    00109         Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
    00110         Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
    00111         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
    00112         Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
    00113         Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
    00114         Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
    00115
    00116         bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
    00117         bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
    00118         bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
    00119         bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
    00120         bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
    00121         bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
    00122     };
    00123
    00130     class Angle
    00131     {
    00132         Real mAngle;
    00133     public:
    00134         explicit Angle ( Real angle ) : mAngle(angle) {}
    00135         operator Radian() const;
    00136         operator Degree() const;
    00137     };
    00138
    00139     // these functions could not be defined within the class definition of class
    00140     // Radian because they required class Degree to be defined
    00141     inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
    00142     }
    00143     inline Radian& Radian::operator = ( const Degree& d ) {
    00144         mRad = d.valueRadians(); return *this;
    00145     }
    00146     inline Radian Radian::operator + ( const Degree& d ) const {
    00147         return Radian ( mRad + d.valueRadians() );
    00148     }
    00149     inline Radian& Radian::operator += ( const Degree& d ) {
    00150         mRad += d.valueRadians();
    00151         return *this;
    00152     }
    00153     inline Radian Radian::operator - ( const Degree& d ) const {
    00154         return Radian ( mRad - d.valueRadians() );
    00155     }
    00156     inline Radian& Radian::operator -= ( const Degree& d ) {
    00157         mRad -= d.valueRadians();
    00158         return *this;
    00159     }
    00160
    00171     class _OgreExport Math
    00172     {
    00173    public:
    00179        enum AngleUnit
    00180        {
    00181            AU_DEGREE,
    00182            AU_RADIAN
    00183        };
    00184
    00185     protected:
    00186        // angle units used by the api
    00187        static AngleUnit msAngleUnit;
    00188
    00190         static int mTrigTableSize;
    00191
    00193         static Real mTrigTableFactor;
    00194         static Real* mSinTable;
    00195         static Real* mTanTable;
    00196
    00199         void buildTrigTables();
    00200
    00201         static Real SinTable (Real fValue);
    00202         static Real TanTable (Real fValue);
    00203     public:
    00209         Math(unsigned int trigTableSize = 4096);
    00210
    00213         ~Math();
    00214
    00215         static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
    00216         static inline int ICeil (float fValue) { return int(ceil(fValue)); }
    00217         static inline int IFloor (float fValue) { return int(floor(fValue)); }
    00218         static int ISign (int iValue);
    00219
    00220         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
    00221         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
    00222         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
    00223         static Radian ACos (Real fValue);
    00224         static Radian ASin (Real fValue);
    00225         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
    00226         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
    00227         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
    00228
    00236         static inline Real Cos (const Radian& fValue, bool useTables = false) {
    00237             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
    00238         }
    00246         static inline Real Cos (Real fValue, bool useTables = false) {
    00247             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
    00248         }
    00249
    00250         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
    00251
    00252         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
    00253
    00254         static inline Real Log (Real fValue) { return Real(log(fValue)); }
    00255
    00256         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
    00257
    00258         static Real Sign (Real fValue);
    00259         static inline Radian Sign ( const Radian& rValue )
    00260         {
    00261             return Radian(Sign(rValue.valueRadians()));
    00262         }
    00263         static inline Degree Sign ( const Degree& dValue )
    00264         {
    00265             return Degree(Sign(dValue.valueDegrees()));
    00266         }
    00267
    00275         static inline Real Sin (const Radian& fValue, bool useTables = false) {
    00276             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
    00277         }
    00285         static inline Real Sin (Real fValue, bool useTables = false) {
    00286             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
    00287         }
    00288
    00289         static inline Real Sqr (Real fValue) { return fValue*fValue; }
    00290
    00291         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
    00292
    00293         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
    00294
    00295         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
    00296
    00300         static Real InvSqrt(Real fValue);
    00301
    00302         static Real UnitRandom ();  // in [0,1]
    00303
    00304         static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
    00305
    00306         static Real SymmetricRandom ();  // in [-1,1]
    00307
    00315         static inline Real Tan (const Radian& fValue, bool useTables = false) {
    00316             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
    00317         }
    00325         static inline Real Tan (Real fValue, bool useTables = false) {
    00326             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
    00327         }
    00328
    00329         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
    00330         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
    00331
    00338        static void setAngleUnit(AngleUnit unit);
    00340        static AngleUnit getAngleUnit(void);
    00341
    00343        static Real AngleUnitsToRadians(Real units);
    00345        static Real RadiansToAngleUnits(Real radians);
    00347        static Real AngleUnitsToDegrees(Real units);
    00349        static Real DegreesToAngleUnits(Real degrees);
    00350
    00372         static bool pointInTri2D(const Vector2& p, const Vector2& a,
    00373             const Vector2& b, const Vector2& c);
    00374
    00399         static bool pointInTri3D(const Vector3& p, const Vector3& a,
    00400             const Vector3& b, const Vector3& c, const Vector3& normal);
    00402         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
    00403
    00405         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
    00406             bool discardInside = true);
    00407
    00409         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box);
    00410
    00433         static bool intersects(const Ray& ray, const AxisAlignedBox& box,
    00434             Real* d1, Real* d2);
    00435
    00460         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00461             const Vector3& b, const Vector3& c, const Vector3& normal,
    00462             bool positiveSide = true, bool negativeSide = true);
    00463
    00484         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
    00485             const Vector3& b, const Vector3& c,
    00486             bool positiveSide = true, bool negativeSide = true);
    00487
    00489         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
    00490
    00492         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
    00493
    00499         static std::pair<bool, Real> intersects(
    00500             const Ray& ray, const std::vector<Plane>& planeList,
    00501             bool normalIsOutside);
    00507         static std::pair<bool, Real> intersects(
    00508             const Ray& ray, const std::list<Plane>& planeList,
    00509             bool normalIsOutside);
    00510
    00514         static bool intersects(const Sphere& sphere, const Plane& plane);
    00515
    00518         static bool RealEqual(Real a, Real b,
    00519             Real tolerance = std::numeric_limits<Real>::epsilon());
    00520
    00522         static Vector3 calculateTangentSpaceVector(
    00523             const Vector3& position1, const Vector3& position2, const Vector3& position3,
    00524             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
    00525
    00527         static Matrix4 buildReflectionMatrix(const Plane& p);
    00529         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00531         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00533         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00535         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
    00536
    00540         static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
    00541
    00542         static const Real POS_INFINITY;
    00543         static const Real NEG_INFINITY;
    00544         static const Real PI;
    00545         static const Real TWO_PI;
    00546         static const Real HALF_PI;
    00547         static const Real fDeg2Rad;
    00548         static const Real fRad2Deg;
    00549
    00550     };
    00551
    00552     // these functions must be defined down here, because they rely on the
    00553     // angle unit conversion functions in class Math:
    00554
    00555     inline Real Radian::valueDegrees() const
    00556     {
    00557         return Math::RadiansToDegrees ( mRad );
    00558     }
    00559
    00560     inline Real Radian::valueAngleUnits() const
    00561     {
    00562         return Math::RadiansToAngleUnits ( mRad );
    00563     }
    00564
    00565     inline Real Degree::valueRadians() const
    00566     {
    00567         return Math::DegreesToRadians ( mDeg );
    00568     }
    00569
    00570     inline Real Degree::valueAngleUnits() const
    00571     {
    00572         return Math::DegreesToAngleUnits ( mDeg );
    00573     }
    00574
    00575     inline Angle::operator Radian() const
    00576     {
    00577         return Radian(Math::AngleUnitsToRadians(mAngle));
    00578     }
    00579
    00580     inline Angle::operator Degree() const
    00581     {
    00582         return Degree(Math::AngleUnitsToDegrees(mAngle));
    00583     }
    00584
    00585     inline Radian operator * ( Real a, const Radian& b )
    00586     {
    00587         return Radian ( a * b.valueRadians() );
    00588     }
    00589
    00590     inline Radian operator / ( Real a, const Radian& b )
    00591     {
    00592         return Radian ( a / b.valueRadians() );
    00593     }
    00594
    00595     inline Degree operator * ( Real a, const Degree& b )
    00596     {
    00597         return Degree ( a * b.valueDegrees() );
    00598     }
    00599
    00600     inline Degree operator / ( Real a, const Degree& b )
    00601     {
    00602         return Degree ( a / b.valueDegrees() );
    00603     }
    00604
    00605 }
    00606 #endif

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat May 10 16:25:00 2008