Coverage Report

Created: 2025-08-28 06:19

/src/ogre/OgreMain/include/OgreMath.h
Line
Count
Source (jump to first uncovered line)
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 (t < 0) ? 0 : ((t > 1) ? 1 : t); }
396
0
        static inline double saturate(double t) { return (t < 0) ? 0 : ((t > 1) ? 1 : t); }
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
        {
409
            return v0 * (1 - t) + v1 * t;
410
        }
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
0
        static inline float Sin (const Radian& fValue, bool useTables = false) {
420
0
            return (!useTables) ? std::sin(fValue.valueRadians()) : SinTable(fValue.valueRadians());
421
0
        }
422
        /** Sine function.
423
            @param fValue
424
                Angle in radians
425
            @param useTables
426
                If true, uses lookup tables rather than
427
                calculation - faster but less accurate.
428
        */
429
0
        static inline float Sin (Real fValue, bool useTables = false) {
430
0
            return (!useTables) ? std::sin(fValue) : SinTable(fValue);
431
0
        }
432
433
        /** Squared function.
434
            @param fValue
435
                The value to be squared (fValue^2)
436
        */
437
0
        static inline Real Sqr (Real fValue) { return fValue*fValue; }
438
439
        /** Square root function.
440
            @param fValue
441
                The value whose square root will be calculated.
442
         */
443
0
        static inline Real Sqrt (Real fValue) { return std::sqrt(fValue); }
444
445
        /** Square root function.
446
            @param fValue
447
                The value, in radians, whose square root will be calculated.
448
            @return
449
                The square root of the angle in radians.
450
         */
451
0
        static inline Radian Sqrt (const Radian& fValue) { return Radian(std::sqrt(fValue.valueRadians())); }
452
453
        /** Square root function.
454
            @param fValue
455
                The value, in degrees, whose square root will be calculated.
456
            @return
457
                The square root of the angle in degrees.
458
         */
459
0
        static inline Degree Sqrt (const Degree& fValue) { return Degree(std::sqrt(fValue.valueDegrees())); }
460
461
        /** Inverse square root i.e. 1 / Sqrt(x), good for vector
462
            normalisation.
463
            @param fValue
464
                The value whose inverse square root will be calculated.
465
        */
466
0
        static Real InvSqrt (Real fValue) {
467
0
            return Real(1.) / std::sqrt(fValue);
468
0
        }
469
470
        /** Generate a random number of unit length.
471
            @return
472
                A random number in the range from [0,1].
473
        */
474
0
        static float UnitRandom() { return mRandProvider ? mRandProvider->getRandomUnit() : rand() / float(RAND_MAX); }
475
476
        /** Generate a random number within the range provided.
477
            @param fLow
478
                The lower bound of the range.
479
            @param fHigh
480
                The upper bound of the range.
481
            @return
482
                A random number in the range from [fLow,fHigh].
483
         */
484
0
        static float RangeRandom(float fLow, float fHigh) { return (fHigh - fLow) * UnitRandom() + fLow; }
485
486
        /** Generate a random number in the range [-1,1].
487
            @return
488
                A random number in the range from [-1,1].
489
         */
490
0
        static float SymmetricRandom() { return 2.0f * UnitRandom() - 1.0f; }
491
492
        static void SetRandomValueProvider(RandomValueProvider* provider);
493
       
494
        /** Tangent function.
495
            @param fValue
496
                Angle in radians
497
            @param useTables
498
                If true, uses lookup tables rather than
499
                calculation - faster but less accurate.
500
        */
501
0
        static inline float Tan (const Radian& fValue, bool useTables = false) {
502
0
            return (!useTables) ? std::tan(fValue.valueRadians()) : TanTable(fValue.valueRadians());
503
0
        }
504
        /** Tangent function.
505
            @param fValue
506
                Angle in radians
507
            @param useTables
508
                If true, uses lookup tables rather than
509
                calculation - faster but less accurate.
510
        */
511
0
        static inline float Tan (Real fValue, bool useTables = false) {
512
0
            return (!useTables) ? std::tan(fValue) : TanTable(fValue);
513
0
        }
514
515
0
        static inline float DegreesToRadians(float degrees) { return degrees * fDeg2Rad; }
516
0
        static inline float RadiansToDegrees(float radians) { return radians * fRad2Deg; }
517
518
       /** These functions used to set the assumed angle units (radians or degrees) 
519
            expected when using the Angle type.
520
       @par
521
            You can set this directly after creating a new Root, and also before/after resource creation,
522
            depending on whether you want the change to affect resource files.
523
       */
524
       static void setAngleUnit(AngleUnit unit);
525
       /** Get the unit being used for angles. */
526
       static AngleUnit getAngleUnit(void);
527
528
       /** Convert from the current AngleUnit to radians. */
529
       static float AngleUnitsToRadians(float units);
530
       /** Convert from radians to the current AngleUnit . */
531
       static float RadiansToAngleUnits(float radians);
532
       /** Convert from the current AngleUnit to degrees. */
533
       static float AngleUnitsToDegrees(float units);
534
       /** Convert from degrees to the current AngleUnit. */
535
       static float DegreesToAngleUnits(float degrees);
536
537
       /** Checks whether a given point is inside a triangle, in a
538
            2-dimensional (Cartesian) space.
539
540
            The vertices of the triangle must be given in either
541
            trigonometrical (anticlockwise) or inverse trigonometrical
542
            (clockwise) order.
543
            @param p
544
                The point.
545
            @param a
546
                The triangle's first vertex.
547
            @param b
548
                The triangle's second vertex.
549
            @param c
550
                The triangle's third vertex.
551
            @return
552
                If the point resides in the triangle, <b>true</b> is
553
                returned.
554
            @par
555
                If the point is outside the triangle, <b>false</b> is
556
                returned.
557
        */
558
        static bool pointInTri2D(const Vector2& p, const Vector2& a, 
559
            const Vector2& b, const Vector2& c);
560
561
       /** Checks whether a given 3D point is inside a triangle.
562
563
            The vertices of the triangle must be given in either
564
            trigonometrical (anticlockwise) or inverse trigonometrical
565
            (clockwise) order, and the point must be guaranteed to be in the
566
            same plane as the triangle
567
        @param p
568
            p The point.
569
        @param a
570
            The triangle's first vertex.
571
        @param b
572
            The triangle's second vertex.
573
        @param c
574
            The triangle's third vertex.
575
        @param normal
576
            The triangle plane's normal (passed in rather than calculated
577
            on demand since the caller may already have it)
578
        @return
579
            If the point resides in the triangle, <b>true</b> is
580
            returned.
581
        @par
582
            If the point is outside the triangle, <b>false</b> is
583
            returned.
584
        */
585
        static bool pointInTri3D(const Vector3& p, const Vector3& a, 
586
            const Vector3& b, const Vector3& c, const Vector3& normal);
587
        /** Ray / plane intersection */
588
        static inline RayTestResult intersects(const Ray& ray, const Plane& plane);
589
        /** Ray / sphere intersection */
590
        static RayTestResult intersects(const Ray& ray, const Sphere& sphere, bool discardInside = true);
591
        /** Ray / box intersection */
592
        static RayTestResult intersects(const Ray& ray, const AxisAlignedBox& box);
593
594
        /** Ray / box intersection, returns boolean result and two intersection distance.
595
        @param ray
596
            The ray.
597
        @param box
598
            The box.
599
        @param d1
600
            A real pointer to retrieve the near intersection distance
601
            from the ray origin, maybe <b>null</b> which means don't care
602
            about the near intersection distance.
603
        @param d2
604
            A real pointer to retrieve the far intersection distance
605
            from the ray origin, maybe <b>null</b> which means don't care
606
            about the far intersection distance.
607
        @return
608
            If the ray is intersects the box, <b>true</b> is returned, and
609
            the near intersection distance is return by <i>d1</i>, the
610
            far intersection distance is return by <i>d2</i>. Guarantee
611
            <b>0</b> <= <i>d1</i> <= <i>d2</i>.
612
        @par
613
            If the ray isn't intersects the box, <b>false</b> is returned, and
614
            <i>d1</i> and <i>d2</i> is unmodified.
615
        */
616
        static bool intersects(const Ray& ray, const AxisAlignedBox& box,
617
            Real* d1, Real* d2);
618
619
        /** Ray / triangle intersection @cite moller1997fast, returns boolean result and distance.
620
        @param ray
621
            The ray.
622
        @param a
623
            The triangle's first vertex.
624
        @param b
625
            The triangle's second vertex.
626
        @param c
627
            The triangle's third vertex.
628
        @param positiveSide
629
            Intersect with "positive side" of the triangle (as determined by vertex winding)
630
        @param negativeSide
631
            Intersect with "negative side" of the triangle (as determined by vertex winding)
632
        */
633
        static RayTestResult intersects(const Ray& ray, const Vector3& a,
634
            const Vector3& b, const Vector3& c,
635
            bool positiveSide = true, bool negativeSide = true);
636
637
        /// @deprecated normal parameter is not used any more
638
        OGRE_DEPRECATED static RayTestResult intersects(const Ray& ray, const Vector3& a, const Vector3& b,
639
                                                        const Vector3& c, const Vector3& normal,
640
                                                        bool positiveSide = true, bool negativeSide = true)
641
0
        {
642
0
            return intersects(ray, a, b, c, positiveSide, negativeSide);
643
0
        }
644
645
        /** Sphere / box intersection test. */
646
        static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
647
648
        /** Plane / box intersection test. */
649
        static bool intersects(const Plane& plane, const AxisAlignedBox& box);
650
651
        /** Ray / convex plane list intersection test. 
652
        @param ray The ray to test with
653
        @param planeList List of planes which form a convex volume
654
        @param normalIsOutside Does the normal point outside the volume
655
        */
656
        static RayTestResult intersects(const Ray& ray, const std::vector<Plane>& planeList, bool normalIsOutside);
657
658
        /** Sphere / plane intersection test. 
659
        @remarks NB just do a plane.getDistance(sphere.getCenter()) for more detail!
660
        */
661
        static bool intersects(const Sphere& sphere, const Plane& plane);
662
663
        /** Compare 2 reals, using tolerance for inaccuracies.
664
        */
665
        static bool RealEqual(Real a, Real b,
666
0
            Real tolerance = std::numeric_limits<Real>::epsilon()) {
667
0
            return std::abs(b-a) <= tolerance;
668
0
        }
669
670
        /// @deprecated use @ref TangentSpaceCalc
671
        OGRE_DEPRECATED static Vector3 calculateTangentSpaceVector(
672
            const Vector3& position1, const Vector3& position2, const Vector3& position3,
673
            Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
674
675
        /** Build a reflection matrix for the passed in plane. */
676
        static Affine3 buildReflectionMatrix(const Plane& p);
677
        /** Calculate a face normal, including the w component which is the offset from the origin. */
678
        static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
679
        /** Calculate a face normal, no w-information. */
680
        static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
681
        /** Calculate a face normal without normalize, including the w component which is the offset from the origin. */
682
        static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
683
        /** Calculate a face normal without normalize, no w-information. */
684
        static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
685
686
        /** Generates a value based on the Gaussian (normal) distribution function
687
            with the given offset and scale parameters.
688
        */
689
        static Real gaussianDistribution(Real x, Real offset = 0.0f, Real scale = 1.0f);
690
691
        /** Clamp a value within an inclusive range. */
692
        template <typename T>
693
        static T Clamp(T val, T minval, T maxval)
694
0
        {
695
0
            assert (minval <= maxval && "Invalid clamp range");
696
0
            return std::max(std::min(val, maxval), minval);
697
0
        }
698
699
        /** This creates a view matrix
700
701
            [ Lx  Uy  Dz  Tx  ]
702
            [ Lx  Uy  Dz  Ty  ]
703
            [ Lx  Uy  Dz  Tz  ]
704
            [ 0   0   0   1   ]
705
706
            Where T = -(Transposed(Rot) * Pos)
707
         */
708
        static Affine3 makeViewMatrix(const Vector3& position, const Quaternion& orientation,
709
            const Affine3* reflectMatrix = 0);
710
711
        /** Create a rotation matrix from direction and yaw
712
        @param direction the direction to look in. Must be normalised.
713
        @param yaw the yaw axis to use
714
        */
715
        static Matrix3 lookRotation(const Vector3& direction, const Vector3& yaw);
716
717
        /** This creates 'uniform' perspective projection matrix,
718
            which depth range [-1,1], right-handed rules
719
720
           [ A   0   C   0  ]
721
           [ 0   B   D   0  ]
722
           [ 0   0   q   qn ]
723
           [ 0   0   -1  0  ]
724
725
           A = 2 * near / (right - left)
726
           B = 2 * near / (top - bottom)
727
           C = (right + left) / (right - left)
728
           D = (top + bottom) / (top - bottom)
729
           q = - (far + near) / (far - near)
730
           qn = - 2 * (far * near) / (far - near)
731
         */
732
        static Matrix4 makePerspectiveMatrix(Real left, Real right, Real bottom, Real top, Real zNear, Real zFar);
733
734
        /** Get the radius of the origin-centered bounding sphere from the bounding box. */
735
        static Real boundingRadiusFromAABB(const AxisAlignedBox& aabb);
736
737
        /** Get the radius of the bbox-centered bounding sphere from the bounding box. */
738
        static Real boundingRadiusFromAABBCentered(const AxisAlignedBox &aabb);
739
740
741
        static constexpr Real POS_INFINITY = std::numeric_limits<Real>::infinity();
742
        static constexpr Real NEG_INFINITY = -std::numeric_limits<Real>::infinity();
743
        static constexpr Real PI = static_cast<Real> (3.14159265358979323846);
744
        static constexpr Real TWO_PI = Real( 2.0 * PI );
745
        static constexpr Real HALF_PI = Real( 0.5 * PI );
746
        static constexpr float fDeg2Rad = PI / Real(180.0);
747
        static constexpr float fRad2Deg = Real(180.0) / PI;
748
749
    };
750
751
    // these functions must be defined down here, because they rely on the
752
    // angle unit conversion functions in class Math:
753
754
    inline float Radian::valueDegrees() const
755
0
    {
756
0
        return Math::RadiansToDegrees ( mRad );
757
0
    }
758
759
    inline float Radian::valueAngleUnits() const
760
0
    {
761
0
        return Math::RadiansToAngleUnits ( mRad );
762
0
    }
763
764
    inline float Degree::valueRadians() const
765
0
    {
766
0
        return Math::DegreesToRadians ( mDeg );
767
0
    }
768
769
    inline float Degree::valueAngleUnits() const
770
0
    {
771
0
        return Math::DegreesToAngleUnits ( mDeg );
772
0
    }
773
774
    inline Angle::operator Radian() const
775
0
    {
776
0
        return Radian(Math::AngleUnitsToRadians(mAngle));
777
0
    }
778
779
    inline Angle::operator Degree() const
780
0
    {
781
0
        return Degree(Math::AngleUnitsToDegrees(mAngle));
782
0
    }
783
784
    inline Radian operator * ( float a, const Radian& b )
785
0
    {
786
0
        return Radian ( a * b.valueRadians() );
787
0
    }
788
789
    inline Radian operator / ( float a, const Radian& b )
790
0
    {
791
0
        return Radian ( a / b.valueRadians() );
792
0
    }
793
794
    inline Degree operator * ( float a, const Degree& b )
795
0
    {
796
0
        return Degree ( a * b.valueDegrees() );
797
0
    }
798
799
    inline Degree operator / ( float a, const Degree& b )
800
0
    {
801
0
        return Degree ( a / b.valueDegrees() );
802
0
    }
803
    /** @} */
804
    /** @} */
805
806
}
807
808
#include "OgreHeaderSuffix.h"
809
810
#endif