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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:24 2009