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 inline _OgreExport friend std::ostream& operator << 00080 ( std::ostream& o, const Radian& v ) 00081 { 00082 o << "Radian(" << v.valueRadians() << ")"; 00083 return o; 00084 } 00085 }; 00086 00092 class Degree 00093 { 00094 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first 00095 00096 public: 00097 explicit Degree ( Real d=0 ) : mDeg(d) {} 00098 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} 00099 Degree& operator = ( const Real& f ) { mDeg = f; return *this; } 00100 Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } 00101 Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } 00102 00103 Real valueDegrees() const { return mDeg; } 00104 Real valueRadians() const; // see bottom of this file 00105 Real valueAngleUnits() const; 00106 00107 const Degree& operator + () const { return *this; } 00108 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } 00109 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } 00110 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } 00111 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } 00112 Degree operator - () const { return Degree(-mDeg); } 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 * ( Real f ) const { return Degree ( mDeg * f ); } 00118 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } 00119 Degree& operator *= ( Real f ) { mDeg *= f; return *this; } 00120 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } 00121 Degree& operator /= ( Real f ) { mDeg /= f; return *this; } 00122 00123 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } 00124 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } 00125 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } 00126 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } 00127 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } 00128 bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } 00129 00130 inline _OgreExport friend std::ostream& operator << 00131 ( std::ostream& o, const Degree& v ) 00132 { 00133 o << "Degree(" << v.valueDegrees() << ")"; 00134 return o; 00135 } 00136 }; 00137 00144 class Angle 00145 { 00146 Real mAngle; 00147 public: 00148 explicit Angle ( Real angle ) : mAngle(angle) {} 00149 operator Radian() const; 00150 operator Degree() const; 00151 }; 00152 00153 // these functions could not be defined within the class definition of class 00154 // Radian because they required class Degree to be defined 00155 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { 00156 } 00157 inline Radian& Radian::operator = ( const Degree& d ) { 00158 mRad = d.valueRadians(); return *this; 00159 } 00160 inline Radian Radian::operator + ( const Degree& d ) const { 00161 return Radian ( mRad + d.valueRadians() ); 00162 } 00163 inline Radian& Radian::operator += ( const Degree& d ) { 00164 mRad += d.valueRadians(); 00165 return *this; 00166 } 00167 inline Radian Radian::operator - ( const Degree& d ) const { 00168 return Radian ( mRad - d.valueRadians() ); 00169 } 00170 inline Radian& Radian::operator -= ( const Degree& d ) { 00171 mRad -= d.valueRadians(); 00172 return *this; 00173 } 00174 00185 class _OgreExport Math 00186 { 00187 public: 00193 enum AngleUnit 00194 { 00195 AU_DEGREE, 00196 AU_RADIAN 00197 }; 00198 00199 protected: 00200 // angle units used by the api 00201 static AngleUnit msAngleUnit; 00202 00204 static int mTrigTableSize; 00205 00207 static Real mTrigTableFactor; 00208 static Real* mSinTable; 00209 static Real* mTanTable; 00210 00213 void buildTrigTables(); 00214 00215 static Real SinTable (Real fValue); 00216 static Real TanTable (Real fValue); 00217 public: 00223 Math(unsigned int trigTableSize = 4096); 00224 00227 ~Math(); 00228 00229 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } 00230 static inline int ICeil (float fValue) { return int(ceil(fValue)); } 00231 static inline int IFloor (float fValue) { return int(floor(fValue)); } 00232 static int ISign (int iValue); 00233 00234 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } 00235 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } 00236 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); } 00237 static Radian ACos (Real fValue); 00238 static Radian ASin (Real fValue); 00239 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } 00240 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } 00241 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } 00242 00250 static inline Real Cos (const Radian& fValue, bool useTables = false) { 00251 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); 00252 } 00260 static inline Real Cos (Real fValue, bool useTables = false) { 00261 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); 00262 } 00263 00264 static inline Real Exp (Real fValue) { return Real(exp(fValue)); } 00265 00266 static inline Real Floor (Real fValue) { return Real(floor(fValue)); } 00267 00268 static inline Real Log (Real fValue) { return Real(log(fValue)); } 00269 00270 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); } 00271 00272 static Real Sign (Real fValue); 00273 static inline Radian Sign ( const Radian& rValue ) 00274 { 00275 return Radian(Sign(rValue.valueRadians())); 00276 } 00277 static inline Degree Sign ( const Degree& dValue ) 00278 { 00279 return Degree(Sign(dValue.valueDegrees())); 00280 } 00281 00289 static inline Real Sin (const Radian& fValue, bool useTables = false) { 00290 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); 00291 } 00299 static inline Real Sin (Real fValue, bool useTables = false) { 00300 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); 00301 } 00302 00303 static inline Real Sqr (Real fValue) { return fValue*fValue; } 00304 00305 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } 00306 00307 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); } 00308 00309 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); } 00310 00314 static Real InvSqrt(Real fValue); 00315 00316 static Real UnitRandom (); // in [0,1] 00317 00318 static Real RangeRandom (Real fLow, Real fHigh); // in [fLow,fHigh] 00319 00320 static Real SymmetricRandom (); // in [-1,1] 00321 00329 static inline Real Tan (const Radian& fValue, bool useTables = false) { 00330 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); 00331 } 00339 static inline Real Tan (Real fValue, bool useTables = false) { 00340 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); 00341 } 00342 00343 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } 00344 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 00345 00352 static void setAngleUnit(AngleUnit unit); 00354 static AngleUnit getAngleUnit(void); 00355 00357 static Real AngleUnitsToRadians(Real units); 00359 static Real RadiansToAngleUnits(Real radians); 00361 static Real AngleUnitsToDegrees(Real units); 00363 static Real DegreesToAngleUnits(Real degrees); 00364 00386 static bool pointInTri2D(const Vector2& p, const Vector2& a, 00387 const Vector2& b, const Vector2& c); 00388 00413 static bool pointInTri3D(const Vector3& p, const Vector3& a, 00414 const Vector3& b, const Vector3& c, const Vector3& normal); 00416 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane); 00417 00419 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 00420 bool discardInside = true); 00421 00423 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box); 00424 00447 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 00448 Real* d1, Real* d2); 00449 00474 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00475 const Vector3& b, const Vector3& c, const Vector3& normal, 00476 bool positiveSide = true, bool negativeSide = true); 00477 00498 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00499 const Vector3& b, const Vector3& c, 00500 bool positiveSide = true, bool negativeSide = true); 00501 00503 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 00504 00506 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 00507 00513 static std::pair<bool, Real> intersects( 00514 const Ray& ray, const std::vector<Plane>& planeList, 00515 bool normalIsOutside); 00521 static std::pair<bool, Real> intersects( 00522 const Ray& ray, const std::list<Plane>& planeList, 00523 bool normalIsOutside); 00524 00528 static bool intersects(const Sphere& sphere, const Plane& plane); 00529 00532 static bool RealEqual(Real a, Real b, 00533 Real tolerance = std::numeric_limits<Real>::epsilon()); 00534 00536 static Vector3 calculateTangentSpaceVector( 00537 const Vector3& position1, const Vector3& position2, const Vector3& position3, 00538 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 00539 00541 static Matrix4 buildReflectionMatrix(const Plane& p); 00543 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00545 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00547 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00549 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00550 00554 static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); 00555 00557 template <typename T> 00558 static T Clamp(T val, T minval, T maxval) 00559 { 00560 assert (minval < maxval && "Invalid clamp range"); 00561 return std::max(std::min(val, maxval), minval); 00562 } 00563 00564 static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, 00565 const Matrix4* reflectMatrix = 0); 00566 00568 static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb); 00569 00570 00571 00572 static const Real POS_INFINITY; 00573 static const Real NEG_INFINITY; 00574 static const Real PI; 00575 static const Real TWO_PI; 00576 static const Real HALF_PI; 00577 static const Real fDeg2Rad; 00578 static const Real fRad2Deg; 00579 00580 }; 00581 00582 // these functions must be defined down here, because they rely on the 00583 // angle unit conversion functions in class Math: 00584 00585 inline Real Radian::valueDegrees() const 00586 { 00587 return Math::RadiansToDegrees ( mRad ); 00588 } 00589 00590 inline Real Radian::valueAngleUnits() const 00591 { 00592 return Math::RadiansToAngleUnits ( mRad ); 00593 } 00594 00595 inline Real Degree::valueRadians() const 00596 { 00597 return Math::DegreesToRadians ( mDeg ); 00598 } 00599 00600 inline Real Degree::valueAngleUnits() const 00601 { 00602 return Math::DegreesToAngleUnits ( mDeg ); 00603 } 00604 00605 inline Angle::operator Radian() const 00606 { 00607 return Radian(Math::AngleUnitsToRadians(mAngle)); 00608 } 00609 00610 inline Angle::operator Degree() const 00611 { 00612 return Degree(Math::AngleUnitsToDegrees(mAngle)); 00613 } 00614 00615 inline Radian operator * ( Real a, const Radian& b ) 00616 { 00617 return Radian ( a * b.valueRadians() ); 00618 } 00619 00620 inline Radian operator / ( Real a, const Radian& b ) 00621 { 00622 return Radian ( a / b.valueRadians() ); 00623 } 00624 00625 inline Degree operator * ( Real a, const Degree& b ) 00626 { 00627 return Degree ( a * b.valueDegrees() ); 00628 } 00629 00630 inline Degree operator / ( Real a, const Degree& b ) 00631 { 00632 return Degree ( a / b.valueDegrees() ); 00633 } 00634 00635 } 00636 #endif
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 27 22:02:24 2009