Coverage Report

Created: 2026-09-14 06:27

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