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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri May 25 23:36:24 2012