1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 #ifndef __Math_H__ 29 #define __Math_H__ 30 31 #include "OgrePrerequisites.h" 32 #include "OgreHeaderPrefix.h" 33 34 namespace Ogre 35 { 36 /** \addtogroup Core 37 * @{ 38 */ 39 /** \addtogroup Math 40 * @{ 41 */ 42 43 /** A pair structure where the first element indicates whether 44 an intersection occurs 45 46 if true, the second element will 47 indicate the distance along the ray at which it intersects. 48 This can be converted to a point in space by calling Ray::getPoint(). 49 */ 50 typedef std::pair<bool, Real> RayTestResult; 51 52 /** Wrapper class which indicates a given angle value is in Radians. 53 @remarks 54 Radian values are interchangeable with Degree values, and conversions 55 will be done automatically between them. 56 */ 57 class Radian 58 { 59 Real mRad; 60 61 public: mRad(r)62 explicit Radian ( Real r=0 ) : mRad(r) {} 63 Radian ( const Degree& d ); 64 Radian& operator = ( const Real& f ) { mRad = f; return *this; } 65 Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; } 66 Radian& operator = ( const Degree& d ); 67 68 Real valueDegrees() const; // see bottom of this file valueRadians()69 Real valueRadians() const { return mRad; } 70 Real valueAngleUnits() const; 71 72 const Radian& operator + () const { return *this; } 73 Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); } 74 Radian operator + ( const Degree& d ) const; 75 Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; } 76 Radian& operator += ( const Degree& d ); 77 Radian operator - () const { return Radian(-mRad); } 78 Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); } 79 Radian operator - ( const Degree& d ) const; 80 Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; } 81 Radian& operator -= ( const Degree& d ); 82 Radian operator * ( Real f ) const { return Radian ( mRad * f ); } 83 Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); } 84 Radian& operator *= ( Real f ) { mRad *= f; return *this; } 85 Radian operator / ( Real f ) const { return Radian ( mRad / f ); } 86 Radian& operator /= ( Real f ) { mRad /= f; return *this; } 87 88 bool operator < ( const Radian& r ) const { return mRad < r.mRad; } 89 bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; } 90 bool operator == ( const Radian& r ) const { return mRad == r.mRad; } 91 bool operator != ( const Radian& r ) const { return mRad != r.mRad; } 92 bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; } 93 bool operator > ( const Radian& r ) const { return mRad > r.mRad; } 94 95 inline friend std::ostream& operator << 96 ( std::ostream& o, const Radian& v ) 97 { 98 o << "Radian(" << v.valueRadians() << ")"; 99 return o; 100 } 101 }; 102 103 /** Wrapper class which indicates a given angle value is in Degrees. 104 @remarks 105 Degree values are interchangeable with Radian values, and conversions 106 will be done automatically between them. 107 */ 108 class Degree 109 { 110 Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first 111 112 public: mDeg(d)113 explicit Degree ( Real d=0 ) : mDeg(d) {} Degree(const Radian & r)114 Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {} 115 Degree& operator = ( const Real& f ) { mDeg = f; return *this; } 116 Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; } 117 Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; } 118 valueDegrees()119 Real valueDegrees() const { return mDeg; } 120 Real valueRadians() const; // see bottom of this file 121 Real valueAngleUnits() const; 122 123 const Degree& operator + () const { return *this; } 124 Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); } 125 Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); } 126 Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; } 127 Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; } 128 Degree operator - () const { return Degree(-mDeg); } 129 Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); } 130 Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); } 131 Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; } 132 Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; } 133 Degree operator * ( Real f ) const { return Degree ( mDeg * f ); } 134 Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); } 135 Degree& operator *= ( Real f ) { mDeg *= f; return *this; } 136 Degree operator / ( Real f ) const { return Degree ( mDeg / f ); } 137 Degree& operator /= ( Real f ) { mDeg /= f; return *this; } 138 139 bool operator < ( const Degree& d ) const { return mDeg < d.mDeg; } 140 bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; } 141 bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; } 142 bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; } 143 bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; } 144 bool operator > ( const Degree& d ) const { return mDeg > d.mDeg; } 145 146 inline friend std::ostream& operator << 147 ( std::ostream& o, const Degree& v ) 148 { 149 o << "Degree(" << v.valueDegrees() << ")"; 150 return o; 151 } 152 }; 153 154 /** Wrapper class which identifies a value as the currently default angle 155 type, as defined by Math::setAngleUnit. 156 @remarks 157 Angle values will be automatically converted between radians and degrees, 158 as appropriate. 159 */ 160 class Angle 161 { 162 Real mAngle; 163 public: Angle(Real angle)164 explicit Angle ( Real angle ) : mAngle(angle) {} 165 operator Radian() const; 166 operator Degree() const; 167 }; 168 169 // these functions could not be defined within the class definition of class 170 // Radian because they required class Degree to be defined Radian(const Degree & d)171 inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) { 172 } 173 inline Radian& Radian::operator = ( const Degree& d ) { 174 mRad = d.valueRadians(); return *this; 175 } 176 inline Radian Radian::operator + ( const Degree& d ) const { 177 return Radian ( mRad + d.valueRadians() ); 178 } 179 inline Radian& Radian::operator += ( const Degree& d ) { 180 mRad += d.valueRadians(); 181 return *this; 182 } 183 inline Radian Radian::operator - ( const Degree& d ) const { 184 return Radian ( mRad - d.valueRadians() ); 185 } 186 inline Radian& Radian::operator -= ( const Degree& d ) { 187 mRad -= d.valueRadians(); 188 return *this; 189 } 190 191 /** Class to provide access to common mathematical functions. 192 @remarks 193 Most of the maths functions are aliased versions of the C runtime 194 library functions. They are aliased here to provide future 195 optimisation opportunities, either from faster RTLs or custom 196 math approximations. 197 @note 198 <br>This is based on MgcMath.h from 199 <a href="http://www.geometrictools.com/">Wild Magic</a>. 200 */ 201 class _OgreExport Math 202 { 203 public: 204 /** The angular units used by the API. This functionality is now deprecated in favor 205 of discreet angular unit types ( see Degree and Radian above ). The only place 206 this functionality is actually still used is when parsing files. Search for 207 usage of the Angle class for those instances 208 */ 209 enum AngleUnit 210 { 211 AU_DEGREE, 212 AU_RADIAN 213 }; 214 215 216 /** This class is used to provide an external random value provider. 217 */ 218 class RandomValueProvider 219 { 220 public: ~RandomValueProvider()221 virtual ~RandomValueProvider() {} 222 /** When called should return a random values in the range of [0,1] */ 223 virtual Real getRandomUnit() = 0; 224 }; 225 226 protected: 227 /// Angle units used by the api 228 static AngleUnit msAngleUnit; 229 230 /// Size of the trig tables as determined by constructor. 231 static int mTrigTableSize; 232 233 /// Radian -> index factor value ( mTrigTableSize / 2 * PI ) 234 static Real mTrigTableFactor; 235 static Real* mSinTable; 236 static Real* mTanTable; 237 238 /// A random value provider. overriding the default random number generator. 239 static RandomValueProvider* mRandProvider; 240 241 /** Private function to build trig tables. 242 */ 243 void buildTrigTables(); 244 245 static Real SinTable (Real fValue); 246 static Real TanTable (Real fValue); 247 public: 248 /** Default constructor. 249 @param 250 trigTableSize Optional parameter to set the size of the 251 tables used to implement Sin, Cos, Tan 252 */ 253 Math(unsigned int trigTableSize = 4096); 254 255 /** Default destructor. 256 */ 257 ~Math(); 258 IAbs(int iValue)259 static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); } ICeil(float fValue)260 static inline int ICeil (float fValue) { return int(std::ceil(fValue)); } IFloor(float fValue)261 static inline int IFloor (float fValue) { return int(std::floor(fValue)); } ISign(int iValue)262 static int ISign (int iValue) { 263 return ( iValue > 0 ? +1 : ( iValue < 0 ? -1 : 0 ) ); 264 } 265 266 /** Absolute value function 267 @param 268 fValue The value whose absolute value will be returned. 269 */ Abs(Real fValue)270 static inline Real Abs (Real fValue) { return std::abs(fValue); } 271 272 /** Absolute value function 273 @param dValue 274 The value, in degrees, whose absolute value will be returned. 275 */ Abs(const Degree & dValue)276 static inline Degree Abs (const Degree& dValue) { return Degree(std::abs(dValue.valueDegrees())); } 277 278 /** Absolute value function 279 @param rValue 280 The value, in radians, whose absolute value will be returned. 281 */ Abs(const Radian & rValue)282 static inline Radian Abs (const Radian& rValue) { return Radian(std::abs(rValue.valueRadians())); } 283 284 /** Arc cosine function 285 @param fValue 286 The value whose arc cosine will be returned. 287 */ 288 static Radian ACos (Real fValue); 289 290 /** Arc sine function 291 @param fValue 292 The value whose arc sine will be returned. 293 */ 294 static Radian ASin (Real fValue); 295 296 /** Arc tangent function 297 @param fValue 298 The value whose arc tangent will be returned. 299 */ ATan(Real fValue)300 static inline Radian ATan (Real fValue) { return Radian(std::atan(fValue)); } 301 302 /** Arc tangent between two values function 303 @param fY 304 The first value to calculate the arc tangent with. 305 @param fX 306 The second value to calculate the arc tangent with. 307 */ ATan2(Real fY,Real fX)308 static inline Radian ATan2 (Real fY, Real fX) { return Radian(std::atan2(fY,fX)); } 309 310 /** Ceiling function 311 Returns the smallest following integer. (example: Ceil(1.1) = 2) 312 313 @param fValue 314 The value to round up to the nearest integer. 315 */ Ceil(Real fValue)316 static inline Real Ceil (Real fValue) { return std::ceil(fValue); } isNaN(Real f)317 static inline bool isNaN(Real f) 318 { 319 // std::isnan() is C99, not supported by all compilers 320 // However NaN always fails this next test, no other number does. 321 return f != f; 322 } 323 324 /** Cosine function. 325 @param fValue 326 Angle in radians 327 @param useTables 328 If true, uses lookup tables rather than 329 calculation - faster but less accurate. 330 */ 331 static inline Real Cos (const Radian& fValue, bool useTables = false) { 332 return (!useTables) ? std::cos(fValue.valueRadians()) : SinTable(fValue.valueRadians() + HALF_PI); 333 } 334 /** Cosine function. 335 @param fValue 336 Angle in radians 337 @param useTables 338 If true, uses lookup tables rather than 339 calculation - faster but less accurate. 340 */ 341 static inline Real Cos (Real fValue, bool useTables = false) { 342 return (!useTables) ? std::cos(fValue) : SinTable(fValue + HALF_PI); 343 } 344 Exp(Real fValue)345 static inline Real Exp (Real fValue) { return std::exp(fValue); } 346 347 /** Floor function 348 Returns the largest previous integer. (example: Floor(1.9) = 1) 349 350 @param fValue 351 The value to round down to the nearest integer. 352 */ Floor(Real fValue)353 static inline Real Floor (Real fValue) { return std::floor(fValue); } 354 Log(Real fValue)355 static inline Real Log (Real fValue) { return std::log(fValue); } 356 357 /// Stored value of log(2) for frequent use 358 static const Real LOG2; 359 Log2(Real fValue)360 static inline Real Log2 (Real fValue) { return std::log(fValue)/LOG2; } 361 LogN(Real base,Real fValue)362 static inline Real LogN (Real base, Real fValue) { return std::log(fValue)/std::log(base); } 363 Pow(Real fBase,Real fExponent)364 static inline Real Pow (Real fBase, Real fExponent) { return std::pow(fBase,fExponent); } 365 Sign(Real fValue)366 static Real Sign(Real fValue) 367 { 368 if (fValue > 0.0) 369 return 1.0; 370 if (fValue < 0.0) 371 return -1.0; 372 return 0.0; 373 } 374 Sign(const Radian & rValue)375 static inline Radian Sign ( const Radian& rValue ) 376 { 377 return Radian(Sign(rValue.valueRadians())); 378 } Sign(const Degree & dValue)379 static inline Degree Sign ( const Degree& dValue ) 380 { 381 return Degree(Sign(dValue.valueDegrees())); 382 } 383 384 /// Simulate the shader function saturate that clamps a parameter value between 0 and 1 saturate(float t)385 static inline float saturate(float t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); } saturate(double t)386 static inline double saturate(double t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); } 387 388 /// saturated cast of size_t to uint16 uint16Cast(size_t t)389 static inline uint16 uint16Cast(size_t t) { return t < UINT16_MAX ? uint16(t) : UINT16_MAX; } 390 391 /** Simulate the shader function lerp which performers linear interpolation 392 393 given 3 parameters v0, v1 and t the function returns the value of (1 - t)* v0 + t * v1. 394 where v0 and v1 are matching vector or scalar types and t can be either a scalar or a 395 vector of the same type as a and b. 396 */ lerp(const V & v0,const V & v1,const T & t)397 template <typename V, typename T> static V lerp(const V& v0, const V& v1, const T& t) 398 { 399 return v0 * (1 - t) + v1 * t; 400 } 401 402 /** Sine function. 403 @param fValue 404 Angle in radians 405 @param useTables 406 If true, uses lookup tables rather than 407 calculation - faster but less accurate. 408 */ 409 static inline Real Sin (const Radian& fValue, bool useTables = false) { 410 return (!useTables) ? std::sin(fValue.valueRadians()) : SinTable(fValue.valueRadians()); 411 } 412 /** Sine function. 413 @param fValue 414 Angle in radians 415 @param useTables 416 If true, uses lookup tables rather than 417 calculation - faster but less accurate. 418 */ 419 static inline Real Sin (Real fValue, bool useTables = false) { 420 return (!useTables) ? std::sin(fValue) : SinTable(fValue); 421 } 422 423 /** Squared function. 424 @param fValue 425 The value to be squared (fValue^2) 426 */ Sqr(Real fValue)427 static inline Real Sqr (Real fValue) { return fValue*fValue; } 428 429 /** Square root function. 430 @param fValue 431 The value whose square root will be calculated. 432 */ Sqrt(Real fValue)433 static inline Real Sqrt (Real fValue) { return std::sqrt(fValue); } 434 435 /** Square root function. 436 @param fValue 437 The value, in radians, whose square root will be calculated. 438 @return 439 The square root of the angle in radians. 440 */ Sqrt(const Radian & fValue)441 static inline Radian Sqrt (const Radian& fValue) { return Radian(std::sqrt(fValue.valueRadians())); } 442 443 /** Square root function. 444 @param fValue 445 The value, in degrees, whose square root will be calculated. 446 @return 447 The square root of the angle in degrees. 448 */ Sqrt(const Degree & fValue)449 static inline Degree Sqrt (const Degree& fValue) { return Degree(std::sqrt(fValue.valueDegrees())); } 450 451 /** Inverse square root i.e. 1 / Sqrt(x), good for vector 452 normalisation. 453 @param fValue 454 The value whose inverse square root will be calculated. 455 */ InvSqrt(Real fValue)456 static Real InvSqrt (Real fValue) { 457 return Real(1.) / std::sqrt(fValue); 458 } 459 460 /** Generate a random number of unit length. 461 @return 462 A random number in the range from [0,1]. 463 */ 464 static Real UnitRandom (); 465 466 /** Generate a random number within the range provided. 467 @param fLow 468 The lower bound of the range. 469 @param fHigh 470 The upper bound of the range. 471 @return 472 A random number in the range from [fLow,fHigh]. 473 */ RangeRandom(Real fLow,Real fHigh)474 static Real RangeRandom (Real fLow, Real fHigh) { 475 return (fHigh-fLow)*UnitRandom() + fLow; 476 } 477 478 /** Generate a random number in the range [-1,1]. 479 @return 480 A random number in the range from [-1,1]. 481 */ SymmetricRandom()482 static Real SymmetricRandom () { 483 return 2.0f * UnitRandom() - 1.0f; 484 } 485 486 static void SetRandomValueProvider(RandomValueProvider* provider); 487 488 /** Tangent function. 489 @param fValue 490 Angle in radians 491 @param useTables 492 If true, uses lookup tables rather than 493 calculation - faster but less accurate. 494 */ 495 static inline Real Tan (const Radian& fValue, bool useTables = false) { 496 return (!useTables) ? std::tan(fValue.valueRadians()) : TanTable(fValue.valueRadians()); 497 } 498 /** Tangent function. 499 @param fValue 500 Angle in radians 501 @param useTables 502 If true, uses lookup tables rather than 503 calculation - faster but less accurate. 504 */ 505 static inline Real Tan (Real fValue, bool useTables = false) { 506 return (!useTables) ? std::tan(fValue) : TanTable(fValue); 507 } 508 DegreesToRadians(Real degrees)509 static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; } RadiansToDegrees(Real radians)510 static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; } 511 512 /** These functions used to set the assumed angle units (radians or degrees) 513 expected when using the Angle type. 514 @par 515 You can set this directly after creating a new Root, and also before/after resource creation, 516 depending on whether you want the change to affect resource files. 517 */ 518 static void setAngleUnit(AngleUnit unit); 519 /** Get the unit being used for angles. */ 520 static AngleUnit getAngleUnit(void); 521 522 /** Convert from the current AngleUnit to radians. */ 523 static Real AngleUnitsToRadians(Real units); 524 /** Convert from radians to the current AngleUnit . */ 525 static Real RadiansToAngleUnits(Real radians); 526 /** Convert from the current AngleUnit to degrees. */ 527 static Real AngleUnitsToDegrees(Real units); 528 /** Convert from degrees to the current AngleUnit. */ 529 static Real DegreesToAngleUnits(Real degrees); 530 531 /** Checks whether a given point is inside a triangle, in a 532 2-dimensional (Cartesian) space. 533 @remarks 534 The vertices of the triangle must be given in either 535 trigonometrical (anticlockwise) or inverse trigonometrical 536 (clockwise) order. 537 @param p 538 The point. 539 @param a 540 The triangle's first vertex. 541 @param b 542 The triangle's second vertex. 543 @param c 544 The triangle's third vertex. 545 @return 546 If the point resides in the triangle, <b>true</b> is 547 returned. 548 @par 549 If the point is outside the triangle, <b>false</b> is 550 returned. 551 */ 552 static bool pointInTri2D(const Vector2& p, const Vector2& a, 553 const Vector2& b, const Vector2& c); 554 555 /** Checks whether a given 3D point is inside a triangle. 556 @remarks 557 The vertices of the triangle must be given in either 558 trigonometrical (anticlockwise) or inverse trigonometrical 559 (clockwise) order, and the point must be guaranteed to be in the 560 same plane as the triangle 561 @param p 562 p The point. 563 @param a 564 The triangle's first vertex. 565 @param b 566 The triangle's second vertex. 567 @param c 568 The triangle's third vertex. 569 @param normal 570 The triangle plane's normal (passed in rather than calculated 571 on demand since the caller may already have it) 572 @return 573 If the point resides in the triangle, <b>true</b> is 574 returned. 575 @par 576 If the point is outside the triangle, <b>false</b> is 577 returned. 578 */ 579 static bool pointInTri3D(const Vector3& p, const Vector3& a, 580 const Vector3& b, const Vector3& c, const Vector3& normal); 581 /** Ray / plane intersection */ 582 static inline RayTestResult intersects(const Ray& ray, const Plane& plane); 583 /** Ray / sphere intersection */ 584 static RayTestResult intersects(const Ray& ray, const Sphere& sphere, bool discardInside = true); 585 /** Ray / box intersection */ 586 static RayTestResult intersects(const Ray& ray, const AxisAlignedBox& box); 587 588 /** Ray / box intersection, returns boolean result and two intersection distance. 589 @param ray 590 The ray. 591 @param box 592 The box. 593 @param d1 594 A real pointer to retrieve the near intersection distance 595 from the ray origin, maybe <b>null</b> which means don't care 596 about the near intersection distance. 597 @param d2 598 A real pointer to retrieve the far intersection distance 599 from the ray origin, maybe <b>null</b> which means don't care 600 about the far intersection distance. 601 @return 602 If the ray is intersects the box, <b>true</b> is returned, and 603 the near intersection distance is return by <i>d1</i>, the 604 far intersection distance is return by <i>d2</i>. Guarantee 605 <b>0</b> <= <i>d1</i> <= <i>d2</i>. 606 @par 607 If the ray isn't intersects the box, <b>false</b> is returned, and 608 <i>d1</i> and <i>d2</i> is unmodified. 609 */ 610 static bool intersects(const Ray& ray, const AxisAlignedBox& box, 611 Real* d1, Real* d2); 612 613 /** Ray / triangle intersection, returns boolean result and distance. 614 @param ray 615 The ray. 616 @param a 617 The triangle's first vertex. 618 @param b 619 The triangle's second vertex. 620 @param c 621 The triangle's third vertex. 622 @param normal 623 The triangle plane's normal (passed in rather than calculated 624 on demand since the caller may already have it), doesn't need 625 normalised since we don't care. 626 @param positiveSide 627 Intersect with "positive side" of the triangle 628 @param negativeSide 629 Intersect with "negative side" of the triangle 630 */ 631 static RayTestResult intersects(const Ray& ray, const Vector3& a, 632 const Vector3& b, const Vector3& c, const Vector3& normal, 633 bool positiveSide = true, bool negativeSide = true); 634 635 /** Ray / triangle intersection, returns boolean result and distance. 636 @param ray 637 The ray. 638 @param a 639 The triangle's first vertex. 640 @param b 641 The triangle's second vertex. 642 @param c 643 The triangle's third vertex. 644 @param positiveSide 645 Intersect with "positive side" of the triangle 646 @param negativeSide 647 Intersect with "negative side" of the triangle 648 */ 649 static RayTestResult intersects(const Ray& ray, const Vector3& a, 650 const Vector3& b, const Vector3& c, 651 bool positiveSide = true, bool negativeSide = true); 652 653 /** Sphere / box intersection test. */ 654 static bool intersects(const Sphere& sphere, const AxisAlignedBox& box); 655 656 /** Plane / box intersection test. */ 657 static bool intersects(const Plane& plane, const AxisAlignedBox& box); 658 659 /** Ray / convex plane list intersection test. 660 @param ray The ray to test with 661 @param planeList List of planes which form a convex volume 662 @param normalIsOutside Does the normal point outside the volume 663 */ 664 static RayTestResult intersects(const Ray& ray, const std::vector<Plane>& planeList, bool normalIsOutside); 665 /// @deprecated migrate to @ref PlaneList 666 OGRE_DEPRECATED static RayTestResult intersects(const Ray& ray, const std::list<Plane>& planeList, 667 bool normalIsOutside); 668 669 /** Sphere / plane intersection test. 670 @remarks NB just do a plane.getDistance(sphere.getCenter()) for more detail! 671 */ 672 static bool intersects(const Sphere& sphere, const Plane& plane); 673 674 /** Compare 2 reals, using tolerance for inaccuracies. 675 */ 676 static bool RealEqual(Real a, Real b, 677 Real tolerance = std::numeric_limits<Real>::epsilon()) { 678 return std::abs(b-a) <= tolerance; 679 } 680 681 /** Calculates the tangent space vector for a given set of positions / texture coords. */ 682 static Vector3 calculateTangentSpaceVector( 683 const Vector3& position1, const Vector3& position2, const Vector3& position3, 684 Real u1, Real v1, Real u2, Real v2, Real u3, Real v3); 685 686 /** Build a reflection matrix for the passed in plane. */ 687 static Affine3 buildReflectionMatrix(const Plane& p); 688 /** Calculate a face normal, including the w component which is the offset from the origin. */ 689 static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 690 /** Calculate a face normal, no w-information. */ 691 static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3); 692 /** Calculate a face normal without normalize, including the w component which is the offset from the origin. */ 693 static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 694 /** Calculate a face normal without normalize, no w-information. */ 695 static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3); 696 697 /** Generates a value based on the Gaussian (normal) distribution function 698 with the given offset and scale parameters. 699 */ 700 static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f); 701 702 /** Clamp a value within an inclusive range. */ 703 template <typename T> Clamp(T val,T minval,T maxval)704 static T Clamp(T val, T minval, T maxval) 705 { 706 assert (minval <= maxval && "Invalid clamp range"); 707 return std::max(std::min(val, maxval), minval); 708 } 709 710 static Affine3 makeViewMatrix(const Vector3& position, const Quaternion& orientation, 711 const Affine3* reflectMatrix = 0); 712 713 /** Get the radius of the origin-centered bounding sphere from the bounding box. */ 714 static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb); 715 716 /** Get the radius of the bbox-centered bounding sphere from the bounding box. */ 717 static Real boundingRadiusFromAABBCentered(const AxisAlignedBox &aabb); 718 719 720 static const Real POS_INFINITY; 721 static const Real NEG_INFINITY; 722 static const Real PI; 723 static const Real TWO_PI; 724 static const Real HALF_PI; 725 static const Real fDeg2Rad; 726 static const Real fRad2Deg; 727 728 }; 729 730 // these functions must be defined down here, because they rely on the 731 // angle unit conversion functions in class Math: 732 valueDegrees()733 inline Real Radian::valueDegrees() const 734 { 735 return Math::RadiansToDegrees ( mRad ); 736 } 737 valueAngleUnits()738 inline Real Radian::valueAngleUnits() const 739 { 740 return Math::RadiansToAngleUnits ( mRad ); 741 } 742 valueRadians()743 inline Real Degree::valueRadians() const 744 { 745 return Math::DegreesToRadians ( mDeg ); 746 } 747 valueAngleUnits()748 inline Real Degree::valueAngleUnits() const 749 { 750 return Math::DegreesToAngleUnits ( mDeg ); 751 } 752 Radian()753 inline Angle::operator Radian() const 754 { 755 return Radian(Math::AngleUnitsToRadians(mAngle)); 756 } 757 Degree()758 inline Angle::operator Degree() const 759 { 760 return Degree(Math::AngleUnitsToDegrees(mAngle)); 761 } 762 763 inline Radian operator * ( Real a, const Radian& b ) 764 { 765 return Radian ( a * b.valueRadians() ); 766 } 767 768 inline Radian operator / ( Real a, const Radian& b ) 769 { 770 return Radian ( a / b.valueRadians() ); 771 } 772 773 inline Degree operator * ( Real a, const Degree& b ) 774 { 775 return Degree ( a * b.valueDegrees() ); 776 } 777 778 inline Degree operator / ( Real a, const Degree& b ) 779 { 780 return Degree ( a / b.valueDegrees() ); 781 } 782 /** @} */ 783 /** @} */ 784 785 } 786 787 #include "OgreHeaderSuffix.h" 788 789 #endif 790