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-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 #ifndef __Math_H__ 00030 #define __Math_H__ 00031 00032 #include "OgrePrerequisites.h" 00033 00034 namespace Ogre 00035 { 00041 class Radian 00042 { 00043 Real mRad; 00044 00045 public: 00046 explicit Radian ( Real r=0 ) : mRad(r) {} 00047 Radian ( const Degree& d ); 00048 Radian& operator = ( const Real& f ) { mRad = f; return *this; } 00049 Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } 00050 Radian& operator = ( const Degree& d ); 00051 00052 Real valueDegrees() const; // see bottom of this file 00053 Real valueRadians() const { return mRad; } 00054 Real valueAngleUnits() const; 00055 00056 const Radian& operator + () const { return *this; } 00057 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } 00058 Radian operator + ( const Degree& d ) const; 00059 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } 00060 Radian& operator += ( const Degree& d ); 00061 Radian operator - () const { return Radian(-mRad); } 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 * ( Real f ) const { return Radian ( mRad * f ); } 00067 Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); } 00068 Radian& operator *= ( Real f ) { mRad *= f; return *this; } 00069 Radian operator / ( Real f ) const { return Radian ( mRad / f ); } 00070 Radian& operator /= ( Real f ) { mRad /= f; return *this; } 00071 00072 bool operator < ( const Radian& r ) const { return mRad < r.mRad; } 00073 bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; } 00074 bool operator == ( const Radian& r ) const { return mRad == r.mRad; } 00075 bool operator != ( const Radian& r ) const { return mRad != r.mRad; } 00076 bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; } 00077 bool operator > ( const Radian& r ) const { return mRad > r.mRad; } 00078 }; 00079 00085 class Degree 00086 { 00087 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first 00088 00089 public: 00090 explicit Degree ( Real d=0 ) : mDeg(d) {} 00091 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} 00092 Degree& operator = ( const Real& f ) { mDeg = f; return *this; } 00093 Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } 00094 Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } 00095 00096 Real valueDegrees() const { return mDeg; } 00097 Real valueRadians() const; // see bottom of this file 00098 Real valueAngleUnits() const; 00099 00100 const Degree& operator + () const { return *this; } 00101 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } 00102 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } 00103 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } 00104 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } 00105 Degree operator - () const { return Degree(-mDeg); } 00106 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } 00107 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } 00108 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } 00109 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } 00110 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } 00111 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } 00112 Degree& operator *= ( Real f ) { mDeg *= f; return *this; } 00113 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } 00114 Degree& operator /= ( Real f ) { mDeg /= f; return *this; } 00115 00116 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } 00117 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } 00118 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } 00119 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } 00120 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } 00121 bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } 00122 }; 00123 00130 class Angle 00131 { 00132 Real mAngle; 00133 public: 00134 explicit Angle ( Real angle ) : mAngle(angle) {} 00135 operator Radian() const; 00136 operator Degree() const; 00137 }; 00138 00139 // these functions could not be defined within the class definition of class 00140 // Radian because they required class Degree to be defined 00141 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { 00142 } 00143 inline Radian& Radian::operator = ( const Degree& d ) { 00144 mRad = d.valueRadians(); return *this; 00145 } 00146 inline Radian Radian::operator + ( const Degree& d ) const { 00147 return Radian ( mRad + d.valueRadians() ); 00148 } 00149 inline Radian& Radian::operator += ( const Degree& d ) { 00150 mRad += d.valueRadians(); 00151 return *this; 00152 } 00153 inline Radian Radian::operator - ( const Degree& d ) const { 00154 return Radian ( mRad - d.valueRadians() ); 00155 } 00156 inline Radian& Radian::operator -= ( const Degree& d ) { 00157 mRad -= d.valueRadians(); 00158 return *this; 00159 } 00160 00171 class _OgreExport Math 00172 { 00173 public: 00179 enum AngleUnit 00180 { 00181 AU_DEGREE, 00182 AU_RADIAN 00183 }; 00184 00185 protected: 00186 // angle units used by the api 00187 static AngleUnit msAngleUnit; 00188 00190 static int mTrigTableSize; 00191 00193 static Real mTrigTableFactor; 00194 static Real* mSinTable; 00195 static Real* mTanTable; 00196 00199 void buildTrigTables(); 00200 00201 static Real SinTable (Real fValue); 00202 static Real TanTable (Real fValue); 00203 public: 00209 Math(unsigned int trigTableSize = 4096); 00210 00213 ~Math(); 00214 00215 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } 00216 static inline int ICeil (float fValue) { return int(ceil(fValue)); } 00217 static inline int IFloor (float fValue) { return int(floor(fValue)); } 00218 static int ISign (int iValue); 00219 00220 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } 00221 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } 00222 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); } 00223 static Radian ACos (Real fValue); 00224 static Radian ASin (Real fValue); 00225 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } 00226 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } 00227 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } 00228 00236 static inline Real Cos (const Radian& fValue, bool useTables = false) { 00237 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); 00238 } 00246 static inline Real Cos (Real fValue, bool useTables = false) { 00247 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); 00248 } 00249 00250 static inline Real Exp (Real fValue) { return Real(exp(fValue)); } 00251 00252 static inline Real Floor (Real fValue) { return Real(floor(fValue)); } 00253 00254 static inline Real Log (Real fValue) { return Real(log(fValue)); } 00255 00256 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); } 00257 00258 static Real Sign (Real fValue); 00259 static inline Radian Sign ( const Radian& rValue ) 00260 { 00261 return Radian(Sign(rValue.valueRadians())); 00262 } 00263 static inline Degree Sign ( const Degree& dValue ) 00264 { 00265 return Degree(Sign(dValue.valueDegrees())); 00266 } 00267 00275 static inline Real Sin (const Radian& fValue, bool useTables = false) { 00276 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); 00277 } 00285 static inline Real Sin (Real fValue, bool useTables = false) { 00286 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); 00287 } 00288 00289 static inline Real Sqr (Real fValue) { return fValue*fValue; } 00290 00291 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } 00292 00293 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); } 00294 00295 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); } 00296 00300 static Real InvSqrt(Real fValue); 00301 00302 static Real UnitRandom (); // in [0,1] 00303 00304 static Real RangeRandom (Real fLow, Real fHigh); // in [fLow,fHigh] 00305 00306 static Real SymmetricRandom (); // in [-1,1] 00307 00315 static inline Real Tan (const Radian& fValue, bool useTables = false) { 00316 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); 00317 } 00325 static inline Real Tan (Real fValue, bool useTables = false) { 00326 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); 00327 } 00328 00329 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } 00330 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 00331 00338 static void setAngleUnit(AngleUnit unit); 00340 static AngleUnit getAngleUnit(void); 00341 00343 static Real AngleUnitsToRadians(Real units); 00345 static Real RadiansToAngleUnits(Real radians); 00347 static Real AngleUnitsToDegrees(Real units); 00349 static Real DegreesToAngleUnits(Real degrees); 00350 00372 static bool pointInTri2D(const Vector2& p, const Vector2& a, 00373 const Vector2& b, const Vector2& c); 00374 00399 static bool pointInTri3D(const Vector3& p, const Vector3& a, 00400 const Vector3& b, const Vector3& c, const Vector3& normal); 00402 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane); 00403 00405 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 00406 bool discardInside = true); 00407 00409 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box); 00410 00433 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 00434 Real* d1, Real* d2); 00435 00460 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00461 const Vector3& b, const Vector3& c, const Vector3& normal, 00462 bool positiveSide = true, bool negativeSide = true); 00463 00484 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00485 const Vector3& b, const Vector3& c, 00486 bool positiveSide = true, bool negativeSide = true); 00487 00489 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 00490 00492 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 00493 00499 static std::pair<bool, Real> intersects( 00500 const Ray& ray, const std::vector<Plane>& planeList, 00501 bool normalIsOutside); 00507 static std::pair<bool, Real> intersects( 00508 const Ray& ray, const std::list<Plane>& planeList, 00509 bool normalIsOutside); 00510 00514 static bool intersects(const Sphere& sphere, const Plane& plane); 00515 00518 static bool RealEqual(Real a, Real b, 00519 Real tolerance = std::numeric_limits<Real>::epsilon()); 00520 00522 static Vector3 calculateTangentSpaceVector( 00523 const Vector3& position1, const Vector3& position2, const Vector3& position3, 00524 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 00525 00527 static Matrix4 buildReflectionMatrix(const Plane& p); 00529 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00531 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00533 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00535 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00536 00540 static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); 00541 00543 template <typename T> 00544 static T Clamp(T val, T minval, T maxval) 00545 { 00546 assert (minval < maxval && "Invalid clamp range"); 00547 return std::max(std::min(val, maxval), minval); 00548 } 00549 00550 static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, 00551 const Matrix4* reflectMatrix = 0); 00552 00553 00554 00555 static const Real POS_INFINITY; 00556 static const Real NEG_INFINITY; 00557 static const Real PI; 00558 static const Real TWO_PI; 00559 static const Real HALF_PI; 00560 static const Real fDeg2Rad; 00561 static const Real fRad2Deg; 00562 00563 }; 00564 00565 // these functions must be defined down here, because they rely on the 00566 // angle unit conversion functions in class Math: 00567 00568 inline Real Radian::valueDegrees() const 00569 { 00570 return Math::RadiansToDegrees ( mRad ); 00571 } 00572 00573 inline Real Radian::valueAngleUnits() const 00574 { 00575 return Math::RadiansToAngleUnits ( mRad ); 00576 } 00577 00578 inline Real Degree::valueRadians() const 00579 { 00580 return Math::DegreesToRadians ( mDeg ); 00581 } 00582 00583 inline Real Degree::valueAngleUnits() const 00584 { 00585 return Math::DegreesToAngleUnits ( mDeg ); 00586 } 00587 00588 inline Angle::operator Radian() const 00589 { 00590 return Radian(Math::AngleUnitsToRadians(mAngle)); 00591 } 00592 00593 inline Angle::operator Degree() const 00594 { 00595 return Degree(Math::AngleUnitsToDegrees(mAngle)); 00596 } 00597 00598 inline Radian operator * ( Real a, const Radian& b ) 00599 { 00600 return Radian ( a * b.valueRadians() ); 00601 } 00602 00603 inline Radian operator / ( Real a, const Radian& b ) 00604 { 00605 return Radian ( a / b.valueRadians() ); 00606 } 00607 00608 inline Degree operator * ( Real a, const Degree& b ) 00609 { 00610 return Degree ( a * b.valueDegrees() ); 00611 } 00612 00613 inline Degree operator / ( Real a, const Degree& b ) 00614 { 00615 return Degree ( a / b.valueDegrees() ); 00616 } 00617 00618 } 00619 #endif
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Tue Nov 4 11:02:30 2008