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 const Radian& operator = ( const Real& f ) { mRad = f; return *this; } 00045 const Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } 00046 const 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 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } 00053 Radian operator + ( const Degree& d ) const; 00054 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } 00055 Radian& operator += ( const Degree& d ); 00056 Radian operator - () { return Radian(-mRad); } 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 * ( Real f ) const { return Radian ( mRad * f ); } 00062 Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); } 00063 Radian& operator *= ( Real f ) { mRad *= f; return *this; } 00064 Radian operator / ( Real f ) const { return Radian ( mRad / f ); } 00065 Radian& operator /= ( Real f ) { mRad /= f; return *this; } 00066 00067 bool operator < ( const Radian& r ) const { return mRad < r.mRad; } 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 }; 00074 00080 class Degree 00081 { 00082 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first 00083 00084 public: 00085 explicit Degree ( Real d=0 ) : mDeg(d) {} 00086 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} 00087 const Degree& operator = ( const Real& f ) { mDeg = f; return *this; } 00088 const Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } 00089 const Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } 00090 00091 Real valueDegrees() const { return mDeg; } 00092 Real valueRadians() const; // see bottom of this file 00093 Real valueAngleUnits() const; 00094 00095 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } 00096 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } 00097 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } 00098 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } 00099 Degree operator - () { return Degree(-mDeg); } 00100 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } 00101 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } 00102 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } 00103 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } 00104 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } 00105 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } 00106 Degree& operator *= ( Real f ) { mDeg *= f; return *this; } 00107 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } 00108 Degree& operator /= ( Real f ) { mDeg /= f; return *this; } 00109 00110 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } 00111 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } 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 }; 00117 00124 class Angle 00125 { 00126 Real mAngle; 00127 public: 00128 explicit Angle ( Real angle ) : mAngle(angle) {} 00129 operator Radian(); 00130 operator Degree(); 00131 }; 00132 00133 // these functions could not be defined within the class definition of class 00134 // Radian because they required class Degree to be defined 00135 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { 00136 } 00137 inline const Radian& Radian::operator = ( const Degree& d ) { 00138 mRad = d.valueRadians(); return *this; 00139 } 00140 inline Radian Radian::operator + ( const Degree& d ) const { 00141 return Radian ( mRad + d.valueRadians() ); 00142 } 00143 inline Radian& Radian::operator += ( const Degree& d ) { 00144 mRad += d.valueRadians(); 00145 return *this; 00146 } 00147 inline Radian Radian::operator - ( const Degree& d ) const { 00148 return Radian ( mRad - d.valueRadians() ); 00149 } 00150 inline Radian& Radian::operator -= ( const Degree& d ) { 00151 mRad -= d.valueRadians(); 00152 return *this; 00153 } 00154 00165 class _OgreExport Math 00166 { 00167 public: 00173 enum AngleUnit 00174 { 00175 AU_DEGREE, 00176 AU_RADIAN 00177 }; 00178 00179 protected: 00180 // angle units used by the api 00181 static AngleUnit msAngleUnit; 00182 00184 static int mTrigTableSize; 00185 00187 static Real mTrigTableFactor; 00188 static Real* mSinTable; 00189 static Real* mTanTable; 00190 00193 void buildTrigTables(); 00194 00195 static Real SinTable (Real fValue); 00196 static Real TanTable (Real fValue); 00197 public: 00203 Math(unsigned int trigTableSize = 4096); 00204 00207 ~Math(); 00208 00209 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } 00210 static inline int ICeil (float fValue) { return int(ceil(fValue)); } 00211 static inline int IFloor (float fValue) { return int(floor(fValue)); } 00212 static int ISign (int iValue); 00213 00214 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } 00215 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } 00216 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); } 00217 static Radian ACos (Real fValue); 00218 static Radian ASin (Real fValue); 00219 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } 00220 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } 00221 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } 00222 00230 static inline Real Cos (const Radian& fValue, bool useTables = false) { 00231 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); 00232 } 00240 static inline Real Cos (Real fValue, bool useTables = false) { 00241 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); 00242 } 00243 00244 static inline Real Exp (Real fValue) { return Real(exp(fValue)); } 00245 00246 static inline Real Floor (Real fValue) { return Real(floor(fValue)); } 00247 00248 static inline Real Log (Real fValue) { return Real(log(fValue)); } 00249 00250 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); } 00251 00252 static Real Sign (Real fValue); 00253 static inline Radian Sign ( const Radian& rValue ) 00254 { 00255 return Radian(Sign(rValue.valueRadians())); 00256 } 00257 static inline Degree Sign ( const Degree& dValue ) 00258 { 00259 return Degree(Sign(dValue.valueDegrees())); 00260 } 00261 00269 static inline Real Sin (const Radian& fValue, bool useTables = false) { 00270 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); 00271 } 00279 static inline Real Sin (Real fValue, bool useTables = false) { 00280 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); 00281 } 00282 00283 static inline Real Sqr (Real fValue) { return fValue*fValue; } 00284 00285 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } 00286 00287 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); } 00288 00289 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); } 00290 00294 static Real InvSqrt(Real fValue); 00295 00296 static Real UnitRandom (); // in [0,1] 00297 00298 static Real RangeRandom (Real fLow, Real fHigh); // in [fLow,fHigh] 00299 00300 static Real SymmetricRandom (); // in [-1,1] 00301 00309 static inline Real Tan (const Radian& fValue, bool useTables = false) { 00310 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); 00311 } 00319 static inline Real Tan (Real fValue, bool useTables = false) { 00320 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); 00321 } 00322 00323 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } 00324 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 00325 00332 static void setAngleUnit(AngleUnit unit); 00334 static AngleUnit getAngleUnit(void); 00335 00337 static Real AngleUnitsToRadians(Real units); 00339 static Real RadiansToAngleUnits(Real radians); 00341 static Real AngleUnitsToDegrees(Real units); 00343 static Real DegreesToAngleUnits(Real degrees); 00344 00366 static bool pointInTri2D(const Vector2& p, const Vector2& a, 00367 const Vector2& b, const Vector2& c); 00368 00393 static bool pointInTri3D(const Vector3& p, const Vector3& a, 00394 const Vector3& b, const Vector3& c, const Vector3& normal); 00396 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane); 00397 00399 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 00400 bool discardInside = true); 00401 00403 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box); 00404 00427 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 00428 Real* d1, Real* d2); 00429 00454 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00455 const Vector3& b, const Vector3& c, const Vector3& normal, 00456 bool positiveSide = true, bool negativeSide = true); 00457 00478 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00479 const Vector3& b, const Vector3& c, 00480 bool positiveSide = true, bool negativeSide = true); 00481 00483 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 00484 00486 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 00487 00493 static std::pair<bool, Real> intersects( 00494 const Ray& ray, const std::vector<Plane>& planeList, 00495 bool normalIsOutside); 00501 static std::pair<bool, Real> intersects( 00502 const Ray& ray, const std::list<Plane>& planeList, 00503 bool normalIsOutside); 00504 00508 static bool intersects(const Sphere& sphere, const Plane& plane); 00509 00512 static bool RealEqual(Real a, Real b, 00513 Real tolerance = std::numeric_limits<Real>::epsilon()); 00514 00516 static Vector3 calculateTangentSpaceVector( 00517 const Vector3& position1, const Vector3& position2, const Vector3& position3, 00518 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 00519 00521 static Matrix4 buildReflectionMatrix(const Plane& p); 00523 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00525 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00527 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00529 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00530 00531 static const Real POS_INFINITY; 00532 static const Real NEG_INFINITY; 00533 static const Real PI; 00534 static const Real TWO_PI; 00535 static const Real HALF_PI; 00536 static const Real fDeg2Rad; 00537 static const Real fRad2Deg; 00538 00539 }; 00540 00541 // these functions must be defined down here, because they rely on the 00542 // angle unit conversion functions in class Math: 00543 00544 inline Real Radian::valueDegrees() const 00545 { 00546 return Math::RadiansToDegrees ( mRad ); 00547 } 00548 00549 inline Real Radian::valueAngleUnits() const 00550 { 00551 return Math::RadiansToAngleUnits ( mRad ); 00552 } 00553 00554 inline Real Degree::valueRadians() const 00555 { 00556 return Math::DegreesToRadians ( mDeg ); 00557 } 00558 00559 inline Real Degree::valueAngleUnits() const 00560 { 00561 return Math::DegreesToAngleUnits ( mDeg ); 00562 } 00563 00564 inline Angle::operator Radian() 00565 { 00566 return Radian(Math::AngleUnitsToRadians(mAngle)); 00567 } 00568 00569 inline Angle::operator Degree() 00570 { 00571 return Degree(Math::AngleUnitsToDegrees(mAngle)); 00572 } 00573 00574 inline Radian operator * ( Real a, const Radian& b ) 00575 { 00576 return Radian ( a * b.valueRadians() ); 00577 } 00578 00579 inline Radian operator / ( Real a, const Radian& b ) 00580 { 00581 return Radian ( a / b.valueRadians() ); 00582 } 00583 00584 inline Degree operator * ( Real a, const Degree& b ) 00585 { 00586 return Degree ( a * b.valueDegrees() ); 00587 } 00588 00589 inline Degree operator / ( Real a, const Degree& b ) 00590 { 00591 return Degree ( a / b.valueDegrees() ); 00592 } 00593 00594 } 00595 #endif
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:44 2006