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