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