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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Wed Nov 3 2010 19:24:52