Bullet Collision Detection & Physics Library
neon/quat_aos.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 Sony Computer Entertainment Inc.
3  All rights reserved.
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 
15 */
16 
17 #ifndef _VECTORMATH_QUAT_AOS_CPP_H
18 #define _VECTORMATH_QUAT_AOS_CPP_H
19 
20 //-----------------------------------------------------------------------------
21 // Definitions
22 
23 #ifndef _VECTORMATH_INTERNAL_FUNCTIONS
24 #define _VECTORMATH_INTERNAL_FUNCTIONS
25 
26 #endif
27 
28 namespace Vectormath {
29 namespace Aos {
30 
31  inline Quat::Quat( const Quat & quat )
32  {
33  vXYZW = quat.vXYZW;
34  }
35 
36  inline Quat::Quat( float _x, float _y, float _z, float _w )
37  {
38  mXYZW[0] = _x;
39  mXYZW[1] = _y;
40  mXYZW[2] = _z;
41  mXYZW[3] = _w;
42  }
43 
44  inline Quat::Quat( float32x4_t fXYZW )
45  {
46  vXYZW = fXYZW;
47  }
48 
49  inline Quat::Quat( const Vector3 & xyz, float _w )
50  {
51  this->setXYZ( xyz );
52  this->setW( _w );
53  }
54 
55  inline Quat::Quat( const Vector4 & vec )
56  {
57  mXYZW[0] = vec.getX();
58  mXYZW[1] = vec.getY();
59  mXYZW[2] = vec.getZ();
60  mXYZW[3] = vec.getW();
61  }
62 
63  inline Quat::Quat( float scalar )
64  {
65  vXYZW = vdupq_n_f32(scalar);
66  }
67 
68  inline const Quat Quat::identity( )
69  {
70  return Quat( 0.0f, 0.0f, 0.0f, 1.0f );
71  }
72 
73  inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 )
74  {
75  return ( quat0 + ( ( quat1 - quat0 ) * t ) );
76  }
77 
78  inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 )
79  {
80  Quat start;
81  float recipSinAngle, scale0, scale1, cosAngle, angle;
82  cosAngle = dot( unitQuat0, unitQuat1 );
83  if ( cosAngle < 0.0f ) {
84  cosAngle = -cosAngle;
85  start = ( -unitQuat0 );
86  } else {
87  start = unitQuat0;
88  }
89  if ( cosAngle < _VECTORMATH_SLERP_TOL ) {
90  angle = acosf( cosAngle );
91  recipSinAngle = ( 1.0f / sinf( angle ) );
92  scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle );
93  scale1 = ( sinf( ( t * angle ) ) * recipSinAngle );
94  } else {
95  scale0 = ( 1.0f - t );
96  scale1 = t;
97  }
98  return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) );
99  }
100 
101  inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 )
102  {
103  Quat tmp0, tmp1;
104  tmp0 = slerp( t, unitQuat0, unitQuat3 );
105  tmp1 = slerp( t, unitQuat1, unitQuat2 );
106  return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 );
107  }
108 
109  inline void loadXYZW( Quat & quat, const float * fptr )
110  {
111  quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] );
112  }
113 
114  inline void storeXYZW( const Quat & quat, float * fptr )
115  {
116  vst1q_f32(fptr, quat.getvXYZW());
117  }
118 
119  inline Quat & Quat::operator =( const Quat & quat )
120  {
121  vXYZW = quat.getvXYZW();
122  return *this;
123  }
124 
125  inline Quat & Quat::setXYZ( const Vector3 & vec )
126  {
127  mXYZW[0] = vec.getX();
128  mXYZW[1] = vec.getY();
129  mXYZW[2] = vec.getZ();
130  return *this;
131  }
132 
133  inline const Vector3 Quat::getXYZ( ) const
134  {
135  return Vector3( mXYZW[0], mXYZW[1], mXYZW[2] );
136  }
137 
138  inline float32x4_t Quat::getvXYZW( ) const
139  {
140  return vXYZW;
141  }
142 
143  inline Quat & Quat::setX( float _x )
144  {
145  mXYZW[0] = _x;
146  return *this;
147  }
148 
149  inline float Quat::getX( ) const
150  {
151  return mXYZW[0];
152  }
153 
154  inline Quat & Quat::setY( float _y )
155  {
156  mXYZW[1] = _y;
157  return *this;
158  }
159 
160  inline float Quat::getY( ) const
161  {
162  return mXYZW[1];
163  }
164 
165  inline Quat & Quat::setZ( float _z )
166  {
167  mXYZW[2] = _z;
168  return *this;
169  }
170 
171  inline float Quat::getZ( ) const
172  {
173  return mXYZW[2];
174  }
175 
176  inline Quat & Quat::setW( float _w )
177  {
178  mXYZW[3] = _w;
179  return *this;
180  }
181 
182  inline float Quat::getW( ) const
183  {
184  return mXYZW[3];
185  }
186 
187  inline Quat & Quat::setElem( int idx, float value )
188  {
189  *(&mXYZW[0] + idx) = value;
190  return *this;
191  }
192 
193  inline float Quat::getElem( int idx ) const
194  {
195  return *(&mXYZW[0] + idx);
196  }
197 
198  inline float & Quat::operator []( int idx )
199  {
200  return *(&mXYZW[0] + idx);
201  }
202 
203  inline float Quat::operator []( int idx ) const
204  {
205  return *(&mXYZW[0] + idx);
206  }
207 
208  inline const Quat Quat::operator +( const Quat & quat ) const
209  {
210  return Quat( vaddq_f32(vXYZW, quat.vXYZW) );
211  }
212 
213  inline const Quat Quat::operator -( const Quat & quat ) const
214  {
215  return Quat( vsubq_f32(vXYZW, quat.vXYZW) );
216  }
217 
218  inline const Quat Quat::operator *( float scalar ) const
219  {
220  float32x4_t v_scalar = vdupq_n_f32(scalar);
221  return Quat( vmulq_f32(vXYZW, v_scalar) );
222  }
223 
224  inline Quat & Quat::operator +=( const Quat & quat )
225  {
226  *this = *this + quat;
227  return *this;
228  }
229 
230  inline Quat & Quat::operator -=( const Quat & quat )
231  {
232  *this = *this - quat;
233  return *this;
234  }
235 
236  inline Quat & Quat::operator *=( float scalar )
237  {
238  *this = *this * scalar;
239  return *this;
240  }
241 
242  inline const Quat Quat::operator /( float scalar ) const
243  {
244  return Quat(
245  ( mXYZW[0] / scalar ),
246  ( mXYZW[1] / scalar ),
247  ( mXYZW[2] / scalar ),
248  ( mXYZW[3] / scalar )
249  );
250  }
251 
252  inline Quat & Quat::operator /=( float scalar )
253  {
254  *this = *this / scalar;
255  return *this;
256  }
257 
258  inline const Quat Quat::operator -( ) const
259  {
260  return Quat( vnegq_f32(vXYZW) );
261  }
262 
263  inline const Quat operator *( float scalar, const Quat & quat )
264  {
265  return quat * scalar;
266  }
267 
268  inline float dot( const Quat & quat0, const Quat & quat1 )
269  {
270  float result;
271  result = ( quat0.getX() * quat1.getX() );
272  result = ( result + ( quat0.getY() * quat1.getY() ) );
273  result = ( result + ( quat0.getZ() * quat1.getZ() ) );
274  result = ( result + ( quat0.getW() * quat1.getW() ) );
275  return result;
276  }
277 
278  inline float norm( const Quat & quat )
279  {
280  float result;
281  result = ( quat.getX() * quat.getX() );
282  result = ( result + ( quat.getY() * quat.getY() ) );
283  result = ( result + ( quat.getZ() * quat.getZ() ) );
284  result = ( result + ( quat.getW() * quat.getW() ) );
285  return result;
286  }
287 
288  inline float length( const Quat & quat )
289  {
290  return ::sqrtf( norm( quat ) );
291  }
292 
293  inline const Quat normalize( const Quat & quat )
294  {
295  float lenSqr, lenInv;
296  lenSqr = norm( quat );
297  lenInv = ( 1.0f / sqrtf( lenSqr ) );
298  return Quat(
299  ( quat.getX() * lenInv ),
300  ( quat.getY() * lenInv ),
301  ( quat.getZ() * lenInv ),
302  ( quat.getW() * lenInv )
303  );
304  }
305 
306  inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 )
307  {
308  float cosHalfAngleX2, recipCosHalfAngleX2;
309  cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) );
310  recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 );
311  return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) );
312  }
313 
314  inline const Quat Quat::rotation( float radians, const Vector3 & unitVec )
315  {
316  float s, c, angle;
317  angle = ( radians * 0.5f );
318  s = sinf( angle );
319  c = cosf( angle );
320  return Quat( ( unitVec * s ), c );
321  }
322 
323  inline const Quat Quat::rotationX( float radians )
324  {
325  float s, c, angle;
326  angle = ( radians * 0.5f );
327  s = sinf( angle );
328  c = cosf( angle );
329  return Quat( s, 0.0f, 0.0f, c );
330  }
331 
332  inline const Quat Quat::rotationY( float radians )
333  {
334  float s, c, angle;
335  angle = ( radians * 0.5f );
336  s = sinf( angle );
337  c = cosf( angle );
338  return Quat( 0.0f, s, 0.0f, c );
339  }
340 
341  inline const Quat Quat::rotationZ( float radians )
342  {
343  float s, c, angle;
344  angle = ( radians * 0.5f );
345  s = sinf( angle );
346  c = cosf( angle );
347  return Quat( 0.0f, 0.0f, s, c );
348  }
349 
350  inline const Quat Quat::operator *( const Quat & quat ) const
351  {
352  return Quat(
353  ( ( ( ( mXYZW[3] * quat.mXYZW[0] ) + ( mXYZW[0] * quat.mXYZW[3] ) ) + ( mXYZW[1] * quat.mXYZW[2] ) ) - ( mXYZW[2] * quat.mXYZW[1] ) ),
354  ( ( ( ( mXYZW[3] * quat.mXYZW[1] ) + ( mXYZW[1] * quat.mXYZW[3] ) ) + ( mXYZW[2] * quat.mXYZW[0] ) ) - ( mXYZW[0] * quat.mXYZW[2] ) ),
355  ( ( ( ( mXYZW[3] * quat.mXYZW[2] ) + ( mXYZW[2] * quat.mXYZW[3] ) ) + ( mXYZW[0] * quat.mXYZW[1] ) ) - ( mXYZW[1] * quat.mXYZW[0] ) ),
356  ( ( ( ( mXYZW[3] * quat.mXYZW[3] ) - ( mXYZW[0] * quat.mXYZW[0] ) ) - ( mXYZW[1] * quat.mXYZW[1] ) ) - ( mXYZW[2] * quat.mXYZW[2] ) )
357  );
358  }
359 
360  inline Quat & Quat::operator *=( const Quat & quat )
361  {
362  *this = *this * quat;
363  return *this;
364  }
365 
366  inline const Vector3 rotate( const Quat & quat, const Vector3 & vec )
367  {
368  float tmpX, tmpY, tmpZ, tmpW;
369  tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) );
370  tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) );
371  tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) );
372  tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) );
373  return Vector3(
374  ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ),
375  ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ),
376  ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) )
377  );
378  }
379 
380  inline const Quat conj( const Quat & quat )
381  {
382  return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() );
383  }
384 
385  inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 )
386  {
387  return Quat(
388  ( select1 )? quat1.getX() : quat0.getX(),
389  ( select1 )? quat1.getY() : quat0.getY(),
390  ( select1 )? quat1.getZ() : quat0.getZ(),
391  ( select1 )? quat1.getW() : quat0.getW()
392  );
393  }
394 
395 #ifdef _VECTORMATH_DEBUG
396 
397 inline void print( const Quat & quat )
398 {
399  printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() );
400 }
401 
402 inline void print( const Quat & quat, const char * name )
403 {
404  printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() );
405 }
406 
407 #endif
408 
409 } // namespace Aos
410 } // namespace Vectormath
411 
412 #endif
413 
const Quat normalize(const Quat &quat)
float getY() const
static const Quat rotationY(float radians)
float getW() const
Quat & operator*=(const Quat &quat)
Quat & operator-=(const Quat &quat)
const Quat operator+(const Quat &quat) const
Quat & setW(float w)
Quat & operator=(const Quat &quat)
#define _VECTORMATH_SLERP_TOL
Definition: neon/vec_aos.h:23
Quat & setX(float x)
const Vector3 rotate(const Quat &quat, const Vector3 &vec)
float & operator[](int idx)
static const Quat identity()
Definition: neon/quat_aos.h:68
static const Quat rotationZ(float radians)
static const Quat rotation(const Vector3 &unitVec0, const Vector3 &unitVec1)
static const Quat rotationX(float radians)
const Quat operator*(const Quat &quat) const
float norm(const Quat &quat)
const Quat operator/(float scalar) const
const Quat operator-() const
const Vector3 getXYZ() const
void loadXYZW(Quat &quat, const float *fptr)
const Quat conj(const Quat &quat)
Quat & operator/=(float scalar)
void storeXYZW(const Quat &quat, float *fptr)
const Quat lerp(float t, const Quat &quat0, const Quat &quat1)
Definition: neon/quat_aos.h:73
const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1)
Definition: neon/mat_aos.h:409
Quat & setElem(int idx, float value)
float getZ() const
float getElem(int idx) const
Quat & setY(float y)
const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3)
float dot(const Quat &quat0, const Quat &quat1)
Quat & setZ(float z)
const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1)
Definition: neon/vec_aos.h:473
Quat & setXYZ(const Vector3 &vec)
float length(const Quat &quat)
const Matrix3 operator*(float scalar, const Matrix3 &mat)
Definition: neon/mat_aos.h:257
float getX() const
Quat & operator+=(const Quat &quat)
const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1)
Definition: neon/quat_aos.h:78