Coverage Report

Created: 2026-05-24 07:02

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