Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Extras / vectormathlibrary / include / vectormath / ppu / c / quat_soa.h
1 /*
2    Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
3    All rights reserved.
4
5    Redistribution and use in source and binary forms,
6    with or without modification, are permitted provided that the
7    following conditions are met:
8     * Redistributions of source code must retain the above copyright
9       notice, this list of conditions and the following disclaimer.
10     * Redistributions in binary form must reproduce the above copyright
11       notice, this list of conditions and the following disclaimer in the
12       documentation and/or other materials provided with the distribution.
13     * Neither the name of the Sony Computer Entertainment Inc nor the names
14       of its contributors may be used to endorse or promote products derived
15       from this software without specific prior written permission.
16
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27    POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef _VECTORMATH_QUAT_SOA_C_H
31 #define _VECTORMATH_QUAT_SOA_C_H
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35
36 /*-----------------------------------------------------------------------------
37  * Definitions
38  */
39 #ifndef _VECTORMATH_INTERNAL_FUNCTIONS
40 #define _VECTORMATH_INTERNAL_FUNCTIONS
41
42 #endif
43
44 static inline void vmathSoaQCopy( VmathSoaQuat *result, const VmathSoaQuat *quat )
45 {
46     result->x = quat->x;
47     result->y = quat->y;
48     result->z = quat->z;
49     result->w = quat->w;
50 }
51
52 static inline void vmathSoaQMakeFromElems( VmathSoaQuat *result, vec_float4 _x, vec_float4 _y, vec_float4 _z, vec_float4 _w )
53 {
54     result->x = _x;
55     result->y = _y;
56     result->z = _z;
57     result->w = _w;
58 }
59
60 static inline void vmathSoaQMakeFromV3Scalar( VmathSoaQuat *result, const VmathSoaVector3 *xyz, vec_float4 _w )
61 {
62     vmathSoaQSetXYZ( result, xyz );
63     vmathSoaQSetW( result, _w );
64 }
65
66 static inline void vmathSoaQMakeFromV4( VmathSoaQuat *result, const VmathSoaVector4 *vec )
67 {
68     result->x = vec->x;
69     result->y = vec->y;
70     result->z = vec->z;
71     result->w = vec->w;
72 }
73
74 static inline void vmathSoaQMakeFromScalar( VmathSoaQuat *result, vec_float4 scalar )
75 {
76     result->x = scalar;
77     result->y = scalar;
78     result->z = scalar;
79     result->w = scalar;
80 }
81
82 static inline void vmathSoaQMakeFromAos( VmathSoaQuat *result, const VmathQuat *quat )
83 {
84     vec_float4 vec128 = quat->vec128;
85     result->x = vec_splat( vec128, 0 );
86     result->y = vec_splat( vec128, 1 );
87     result->z = vec_splat( vec128, 2 );
88     result->w = vec_splat( vec128, 3 );
89 }
90
91 static inline void vmathSoaQMakeFrom4Aos( VmathSoaQuat *result, const VmathQuat *quat0, const VmathQuat *quat1, const VmathQuat *quat2, const VmathQuat *quat3 )
92 {
93     vec_float4 tmp0, tmp1, tmp2, tmp3;
94     tmp0 = vec_mergeh( quat0->vec128, quat2->vec128 );
95     tmp1 = vec_mergeh( quat1->vec128, quat3->vec128 );
96     tmp2 = vec_mergel( quat0->vec128, quat2->vec128 );
97     tmp3 = vec_mergel( quat1->vec128, quat3->vec128 );
98     result->x = vec_mergeh( tmp0, tmp1 );
99     result->y = vec_mergel( tmp0, tmp1 );
100     result->z = vec_mergeh( tmp2, tmp3 );
101     result->w = vec_mergel( tmp2, tmp3 );
102 }
103
104 static inline void vmathSoaQMakeIdentity( VmathSoaQuat *result )
105 {
106     vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){1.0f,1.0f,1.0f,1.0f}) );
107 }
108
109 static inline void vmathSoaQLerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )
110 {
111     VmathSoaQuat tmpQ_0, tmpQ_1;
112     vmathSoaQSub( &tmpQ_0, quat1, quat0 );
113     vmathSoaQScalarMul( &tmpQ_1, &tmpQ_0, t );
114     vmathSoaQAdd( result, quat0, &tmpQ_1 );
115 }
116
117 static inline void vmathSoaQSlerp( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1 )
118 {
119     VmathSoaQuat start, tmpQ_0, tmpQ_1;
120     vec_float4 recipSinAngle, scale0, scale1, cosAngle, angle;
121     vec_uint4 selectMask;
122     cosAngle = vmathSoaQDot( unitQuat0, unitQuat1 );
123     selectMask = (vec_uint4)vec_cmpgt( (vec_float4){0.0f,0.0f,0.0f,0.0f}, cosAngle );
124     cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask );
125     vmathSoaQSetX( &start, vec_sel( unitQuat0->x, negatef4( unitQuat0->x ), selectMask ) );
126     vmathSoaQSetY( &start, vec_sel( unitQuat0->y, negatef4( unitQuat0->y ), selectMask ) );
127     vmathSoaQSetZ( &start, vec_sel( unitQuat0->z, negatef4( unitQuat0->z ), selectMask ) );
128     vmathSoaQSetW( &start, vec_sel( unitQuat0->w, negatef4( unitQuat0->w ), selectMask ) );
129     selectMask = (vec_uint4)vec_cmpgt( (vec_float4){_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL,_VECTORMATH_SLERP_TOL}, cosAngle );
130     angle = acosf4( cosAngle );
131     recipSinAngle = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sinf4( angle ) );
132     scale0 = vec_sel( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), vec_madd( sinf4( vec_madd( vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );
133     scale1 = vec_sel( t, vec_madd( sinf4( vec_madd( t, angle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), recipSinAngle, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), selectMask );
134     vmathSoaQScalarMul( &tmpQ_0, &start, scale0 );
135     vmathSoaQScalarMul( &tmpQ_1, unitQuat1, scale1 );
136     vmathSoaQAdd( result, &tmpQ_0, &tmpQ_1 );
137 }
138
139 static inline void vmathSoaQSquad( VmathSoaQuat *result, vec_float4 t, const VmathSoaQuat *unitQuat0, const VmathSoaQuat *unitQuat1, const VmathSoaQuat *unitQuat2, const VmathSoaQuat *unitQuat3 )
140 {
141     VmathSoaQuat tmp0, tmp1;
142     vmathSoaQSlerp( &tmp0, t, unitQuat0, unitQuat3 );
143     vmathSoaQSlerp( &tmp1, t, unitQuat1, unitQuat2 );
144     vmathSoaQSlerp( result, vec_madd( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), t, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_sub( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), t ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), &tmp0, &tmp1 );
145 }
146
147 static inline void vmathSoaQGet4Aos( const VmathSoaQuat *quat, VmathQuat *result0, VmathQuat *result1, VmathQuat *result2, VmathQuat *result3 )
148 {
149     vec_float4 tmp0, tmp1, tmp2, tmp3;
150     tmp0 = vec_mergeh( quat->x, quat->z );
151     tmp1 = vec_mergeh( quat->y, quat->w );
152     tmp2 = vec_mergel( quat->x, quat->z );
153     tmp3 = vec_mergel( quat->y, quat->w );
154     vmathQMakeFrom128( result0, vec_mergeh( tmp0, tmp1 ) );
155     vmathQMakeFrom128( result1, vec_mergel( tmp0, tmp1 ) );
156     vmathQMakeFrom128( result2, vec_mergeh( tmp2, tmp3 ) );
157     vmathQMakeFrom128( result3, vec_mergel( tmp2, tmp3 ) );
158 }
159
160 static inline void vmathSoaQSetXYZ( VmathSoaQuat *result, const VmathSoaVector3 *vec )
161 {
162     result->x = vec->x;
163     result->y = vec->y;
164     result->z = vec->z;
165 }
166
167 static inline void vmathSoaQGetXYZ( VmathSoaVector3 *result, const VmathSoaQuat *quat )
168 {
169     vmathSoaV3MakeFromElems( result, quat->x, quat->y, quat->z );
170 }
171
172 static inline void vmathSoaQSetX( VmathSoaQuat *result, vec_float4 _x )
173 {
174     result->x = _x;
175 }
176
177 static inline vec_float4 vmathSoaQGetX( const VmathSoaQuat *quat )
178 {
179     return quat->x;
180 }
181
182 static inline void vmathSoaQSetY( VmathSoaQuat *result, vec_float4 _y )
183 {
184     result->y = _y;
185 }
186
187 static inline vec_float4 vmathSoaQGetY( const VmathSoaQuat *quat )
188 {
189     return quat->y;
190 }
191
192 static inline void vmathSoaQSetZ( VmathSoaQuat *result, vec_float4 _z )
193 {
194     result->z = _z;
195 }
196
197 static inline vec_float4 vmathSoaQGetZ( const VmathSoaQuat *quat )
198 {
199     return quat->z;
200 }
201
202 static inline void vmathSoaQSetW( VmathSoaQuat *result, vec_float4 _w )
203 {
204     result->w = _w;
205 }
206
207 static inline vec_float4 vmathSoaQGetW( const VmathSoaQuat *quat )
208 {
209     return quat->w;
210 }
211
212 static inline void vmathSoaQSetElem( VmathSoaQuat *result, int idx, vec_float4 value )
213 {
214     *(&result->x + idx) = value;
215 }
216
217 static inline vec_float4 vmathSoaQGetElem( const VmathSoaQuat *quat, int idx )
218 {
219     return *(&quat->x + idx);
220 }
221
222 static inline void vmathSoaQAdd( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )
223 {
224     result->x = vec_add( quat0->x, quat1->x );
225     result->y = vec_add( quat0->y, quat1->y );
226     result->z = vec_add( quat0->z, quat1->z );
227     result->w = vec_add( quat0->w, quat1->w );
228 }
229
230 static inline void vmathSoaQSub( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )
231 {
232     result->x = vec_sub( quat0->x, quat1->x );
233     result->y = vec_sub( quat0->y, quat1->y );
234     result->z = vec_sub( quat0->z, quat1->z );
235     result->w = vec_sub( quat0->w, quat1->w );
236 }
237
238 static inline void vmathSoaQScalarMul( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )
239 {
240     result->x = vec_madd( quat->x, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
241     result->y = vec_madd( quat->y, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
242     result->z = vec_madd( quat->z, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
243     result->w = vec_madd( quat->w, scalar, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
244 }
245
246 static inline void vmathSoaQScalarDiv( VmathSoaQuat *result, const VmathSoaQuat *quat, vec_float4 scalar )
247 {
248     result->x = divf4( quat->x, scalar );
249     result->y = divf4( quat->y, scalar );
250     result->z = divf4( quat->z, scalar );
251     result->w = divf4( quat->w, scalar );
252 }
253
254 static inline void vmathSoaQNeg( VmathSoaQuat *result, const VmathSoaQuat *quat )
255 {
256     result->x = negatef4( quat->x );
257     result->y = negatef4( quat->y );
258     result->z = negatef4( quat->z );
259     result->w = negatef4( quat->w );
260 }
261
262 static inline vec_float4 vmathSoaQDot( const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )
263 {
264     vec_float4 result;
265     result = vec_madd( quat0->x, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
266     result = vec_add( result, vec_madd( quat0->y, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
267     result = vec_add( result, vec_madd( quat0->z, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
268     result = vec_add( result, vec_madd( quat0->w, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
269     return result;
270 }
271
272 static inline vec_float4 vmathSoaQNorm( const VmathSoaQuat *quat )
273 {
274     vec_float4 result;
275     result = vec_madd( quat->x, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
276     result = vec_add( result, vec_madd( quat->y, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
277     result = vec_add( result, vec_madd( quat->z, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
278     result = vec_add( result, vec_madd( quat->w, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
279     return result;
280 }
281
282 static inline vec_float4 vmathSoaQLength( const VmathSoaQuat *quat )
283 {
284     return sqrtf4( vmathSoaQNorm( quat ) );
285 }
286
287 static inline void vmathSoaQNormalize( VmathSoaQuat *result, const VmathSoaQuat *quat )
288 {
289     vec_float4 lenSqr, lenInv;
290     lenSqr = vmathSoaQNorm( quat );
291     lenInv = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), sqrtf4( lenSqr ) );
292     result->x = vec_madd( quat->x, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
293     result->y = vec_madd( quat->y, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
294     result->z = vec_madd( quat->z, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
295     result->w = vec_madd( quat->w, lenInv, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
296 }
297
298 static inline void vmathSoaQMakeRotationArc( VmathSoaQuat *result, const VmathSoaVector3 *unitVec0, const VmathSoaVector3 *unitVec1 )
299 {
300     VmathSoaVector3 tmpV3_0, tmpV3_1;
301     vec_float4 cosHalfAngleX2, recipCosHalfAngleX2;
302     cosHalfAngleX2 = sqrtf4( vec_madd( ((vec_float4){2.0f,2.0f,2.0f,2.0f}), vec_add( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), vmathSoaV3Dot( unitVec0, unitVec1 ) ), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
303     recipCosHalfAngleX2 = divf4( ((vec_float4){1.0f,1.0f,1.0f,1.0f}), cosHalfAngleX2 );
304     vmathSoaV3Cross( &tmpV3_0, unitVec0, unitVec1 );
305     vmathSoaV3ScalarMul( &tmpV3_1, &tmpV3_0, recipCosHalfAngleX2 );
306     vmathSoaQMakeFromV3Scalar( result, &tmpV3_1, vec_madd( cosHalfAngleX2, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
307 }
308
309 static inline void vmathSoaQMakeRotationAxis( VmathSoaQuat *result, vec_float4 radians, const VmathSoaVector3 *unitVec )
310 {
311     VmathSoaVector3 tmpV3_0;
312     vec_float4 s, c, angle;
313     angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
314     sincosf4( angle, &s, &c );
315     vmathSoaV3ScalarMul( &tmpV3_0, unitVec, s );
316     vmathSoaQMakeFromV3Scalar( result, &tmpV3_0, c );
317 }
318
319 static inline void vmathSoaQMakeRotationX( VmathSoaQuat *result, vec_float4 radians )
320 {
321     vec_float4 s, c, angle;
322     angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
323     sincosf4( angle, &s, &c );
324     vmathSoaQMakeFromElems( result, s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );
325 }
326
327 static inline void vmathSoaQMakeRotationY( VmathSoaQuat *result, vec_float4 radians )
328 {
329     vec_float4 s, c, angle;
330     angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
331     sincosf4( angle, &s, &c );
332     vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), c );
333 }
334
335 static inline void vmathSoaQMakeRotationZ( VmathSoaQuat *result, vec_float4 radians )
336 {
337     vec_float4 s, c, angle;
338     angle = vec_madd( radians, ((vec_float4){0.5f,0.5f,0.5f,0.5f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}) );
339     sincosf4( angle, &s, &c );
340     vmathSoaQMakeFromElems( result, ((vec_float4){0.0f,0.0f,0.0f,0.0f}), ((vec_float4){0.0f,0.0f,0.0f,0.0f}), s, c );
341 }
342
343 static inline void vmathSoaQMul( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1 )
344 {
345     vec_float4 tmpX, tmpY, tmpZ, tmpW;
346     tmpX = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->x, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
347     tmpY = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->y, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->x, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
348     tmpZ = vec_sub( vec_add( vec_add( vec_madd( quat0->w, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->z, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->x, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
349     tmpW = vec_sub( vec_sub( vec_sub( vec_madd( quat0->w, quat1->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat0->x, quat1->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->y, quat1->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat0->z, quat1->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
350     vmathSoaQMakeFromElems( result, tmpX, tmpY, tmpZ, tmpW );
351 }
352
353 static inline void vmathSoaQRotate( VmathSoaVector3 *result, const VmathSoaQuat *quat, const VmathSoaVector3 *vec )
354 {
355     vec_float4 tmpX, tmpY, tmpZ, tmpW;
356     tmpX = vec_sub( vec_add( vec_madd( quat->w, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->y, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->z, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
357     tmpY = vec_sub( vec_add( vec_madd( quat->w, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->z, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->x, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
358     tmpZ = vec_sub( vec_add( vec_madd( quat->w, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->x, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->y, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
359     tmpW = vec_add( vec_add( vec_madd( quat->x, vec->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( quat->y, vec->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( quat->z, vec->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
360     result->x = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpX, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
361     result->y = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpY, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpZ, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
362     result->z = vec_add( vec_sub( vec_add( vec_madd( tmpW, quat->z, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ), vec_madd( tmpZ, quat->w, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpX, quat->y, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) ), vec_madd( tmpY, quat->x, ((vec_float4){0.0f,0.0f,0.0f,0.0f}) ) );
363 }
364
365 static inline void vmathSoaQConj( VmathSoaQuat *result, const VmathSoaQuat *quat )
366 {
367     vmathSoaQMakeFromElems( result, negatef4( quat->x ), negatef4( quat->y ), negatef4( quat->z ), quat->w );
368 }
369
370 static inline void vmathSoaQSelect( VmathSoaQuat *result, const VmathSoaQuat *quat0, const VmathSoaQuat *quat1, vec_uint4 select1 )
371 {
372     result->x = vec_sel( quat0->x, quat1->x, select1 );
373     result->y = vec_sel( quat0->y, quat1->y, select1 );
374     result->z = vec_sel( quat0->z, quat1->z, select1 );
375     result->w = vec_sel( quat0->w, quat1->w, select1 );
376 }
377
378 #ifdef _VECTORMATH_DEBUG
379
380 static inline void vmathSoaQPrint( const VmathSoaQuat *quat )
381 {
382     VmathQuat vec0, vec1, vec2, vec3;
383     vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );
384     printf("slot 0:\n");
385     vmathQPrint( &vec0 );
386     printf("slot 1:\n");
387     vmathQPrint( &vec1 );
388     printf("slot 2:\n");
389     vmathQPrint( &vec2 );
390     printf("slot 3:\n");
391     vmathQPrint( &vec3 );
392 }
393
394 static inline void vmathSoaQPrints( const VmathSoaQuat *quat, const char *name )
395 {
396     VmathQuat vec0, vec1, vec2, vec3;
397     printf( "%s:\n", name );
398     vmathSoaQGet4Aos( quat, &vec0, &vec1, &vec2, &vec3 );
399     printf("slot 0:\n");
400     vmathQPrint( &vec0 );
401     printf("slot 1:\n");
402     vmathQPrint( &vec1 );
403     printf("slot 2:\n");
404     vmathQPrint( &vec2 );
405     printf("slot 3:\n");
406     vmathQPrint( &vec3 );
407 }
408
409 #endif
410
411 #ifdef __cplusplus
412 }
413 #endif /* __cplusplus */
414
415 #endif