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