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

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Mon Jul 27 2020 13:40:44