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-2013 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 #include "OgreHeaderPrefix.h"
00033 
00034 namespace Ogre
00035 {
00047     class Radian
00048     {
00049         Real mRad;
00050 
00051     public:
00052         explicit Radian ( Real r=0 ) : mRad(r) {}
00053         Radian ( const Degree& d );
00054         Radian& operator = ( const Real& f ) { mRad = f; return *this; }
00055         Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
00056         Radian& operator = ( const Degree& d );
00057 
00058         Real valueDegrees() const; // see bottom of this file
00059         Real valueRadians() const { return mRad; }
00060         Real valueAngleUnits() const;
00061 
00062         const Radian& operator + () const { return *this; }
00063         Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
00064         Radian operator + ( const Degree& d ) const;
00065         Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
00066         Radian& operator += ( const Degree& d );
00067         Radian operator - () const { return Radian(-mRad); }
00068         Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
00069         Radian operator - ( const Degree& d ) const;
00070         Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
00071         Radian& operator -= ( const Degree& d );
00072         Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
00073         Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
00074         Radian& operator *= ( Real f ) { mRad *= f; return *this; }
00075         Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
00076         Radian& operator /= ( Real f ) { mRad /= f; return *this; }
00077 
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         bool operator >  ( const Radian& r ) const { return mRad >  r.mRad; }
00084 
00085         inline _OgreExport friend std::ostream& operator <<
00086             ( std::ostream& o, const Radian& v )
00087         {
00088             o << "Radian(" << v.valueRadians() << ")";
00089             return o;
00090         }
00091     };
00092 
00098     class Degree
00099     {
00100         Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
00101 
00102     public:
00103         explicit Degree ( Real d=0 ) : mDeg(d) {}
00104         Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
00105         Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
00106         Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
00107         Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
00108 
00109         Real valueDegrees() const { return mDeg; }
00110         Real valueRadians() const; // see bottom of this file
00111         Real valueAngleUnits() const;
00112 
00113         const Degree& operator + () const { return *this; }
00114         Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
00115         Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
00116         Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
00117         Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
00118         Degree operator - () const { return Degree(-mDeg); }
00119         Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
00120         Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
00121         Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
00122         Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
00123         Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
00124         Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
00125         Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
00126         Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
00127         Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
00128 
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         bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
00135 
00136         inline _OgreExport friend std::ostream& operator <<
00137             ( std::ostream& o, const Degree& v )
00138         {
00139             o << "Degree(" << v.valueDegrees() << ")";
00140             return o;
00141         }
00142     };
00143 
00150     class Angle
00151     {
00152         Real mAngle;
00153     public:
00154         explicit Angle ( Real angle ) : mAngle(angle) {}
00155         operator Radian() const;
00156         operator Degree() const;
00157     };
00158 
00159     // these functions could not be defined within the class definition of class
00160     // Radian because they required class Degree to be defined
00161     inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
00162     }
00163     inline Radian& Radian::operator = ( const Degree& d ) {
00164         mRad = d.valueRadians(); return *this;
00165     }
00166     inline Radian Radian::operator + ( const Degree& d ) const {
00167         return Radian ( mRad + d.valueRadians() );
00168     }
00169     inline Radian& Radian::operator += ( const Degree& d ) {
00170         mRad += d.valueRadians();
00171         return *this;
00172     }
00173     inline Radian Radian::operator - ( const Degree& d ) const {
00174         return Radian ( mRad - d.valueRadians() );
00175     }
00176     inline Radian& Radian::operator -= ( const Degree& d ) {
00177         mRad -= d.valueRadians();
00178         return *this;
00179     }
00180 
00191     class _OgreExport Math 
00192     {
00193     public:
00199        enum AngleUnit
00200        {
00201            AU_DEGREE,
00202            AU_RADIAN
00203        };
00204 
00205 
00208        class RandomValueProvider
00209        {
00210        public:
00211             virtual ~RandomValueProvider() {}
00213             virtual Real getRandomUnit() = 0;
00214        };
00215 
00216     protected:
00218         static AngleUnit msAngleUnit;
00219 
00221         static int mTrigTableSize;
00222 
00224         static Real mTrigTableFactor;
00225         static Real* mSinTable;
00226         static Real* mTanTable;
00227 
00229         static RandomValueProvider* mRandProvider;
00230 
00233         void buildTrigTables();
00234 
00235         static Real SinTable (Real fValue);
00236         static Real TanTable (Real fValue);
00237     public:
00243         Math(unsigned int trigTableSize = 4096);
00244 
00247         ~Math();
00248 
00249         static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
00250         static inline int ICeil (float fValue) { return int(ceil(fValue)); }
00251         static inline int IFloor (float fValue) { return int(floor(fValue)); }
00252         static int ISign (int iValue);
00253 
00258         static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
00259 
00264         static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
00265 
00270         static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
00271 
00276         static Radian ACos (Real fValue);
00277 
00282         static Radian ASin (Real fValue);
00283 
00288         static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
00289 
00296         static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
00297 
00304         static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
00305         static inline bool isNaN(Real f)
00306         {
00307             // std::isnan() is C99, not supported by all compilers
00308             // However NaN always fails this next test, no other number does.
00309             return f != f;
00310         }
00311 
00319         static inline Real Cos (const Radian& fValue, bool useTables = false) {
00320             return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
00321         }
00329         static inline Real Cos (Real fValue, bool useTables = false) {
00330             return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
00331         }
00332 
00333         static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
00334 
00341         static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
00342 
00343         static inline Real Log (Real fValue) { return Real(log(fValue)); }
00344 
00346         static const Real LOG2;
00347 
00348         static inline Real Log2 (Real fValue) { return Real(log(fValue)/LOG2); }
00349 
00350         static inline Real LogN (Real base, Real fValue) { return Real(log(fValue)/log(base)); }
00351 
00352         static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
00353 
00354         static Real Sign (Real fValue);
00355         static inline Radian Sign ( const Radian& rValue )
00356         {
00357             return Radian(Sign(rValue.valueRadians()));
00358         }
00359         static inline Degree Sign ( const Degree& dValue )
00360         {
00361             return Degree(Sign(dValue.valueDegrees()));
00362         }
00363 
00364         //Simulate the shader function saturate that clamps a parameter value between 0 and 1
00365         static inline float saturate(float t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); }
00366         static inline double saturate(double t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); }
00367         
00368         //Simulate the shader function lerp which performers linear interpolation
00369         //given 3 parameters v0, v1 and t the function returns the value of (1 – t)* v0 + t * v1. 
00370         //where v0 and v1 are matching vector or scalar types and t can be either a scalar or a vector of the same type as a and b.
00371         template<typename V, typename T> static V lerp(const V& v0, const V& v1, const T& t) { 
00372             return v0 * (1 - t) + v1 * t; }
00373 
00381         static inline Real Sin (const Radian& fValue, bool useTables = false) {
00382             return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
00383         }
00391         static inline Real Sin (Real fValue, bool useTables = false) {
00392             return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
00393         }
00394 
00399         static inline Real Sqr (Real fValue) { return fValue*fValue; }
00400 
00405         static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
00406 
00413         static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
00414 
00421         static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
00422 
00428         static Real InvSqrt (Real fValue);
00429 
00434         static Real UnitRandom ();
00435 
00444         static Real RangeRandom (Real fLow, Real fHigh);
00445 
00450         static Real SymmetricRandom ();
00451 
00452         static void SetRandomValueProvider(RandomValueProvider* provider);
00453        
00461         static inline Real Tan (const Radian& fValue, bool useTables = false) {
00462             return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
00463         }
00471         static inline Real Tan (Real fValue, bool useTables = false) {
00472             return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
00473         }
00474 
00475         static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
00476         static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
00477 
00484        static void setAngleUnit(AngleUnit unit);
00486        static AngleUnit getAngleUnit(void);
00487 
00489        static Real AngleUnitsToRadians(Real units);
00491        static Real RadiansToAngleUnits(Real radians);
00493        static Real AngleUnitsToDegrees(Real units);
00495        static Real DegreesToAngleUnits(Real degrees);
00496 
00518         static bool pointInTri2D(const Vector2& p, const Vector2& a, 
00519             const Vector2& b, const Vector2& c);
00520 
00545         static bool pointInTri3D(const Vector3& p, const Vector3& a, 
00546             const Vector3& b, const Vector3& c, const Vector3& normal);
00548         static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
00549 
00551         static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 
00552             bool discardInside = true);
00553         
00555         static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box);
00556 
00579         static bool intersects(const Ray& ray, const AxisAlignedBox& box,
00580             Real* d1, Real* d2);
00581 
00606         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
00607             const Vector3& b, const Vector3& c, const Vector3& normal,
00608             bool positiveSide = true, bool negativeSide = true);
00609 
00630         static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a,
00631             const Vector3& b, const Vector3& c,
00632             bool positiveSide = true, bool negativeSide = true);
00633 
00635         static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
00636 
00638         static bool intersects(const Plane& plane, const AxisAlignedBox& box);
00639 
00645         static std::pair<bool, Real> intersects(
00646             const Ray& ray, const vector<Plane>::type& planeList, 
00647             bool normalIsOutside);
00653         static std::pair<bool, Real> intersects(
00654             const Ray& ray, const list<Plane>::type& planeList, 
00655             bool normalIsOutside);
00656 
00660         static bool intersects(const Sphere& sphere, const Plane& plane);
00661 
00664         static bool RealEqual(Real a, Real b,
00665             Real tolerance = std::numeric_limits<Real>::epsilon());
00666 
00668         static Vector3 calculateTangentSpaceVector(
00669             const Vector3& position1, const Vector3& position2, const Vector3& position3,
00670             Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
00671 
00673         static Matrix4 buildReflectionMatrix(const Plane& p);
00675         static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00677         static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00679         static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00681         static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
00682 
00686         static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
00687 
00689         template <typename T>
00690         static T Clamp(T val, T minval, T maxval)
00691         {
00692             assert (minval <= maxval && "Invalid clamp range");
00693             return std::max(std::min(val, maxval), minval);
00694         }
00695 
00696         static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, 
00697             const Matrix4* reflectMatrix = 0);
00698 
00700         static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);
00701 
00702 
00703 
00704         static const Real POS_INFINITY;
00705         static const Real NEG_INFINITY;
00706         static const Real PI;
00707         static const Real TWO_PI;
00708         static const Real HALF_PI;
00709         static const Real fDeg2Rad;
00710         static const Real fRad2Deg;
00711 
00712     };
00713 
00714     // these functions must be defined down here, because they rely on the
00715     // angle unit conversion functions in class Math:
00716 
00717     inline Real Radian::valueDegrees() const
00718     {
00719         return Math::RadiansToDegrees ( mRad );
00720     }
00721 
00722     inline Real Radian::valueAngleUnits() const
00723     {
00724         return Math::RadiansToAngleUnits ( mRad );
00725     }
00726 
00727     inline Real Degree::valueRadians() const
00728     {
00729         return Math::DegreesToRadians ( mDeg );
00730     }
00731 
00732     inline Real Degree::valueAngleUnits() const
00733     {
00734         return Math::DegreesToAngleUnits ( mDeg );
00735     }
00736 
00737     inline Angle::operator Radian() const
00738     {
00739         return Radian(Math::AngleUnitsToRadians(mAngle));
00740     }
00741 
00742     inline Angle::operator Degree() const
00743     {
00744         return Degree(Math::AngleUnitsToDegrees(mAngle));
00745     }
00746 
00747     inline Radian operator * ( Real a, const Radian& b )
00748     {
00749         return Radian ( a * b.valueRadians() );
00750     }
00751 
00752     inline Radian operator / ( Real a, const Radian& b )
00753     {
00754         return Radian ( a / b.valueRadians() );
00755     }
00756 
00757     inline Degree operator * ( Real a, const Degree& b )
00758     {
00759         return Degree ( a * b.valueDegrees() );
00760     }
00761 
00762     inline Degree operator / ( Real a, const Degree& b )
00763     {
00764         return Degree ( a / b.valueDegrees() );
00765     }
00769 }
00770 
00771 #include "OgreHeaderSuffix.h"
00772 
00773 #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 Mon Jul 27 2020 13:40:44