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_AOS_CPP_H
31 #define _VECTORMATH_QUAT_AOS_CPP_H
32
33 //-----------------------------------------------------------------------------
34 // Definitions
35
36 #ifndef _VECTORMATH_INTERNAL_FUNCTIONS
37 #define _VECTORMATH_INTERNAL_FUNCTIONS
38
39 #endif
40
41 namespace Vectormath
42 {
43 namespace Aos
44 {
set128(vec_float4 vec)45 VECTORMATH_FORCE_INLINE void Quat::set128(vec_float4 vec)
46 {
47 mVec128 = vec;
48 }
49
Quat(const floatInVec & _x,const floatInVec & _y,const floatInVec & _z,const floatInVec & _w)50 VECTORMATH_FORCE_INLINE Quat::Quat(const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w)
51 {
52 mVec128 = _mm_unpacklo_ps(
53 _mm_unpacklo_ps(_x.get128(), _z.get128()),
54 _mm_unpacklo_ps(_y.get128(), _w.get128()));
55 }
56
Quat(const Vector3 & xyz,float _w)57 VECTORMATH_FORCE_INLINE Quat::Quat(const Vector3 &xyz, float _w)
58 {
59 mVec128 = xyz.get128();
60 _vmathVfSetElement(mVec128, _w, 3);
61 }
62
Quat(const Quat & quat)63 VECTORMATH_FORCE_INLINE Quat::Quat(const Quat &quat)
64 {
65 mVec128 = quat.get128();
66 }
67
Quat(float _x,float _y,float _z,float _w)68 VECTORMATH_FORCE_INLINE Quat::Quat(float _x, float _y, float _z, float _w)
69 {
70 mVec128 = _mm_setr_ps(_x, _y, _z, _w);
71 }
72
Quat(const Vector3 & xyz,const floatInVec & _w)73 VECTORMATH_FORCE_INLINE Quat::Quat(const Vector3 &xyz, const floatInVec &_w)
74 {
75 mVec128 = xyz.get128();
76 mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);
77 }
78
Quat(const Vector4 & vec)79 VECTORMATH_FORCE_INLINE Quat::Quat(const Vector4 &vec)
80 {
81 mVec128 = vec.get128();
82 }
83
Quat(float scalar)84 VECTORMATH_FORCE_INLINE Quat::Quat(float scalar)
85 {
86 mVec128 = floatInVec(scalar).get128();
87 }
88
Quat(const floatInVec & scalar)89 VECTORMATH_FORCE_INLINE Quat::Quat(const floatInVec &scalar)
90 {
91 mVec128 = scalar.get128();
92 }
93
Quat(__m128 vf4)94 VECTORMATH_FORCE_INLINE Quat::Quat(__m128 vf4)
95 {
96 mVec128 = vf4;
97 }
98
identity()99 VECTORMATH_FORCE_INLINE const Quat Quat::identity()
100 {
101 return Quat(_VECTORMATH_UNIT_0001);
102 }
103
lerp(float t,const Quat & quat0,const Quat & quat1)104 VECTORMATH_FORCE_INLINE const Quat lerp(float t, const Quat &quat0, const Quat &quat1)
105 {
106 return lerp(floatInVec(t), quat0, quat1);
107 }
108
lerp(const floatInVec & t,const Quat & quat0,const Quat & quat1)109 VECTORMATH_FORCE_INLINE const Quat lerp(const floatInVec &t, const Quat &quat0, const Quat &quat1)
110 {
111 return (quat0 + ((quat1 - quat0) * t));
112 }
113
slerp(float t,const Quat & unitQuat0,const Quat & unitQuat1)114 VECTORMATH_FORCE_INLINE const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1)
115 {
116 return slerp(floatInVec(t), unitQuat0, unitQuat1);
117 }
118
slerp(const floatInVec & t,const Quat & unitQuat0,const Quat & unitQuat1)119 VECTORMATH_FORCE_INLINE const Quat slerp(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1)
120 {
121 Quat start;
122 vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines;
123 __m128 selectMask;
124 cosAngle = _vmathVfDot4(unitQuat0.get128(), unitQuat1.get128());
125 selectMask = (__m128)vec_cmpgt(_mm_setzero_ps(), cosAngle);
126 cosAngle = vec_sel(cosAngle, negatef4(cosAngle), selectMask);
127 start = Quat(vec_sel(unitQuat0.get128(), negatef4(unitQuat0.get128()), selectMask));
128 selectMask = (__m128)vec_cmpgt(_mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle);
129 angle = acosf4(cosAngle);
130 tttt = t.get128();
131 oneMinusT = vec_sub(_mm_set1_ps(1.0f), tttt);
132 angles = vec_mergeh(_mm_set1_ps(1.0f), tttt);
133 angles = vec_mergeh(angles, oneMinusT);
134 angles = vec_madd(angles, angle, _mm_setzero_ps());
135 sines = sinf4(angles);
136 scales = _mm_div_ps(sines, vec_splat(sines, 0));
137 scale0 = vec_sel(oneMinusT, vec_splat(scales, 1), selectMask);
138 scale1 = vec_sel(tttt, vec_splat(scales, 2), selectMask);
139 return Quat(vec_madd(start.get128(), scale0, vec_mul(unitQuat1.get128(), scale1)));
140 }
141
squad(float t,const Quat & unitQuat0,const Quat & unitQuat1,const Quat & unitQuat2,const Quat & unitQuat3)142 VECTORMATH_FORCE_INLINE const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3)
143 {
144 return squad(floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3);
145 }
146
squad(const floatInVec & t,const Quat & unitQuat0,const Quat & unitQuat1,const Quat & unitQuat2,const Quat & unitQuat3)147 VECTORMATH_FORCE_INLINE const Quat squad(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3)
148 {
149 return slerp(((floatInVec(2.0f) * t) * (floatInVec(1.0f) - t)), slerp(t, unitQuat0, unitQuat3), slerp(t, unitQuat1, unitQuat2));
150 }
151
get128()152 VECTORMATH_FORCE_INLINE __m128 Quat::get128() const
153 {
154 return mVec128;
155 }
156
157 VECTORMATH_FORCE_INLINE Quat &Quat::operator=(const Quat &quat)
158 {
159 mVec128 = quat.mVec128;
160 return *this;
161 }
162
setXYZ(const Vector3 & vec)163 VECTORMATH_FORCE_INLINE Quat &Quat::setXYZ(const Vector3 &vec)
164 {
165 VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff};
166 mVec128 = vec_sel(vec.get128(), mVec128, sw);
167 return *this;
168 }
169
getXYZ()170 VECTORMATH_FORCE_INLINE const Vector3 Quat::getXYZ() const
171 {
172 return Vector3(mVec128);
173 }
174
setX(float _x)175 VECTORMATH_FORCE_INLINE Quat &Quat::setX(float _x)
176 {
177 _vmathVfSetElement(mVec128, _x, 0);
178 return *this;
179 }
180
setX(const floatInVec & _x)181 VECTORMATH_FORCE_INLINE Quat &Quat::setX(const floatInVec &_x)
182 {
183 mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0);
184 return *this;
185 }
186
getX()187 VECTORMATH_FORCE_INLINE const floatInVec Quat::getX() const
188 {
189 return floatInVec(mVec128, 0);
190 }
191
setY(float _y)192 VECTORMATH_FORCE_INLINE Quat &Quat::setY(float _y)
193 {
194 _vmathVfSetElement(mVec128, _y, 1);
195 return *this;
196 }
197
setY(const floatInVec & _y)198 VECTORMATH_FORCE_INLINE Quat &Quat::setY(const floatInVec &_y)
199 {
200 mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1);
201 return *this;
202 }
203
getY()204 VECTORMATH_FORCE_INLINE const floatInVec Quat::getY() const
205 {
206 return floatInVec(mVec128, 1);
207 }
208
setZ(float _z)209 VECTORMATH_FORCE_INLINE Quat &Quat::setZ(float _z)
210 {
211 _vmathVfSetElement(mVec128, _z, 2);
212 return *this;
213 }
214
setZ(const floatInVec & _z)215 VECTORMATH_FORCE_INLINE Quat &Quat::setZ(const floatInVec &_z)
216 {
217 mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2);
218 return *this;
219 }
220
getZ()221 VECTORMATH_FORCE_INLINE const floatInVec Quat::getZ() const
222 {
223 return floatInVec(mVec128, 2);
224 }
225
setW(float _w)226 VECTORMATH_FORCE_INLINE Quat &Quat::setW(float _w)
227 {
228 _vmathVfSetElement(mVec128, _w, 3);
229 return *this;
230 }
231
setW(const floatInVec & _w)232 VECTORMATH_FORCE_INLINE Quat &Quat::setW(const floatInVec &_w)
233 {
234 mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3);
235 return *this;
236 }
237
getW()238 VECTORMATH_FORCE_INLINE const floatInVec Quat::getW() const
239 {
240 return floatInVec(mVec128, 3);
241 }
242
setElem(int idx,float value)243 VECTORMATH_FORCE_INLINE Quat &Quat::setElem(int idx, float value)
244 {
245 _vmathVfSetElement(mVec128, value, idx);
246 return *this;
247 }
248
setElem(int idx,const floatInVec & value)249 VECTORMATH_FORCE_INLINE Quat &Quat::setElem(int idx, const floatInVec &value)
250 {
251 mVec128 = _vmathVfInsert(mVec128, value.get128(), idx);
252 return *this;
253 }
254
getElem(int idx)255 VECTORMATH_FORCE_INLINE const floatInVec Quat::getElem(int idx) const
256 {
257 return floatInVec(mVec128, idx);
258 }
259
260 VECTORMATH_FORCE_INLINE VecIdx Quat::operator[](int idx)
261 {
262 return VecIdx(mVec128, idx);
263 }
264
265 VECTORMATH_FORCE_INLINE const floatInVec Quat::operator[](int idx) const
266 {
267 return floatInVec(mVec128, idx);
268 }
269
270 VECTORMATH_FORCE_INLINE const Quat Quat::operator+(const Quat &quat) const
271 {
272 return Quat(_mm_add_ps(mVec128, quat.mVec128));
273 }
274
275 VECTORMATH_FORCE_INLINE const Quat Quat::operator-(const Quat &quat) const
276 {
277 return Quat(_mm_sub_ps(mVec128, quat.mVec128));
278 }
279
280 VECTORMATH_FORCE_INLINE const Quat Quat::operator*(float scalar) const
281 {
282 return *this * floatInVec(scalar);
283 }
284
285 VECTORMATH_FORCE_INLINE const Quat Quat::operator*(const floatInVec &scalar) const
286 {
287 return Quat(_mm_mul_ps(mVec128, scalar.get128()));
288 }
289
290 VECTORMATH_FORCE_INLINE Quat &Quat::operator+=(const Quat &quat)
291 {
292 *this = *this + quat;
293 return *this;
294 }
295
296 VECTORMATH_FORCE_INLINE Quat &Quat::operator-=(const Quat &quat)
297 {
298 *this = *this - quat;
299 return *this;
300 }
301
302 VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(float scalar)
303 {
304 *this = *this * scalar;
305 return *this;
306 }
307
308 VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(const floatInVec &scalar)
309 {
310 *this = *this * scalar;
311 return *this;
312 }
313
314 VECTORMATH_FORCE_INLINE const Quat Quat::operator/(float scalar) const
315 {
316 return *this / floatInVec(scalar);
317 }
318
319 VECTORMATH_FORCE_INLINE const Quat Quat::operator/(const floatInVec &scalar) const
320 {
321 return Quat(_mm_div_ps(mVec128, scalar.get128()));
322 }
323
324 VECTORMATH_FORCE_INLINE Quat &Quat::operator/=(float scalar)
325 {
326 *this = *this / scalar;
327 return *this;
328 }
329
330 VECTORMATH_FORCE_INLINE Quat &Quat::operator/=(const floatInVec &scalar)
331 {
332 *this = *this / scalar;
333 return *this;
334 }
335
336 VECTORMATH_FORCE_INLINE const Quat Quat::operator-() const
337 {
338 return Quat(_mm_sub_ps(_mm_setzero_ps(), mVec128));
339 }
340
341 VECTORMATH_FORCE_INLINE const Quat operator*(float scalar, const Quat &quat)
342 {
343 return floatInVec(scalar) * quat;
344 }
345
346 VECTORMATH_FORCE_INLINE const Quat operator*(const floatInVec &scalar, const Quat &quat)
347 {
348 return quat * scalar;
349 }
350
dot(const Quat & quat0,const Quat & quat1)351 VECTORMATH_FORCE_INLINE const floatInVec dot(const Quat &quat0, const Quat &quat1)
352 {
353 return floatInVec(_vmathVfDot4(quat0.get128(), quat1.get128()), 0);
354 }
355
norm(const Quat & quat)356 VECTORMATH_FORCE_INLINE const floatInVec norm(const Quat &quat)
357 {
358 return floatInVec(_vmathVfDot4(quat.get128(), quat.get128()), 0);
359 }
360
length(const Quat & quat)361 VECTORMATH_FORCE_INLINE const floatInVec length(const Quat &quat)
362 {
363 return floatInVec(_mm_sqrt_ps(_vmathVfDot4(quat.get128(), quat.get128())), 0);
364 }
365
normalize(const Quat & quat)366 VECTORMATH_FORCE_INLINE const Quat normalize(const Quat &quat)
367 {
368 vec_float4 dot = _vmathVfDot4(quat.get128(), quat.get128());
369 return Quat(_mm_mul_ps(quat.get128(), newtonrapson_rsqrt4(dot)));
370 }
371
rotation(const Vector3 & unitVec0,const Vector3 & unitVec1)372 VECTORMATH_FORCE_INLINE const Quat Quat::rotation(const Vector3 &unitVec0, const Vector3 &unitVec1)
373 {
374 Vector3 crossVec;
375 __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res;
376 cosAngle = _vmathVfDot3(unitVec0.get128(), unitVec1.get128());
377 cosAngleX2Plus2 = vec_madd(cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f));
378 recipCosHalfAngleX2 = _mm_rsqrt_ps(cosAngleX2Plus2);
379 cosHalfAngleX2 = vec_mul(recipCosHalfAngleX2, cosAngleX2Plus2);
380 crossVec = cross(unitVec0, unitVec1);
381 res = vec_mul(crossVec.get128(), recipCosHalfAngleX2);
382 VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff};
383 res = vec_sel(res, vec_mul(cosHalfAngleX2, _mm_set1_ps(0.5f)), sw);
384 return Quat(res);
385 }
386
rotation(float radians,const Vector3 & unitVec)387 VECTORMATH_FORCE_INLINE const Quat Quat::rotation(float radians, const Vector3 &unitVec)
388 {
389 return rotation(floatInVec(radians), unitVec);
390 }
391
rotation(const floatInVec & radians,const Vector3 & unitVec)392 VECTORMATH_FORCE_INLINE const Quat Quat::rotation(const floatInVec &radians, const Vector3 &unitVec)
393 {
394 __m128 s, c, angle, res;
395 angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f));
396 sincosf4(angle, &s, &c);
397 VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff};
398 res = vec_sel(vec_mul(unitVec.get128(), s), c, sw);
399 return Quat(res);
400 }
401
rotationX(float radians)402 VECTORMATH_FORCE_INLINE const Quat Quat::rotationX(float radians)
403 {
404 return rotationX(floatInVec(radians));
405 }
406
rotationX(const floatInVec & radians)407 VECTORMATH_FORCE_INLINE const Quat Quat::rotationX(const floatInVec &radians)
408 {
409 __m128 s, c, angle, res;
410 angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f));
411 sincosf4(angle, &s, &c);
412 VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0xffffffff, 0, 0, 0};
413 VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff};
414 res = vec_sel(_mm_setzero_ps(), s, xsw);
415 res = vec_sel(res, c, wsw);
416 return Quat(res);
417 }
418
rotationY(float radians)419 VECTORMATH_FORCE_INLINE const Quat Quat::rotationY(float radians)
420 {
421 return rotationY(floatInVec(radians));
422 }
423
rotationY(const floatInVec & radians)424 VECTORMATH_FORCE_INLINE const Quat Quat::rotationY(const floatInVec &radians)
425 {
426 __m128 s, c, angle, res;
427 angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f));
428 sincosf4(angle, &s, &c);
429 VM_ATTRIBUTE_ALIGN16 unsigned int ysw[4] = {0, 0xffffffff, 0, 0};
430 VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff};
431 res = vec_sel(_mm_setzero_ps(), s, ysw);
432 res = vec_sel(res, c, wsw);
433 return Quat(res);
434 }
435
rotationZ(float radians)436 VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ(float radians)
437 {
438 return rotationZ(floatInVec(radians));
439 }
440
rotationZ(const floatInVec & radians)441 VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ(const floatInVec &radians)
442 {
443 __m128 s, c, angle, res;
444 angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f));
445 sincosf4(angle, &s, &c);
446 VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0, 0, 0xffffffff, 0};
447 VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff};
448 res = vec_sel(_mm_setzero_ps(), s, zsw);
449 res = vec_sel(res, c, wsw);
450 return Quat(res);
451 }
452
453 VECTORMATH_FORCE_INLINE const Quat Quat::operator*(const Quat &quat) const
454 {
455 __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3;
456 __m128 product, l_wxyz, r_wxyz, xy, qw;
457 ldata = mVec128;
458 rdata = quat.mVec128;
459 tmp0 = _mm_shuffle_ps(ldata, ldata, _MM_SHUFFLE(3, 0, 2, 1));
460 tmp1 = _mm_shuffle_ps(rdata, rdata, _MM_SHUFFLE(3, 1, 0, 2));
461 tmp2 = _mm_shuffle_ps(ldata, ldata, _MM_SHUFFLE(3, 1, 0, 2));
462 tmp3 = _mm_shuffle_ps(rdata, rdata, _MM_SHUFFLE(3, 0, 2, 1));
463 qv = vec_mul(vec_splat(ldata, 3), rdata);
464 qv = vec_madd(vec_splat(rdata, 3), ldata, qv);
465 qv = vec_madd(tmp0, tmp1, qv);
466 qv = vec_nmsub(tmp2, tmp3, qv);
467 product = vec_mul(ldata, rdata);
468 l_wxyz = vec_sld(ldata, ldata, 12);
469 r_wxyz = vec_sld(rdata, rdata, 12);
470 qw = vec_nmsub(l_wxyz, r_wxyz, product);
471 xy = vec_madd(l_wxyz, r_wxyz, product);
472 qw = vec_sub(qw, vec_sld(xy, xy, 8));
473 VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff};
474 return Quat(vec_sel(qv, qw, sw));
475 }
476
477 VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(const Quat &quat)
478 {
479 *this = *this * quat;
480 return *this;
481 }
482
rotate(const Quat & quat,const Vector3 & vec)483 VECTORMATH_FORCE_INLINE const Vector3 rotate(const Quat &quat, const Vector3 &vec)
484 {
485 __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res;
486 qdata = quat.get128();
487 vdata = vec.get128();
488 tmp0 = _mm_shuffle_ps(qdata, qdata, _MM_SHUFFLE(3, 0, 2, 1));
489 tmp1 = _mm_shuffle_ps(vdata, vdata, _MM_SHUFFLE(3, 1, 0, 2));
490 tmp2 = _mm_shuffle_ps(qdata, qdata, _MM_SHUFFLE(3, 1, 0, 2));
491 tmp3 = _mm_shuffle_ps(vdata, vdata, _MM_SHUFFLE(3, 0, 2, 1));
492 wwww = vec_splat(qdata, 3);
493 qv = vec_mul(wwww, vdata);
494 qv = vec_madd(tmp0, tmp1, qv);
495 qv = vec_nmsub(tmp2, tmp3, qv);
496 product = vec_mul(qdata, vdata);
497 qw = vec_madd(vec_sld(qdata, qdata, 4), vec_sld(vdata, vdata, 4), product);
498 qw = vec_add(vec_sld(product, product, 8), qw);
499 tmp1 = _mm_shuffle_ps(qv, qv, _MM_SHUFFLE(3, 1, 0, 2));
500 tmp3 = _mm_shuffle_ps(qv, qv, _MM_SHUFFLE(3, 0, 2, 1));
501 res = vec_mul(vec_splat(qw, 0), qdata);
502 res = vec_madd(wwww, qv, res);
503 res = vec_madd(tmp0, tmp1, res);
504 res = vec_nmsub(tmp2, tmp3, res);
505 return Vector3(res);
506 }
507
conj(const Quat & quat)508 VECTORMATH_FORCE_INLINE const Quat conj(const Quat &quat)
509 {
510 VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0x80000000, 0x80000000, 0x80000000, 0};
511 return Quat(vec_xor(quat.get128(), _mm_load_ps((float *)sw)));
512 }
513
select(const Quat & quat0,const Quat & quat1,bool select1)514 VECTORMATH_FORCE_INLINE const Quat select(const Quat &quat0, const Quat &quat1, bool select1)
515 {
516 return select(quat0, quat1, boolInVec(select1));
517 }
518
519 //VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 )
520 //{
521 // return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) );
522 //}
523
loadXYZW(Quat & quat,const float * fptr)524 VECTORMATH_FORCE_INLINE void loadXYZW(Quat &quat, const float *fptr)
525 {
526 #ifdef USE_SSE3_LDDQU
527 quat = Quat(SSEFloat(_mm_lddqu_si128((const __m128i *)((float *)(fptr)))).m128);
528 #else
529 SSEFloat fl;
530 fl.f[0] = fptr[0];
531 fl.f[1] = fptr[1];
532 fl.f[2] = fptr[2];
533 fl.f[3] = fptr[3];
534 quat = Quat(fl.m128);
535 #endif
536 }
537
storeXYZW(const Quat & quat,float * fptr)538 VECTORMATH_FORCE_INLINE void storeXYZW(const Quat &quat, float *fptr)
539 {
540 fptr[0] = quat.getX();
541 fptr[1] = quat.getY();
542 fptr[2] = quat.getZ();
543 fptr[3] = quat.getW();
544 // _mm_storeu_ps((float*)quat.get128(),fptr);
545 }
546
547 #ifdef _VECTORMATH_DEBUG
548
print(const Quat & quat)549 VECTORMATH_FORCE_INLINE void print(const Quat &quat)
550 {
551 union {
552 __m128 v;
553 float s[4];
554 } tmp;
555 tmp.v = quat.get128();
556 printf("( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]);
557 }
558
print(const Quat & quat,const char * name)559 VECTORMATH_FORCE_INLINE void print(const Quat &quat, const char *name)
560 {
561 union {
562 __m128 v;
563 float s[4];
564 } tmp;
565 tmp.v = quat.get128();
566 printf("%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]);
567 }
568
569 #endif
570
571 } // namespace Aos
572 } // namespace Vectormath
573
574 #endif
575