OGRE  2.0
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OgreMathlibNEON.h
Go to the documentation of this file.
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 
29 #ifndef __MathlibNEON_H__
30 #define __MathlibNEON_H__
31 
32 #if __OGRE_HAVE_NEON
33 
34 #ifndef __Mathlib_H__
35  #error "Don't include this file directly. include Math/Array/OgreMathlib.h"
36 #endif
37 
38 #include "OgrePrerequisites.h"
39 
40 namespace Ogre
41 {
42  // A few shortcut functions to emulate instructions included with SSE2 that NEON lacks.
43  // See http://rcl-rs-vvg.blogspot.com/2010/08/simd-etudes.html
44 
45  // Similar to _mm_movemask_ps
46  static inline uint32 vmovemaskq_u32( uint32x4_t conditions )
47  {
48  const uint32x4_t qMask = { 1, 2, 4, 8 };
49  const uint32x4_t qAnded = vandq_u32( conditions, qMask );
50 
51  // These two are no-ops, they only tell compiler to treat Q register as two D regs
52  const uint32x2_t dHigh = vget_high_u32( qAnded );
53  const uint32x2_t dLow = vget_low_u32( qAnded );
54 
55  const uint32x2_t dOred = vorr_u32( dHigh, dLow );
56  const uint32x2_t dOred2 = dOred;
57  // For some reason vpadd_u32 doesn't work right if both arguments
58  // are the same variable so we use a copy.
59  const uint32x2_t dMask = vpadd_u32( dOred, dOred2 );
60  return vget_lane_u32( dMask, 0 );
61  }
62 
63  static inline ArrayInt vnand_s32(ArrayInt a, ArrayInt b)
64  {
65  return vandq_s32(vmvnq_s32(a), b);
66  }
67 
68  static inline ArrayReal vnand_f32(ArrayReal a, ArrayReal b)
69  {
70  return vreinterpretq_f32_u32( vandq_u32( vmvnq_u32(vreinterpretq_u32_f32(a)),
71  vreinterpretq_u32_f32(b) ) );
72  }
73 
74 #define vnand_u32( a, b ) vandq_u32( vmvnq_u32(a), b )
75 
76  static inline ArrayReal vorrq_f32(ArrayReal a, ArrayReal b)
77  {
78  return (ArrayReal)vorrq_s32((ArrayInt)a, (ArrayInt)b);
79  }
80 
81  static inline ArrayReal vdivq_f32( ArrayReal num, ArrayReal den )
82  {
83  const ArrayReal inv0 = vrecpeq_f32(den);
84  const ArrayReal step0 = vrecpsq_f32(inv0, den);
85 
86  const ArrayReal inv1 = vmulq_f32(step0, inv0);
87  return vmulq_f32( num, inv1 );
88  }
89 
90 #define vandq_f32( a, b ) vreinterpretq_f32_u32( vandq_u32( vreinterpretq_u32_f32( a ), vreinterpretq_u32_f32( b ) ) )
91 #define veorq_f32( a, b ) vreinterpretq_f32_u32( veorq_u32( vreinterpretq_u32_f32( a ), vreinterpretq_u32_f32( b ) ) )
92 #define vandq_f32u32( a, b ) vreinterpretq_f32_u32( vandq_u32( vreinterpretq_u32_f32( a ), b ) )
93 
94 #define _MM_SHUFFLE(z, y, x, w) (((z) << 6) | ((y) << 4) | ((x) << 2) | (w))
95 
96  static inline ArrayReal vshuf_f32(ArrayReal a, ArrayReal b, unsigned int idx)
97  {
98  float x, y, z, w;
99 
100  // First index used to retrieve from a
101  switch((idx >> 6) & 0x03)
102  {
103  case 0:
104  z = vgetq_lane_f32(a, 0);
105  break;
106  case 1:
107  z = vgetq_lane_f32(a, 1);
108  break;
109  case 2:
110  z = vgetq_lane_f32(a, 2);
111  break;
112  case 3:
113  z = vgetq_lane_f32(a, 3);
114  break;
115  }
116 
117  // Second index used to retrieve from a
118  switch((idx >> 4) & 0x03)
119  {
120  case 0:
121  y = vgetq_lane_f32(a, 0);
122  break;
123  case 1:
124  y = vgetq_lane_f32(a, 1);
125  break;
126  case 2:
127  y = vgetq_lane_f32(a, 2);
128  break;
129  case 3:
130  y = vgetq_lane_f32(a, 3);
131  break;
132  }
133 
134  // Third index used to retrieve from b
135  switch((idx >> 2) & 0x03)
136  {
137  case 0:
138  x = vgetq_lane_f32(b, 0);
139  break;
140  case 1:
141  x = vgetq_lane_f32(b, 1);
142  break;
143  case 2:
144  x = vgetq_lane_f32(b, 2);
145  break;
146  case 3:
147  x = vgetq_lane_f32(b, 3);
148  break;
149  }
150 
151  // Four index used to retrieve from b
152  switch(idx & 0x03)
153  {
154  case 0:
155  w = vgetq_lane_f32(b, 0);
156  break;
157  case 1:
158  w = vgetq_lane_f32(b, 1);
159  break;
160  case 2:
161  w = vgetq_lane_f32(b, 2);
162  break;
163  case 3:
164  w = vgetq_lane_f32(b, 3);
165  break;
166  }
167 
168  return (ArrayReal) { x, y, z, w };
169  }
170 
171  inline uint32x4_t vcneqq_f32(ArrayReal a, ArrayReal b)
172  {
173  return vceqq_u32(vceqq_f32(a, b), vdupq_n_u32( 0 ));
174  }
175 
176  class ArrayRadian
177  {
178  ArrayReal mRad;
179 
180  public:
181  explicit ArrayRadian ( ArrayReal r ) : mRad( r ) {}
182  //ArrayRadian ( const ArrayDegree& d );
183  ArrayRadian& operator = ( const ArrayReal &f ) { mRad = f; return *this; }
184  ArrayRadian& operator = ( const ArrayRadian &r ) { mRad = r.mRad; return *this; }
185  //ArrayRadian& operator = ( const ArrayDegree& d );
186 
187  //ArrayReal valueDegrees() const; // see bottom of this file
188  ArrayReal valueRadians() const { return mRad; }
189 
190  inline const ArrayRadian& operator + () const;
191  inline ArrayRadian operator + ( const ArrayRadian& r ) const;
192  //inline ArrayRadian operator + ( const ArrayDegree& d ) const;
193  inline ArrayRadian& operator += ( const ArrayRadian& r );
194  //inline ArrayRadian& operator += ( const ArrayDegree& d );
195  inline ArrayRadian operator - () const;
196  inline ArrayRadian operator - ( const ArrayRadian& r ) const;
197  //inline ArrayRadian operator - ( const ArrayDegree& d ) const;
198  inline ArrayRadian& operator -= ( const ArrayRadian& r );
199  //inline ArrayRadian& operator -= ( const ArrayDegree& d );
200  inline ArrayRadian operator * ( ArrayReal f ) const;
201  inline ArrayRadian operator * ( const ArrayRadian& f ) const;
202  inline ArrayRadian& operator *= ( ArrayReal f );
203  inline ArrayRadian operator / ( ArrayReal f ) const;
204  inline ArrayRadian& operator /= ( ArrayReal f );
205 
206  inline ArrayMaskR operator < ( const ArrayRadian& r ) const;
207  inline ArrayMaskR operator <= ( const ArrayRadian& r ) const;
208  inline ArrayMaskR operator == ( const ArrayRadian& r ) const;
209  inline ArrayMaskR operator != ( const ArrayRadian& r ) const;
210  inline ArrayMaskR operator >= ( const ArrayRadian& r ) const;
211  inline ArrayMaskR operator > ( const ArrayRadian& r ) const;
212  };
213 
214  class _OgreExport MathlibNEON
215  {
216  public:
217  static const ArrayReal HALF; //0.5f, 0.5f, 0.5f, 0.5f
218  static const ArrayReal ONE; //1.0f, 1.0f, 1.0f, 1.0f
219  static const ArrayReal THREE; //3.0f, 3.0f, 3.0f, 3.0f
220  static const ArrayReal NEG_ONE; //-1.0f, -1.0f, -1.0f, -1.0f
221  static const ArrayReal PI; //PI, PI, PI, PI
222  static const ArrayReal TWO_PI; //2*PI, 2*PI, 2*PI, 2*PI
223  static const ArrayReal ONE_DIV_2PI; //1 / 2PI, 1 / 2PI, 1 / 2PI, 1 / 2PI
224  static const ArrayReal fEpsilon; //1e-6f, 1e-6f, 1e-6f, 1e-6f
225  static const ArrayReal fSqEpsilon; //1e-12f, 1e-12f, 1e-12f, 1e-12f
226  static const ArrayReal OneMinusEpsilon;//1 - 1e-6f, 1 - 1e-6f, 1 - 1e-6f, 1 - 1e-6f
227  static const ArrayReal fDeg2Rad; //Math::fDeg2Rad, Math::fDeg2Rad, Math::fDeg2Rad, Math::fDeg2Rad
228  static const ArrayReal fRad2Deg; //Math::fRad2Deg, Math::fRad2Deg, Math::fRad2Deg, Math::fRad2Deg
229  static const ArrayReal FLOAT_MIN; //FLT_MIN, FLT_MIN, FLT_MIN, FLT_MIN
230  static const ArrayReal SIGN_MASK; //0x80000000, 0x80000000, 0x80000000, 0x80000000
231  //INFINITE is taken in Windows, INFINITY by C99 (bloody macros). A joke on Infinite Tea
232  static const ArrayReal INFINITEA; //Inf, Inf, Inf, Inf
233  static const ArrayReal MAX_NEG; //Max negative number (x4)
234  static const ArrayReal MAX_POS; //Max negative number (x4)
235  static const ArrayReal LAST_AFFINE_COLUMN;//0, 0, 0, 1
236 
243  static inline ArrayReal Abs4( ArrayReal a )
244  {
245  return vnand_f32( vdupq_n_f32( -0.0f ), a );
246  }
247 
268  static inline ArrayReal Cmov4( ArrayReal arg1, ArrayReal arg2, ArrayMaskR mask )
269  {
270  assert( vmovemaskq_u32( vceqq_f32( arg1, arg1 ) ) == 0x0f &&
271  vmovemaskq_u32( vceqq_f32( arg2, arg2 ) ) == 0x0f &&
272  "Passing NaN values to CMov4" );
273 #ifndef NDEBUG
274  ArrayReal newNan1 = vmulq_f32( arg1, vdupq_n_f32(0.0f) ); //+-Inf * 0 = nan
275  ArrayReal newNan2 = vmulq_f32( arg2, vdupq_n_f32(0.0f) ); //+-Inf * 0 = nan
276  assert( vmovemaskq_u32( vceqq_f32( newNan1, newNan1 ) ) == 0x0f &&
277  vmovemaskq_u32( vceqq_f32( newNan2, newNan2 ) ) == 0x0f &&
278  "Passing +/- Infinity values to CMov4" );
279 #endif
280 
281  ArrayReal t = vsubq_f32( arg1, arg2 ); // t = arg1 - arg2
282  return vaddq_f32( arg2, vandq_f32u32( t, mask ) ); // r = arg2 + (t & mask)
283  }
284 
311  static inline ArrayReal CmovRobust( ArrayReal arg1, ArrayReal arg2, ArrayMaskR mask )
312  {
313  return vreinterpretq_f32_u32(
314  vorrq_u32( vandq_u32( vreinterpretq_u32_f32( arg1 ), mask ),
315  vnand_u32( mask, vreinterpretq_u32_f32( arg2 ) ) ) );
316  }
317  static inline ArrayInt CmovRobust( ArrayInt arg1, ArrayInt arg2, ArrayMaskI mask )
318  {
319  return vorrq_s32( vandq_s32( arg1, vreinterpretq_s32_u32( mask ) ),
320  vnand_s32( vreinterpretq_s32_u32( mask ), arg2 ) );
321  }
322 
327  static inline ArrayReal And( ArrayReal a, ArrayReal b )
328  {
329  return vandq_f32( a, b );
330  }
331  static inline ArrayInt And( ArrayInt a, ArrayInt b )
332  {
333  return vandq_s32( a, b );
334  }
335  static inline ArrayInt And( ArrayInt a, ArrayMaskI b )
336  {
337  return vandq_s32( a, vreinterpretq_s32_u32( b ) );
338  }
339  static inline ArrayMaskI And( ArrayMaskI a, ArrayInt b )
340  {
341  return vreinterpretq_u32_s32( vandq_s32( vreinterpretq_s32_u32( a ), b ) );
342  }
343  static inline ArrayMaskI And( ArrayMaskI a, ArrayMaskI b )
344  {
345  return vandq_u32( a, b );
346  }
347 
352  static inline ArrayInt And( ArrayInt a, uint32 b )
353  {
354  return vandq_s32( a, vdupq_n_s32( b ) );
355  }
356 
367  static inline ArrayMaskI TestFlags4( ArrayInt a, ArrayInt b )
368  {
369  // !( (a & b) == 0 ) --> ( (a & b) == 0 ) ^ -1
370  return veorq_u32( vceqq_s32( vandq_s32( a, b ), vdupq_n_s32(0) ),
371  vdupq_n_u32( ~0 ) );
372  }
373  static inline ArrayMaskI TestFlags4( ArrayInt a, ArrayMaskI b )
374  {
375  // !( (a & b) == 0 ) --> ( (a & b) == 0 ) ^ -1
376  return veorq_u32( vceqq_u32( vandq_u32( vreinterpretq_u32_s32( a ), b ),
377  vdupq_n_u32(0) ), vdupq_n_u32( ~0 ) );
378  }
379  static inline ArrayMaskI TestFlags4( ArrayMaskI a, ArrayInt b )
380  {
381  // !( (a & b) == 0 ) --> ( (a & b) == 0 ) ^ -1
382  return veorq_u32( vceqq_u32( vandq_u32( a, vreinterpretq_u32_s32( b ) ),
383  vdupq_n_u32(0) ), vdupq_n_u32( ~0 ) );
384  }
385 
386 
391  /*static inline ArrayInt AndNot( ArrayInt a, ArrayInt b )
392  {
393  return vnand_s32( b, a );
394  }*/
395  static inline ArrayMaskI AndNot( ArrayMaskI a, ArrayMaskI b )
396  {
397  return vnand_u32( b, a );
398  }
399 
404  static inline ArrayReal Or( ArrayReal a, ArrayReal b )
405  {
406  return vorrq_f32( a, b );
407  }
408  static inline ArrayInt Or( ArrayInt a, ArrayInt b )
409  {
410  return vorrq_s32( a, b );
411  }
412  static inline ArrayMaskI Or( ArrayMaskI a, ArrayMaskI b )
413  {
414  return vorrq_u32( a, b );
415  }
416 
421  static inline ArrayMaskR CompareLess( ArrayReal a, ArrayReal b )
422  {
423  return vcltq_f32( a, b );
424  }
425 
430  static inline ArrayMaskR CompareLessEqual( ArrayReal a, ArrayReal b )
431  {
432  return vcleq_f32( a, b );
433  }
434 
439  static inline ArrayMaskR CompareGreater( ArrayReal a, ArrayReal b )
440  {
441  return vcgtq_f32( a, b );
442  }
443 
448  static inline ArrayMaskR CompareGreaterEqual( ArrayReal a, ArrayReal b )
449  {
450  return vcgeq_f32( a, b );
451  }
452 
453  static inline ArrayReal SetAll( Real val )
454  {
455  return vdupq_n_f32( val );
456  }
457 
458  static inline ArrayInt SetAll( uint32 val )
459  {
460  return vdupq_n_s32( val );
461  }
462 
467  static inline ArrayMaskR isInfinity( ArrayReal a )
468  {
469  return vceqq_f32( a, MathlibNEON::INFINITEA );
470  }
471 
473  static inline ArrayReal Max( ArrayReal a, ArrayReal b )
474  {
475  return vmaxq_f32( a, b );
476  }
477 
479  static inline ArrayReal Min( ArrayReal a, ArrayReal b )
480  {
481  return vminq_f32( a, b );
482  }
483 
488  static inline Real CollapseMin( ArrayReal a )
489  {
490  float32x2_t a_lo, a_hi, min;
491  a_lo = vget_low_f32(a);
492  a_hi = vget_high_f32(a);
493  min = vpmin_f32(a_lo, a_hi);
494  min = vpmin_f32(min, min);
495 
496  return vget_lane_f32(min, 0);
497  }
498 
503  static inline Real CollapseMax( ArrayReal a )
504  {
505  float32x2_t a_lo, a_hi, max;
506  a_lo = vget_low_f32(a);
507  a_hi = vget_high_f32(a);
508  max = vpmax_f32(a_lo, a_hi);
509  max = vpmax_f32(max, max);
510 
511  return vget_lane_f32(max, 0);
512  }
513 
535  static inline ArrayReal Inv4( ArrayReal val )
536  {
537  ArrayReal inv = vrecpeq_f32( val );
538  ArrayReal twoRcp = vaddq_f32( inv, inv ); //2 * rcp( f )
539  ArrayReal rightSide = vmulq_f32( val, vmulq_f32( inv, inv ) ); //f * rcp( f ) * rcp( f )
540  rightSide = vreinterpretq_f32_u32(
541  vandq_u32( vreinterpretq_u32_f32( rightSide ),
542  vcneqq_f32( val, vdupq_n_f32(0.0f) ) ) ); //Nuke this NaN
543  return vsubq_f32( twoRcp, rightSide );
544  }
545 
568  static inline ArrayReal InvNonZero4( ArrayReal val )
569  {
570  ArrayReal inv = vrecpeq_f32( val );
571  ArrayReal twoRcp = vaddq_f32( inv, inv ); //2 * rcp( f )
572  ArrayReal rightSide= vmulq_f32( val, vmulq_f32( inv, inv ) ); //f * rcp( f ) * rcp( f )
573  return vsubq_f32( twoRcp, rightSide );
574  }
575 
594  static inline ArrayReal InvSqrt4( ArrayReal f )
595  {
596  ArrayReal invSqrt = vrsqrteq_f32( f );
597 
598  ArrayReal halfInvSqrt= vmulq_f32( HALF, invSqrt ); //0.5 * rsqrt( f )
599  ArrayReal rightSide = vmulq_f32( invSqrt, vmulq_f32( f, invSqrt ) ); //f * rsqrt( f ) * rsqrt( f )
600  rightSide = vreinterpretq_f32_u32(
601  vandq_u32( vreinterpretq_u32_f32( rightSide ),
602  vcneqq_f32( f, vdupq_n_f32(0.0f) ) ));//Nuke this NaN
603  return vmulq_f32( halfInvSqrt, vsubq_f32( THREE, rightSide ) ); //halfInvSqrt*(3 - rightSide)
604  }
605 
626  static inline ArrayReal InvSqrtNonZero4( ArrayReal f )
627  {
628  ArrayReal invSqrt = vrsqrteq_f32( f );
629 
630  ArrayReal halfInvSqrt= vmulq_f32( HALF, invSqrt ); //0.5 * rsqrt( f )
631  ArrayReal rightSide = vmulq_f32( invSqrt, vmulq_f32( f, invSqrt ) ); //f * rsqrt( f ) * rsqrt( f )
632  return vmulq_f32( halfInvSqrt, vsubq_f32( THREE, rightSide ) ); //halfInvSqrt*(3 - rightSide)
633  }
634 
643  static inline ArrayReal Modf4( ArrayReal x, ArrayReal &outIntegral );
644 
651  static inline ArrayReal ACos4( ArrayReal x );
652 
659  static ArrayReal Sin4( ArrayReal x );
660 
667  static ArrayReal Cos4( ArrayReal x );
668 
678  static void SinCos4( ArrayReal x, ArrayReal &outSin, ArrayReal &outCos );
679  };
680 
681 #if OGRE_COMPILER != OGRE_COMPILER_CLANG && OGRE_COMPILER != OGRE_COMPILER_GNUC
682 // inline ArrayReal operator - ( ArrayReal l ) { return _mm_xor_ps( l, MathlibNEON::SIGN_MASK ); }
683 // inline ArrayReal operator + ( ArrayReal l, Real r ) { return vaddq_f32( l, vdupq_n_f32( r ) ); }
684 // inline ArrayReal operator + ( Real l, ArrayReal r ) { return vaddq_f32( vdupq_n_f32( l ), r ); }
685 // inline ArrayReal operator + ( ArrayReal l, ArrayReal r ) { return vaddq_f32( l, r ); }
686 // inline ArrayReal operator - ( ArrayReal l, Real r ) { return vsubq_f32( l, vdupq_n_f32( r ) ); }
687 // inline ArrayReal operator - ( Real l, ArrayReal r ) { return vsubq_f32( vdupq_n_f32( l ), r ); }
688  inline ArrayReal operator - ( ArrayReal l, ArrayReal r ) { return vsubq_f32( l, r ); }
689 // inline ArrayReal operator * ( ArrayReal l, Real r ) { return vmulq_f32( l, vdupq_n_f32( r ) ); }
690 // inline ArrayReal operator * ( Real l, ArrayReal r ) { return vmulq_f32( vdupq_n_f32( l ), r ); }
691  inline ArrayReal operator * ( ArrayReal l, ArrayReal r ) { return vmulq_f32( l, r ); }
692 // inline ArrayReal operator / ( ArrayReal l, Real r ) { return _mm_div_ps( l, vdupq_n_f32( r ) ); }
693 // inline ArrayReal operator / ( Real l, ArrayReal r ) { return _mm_div_ps( vdupq_n_f32( l ), r ); }
694 // inline ArrayReal operator / ( ArrayReal l, ArrayReal r ) { return _mm_div_ps( l, r ); }
695 #endif
696 }
697 
698 #include "OgreMathlibNEON.inl"
699 
700 #endif
701 #endif
Radian & operator+=(const Radian &r)
Definition: OgreMath.h:67
float Real
Software floating point type.
bool ArrayMaskR
unsigned int uint32
Definition: OgrePlatform.h:420
#define _OgreExport
Definition: OgrePlatform.h:255
const float & max(const float &a, const float &b)
Definition: OgreCommon.h:851
bool operator<=(const Radian &r) const
Definition: OgreMath.h:81
Real mRad
Definition: OgreMath.h:51
Real ArrayReal
Radian & operator/=(Real f)
Definition: OgreMath.h:78
Radian ArrayRadian
bool operator>(const Radian &r) const
Definition: OgreMath.h:85
bool operator!=(const Radian &r) const
Definition: OgreMath.h:83
Radian & operator-=(const Radian &r)
Definition: OgreMath.h:72
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:782
Radian operator/(Real f) const
Definition: OgreMath.h:77
const float & min(const float &a, const float &b)
Definition: OgreCommon.h:846
bool ArrayMaskI
Real valueRadians() const
Definition: OgreMath.h:61
Radian & operator=(const Real &f)
Definition: OgreMath.h:56
bool operator<(const Radian &r) const
Definition: OgreMath.h:80
const Radian & operator+() const
Definition: OgreMath.h:64
bool operator>=(const Radian &r) const
Definition: OgreMath.h:84
Radian & operator*=(Real f)
Definition: OgreMath.h:76
bool operator==(const Radian &r) const
Definition: OgreMath.h:82
Radian operator-() const
Definition: OgreMath.h:69
Radian operator*(Real f) const
Definition: OgreMath.h:74
uint32 ArrayInt