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-2005 The OGRE Team 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 */ 00025 #ifndef __Math_H__ 00026 #define __Math_H__ 00027 00028 #include "OgrePrerequisites.h" 00029 00030 namespace Ogre 00031 { 00037 class Radian 00038 { 00039 Real mRad; 00040 00041 public: 00042 explicit Radian ( Real r=0 ) : mRad(r) {} 00043 Radian ( const Degree& d ); 00044 Radian& operator = ( const Real& f ) { mRad = f; return *this; } 00045 Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } 00046 Radian& operator = ( const Degree& d ); 00047 00048 Real valueDegrees() const; // see bottom of this file 00049 Real valueRadians() const { return mRad; } 00050 Real valueAngleUnits() const; 00051 00052 const Radian& operator + () const { return *this; } 00053 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } 00054 Radian operator + ( const Degree& d ) const; 00055 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } 00056 Radian& operator += ( const Degree& d ); 00057 Radian operator - () const { return Radian(-mRad); } 00058 Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); } 00059 Radian operator - ( const Degree& d ) const; 00060 Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; } 00061 Radian& operator -= ( const Degree& d ); 00062 Radian operator * ( Real f ) const { return Radian ( mRad * f ); } 00063 Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); } 00064 Radian& operator *= ( Real f ) { mRad *= f; return *this; } 00065 Radian operator / ( Real f ) const { return Radian ( mRad / f ); } 00066 Radian& operator /= ( Real f ) { mRad /= f; return *this; } 00067 00068 bool operator < ( const Radian& r ) const { return mRad < r.mRad; } 00069 bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; } 00070 bool operator == ( const Radian& r ) const { return mRad == r.mRad; } 00071 bool operator != ( const Radian& r ) const { return mRad != r.mRad; } 00072 bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; } 00073 bool operator > ( const Radian& r ) const { return mRad > r.mRad; } 00074 }; 00075 00081 class Degree 00082 { 00083 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first 00084 00085 public: 00086 explicit Degree ( Real d=0 ) : mDeg(d) {} 00087 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} 00088 Degree& operator = ( const Real& f ) { mDeg = f; return *this; } 00089 Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } 00090 Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } 00091 00092 Real valueDegrees() const { return mDeg; } 00093 Real valueRadians() const; // see bottom of this file 00094 Real valueAngleUnits() const; 00095 00096 const Degree& operator + () const { return *this; } 00097 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } 00098 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } 00099 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } 00100 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } 00101 Degree operator - () const { return Degree(-mDeg); } 00102 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } 00103 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } 00104 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } 00105 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } 00106 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } 00107 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } 00108 Degree& operator *= ( Real f ) { mDeg *= f; return *this; } 00109 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } 00110 Degree& operator /= ( Real f ) { mDeg /= f; return *this; } 00111 00112 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } 00113 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } 00114 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } 00115 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } 00116 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } 00117 bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } 00118 }; 00119 00126 class Angle 00127 { 00128 Real mAngle; 00129 public: 00130 explicit Angle ( Real angle ) : mAngle(angle) {} 00131 operator Radian() const; 00132 operator Degree() const; 00133 }; 00134 00135 // these functions could not be defined within the class definition of class 00136 // Radian because they required class Degree to be defined 00137 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { 00138 } 00139 inline Radian& Radian::operator = ( const Degree& d ) { 00140 mRad = d.valueRadians(); return *this; 00141 } 00142 inline Radian Radian::operator + ( const Degree& d ) const { 00143 return Radian ( mRad + d.valueRadians() ); 00144 } 00145 inline Radian& Radian::operator += ( const Degree& d ) { 00146 mRad += d.valueRadians(); 00147 return *this; 00148 } 00149 inline Radian Radian::operator - ( const Degree& d ) const { 00150 return Radian ( mRad - d.valueRadians() ); 00151 } 00152 inline Radian& Radian::operator -= ( const Degree& d ) { 00153 mRad -= d.valueRadians(); 00154 return *this; 00155 } 00156 00167 class _OgreExport Math 00168 { 00169 public: 00175 enum AngleUnit 00176 { 00177 AU_DEGREE, 00178 AU_RADIAN 00179 }; 00180 00181 protected: 00182 // angle units used by the api 00183 static AngleUnit msAngleUnit; 00184 00186 static int mTrigTableSize; 00187 00189 static Real mTrigTableFactor; 00190 static Real* mSinTable; 00191 static Real* mTanTable; 00192 00195 void buildTrigTables(); 00196 00197 static Real SinTable (Real fValue); 00198 static Real TanTable (Real fValue); 00199 public: 00205 Math(unsigned int trigTableSize = 4096); 00206 00209 ~Math(); 00210 00211 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } 00212 static inline int ICeil (float fValue) { return int(ceil(fValue)); } 00213 static inline int IFloor (float fValue) { return int(floor(fValue)); } 00214 static int ISign (int iValue); 00215 00216 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } 00217 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } 00218 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); } 00219 static Radian ACos (Real fValue); 00220 static Radian ASin (Real fValue); 00221 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } 00222 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } 00223 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } 00224 00232 static inline Real Cos (const Radian& fValue, bool useTables = false) { 00233 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); 00234 } 00242 static inline Real Cos (Real fValue, bool useTables = false) { 00243 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); 00244 } 00245 00246 static inline Real Exp (Real fValue) { return Real(exp(fValue)); } 00247 00248 static inline Real Floor (Real fValue) { return Real(floor(fValue)); } 00249 00250 static inline Real Log (Real fValue) { return Real(log(fValue)); } 00251 00252 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); } 00253 00254 static Real Sign (Real fValue); 00255 static inline Radian Sign ( const Radian& rValue ) 00256 { 00257 return Radian(Sign(rValue.valueRadians())); 00258 } 00259 static inline Degree Sign ( const Degree& dValue ) 00260 { 00261 return Degree(Sign(dValue.valueDegrees())); 00262 } 00263 00271 static inline Real Sin (const Radian& fValue, bool useTables = false) { 00272 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); 00273 } 00281 static inline Real Sin (Real fValue, bool useTables = false) { 00282 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); 00283 } 00284 00285 static inline Real Sqr (Real fValue) { return fValue*fValue; } 00286 00287 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } 00288 00289 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); } 00290 00291 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); } 00292 00296 static Real InvSqrt(Real fValue); 00297 00298 static Real UnitRandom (); // in [0,1] 00299 00300 static Real RangeRandom (Real fLow, Real fHigh); // in [fLow,fHigh] 00301 00302 static Real SymmetricRandom (); // in [-1,1] 00303 00311 static inline Real Tan (const Radian& fValue, bool useTables = false) { 00312 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); 00313 } 00321 static inline Real Tan (Real fValue, bool useTables = false) { 00322 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); 00323 } 00324 00325 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } 00326 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 00327 00334 static void setAngleUnit(AngleUnit unit); 00336 static AngleUnit getAngleUnit(void); 00337 00339 static Real AngleUnitsToRadians(Real units); 00341 static Real RadiansToAngleUnits(Real radians); 00343 static Real AngleUnitsToDegrees(Real units); 00345 static Real DegreesToAngleUnits(Real degrees); 00346 00368 static bool pointInTri2D(const Vector2& p, const Vector2& a, 00369 const Vector2& b, const Vector2& c); 00370 00395 static bool pointInTri3D(const Vector3& p, const Vector3& a, 00396 const Vector3& b, const Vector3& c, const Vector3& normal); 00398 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane); 00399 00401 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 00402 bool discardInside = true); 00403 00405 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box); 00406 00429 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 00430 Real* d1, Real* d2); 00431 00456 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00457 const Vector3& b, const Vector3& c, const Vector3& normal, 00458 bool positiveSide = true, bool negativeSide = true); 00459 00480 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00481 const Vector3& b, const Vector3& c, 00482 bool positiveSide = true, bool negativeSide = true); 00483 00485 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 00486 00488 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 00489 00495 static std::pair<bool, Real> intersects( 00496 const Ray& ray, const std::vector<Plane>& planeList, 00497 bool normalIsOutside); 00503 static std::pair<bool, Real> intersects( 00504 const Ray& ray, const std::list<Plane>& planeList, 00505 bool normalIsOutside); 00506 00510 static bool intersects(const Sphere& sphere, const Plane& plane); 00511 00514 static bool RealEqual(Real a, Real b, 00515 Real tolerance = std::numeric_limits<Real>::epsilon()); 00516 00518 static Vector3 calculateTangentSpaceVector( 00519 const Vector3& position1, const Vector3& position2, const Vector3& position3, 00520 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 00521 00523 static Matrix4 buildReflectionMatrix(const Plane& p); 00525 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00527 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00529 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00531 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00532 00536 static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); 00537 00538 static const Real POS_INFINITY; 00539 static const Real NEG_INFINITY; 00540 static const Real PI; 00541 static const Real TWO_PI; 00542 static const Real HALF_PI; 00543 static const Real fDeg2Rad; 00544 static const Real fRad2Deg; 00545 00546 }; 00547 00548 // these functions must be defined down here, because they rely on the 00549 // angle unit conversion functions in class Math: 00550 00551 inline Real Radian::valueDegrees() const 00552 { 00553 return Math::RadiansToDegrees ( mRad ); 00554 } 00555 00556 inline Real Radian::valueAngleUnits() const 00557 { 00558 return Math::RadiansToAngleUnits ( mRad ); 00559 } 00560 00561 inline Real Degree::valueRadians() const 00562 { 00563 return Math::DegreesToRadians ( mDeg ); 00564 } 00565 00566 inline Real Degree::valueAngleUnits() const 00567 { 00568 return Math::DegreesToAngleUnits ( mDeg ); 00569 } 00570 00571 inline Angle::operator Radian() const 00572 { 00573 return Radian(Math::AngleUnitsToRadians(mAngle)); 00574 } 00575 00576 inline Angle::operator Degree() const 00577 { 00578 return Degree(Math::AngleUnitsToDegrees(mAngle)); 00579 } 00580 00581 inline Radian operator * ( Real a, const Radian& b ) 00582 { 00583 return Radian ( a * b.valueRadians() ); 00584 } 00585 00586 inline Radian operator / ( Real a, const Radian& b ) 00587 { 00588 return Radian ( a / b.valueRadians() ); 00589 } 00590 00591 inline Degree operator * ( Real a, const Degree& b ) 00592 { 00593 return Degree ( a * b.valueDegrees() ); 00594 } 00595 00596 inline Degree operator / ( Real a, const Degree& b ) 00597 { 00598 return Degree ( a / b.valueDegrees() ); 00599 } 00600 00601 } 00602 #endif
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Jan 21 10:01:37 2007