source: GTP/trunk/App/Demos/Geom/OgreStuff/include/OgreMath.h @ 1030

Revision 1030, 20.0 KB checked in by gumbau, 18 years ago (diff)

Ogre Stuff initial import

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#ifndef __Math_H__
26#define __Math_H__
27
28#include "OgrePrerequisites.h"
29
30namespace Ogre
31{
32    /** Wrapper class which indicates a given angle value is in Radians.
33    @remarks
34        Radian values are interchangeable with Degree values, and conversions
35        will be done automatically between them.
36    */
37        class Radian
38        {
39                Real mRad;
40
41        public:
42                explicit Radian ( Real r=0 ) : mRad(r) {}
43                Radian ( const Degree& d );
44                const Radian& operator = ( const Real& f ) { mRad = f; return *this; }
45                const Radian& operator = ( const Radian& r ) { mRad = r.mRad; return *this; }
46                const Radian& operator = ( const Degree& d );
47
48                Real valueDegrees() const; // see bottom of this file
49                Real valueRadians() const { return mRad; }
50                Real valueAngleUnits() const;
51
52                Radian operator + ( const Radian& r ) const { return Radian ( mRad + r.mRad ); }
53                Radian operator + ( const Degree& d ) const;
54                Radian& operator += ( const Radian& r ) { mRad += r.mRad; return *this; }
55                Radian& operator += ( const Degree& d );
56                Radian operator - () { return Radian(-mRad); }
57                Radian operator - ( const Radian& r ) const { return Radian ( mRad - r.mRad ); }
58                Radian operator - ( const Degree& d ) const;
59                Radian& operator -= ( const Radian& r ) { mRad -= r.mRad; return *this; }
60                Radian& operator -= ( const Degree& d );
61                Radian operator * ( Real f ) const { return Radian ( mRad * f ); }
62        Radian operator * ( const Radian& f ) const { return Radian ( mRad * f.mRad ); }
63                Radian& operator *= ( Real f ) { mRad *= f; return *this; }
64                Radian operator / ( Real f ) const { return Radian ( mRad / f ); }
65                Radian& operator /= ( Real f ) { mRad /= f; return *this; }
66
67                bool operator <  ( const Radian& r ) const { return mRad <  r.mRad; }
68                bool operator <= ( const Radian& r ) const { return mRad <= r.mRad; }
69                bool operator == ( const Radian& r ) const { return mRad == r.mRad; }
70                bool operator != ( const Radian& r ) const { return mRad != r.mRad; }
71                bool operator >= ( const Radian& r ) const { return mRad >= r.mRad; }
72                bool operator >  ( const Radian& r ) const { return mRad >  r.mRad; }
73        };
74
75    /** Wrapper class which indicates a given angle value is in Degrees.
76    @remarks
77        Degree values are interchangeable with Radian values, and conversions
78        will be done automatically between them.
79    */
80        class Degree
81        {
82                Real mDeg; // if you get an error here - make sure to define/typedef 'Real' first
83
84        public:
85                explicit Degree ( Real d=0 ) : mDeg(d) {}
86                Degree ( const Radian& r ) : mDeg(r.valueDegrees()) {}
87                const Degree& operator = ( const Real& f ) { mDeg = f; return *this; }
88                const Degree& operator = ( const Degree& d ) { mDeg = d.mDeg; return *this; }
89                const Degree& operator = ( const Radian& r ) { mDeg = r.valueDegrees(); return *this; }
90
91                Real valueDegrees() const { return mDeg; }
92                Real valueRadians() const; // see bottom of this file
93                Real valueAngleUnits() const;
94
95                Degree operator + ( const Degree& d ) const { return Degree ( mDeg + d.mDeg ); }
96                Degree operator + ( const Radian& r ) const { return Degree ( mDeg + r.valueDegrees() ); }
97                Degree& operator += ( const Degree& d ) { mDeg += d.mDeg; return *this; }
98                Degree& operator += ( const Radian& r ) { mDeg += r.valueDegrees(); return *this; }
99                Degree operator - () { return Degree(-mDeg); }
100                Degree operator - ( const Degree& d ) const { return Degree ( mDeg - d.mDeg ); }
101                Degree operator - ( const Radian& r ) const { return Degree ( mDeg - r.valueDegrees() ); }
102                Degree& operator -= ( const Degree& d ) { mDeg -= d.mDeg; return *this; }
103                Degree& operator -= ( const Radian& r ) { mDeg -= r.valueDegrees(); return *this; }
104                Degree operator * ( Real f ) const { return Degree ( mDeg * f ); }
105        Degree operator * ( const Degree& f ) const { return Degree ( mDeg * f.mDeg ); }
106                Degree& operator *= ( Real f ) { mDeg *= f; return *this; }
107                Degree operator / ( Real f ) const { return Degree ( mDeg / f ); }
108                Degree& operator /= ( Real f ) { mDeg /= f; return *this; }
109
110                bool operator <  ( const Degree& d ) const { return mDeg <  d.mDeg; }
111                bool operator <= ( const Degree& d ) const { return mDeg <= d.mDeg; }
112                bool operator == ( const Degree& d ) const { return mDeg == d.mDeg; }
113                bool operator != ( const Degree& d ) const { return mDeg != d.mDeg; }
114                bool operator >= ( const Degree& d ) const { return mDeg >= d.mDeg; }
115                bool operator >  ( const Degree& d ) const { return mDeg >  d.mDeg; }
116        };
117
118    /** Wrapper class which identifies a value as the currently default angle
119        type, as defined by Math::setAngleUnit.
120    @remarks
121        Angle values will be automatically converted between radians and degrees,
122        as appropriate.
123    */
124        class Angle
125        {
126                Real mAngle;
127        public:
128                explicit Angle ( Real angle ) : mAngle(angle) {}
129                operator Radian();
130                operator Degree();
131        };
132
133        // these functions could not be defined within the class definition of class
134        // Radian because they required class Degree to be defined
135        inline Radian::Radian ( const Degree& d ) : mRad(d.valueRadians()) {
136        }
137        inline const Radian& Radian::operator = ( const Degree& d ) {
138                mRad = d.valueRadians(); return *this;
139        }
140        inline Radian Radian::operator + ( const Degree& d ) const {
141                return Radian ( mRad + d.valueRadians() );
142        }
143        inline Radian& Radian::operator += ( const Degree& d ) {
144                mRad += d.valueRadians();
145                return *this;
146        }
147        inline Radian Radian::operator - ( const Degree& d ) const {
148                return Radian ( mRad - d.valueRadians() );
149        }
150        inline Radian& Radian::operator -= ( const Degree& d ) {
151                mRad -= d.valueRadians();
152                return *this;
153        }
154
155    /** Class to provide access to common mathematical functions.
156        @remarks
157            Most of the maths functions are aliased versions of the C runtime
158            library functions. They are aliased here to provide future
159            optimisation opportunities, either from faster RTLs or custom
160            math approximations.
161        @note
162            <br>This is based on MgcMath.h from
163            <a href="http://www.magic-software.com">Wild Magic</a>.
164    */
165    class _OgreExport Math
166    {
167   public:
168       /** The angular units used by the API. This functionality is now deprecated in favor
169               of discreet angular unit types ( see Degree and Radian above ). The only place
170                   this functionality is actually still used is when parsing files. Search for
171                   usage of the Angle class for those instances
172       */
173       enum AngleUnit
174       {
175           AU_DEGREE,
176           AU_RADIAN
177       };
178
179    protected:
180       // angle units used by the api
181       static AngleUnit msAngleUnit;
182
183        /// Size of the trig tables as determined by constructor.
184        static int mTrigTableSize;
185
186        /// Radian -> index factor value ( mTrigTableSize / 2 * PI )
187        static Real mTrigTableFactor;
188        static Real* mSinTable;
189        static Real* mTanTable;
190
191        /** Private function to build trig tables.
192        */
193        void buildTrigTables();
194
195                static Real SinTable (Real fValue);
196                static Real TanTable (Real fValue);
197    public:
198        /** Default constructor.
199            @param
200                trigTableSize Optional parameter to set the size of the
201                tables used to implement Sin, Cos, Tan
202        */
203        Math(unsigned int trigTableSize = 4096);
204
205        /** Default destructor.
206        */
207        ~Math();
208
209                static inline int IAbs (int iValue) { return ( iValue >= 0 ? iValue : -iValue ); }
210                static inline int ICeil (float fValue) { return int(ceil(fValue)); }
211                static inline int IFloor (float fValue) { return int(floor(fValue)); }
212        static int ISign (int iValue);
213
214                static inline Real Abs (Real fValue) { return Real(fabs(fValue)); }
215                static inline Degree Abs (const Degree& dValue) { return Degree(fabs(dValue.valueDegrees())); }
216                static inline Radian Abs (const Radian& rValue) { return Radian(fabs(rValue.valueRadians())); }
217                static Radian ACos (Real fValue);
218                static Radian ASin (Real fValue);
219                static inline Radian ATan (Real fValue) { return Radian(atan(fValue)); }
220                static inline Radian ATan2 (Real fY, Real fX) { return Radian(atan2(fY,fX)); }
221                static inline Real Ceil (Real fValue) { return Real(ceil(fValue)); }
222
223        /** Cosine function.
224            @param
225                fValue Angle in radians
226            @param
227                useTables If true, uses lookup tables rather than
228                calculation - faster but less accurate.
229        */
230        static inline Real Cos (const Radian& fValue, bool useTables = false) {
231                        return (!useTables) ? Real(cos(fValue.valueRadians())) : SinTable(fValue.valueRadians() + HALF_PI);
232                }
233        /** Cosine function.
234            @param
235                fValue Angle in radians
236            @param
237                useTables If true, uses lookup tables rather than
238                calculation - faster but less accurate.
239        */
240        static inline Real Cos (Real fValue, bool useTables = false) {
241                        return (!useTables) ? Real(cos(fValue)) : SinTable(fValue + HALF_PI);
242                }
243
244                static inline Real Exp (Real fValue) { return Real(exp(fValue)); }
245
246                static inline Real Floor (Real fValue) { return Real(floor(fValue)); }
247
248                static inline Real Log (Real fValue) { return Real(log(fValue)); }
249
250                static inline Real Pow (Real fBase, Real fExponent) { return Real(pow(fBase,fExponent)); }
251
252        static Real Sign (Real fValue);
253                static inline Radian Sign ( const Radian& rValue )
254                {
255                        return Radian(Sign(rValue.valueRadians()));
256                }
257                static inline Degree Sign ( const Degree& dValue )
258                {
259                        return Degree(Sign(dValue.valueDegrees()));
260                }
261
262        /** Sine function.
263            @param
264                fValue Angle in radians
265            @param
266                useTables If true, uses lookup tables rather than
267                calculation - faster but less accurate.
268        */
269        static inline Real Sin (const Radian& fValue, bool useTables = false) {
270                        return (!useTables) ? Real(sin(fValue.valueRadians())) : SinTable(fValue.valueRadians());
271                }
272        /** Sine function.
273            @param
274                fValue Angle in radians
275            @param
276                useTables If true, uses lookup tables rather than
277                calculation - faster but less accurate.
278        */
279        static inline Real Sin (Real fValue, bool useTables = false) {
280                        return (!useTables) ? Real(sin(fValue)) : SinTable(fValue);
281                }
282
283                static inline Real Sqr (Real fValue) { return fValue*fValue; }
284
285                static inline Real Sqrt (Real fValue) { return Real(sqrt(fValue)); }
286
287        static inline Radian Sqrt (const Radian& fValue) { return Radian(sqrt(fValue.valueRadians())); }
288
289        static inline Degree Sqrt (const Degree& fValue) { return Degree(sqrt(fValue.valueDegrees())); }
290
291        /** Inverse square root i.e. 1 / Sqrt(x), good for vector
292            normalisation.
293        */
294                static Real InvSqrt(Real fValue);
295
296        static Real UnitRandom ();  // in [0,1]
297
298        static Real RangeRandom (Real fLow, Real fHigh);  // in [fLow,fHigh]
299
300        static Real SymmetricRandom ();  // in [-1,1]
301
302        /** Tangent function.
303            @param
304                fValue Angle in radians
305            @param
306                useTables If true, uses lookup tables rather than
307                calculation - faster but less accurate.
308        */
309                static inline Real Tan (const Radian& fValue, bool useTables = false) {
310                        return (!useTables) ? Real(tan(fValue.valueRadians())) : TanTable(fValue.valueRadians());
311                }
312        /** Tangent function.
313            @param
314                fValue Angle in radians
315            @param
316                useTables If true, uses lookup tables rather than
317                calculation - faster but less accurate.
318        */
319                static inline Real Tan (Real fValue, bool useTables = false) {
320                        return (!useTables) ? Real(tan(fValue)) : TanTable(fValue);
321                }
322
323                static inline Real DegreesToRadians(Real degrees) { return degrees * fDeg2Rad; }
324        static inline Real RadiansToDegrees(Real radians) { return radians * fRad2Deg; }
325
326       /** These functions used to set the assumed angle units (radians or degrees)
327            expected when using the Angle type.
328       @par
329            You can set this directly after creating a new Root, and also before/after resource creation,
330            depending on whether you want the change to affect resource files.
331       */
332       static void setAngleUnit(AngleUnit unit);
333       /** Get the unit being used for angles. */
334       static AngleUnit getAngleUnit(void);
335
336       /** Convert from the current AngleUnit to radians. */
337       static Real AngleUnitsToRadians(Real units);
338       /** Convert from radians to the current AngleUnit . */
339       static Real RadiansToAngleUnits(Real radians);
340       /** Convert from the current AngleUnit to degrees. */
341       static Real AngleUnitsToDegrees(Real units);
342       /** Convert from degrees to the current AngleUnit. */
343       static Real DegreesToAngleUnits(Real degrees);
344
345       /** Checks wether a given point is inside a triangle, in a
346            2-dimensional (Cartesian) space.
347            @remarks
348                The vertices of the triangle must be given in either
349                trigonometrical (anticlockwise) or inverse trigonometrical
350                (clockwise) order.
351            @param
352                px The X-coordinate of the point.
353            @param
354                py The Y-coordinate of the point.
355            @param
356                ax The X-coordinate of the triangle's first vertex.
357            @param
358                ay The Y-coordinate of the triangle's first vertex.
359            @param
360                bx The X-coordinate of the triangle's second vertex.
361            @param
362                by The Y-coordinate of the triangle's second vertex.
363            @param
364                cx The X-coordinate of the triangle's third vertex.
365            @param
366                cy The Y-coordinate of the triangle's third vertex.
367            @returns
368                If the point resides in the triangle, <b>true</b> is
369                returned.
370            @par
371                If the point is outside the triangle, <b>false</b> is
372                returned.
373        */
374        static bool pointInTri2D( Real px, Real pz, Real ax, Real az, Real bx, Real bz, Real cx, Real cz );
375
376        /** Ray / plane intersection, returns boolean result and distance. */
377        static std::pair<bool, Real> intersects(const Ray& ray, const Plane& plane);
378
379        /** Ray / sphere intersection, returns boolean result and distance. */
380        static std::pair<bool, Real> intersects(const Ray& ray, const Sphere& sphere,
381            bool discardInside = true);
382       
383        /** Ray / box intersection, returns boolean result and distance. */
384        static std::pair<bool, Real> intersects(const Ray& ray, const AxisAlignedBox& sphere);
385
386        /** Sphere / box intersection test. */
387        static bool intersects(const Sphere& sphere, const AxisAlignedBox& box);
388
389        /** Plane / box intersection test. */
390        static bool intersects(const Plane& plane, const AxisAlignedBox& box);
391
392        /** Ray / convex plane list intersection test.
393        @param ray The ray to test with
394        @param plaeList List of planes which form a convex volume
395        @param normalIsOutside Does the normal point outside the volume
396        */
397        static std::pair<bool, Real> intersects(
398            const Ray& ray, const std::vector<Plane>& planeList,
399            bool normalIsOutside);
400        /** Ray / convex plane list intersection test.
401        @param ray The ray to test with
402        @param plaeList List of planes which form a convex volume
403        @param normalIsOutside Does the normal point outside the volume
404        */
405        static std::pair<bool, Real> intersects(
406            const Ray& ray, const std::list<Plane>& planeList,
407            bool normalIsOutside);
408
409        /** Sphere / plane intersection test.
410        @remarks NB just do a plane.getDistance(sphere.getCenter()) for more detail!
411        */
412        static bool intersects(const Sphere& sphere, const Plane& plane);
413
414        /** Compare 2 reals, using tolerance for inaccuracies.
415        */
416        static bool RealEqual(Real a, Real b,
417            Real tolerance = std::numeric_limits<Real>::epsilon());
418
419        /** Calculates the tangent space vector for a given set of positions / texture coords. */
420        static Vector3 calculateTangentSpaceVector(
421            const Vector3& position1, const Vector3& position2, const Vector3& position3,
422            Real u1, Real v1, Real u2, Real v2, Real u3, Real v3);
423
424        /** Build a reflection matrix for the passed in plane. */
425        static Matrix4 buildReflectionMatrix(const Plane& p);
426        /** Calculate a face normal, including the w component which is the offset from the origin. */
427        static Vector4 calculateFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
428        /** Calculate a face normal, no w-information. */
429        static Vector3 calculateBasicFaceNormal(const Vector3& v1, const Vector3& v2, const Vector3& v3);
430        /** Calculate a face normal without normalize, including the w component which is the offset from the origin. */
431        static Vector4 calculateFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
432        /** Calculate a face normal without normalize, no w-information. */
433        static Vector3 calculateBasicFaceNormalWithoutNormalize(const Vector3& v1, const Vector3& v2, const Vector3& v3);
434
435        static const Real POS_INFINITY;
436        static const Real NEG_INFINITY;
437        static const Real PI;
438        static const Real TWO_PI;
439        static const Real HALF_PI;
440                static const Real fDeg2Rad;
441                static const Real fRad2Deg;
442
443    };
444
445        // these functions must be defined down here, because they rely on the
446        // angle unit conversion functions in class Math:
447
448        inline Real Radian::valueDegrees() const
449        {
450                return Math::RadiansToDegrees ( mRad );
451        }
452
453        inline Real Radian::valueAngleUnits() const
454        {
455                return Math::RadiansToAngleUnits ( mRad );
456        }
457
458        inline Real Degree::valueRadians() const
459        {
460                return Math::DegreesToRadians ( mDeg );
461        }
462
463        inline Real Degree::valueAngleUnits() const
464        {
465                return Math::DegreesToAngleUnits ( mDeg );
466        }
467
468        inline Angle::operator Radian()
469        {
470                return Radian(Math::AngleUnitsToRadians(mAngle));
471        }
472
473        inline Angle::operator Degree()
474        {
475                return Degree(Math::AngleUnitsToDegrees(mAngle));
476        }
477
478        inline Radian operator * ( Real a, const Radian& b )
479        {
480                return Radian ( a * b.valueRadians() );
481        }
482
483        inline Radian operator / ( Real a, const Radian& b )
484        {
485                return Radian ( a / b.valueRadians() );
486        }
487
488        inline Degree operator * ( Real a, const Degree& b )
489        {
490                return Degree ( a * b.valueDegrees() );
491        }
492
493        inline Degree operator / ( Real a, const Degree& b )
494        {
495                return Degree ( a / b.valueDegrees() );
496        }
497
498}
499#endif
Note: See TracBrowser for help on using the repository browser.