/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 |