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-2011 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 00239 static inline Real Abs (Real fValue) { return Real(fabs(fValue)); } 00240 static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); } 00241 static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); } 00242 static Radian ACos (Real fValue); 00243 static Radian ASin (Real fValue); 00244 static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); } 00245 static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); } 00246 static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); } 00247 static inline bool isNaN(Real f) 00248 { 00249 // std::isnan() is C99, not supported by all compilers 00250 // However NaN always fails this next test, no other number does. 00251 return f != f; 00252 } 00253 00261 static inline Real Cos (const Radian& fValue, bool useTables = false) { 00262 return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI); 00263 } 00271 static inline Real Cos (Real fValue, bool useTables = false) { 00272 return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI); 00273 } 00274 00275 static inline Real Exp (Real fValue) { return Real(exp(fValue)); } 00276 00277 static inline Real Floor (Real fValue) { return Real(floor(fValue)); } 00278 00279 static inline Real Log (Real fValue) { return Real(log(fValue)); } 00280 00282 static const Real LOG2; 00283 00284 static inline Real Log2 (Real fValue) { return Real(log(fValue)/LOG2); } 00285 00286 static inline Real LogN (Real base, Real fValue) { return Real(log(fValue)/log(base)); } 00287 00288 static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); } 00289 00290 static Real Sign (Real fValue); 00291 static inline Radian Sign ( const Radian& rValue ) 00292 { 00293 return Radian(Sign(rValue.valueRadians())); 00294 } 00295 static inline Degree Sign ( const Degree& dValue ) 00296 { 00297 return Degree(Sign(dValue.valueDegrees())); 00298 } 00299 00307 static inline Real Sin (const Radian& fValue, bool useTables = false) { 00308 return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians()); 00309 } 00317 static inline Real Sin (Real fValue, bool useTables = false) { 00318 return (!useTables) ? Real(sin(fValue)) : SinTable(fValue); 00319 } 00320 00321 static inline Real Sqr (Real fValue) { return fValue*fValue; } 00322 00323 static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); } 00324 00325 static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); } 00326 00327 static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); } 00328 00332 static Real InvSqrt(Real fValue); 00333 00334 static Real UnitRandom (); // in [0,1] 00335 00336 static Real RangeRandom (Real fLow, Real fHigh); // in [fLow,fHigh] 00337 00338 static Real SymmetricRandom (); // in [-1,1] 00339 00347 static inline Real Tan (const Radian& fValue, bool useTables = false) { 00348 return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians()); 00349 } 00357 static inline Real Tan (Real fValue, bool useTables = false) { 00358 return (!useTables) ? Real(tan(fValue)) : TanTable(fValue); 00359 } 00360 00361 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } 00362 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 00363 00370 static void setAngleUnit(AngleUnit unit); 00372 static AngleUnit getAngleUnit(void); 00373 00375 static Real AngleUnitsToRadians(Real units); 00377 static Real RadiansToAngleUnits(Real radians); 00379 static Real AngleUnitsToDegrees(Real units); 00381 static Real DegreesToAngleUnits(Real degrees); 00382 00404 static bool pointInTri2D(const Vector2& p, const Vector2& a, 00405 const Vector2& b, const Vector2& c); 00406 00431 static bool pointInTri3D(const Vector3& p, const Vector3& a, 00432 const Vector3& b, const Vector3& c, const Vector3& normal); 00434 static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane); 00435 00437 static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere, 00438 bool discardInside = true); 00439 00441 static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& box); 00442 00465 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 00466 Real* d1, Real* d2); 00467 00492 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00493 const Vector3& b, const Vector3& c, const Vector3& normal, 00494 bool positiveSide = true, bool negativeSide = true); 00495 00516 static std::pair<bool, Real> intersects(const Ray& ray, const Vector3& a, 00517 const Vector3& b, const Vector3& c, 00518 bool positiveSide = true, bool negativeSide = true); 00519 00521 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 00522 00524 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 00525 00531 static std::pair<bool, Real> intersects( 00532 const Ray& ray, const vector<Plane>::type& planeList, 00533 bool normalIsOutside); 00539 static std::pair<bool, Real> intersects( 00540 const Ray& ray, const list<Plane>::type& planeList, 00541 bool normalIsOutside); 00542 00546 static bool intersects(const Sphere& sphere, const Plane& plane); 00547 00550 static bool RealEqual(Real a, Real b, 00551 Real tolerance = std::numeric_limits<Real>::epsilon()); 00552 00554 static Vector3 calculateTangentSpaceVector( 00555 const Vector3& position1, const Vector3& position2, const Vector3& position3, 00556 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 00557 00559 static Matrix4 buildReflectionMatrix(const Plane& p); 00561 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00563 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00565 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00567 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 00568 00572 static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); 00573 00575 template <typename T> 00576 static T Clamp(T val, T minval, T maxval) 00577 { 00578 assert (minval < maxval && "Invalid clamp range"); 00579 return std::max(std::min(val, maxval), minval); 00580 } 00581 00582 static Matrix4 makeViewMatrix(const Vector3& position, const Quaternion& orientation, 00583 const Matrix4* reflectMatrix = 0); 00584 00586 static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb); 00587 00588 00589 00590 static const Real POS_INFINITY; 00591 static const Real NEG_INFINITY; 00592 static const Real PI; 00593 static const Real TWO_PI; 00594 static const Real HALF_PI; 00595 static const Real fDeg2Rad; 00596 static const Real fRad2Deg; 00597 00598 }; 00599 00600 // these functions must be defined down here, because they rely on the 00601 // angle unit conversion functions in class Math: 00602 00603 inline Real Radian::valueDegrees() const 00604 { 00605 return Math::RadiansToDegrees ( mRad ); 00606 } 00607 00608 inline Real Radian::valueAngleUnits() const 00609 { 00610 return Math::RadiansToAngleUnits ( mRad ); 00611 } 00612 00613 inline Real Degree::valueRadians() const 00614 { 00615 return Math::DegreesToRadians ( mDeg ); 00616 } 00617 00618 inline Real Degree::valueAngleUnits() const 00619 { 00620 return Math::DegreesToAngleUnits ( mDeg ); 00621 } 00622 00623 inline Angle::operator Radian() const 00624 { 00625 return Radian(Math::AngleUnitsToRadians(mAngle)); 00626 } 00627 00628 inline Angle::operator Degree() const 00629 { 00630 return Degree(Math::AngleUnitsToDegrees(mAngle)); 00631 } 00632 00633 inline Radian operator * ( Real a, const Radian& b ) 00634 { 00635 return Radian ( a * b.valueRadians() ); 00636 } 00637 00638 inline Radian operator / ( Real a, const Radian& b ) 00639 { 00640 return Radian ( a / b.valueRadians() ); 00641 } 00642 00643 inline Degree operator * ( Real a, const Degree& b ) 00644 { 00645 return Degree ( a * b.valueDegrees() ); 00646 } 00647 00648 inline Degree operator / ( Real a, const Degree& b ) 00649 { 00650 return Degree ( a / b.valueDegrees() ); 00651 } 00655 } 00656 #endif
Copyright © 2008 Torus Knot Software Ltd
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Sat Jan 14 2012 18:40:43