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 This source version has been altered.
16 
17 */
18 
19 #ifndef _VECTORMATH_AOS_CPP_H
20 #define _VECTORMATH_AOS_CPP_H
21 
22 #include <math.h>
23 
24 #ifdef _VECTORMATH_DEBUG
25 #include <stdio.h>
26 #endif
27 
28 namespace Vectormath
29 {
30 namespace Aos
31 {
32 //-----------------------------------------------------------------------------
33 // Forward Declarations
34 //
35 
36 class Vector3;
37 class Vector4;
38 class Point3;
39 class Quat;
40 class Matrix3;
41 class Matrix4;
42 class Transform3;
43 
44 // A 3-D vector in array-of-structures format
45 //
46 class Vector3
47 {
48 	float mX;
49 	float mY;
50 	float mZ;
51 #ifndef __GNUC__
52 	float d;
53 #endif
54 
55 public:
56 	// Default constructor; does no initialization
57 	//
Vector3()58 	inline Vector3(){};
59 
60 	// Copy a 3-D vector
61 	//
62 	inline Vector3(const Vector3 &vec);
63 
64 	// Construct a 3-D vector from x, y, and z elements
65 	//
66 	inline Vector3(float x, float y, float z);
67 
68 	// Copy elements from a 3-D point into a 3-D vector
69 	//
70 	explicit inline Vector3(const Point3 &pnt);
71 
72 	// Set all elements of a 3-D vector to the same scalar value
73 	//
74 	explicit inline Vector3(float scalar);
75 
76 	// Assign one 3-D vector to another
77 	//
78 	inline Vector3 &operator=(const Vector3 &vec);
79 
80 	// Set the x element of a 3-D vector
81 	//
82 	inline Vector3 &setX(float x);
83 
84 	// Set the y element of a 3-D vector
85 	//
86 	inline Vector3 &setY(float y);
87 
88 	// Set the z element of a 3-D vector
89 	//
90 	inline Vector3 &setZ(float z);
91 
92 	// Get the x element of a 3-D vector
93 	//
94 	inline float getX() const;
95 
96 	// Get the y element of a 3-D vector
97 	//
98 	inline float getY() const;
99 
100 	// Get the z element of a 3-D vector
101 	//
102 	inline float getZ() const;
103 
104 	// Set an x, y, or z element of a 3-D vector by index
105 	//
106 	inline Vector3 &setElem(int idx, float value);
107 
108 	// Get an x, y, or z element of a 3-D vector by index
109 	//
110 	inline float getElem(int idx) const;
111 
112 	// Subscripting operator to set or get an element
113 	//
114 	inline float &operator[](int idx);
115 
116 	// Subscripting operator to get an element
117 	//
118 	inline float operator[](int idx) const;
119 
120 	// Add two 3-D vectors
121 	//
122 	inline const Vector3 operator+(const Vector3 &vec) const;
123 
124 	// Subtract a 3-D vector from another 3-D vector
125 	//
126 	inline const Vector3 operator-(const Vector3 &vec) const;
127 
128 	// Add a 3-D vector to a 3-D point
129 	//
130 	inline const Point3 operator+(const Point3 &pnt) const;
131 
132 	// Multiply a 3-D vector by a scalar
133 	//
134 	inline const Vector3 operator*(float scalar) const;
135 
136 	// Divide a 3-D vector by a scalar
137 	//
138 	inline const Vector3 operator/(float scalar) const;
139 
140 	// Perform compound assignment and addition with a 3-D vector
141 	//
142 	inline Vector3 &operator+=(const Vector3 &vec);
143 
144 	// Perform compound assignment and subtraction by a 3-D vector
145 	//
146 	inline Vector3 &operator-=(const Vector3 &vec);
147 
148 	// Perform compound assignment and multiplication by a scalar
149 	//
150 	inline Vector3 &operator*=(float scalar);
151 
152 	// Perform compound assignment and division by a scalar
153 	//
154 	inline Vector3 &operator/=(float scalar);
155 
156 	// Negate all elements of a 3-D vector
157 	//
158 	inline const Vector3 operator-() const;
159 
160 	// Construct x axis
161 	//
162 	static inline const Vector3 xAxis();
163 
164 	// Construct y axis
165 	//
166 	static inline const Vector3 yAxis();
167 
168 	// Construct z axis
169 	//
170 	static inline const Vector3 zAxis();
171 
172 }
173 #ifdef __GNUC__
174 __attribute__((aligned(16)))
175 #endif
176 ;
177 
178 // Multiply a 3-D vector by a scalar
179 //
180 inline const Vector3 operator*(float scalar, const Vector3 &vec);
181 
182 // Multiply two 3-D vectors per element
183 //
184 inline const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1);
185 
186 // Divide two 3-D vectors per element
187 // NOTE:
188 // Floating-point behavior matches standard library function divf4.
189 //
190 inline const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1);
191 
192 // Compute the reciprocal of a 3-D vector per element
193 // NOTE:
194 // Floating-point behavior matches standard library function recipf4.
195 //
196 inline const Vector3 recipPerElem(const Vector3 &vec);
197 
198 // Compute the square root of a 3-D vector per element
199 // NOTE:
200 // Floating-point behavior matches standard library function sqrtf4.
201 //
202 inline const Vector3 sqrtPerElem(const Vector3 &vec);
203 
204 // Compute the reciprocal square root of a 3-D vector per element
205 // NOTE:
206 // Floating-point behavior matches standard library function rsqrtf4.
207 //
208 inline const Vector3 rsqrtPerElem(const Vector3 &vec);
209 
210 // Compute the absolute value of a 3-D vector per element
211 //
212 inline const Vector3 absPerElem(const Vector3 &vec);
213 
214 // Copy sign from one 3-D vector to another, per element
215 //
216 inline const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1);
217 
218 // Maximum of two 3-D vectors per element
219 //
220 inline const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1);
221 
222 // Minimum of two 3-D vectors per element
223 //
224 inline const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1);
225 
226 // Maximum element of a 3-D vector
227 //
228 inline float maxElem(const Vector3 &vec);
229 
230 // Minimum element of a 3-D vector
231 //
232 inline float minElem(const Vector3 &vec);
233 
234 // Compute the sum of all elements of a 3-D vector
235 //
236 inline float sum(const Vector3 &vec);
237 
238 // Compute the dot product of two 3-D vectors
239 //
240 inline float dot(const Vector3 &vec0, const Vector3 &vec1);
241 
242 // Compute the square of the length of a 3-D vector
243 //
244 inline float lengthSqr(const Vector3 &vec);
245 
246 // Compute the length of a 3-D vector
247 //
248 inline float length(const Vector3 &vec);
249 
250 // Normalize a 3-D vector
251 // NOTE:
252 // The result is unpredictable when all elements of vec are at or near zero.
253 //
254 inline const Vector3 normalize(const Vector3 &vec);
255 
256 // Compute cross product of two 3-D vectors
257 //
258 inline const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1);
259 
260 // Outer product of two 3-D vectors
261 //
262 inline const Matrix3 outer(const Vector3 &vec0, const Vector3 &vec1);
263 
264 // Pre-multiply a row vector by a 3x3 matrix
265 //
266 inline const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat);
267 
268 // Cross-product matrix of a 3-D vector
269 //
270 inline const Matrix3 crossMatrix(const Vector3 &vec);
271 
272 // Create cross-product matrix and multiply
273 // NOTE:
274 // Faster than separately creating a cross-product matrix and multiplying.
275 //
276 inline const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat);
277 
278 // Linear interpolation between two 3-D vectors
279 // NOTE:
280 // Does not clamp t between 0 and 1.
281 //
282 inline const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1);
283 
284 // Spherical linear interpolation between two 3-D vectors
285 // NOTE:
286 // The result is unpredictable if the vectors point in opposite directions.
287 // Does not clamp t between 0 and 1.
288 //
289 inline const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1);
290 
291 // Conditionally select between two 3-D vectors
292 //
293 inline const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1);
294 
295 // Load x, y, and z elements from the first three words of a float array.
296 //
297 //
298 inline void loadXYZ(Vector3 &vec, const float *fptr);
299 
300 // Store x, y, and z elements of a 3-D vector in the first three words of a float array.
301 // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed
302 //
303 inline void storeXYZ(const Vector3 &vec, float *fptr);
304 
305 // Load three-half-floats as a 3-D vector
306 // NOTE:
307 // This transformation does not support either denormalized numbers or NaNs.
308 //
309 inline void loadHalfFloats(Vector3 &vec, const unsigned short *hfptr);
310 
311 // Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from <code><i>hfptr</i></code> might be accessed.
312 // NOTE:
313 // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed.
314 //
315 inline void storeHalfFloats(const Vector3 &vec, unsigned short *hfptr);
316 
317 #ifdef _VECTORMATH_DEBUG
318 
319 // Print a 3-D vector
320 // NOTE:
321 // Function is only defined when _VECTORMATH_DEBUG is defined.
322 //
323 inline void print(const Vector3 &vec);
324 
325 // Print a 3-D vector and an associated string identifier
326 // NOTE:
327 // Function is only defined when _VECTORMATH_DEBUG is defined.
328 //
329 inline void print(const Vector3 &vec, const char *name);
330 
331 #endif
332 
333 // A 4-D vector in array-of-structures format
334 //
335 class Vector4
336 {
337 	float mX;
338 	float mY;
339 	float mZ;
340 	float mW;
341 
342 public:
343 	// Default constructor; does no initialization
344 	//
Vector4()345 	inline Vector4(){};
346 
347 	// Copy a 4-D vector
348 	//
349 	inline Vector4(const Vector4 &vec);
350 
351 	// Construct a 4-D vector from x, y, z, and w elements
352 	//
353 	inline Vector4(float x, float y, float z, float w);
354 
355 	// Construct a 4-D vector from a 3-D vector and a scalar
356 	//
357 	inline Vector4(const Vector3 &xyz, float w);
358 
359 	// Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0
360 	//
361 	explicit inline Vector4(const Vector3 &vec);
362 
363 	// Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1
364 	//
365 	explicit inline Vector4(const Point3 &pnt);
366 
367 	// Copy elements from a quaternion into a 4-D vector
368 	//
369 	explicit inline Vector4(const Quat &quat);
370 
371 	// Set all elements of a 4-D vector to the same scalar value
372 	//
373 	explicit inline Vector4(float scalar);
374 
375 	// Assign one 4-D vector to another
376 	//
377 	inline Vector4 &operator=(const Vector4 &vec);
378 
379 	// Set the x, y, and z elements of a 4-D vector
380 	// NOTE:
381 	// This function does not change the w element.
382 	//
383 	inline Vector4 &setXYZ(const Vector3 &vec);
384 
385 	// Get the x, y, and z elements of a 4-D vector
386 	//
387 	inline const Vector3 getXYZ() const;
388 
389 	// Set the x element of a 4-D vector
390 	//
391 	inline Vector4 &setX(float x);
392 
393 	// Set the y element of a 4-D vector
394 	//
395 	inline Vector4 &setY(float y);
396 
397 	// Set the z element of a 4-D vector
398 	//
399 	inline Vector4 &setZ(float z);
400 
401 	// Set the w element of a 4-D vector
402 	//
403 	inline Vector4 &setW(float w);
404 
405 	// Get the x element of a 4-D vector
406 	//
407 	inline float getX() const;
408 
409 	// Get the y element of a 4-D vector
410 	//
411 	inline float getY() const;
412 
413 	// Get the z element of a 4-D vector
414 	//
415 	inline float getZ() const;
416 
417 	// Get the w element of a 4-D vector
418 	//
419 	inline float getW() const;
420 
421 	// Set an x, y, z, or w element of a 4-D vector by index
422 	//
423 	inline Vector4 &setElem(int idx, float value);
424 
425 	// Get an x, y, z, or w element of a 4-D vector by index
426 	//
427 	inline float getElem(int idx) const;
428 
429 	// Subscripting operator to set or get an element
430 	//
431 	inline float &operator[](int idx);
432 
433 	// Subscripting operator to get an element
434 	//
435 	inline float operator[](int idx) const;
436 
437 	// Add two 4-D vectors
438 	//
439 	inline const Vector4 operator+(const Vector4 &vec) const;
440 
441 	// Subtract a 4-D vector from another 4-D vector
442 	//
443 	inline const Vector4 operator-(const Vector4 &vec) const;
444 
445 	// Multiply a 4-D vector by a scalar
446 	//
447 	inline const Vector4 operator*(float scalar) const;
448 
449 	// Divide a 4-D vector by a scalar
450 	//
451 	inline const Vector4 operator/(float scalar) const;
452 
453 	// Perform compound assignment and addition with a 4-D vector
454 	//
455 	inline Vector4 &operator+=(const Vector4 &vec);
456 
457 	// Perform compound assignment and subtraction by a 4-D vector
458 	//
459 	inline Vector4 &operator-=(const Vector4 &vec);
460 
461 	// Perform compound assignment and multiplication by a scalar
462 	//
463 	inline Vector4 &operator*=(float scalar);
464 
465 	// Perform compound assignment and division by a scalar
466 	//
467 	inline Vector4 &operator/=(float scalar);
468 
469 	// Negate all elements of a 4-D vector
470 	//
471 	inline const Vector4 operator-() const;
472 
473 	// Construct x axis
474 	//
475 	static inline const Vector4 xAxis();
476 
477 	// Construct y axis
478 	//
479 	static inline const Vector4 yAxis();
480 
481 	// Construct z axis
482 	//
483 	static inline const Vector4 zAxis();
484 
485 	// Construct w axis
486 	//
487 	static inline const Vector4 wAxis();
488 
489 }
490 #ifdef __GNUC__
491 __attribute__((aligned(16)))
492 #endif
493 ;
494 
495 // Multiply a 4-D vector by a scalar
496 //
497 inline const Vector4 operator*(float scalar, const Vector4 &vec);
498 
499 // Multiply two 4-D vectors per element
500 //
501 inline const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1);
502 
503 // Divide two 4-D vectors per element
504 // NOTE:
505 // Floating-point behavior matches standard library function divf4.
506 //
507 inline const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1);
508 
509 // Compute the reciprocal of a 4-D vector per element
510 // NOTE:
511 // Floating-point behavior matches standard library function recipf4.
512 //
513 inline const Vector4 recipPerElem(const Vector4 &vec);
514 
515 // Compute the square root of a 4-D vector per element
516 // NOTE:
517 // Floating-point behavior matches standard library function sqrtf4.
518 //
519 inline const Vector4 sqrtPerElem(const Vector4 &vec);
520 
521 // Compute the reciprocal square root of a 4-D vector per element
522 // NOTE:
523 // Floating-point behavior matches standard library function rsqrtf4.
524 //
525 inline const Vector4 rsqrtPerElem(const Vector4 &vec);
526 
527 // Compute the absolute value of a 4-D vector per element
528 //
529 inline const Vector4 absPerElem(const Vector4 &vec);
530 
531 // Copy sign from one 4-D vector to another, per element
532 //
533 inline const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1);
534 
535 // Maximum of two 4-D vectors per element
536 //
537 inline const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1);
538 
539 // Minimum of two 4-D vectors per element
540 //
541 inline const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1);
542 
543 // Maximum element of a 4-D vector
544 //
545 inline float maxElem(const Vector4 &vec);
546 
547 // Minimum element of a 4-D vector
548 //
549 inline float minElem(const Vector4 &vec);
550 
551 // Compute the sum of all elements of a 4-D vector
552 //
553 inline float sum(const Vector4 &vec);
554 
555 // Compute the dot product of two 4-D vectors
556 //
557 inline float dot(const Vector4 &vec0, const Vector4 &vec1);
558 
559 // Compute the square of the length of a 4-D vector
560 //
561 inline float lengthSqr(const Vector4 &vec);
562 
563 // Compute the length of a 4-D vector
564 //
565 inline float length(const Vector4 &vec);
566 
567 // Normalize a 4-D vector
568 // NOTE:
569 // The result is unpredictable when all elements of vec are at or near zero.
570 //
571 inline const Vector4 normalize(const Vector4 &vec);
572 
573 // Outer product of two 4-D vectors
574 //
575 inline const Matrix4 outer(const Vector4 &vec0, const Vector4 &vec1);
576 
577 // Linear interpolation between two 4-D vectors
578 // NOTE:
579 // Does not clamp t between 0 and 1.
580 //
581 inline const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1);
582 
583 // Spherical linear interpolation between two 4-D vectors
584 // NOTE:
585 // The result is unpredictable if the vectors point in opposite directions.
586 // Does not clamp t between 0 and 1.
587 //
588 inline const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1);
589 
590 // Conditionally select between two 4-D vectors
591 //
592 inline const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1);
593 
594 // Load x, y, z, and w elements from the first four words of a float array.
595 //
596 //
597 inline void loadXYZW(Vector4 &vec, const float *fptr);
598 
599 // Store x, y, z, and w elements of a 4-D vector in the first four words of a float array.
600 // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed
601 //
602 inline void storeXYZW(const Vector4 &vec, float *fptr);
603 
604 // Load four-half-floats as a 4-D vector
605 // NOTE:
606 // This transformation does not support either denormalized numbers or NaNs.
607 //
608 inline void loadHalfFloats(Vector4 &vec, const unsigned short *hfptr);
609 
610 // Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from <code><i>hfptr</i></code> might be accessed.
611 // NOTE:
612 // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed.
613 //
614 inline void storeHalfFloats(const Vector4 &vec, unsigned short *hfptr);
615 
616 #ifdef _VECTORMATH_DEBUG
617 
618 // Print a 4-D vector
619 // NOTE:
620 // Function is only defined when _VECTORMATH_DEBUG is defined.
621 //
622 inline void print(const Vector4 &vec);
623 
624 // Print a 4-D vector and an associated string identifier
625 // NOTE:
626 // Function is only defined when _VECTORMATH_DEBUG is defined.
627 //
628 inline void print(const Vector4 &vec, const char *name);
629 
630 #endif
631 
632 // A 3-D point in array-of-structures format
633 //
634 class Point3
635 {
636 	float mX;
637 	float mY;
638 	float mZ;
639 #ifndef __GNUC__
640 	float d;
641 #endif
642 
643 public:
644 	// Default constructor; does no initialization
645 	//
Point3()646 	inline Point3(){};
647 
648 	// Copy a 3-D point
649 	//
650 	inline Point3(const Point3 &pnt);
651 
652 	// Construct a 3-D point from x, y, and z elements
653 	//
654 	inline Point3(float x, float y, float z);
655 
656 	// Copy elements from a 3-D vector into a 3-D point
657 	//
658 	explicit inline Point3(const Vector3 &vec);
659 
660 	// Set all elements of a 3-D point to the same scalar value
661 	//
662 	explicit inline Point3(float scalar);
663 
664 	// Assign one 3-D point to another
665 	//
666 	inline Point3 &operator=(const Point3 &pnt);
667 
668 	// Set the x element of a 3-D point
669 	//
670 	inline Point3 &setX(float x);
671 
672 	// Set the y element of a 3-D point
673 	//
674 	inline Point3 &setY(float y);
675 
676 	// Set the z element of a 3-D point
677 	//
678 	inline Point3 &setZ(float z);
679 
680 	// Get the x element of a 3-D point
681 	//
682 	inline float getX() const;
683 
684 	// Get the y element of a 3-D point
685 	//
686 	inline float getY() const;
687 
688 	// Get the z element of a 3-D point
689 	//
690 	inline float getZ() const;
691 
692 	// Set an x, y, or z element of a 3-D point by index
693 	//
694 	inline Point3 &setElem(int idx, float value);
695 
696 	// Get an x, y, or z element of a 3-D point by index
697 	//
698 	inline float getElem(int idx) const;
699 
700 	// Subscripting operator to set or get an element
701 	//
702 	inline float &operator[](int idx);
703 
704 	// Subscripting operator to get an element
705 	//
706 	inline float operator[](int idx) const;
707 
708 	// Subtract a 3-D point from another 3-D point
709 	//
710 	inline const Vector3 operator-(const Point3 &pnt) const;
711 
712 	// Add a 3-D point to a 3-D vector
713 	//
714 	inline const Point3 operator+(const Vector3 &vec) const;
715 
716 	// Subtract a 3-D vector from a 3-D point
717 	//
718 	inline const Point3 operator-(const Vector3 &vec) const;
719 
720 	// Perform compound assignment and addition with a 3-D vector
721 	//
722 	inline Point3 &operator+=(const Vector3 &vec);
723 
724 	// Perform compound assignment and subtraction by a 3-D vector
725 	//
726 	inline Point3 &operator-=(const Vector3 &vec);
727 
728 }
729 #ifdef __GNUC__
730 __attribute__((aligned(16)))
731 #endif
732 ;
733 
734 // Multiply two 3-D points per element
735 //
736 inline const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1);
737 
738 // Divide two 3-D points per element
739 // NOTE:
740 // Floating-point behavior matches standard library function divf4.
741 //
742 inline const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1);
743 
744 // Compute the reciprocal of a 3-D point per element
745 // NOTE:
746 // Floating-point behavior matches standard library function recipf4.
747 //
748 inline const Point3 recipPerElem(const Point3 &pnt);
749 
750 // Compute the square root of a 3-D point per element
751 // NOTE:
752 // Floating-point behavior matches standard library function sqrtf4.
753 //
754 inline const Point3 sqrtPerElem(const Point3 &pnt);
755 
756 // Compute the reciprocal square root of a 3-D point per element
757 // NOTE:
758 // Floating-point behavior matches standard library function rsqrtf4.
759 //
760 inline const Point3 rsqrtPerElem(const Point3 &pnt);
761 
762 // Compute the absolute value of a 3-D point per element
763 //
764 inline const Point3 absPerElem(const Point3 &pnt);
765 
766 // Copy sign from one 3-D point to another, per element
767 //
768 inline const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1);
769 
770 // Maximum of two 3-D points per element
771 //
772 inline const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1);
773 
774 // Minimum of two 3-D points per element
775 //
776 inline const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1);
777 
778 // Maximum element of a 3-D point
779 //
780 inline float maxElem(const Point3 &pnt);
781 
782 // Minimum element of a 3-D point
783 //
784 inline float minElem(const Point3 &pnt);
785 
786 // Compute the sum of all elements of a 3-D point
787 //
788 inline float sum(const Point3 &pnt);
789 
790 // Apply uniform scale to a 3-D point
791 //
792 inline const Point3 scale(const Point3 &pnt, float scaleVal);
793 
794 // Apply non-uniform scale to a 3-D point
795 //
796 inline const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec);
797 
798 // Scalar projection of a 3-D point on a unit-length 3-D vector
799 //
800 inline float projection(const Point3 &pnt, const Vector3 &unitVec);
801 
802 // Compute the square of the distance of a 3-D point from the coordinate-system origin
803 //
804 inline float distSqrFromOrigin(const Point3 &pnt);
805 
806 // Compute the distance of a 3-D point from the coordinate-system origin
807 //
808 inline float distFromOrigin(const Point3 &pnt);
809 
810 // Compute the square of the distance between two 3-D points
811 //
812 inline float distSqr(const Point3 &pnt0, const Point3 &pnt1);
813 
814 // Compute the distance between two 3-D points
815 //
816 inline float dist(const Point3 &pnt0, const Point3 &pnt1);
817 
818 // Linear interpolation between two 3-D points
819 // NOTE:
820 // Does not clamp t between 0 and 1.
821 //
822 inline const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1);
823 
824 // Conditionally select between two 3-D points
825 //
826 inline const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1);
827 
828 // Load x, y, and z elements from the first three words of a float array.
829 //
830 //
831 inline void loadXYZ(Point3 &pnt, const float *fptr);
832 
833 // Store x, y, and z elements of a 3-D point in the first three words of a float array.
834 // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed
835 //
836 inline void storeXYZ(const Point3 &pnt, float *fptr);
837 
838 // Load three-half-floats as a 3-D point
839 // NOTE:
840 // This transformation does not support either denormalized numbers or NaNs.
841 //
842 inline void loadHalfFloats(Point3 &pnt, const unsigned short *hfptr);
843 
844 // Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from <code><i>hfptr</i></code> might be accessed.
845 // NOTE:
846 // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed.
847 //
848 inline void storeHalfFloats(const Point3 &pnt, unsigned short *hfptr);
849 
850 #ifdef _VECTORMATH_DEBUG
851 
852 // Print a 3-D point
853 // NOTE:
854 // Function is only defined when _VECTORMATH_DEBUG is defined.
855 //
856 inline void print(const Point3 &pnt);
857 
858 // Print a 3-D point and an associated string identifier
859 // NOTE:
860 // Function is only defined when _VECTORMATH_DEBUG is defined.
861 //
862 inline void print(const Point3 &pnt, const char *name);
863 
864 #endif
865 
866 // A quaternion in array-of-structures format
867 //
868 class Quat
869 {
870 #if defined(__APPLE__) && defined(BT_USE_NEON)
871 	union {
872 		float32x4_t vXYZW;
873 		float mXYZW[4];
874 	};
875 #else
876 	float mX;
877 	float mY;
878 	float mZ;
879 	float mW;
880 #endif
881 
882 public:
883 	// Default constructor; does no initialization
884 	//
Quat()885 	inline Quat(){};
886 
887 	// Copy a quaternion
888 	//
889 	inline Quat(const Quat &quat);
890 
891 	// Construct a quaternion from x, y, z, and w elements
892 	//
893 	inline Quat(float x, float y, float z, float w);
894 
895 	// Construct a quaternion from vector of x, y, z, and w elements
896 	//
897 	inline Quat(float32x4_t fXYZW);
898 
899 	// Construct a quaternion from a 3-D vector and a scalar
900 	//
901 	inline Quat(const Vector3 &xyz, float w);
902 
903 	// Copy elements from a 4-D vector into a quaternion
904 	//
905 	explicit inline Quat(const Vector4 &vec);
906 
907 	// Convert a rotation matrix to a unit-length quaternion
908 	//
909 	explicit inline Quat(const Matrix3 &rotMat);
910 
911 	// Set all elements of a quaternion to the same scalar value
912 	//
913 	explicit inline Quat(float scalar);
914 
915 	// Assign one quaternion to another
916 	//
917 	inline Quat &operator=(const Quat &quat);
918 
919 	// Set the x, y, and z elements of a quaternion
920 	// NOTE:
921 	// This function does not change the w element.
922 	//
923 	inline Quat &setXYZ(const Vector3 &vec);
924 
925 	// Get the x, y, and z elements of a quaternion
926 	//
927 	inline const Vector3 getXYZ() const;
928 
929 	// Set the x element of a quaternion
930 	//
931 	inline Quat &setX(float x);
932 
933 	// Set the y element of a quaternion
934 	//
935 	inline Quat &setY(float y);
936 
937 	// Set the z element of a quaternion
938 	//
939 	inline Quat &setZ(float z);
940 
941 	// Set the w element of a quaternion
942 	//
943 	inline Quat &setW(float w);
944 
945 #if defined(__APPLE__) && defined(BT_USE_NEON)
946 	inline float32x4_t getvXYZW() const;
947 #endif
948 
949 	// Get the x element of a quaternion
950 	//
951 	inline float getX() const;
952 
953 	// Get the y element of a quaternion
954 	//
955 	inline float getY() const;
956 
957 	// Get the z element of a quaternion
958 	//
959 	inline float getZ() const;
960 
961 	// Get the w element of a quaternion
962 	//
963 	inline float getW() const;
964 
965 	// Set an x, y, z, or w element of a quaternion by index
966 	//
967 	inline Quat &setElem(int idx, float value);
968 
969 	// Get an x, y, z, or w element of a quaternion by index
970 	//
971 	inline float getElem(int idx) const;
972 
973 	// Subscripting operator to set or get an element
974 	//
975 	inline float &operator[](int idx);
976 
977 	// Subscripting operator to get an element
978 	//
979 	inline float operator[](int idx) const;
980 
981 	// Add two quaternions
982 	//
983 	inline const Quat operator+(const Quat &quat) const;
984 
985 	// Subtract a quaternion from another quaternion
986 	//
987 	inline const Quat operator-(const Quat &quat) const;
988 
989 	// Multiply two quaternions
990 	//
991 	inline const Quat operator*(const Quat &quat) const;
992 
993 	// Multiply a quaternion by a scalar
994 	//
995 	inline const Quat operator*(float scalar) const;
996 
997 	// Divide a quaternion by a scalar
998 	//
999 	inline const Quat operator/(float scalar) const;
1000 
1001 	// Perform compound assignment and addition with a quaternion
1002 	//
1003 	inline Quat &operator+=(const Quat &quat);
1004 
1005 	// Perform compound assignment and subtraction by a quaternion
1006 	//
1007 	inline Quat &operator-=(const Quat &quat);
1008 
1009 	// Perform compound assignment and multiplication by a quaternion
1010 	//
1011 	inline Quat &operator*=(const Quat &quat);
1012 
1013 	// Perform compound assignment and multiplication by a scalar
1014 	//
1015 	inline Quat &operator*=(float scalar);
1016 
1017 	// Perform compound assignment and division by a scalar
1018 	//
1019 	inline Quat &operator/=(float scalar);
1020 
1021 	// Negate all elements of a quaternion
1022 	//
1023 	inline const Quat operator-() const;
1024 
1025 	// Construct an identity quaternion
1026 	//
1027 	static inline const Quat identity();
1028 
1029 	// Construct a quaternion to rotate between two unit-length 3-D vectors
1030 	// NOTE:
1031 	// The result is unpredictable if unitVec0 and unitVec1 point in opposite directions.
1032 	//
1033 	static inline const Quat rotation(const Vector3 &unitVec0, const Vector3 &unitVec1);
1034 
1035 	// Construct a quaternion to rotate around a unit-length 3-D vector
1036 	//
1037 	static inline const Quat rotation(float radians, const Vector3 &unitVec);
1038 
1039 	// Construct a quaternion to rotate around the x axis
1040 	//
1041 	static inline const Quat rotationX(float radians);
1042 
1043 	// Construct a quaternion to rotate around the y axis
1044 	//
1045 	static inline const Quat rotationY(float radians);
1046 
1047 	// Construct a quaternion to rotate around the z axis
1048 	//
1049 	static inline const Quat rotationZ(float radians);
1050 
1051 }
1052 #ifdef __GNUC__
1053 __attribute__((aligned(16)))
1054 #endif
1055 ;
1056 
1057 // Multiply a quaternion by a scalar
1058 //
1059 inline const Quat operator*(float scalar, const Quat &quat);
1060 
1061 // Compute the conjugate of a quaternion
1062 //
1063 inline const Quat conj(const Quat &quat);
1064 
1065 // Use a unit-length quaternion to rotate a 3-D vector
1066 //
1067 inline const Vector3 rotate(const Quat &unitQuat, const Vector3 &vec);
1068 
1069 // Compute the dot product of two quaternions
1070 //
1071 inline float dot(const Quat &quat0, const Quat &quat1);
1072 
1073 // Compute the norm of a quaternion
1074 //
1075 inline float norm(const Quat &quat);
1076 
1077 // Compute the length of a quaternion
1078 //
1079 inline float length(const Quat &quat);
1080 
1081 // Normalize a quaternion
1082 // NOTE:
1083 // The result is unpredictable when all elements of quat are at or near zero.
1084 //
1085 inline const Quat normalize(const Quat &quat);
1086 
1087 // Linear interpolation between two quaternions
1088 // NOTE:
1089 // Does not clamp t between 0 and 1.
1090 //
1091 inline const Quat lerp(float t, const Quat &quat0, const Quat &quat1);
1092 
1093 // Spherical linear interpolation between two quaternions
1094 // NOTE:
1095 // Interpolates along the shortest path between orientations.
1096 // Does not clamp t between 0 and 1.
1097 //
1098 inline const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1);
1099 
1100 // Spherical quadrangle interpolation
1101 //
1102 inline const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3);
1103 
1104 // Conditionally select between two quaternions
1105 //
1106 inline const Quat select(const Quat &quat0, const Quat &quat1, bool select1);
1107 
1108 // Load x, y, z, and w elements from the first four words of a float array.
1109 //
1110 //
1111 inline void loadXYZW(Quat &quat, const float *fptr);
1112 
1113 // Store x, y, z, and w elements of a quaternion in the first four words of a float array.
1114 // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed
1115 //
1116 inline void storeXYZW(const Quat &quat, float *fptr);
1117 
1118 #ifdef _VECTORMATH_DEBUG
1119 
1120 // Print a quaternion
1121 // NOTE:
1122 // Function is only defined when _VECTORMATH_DEBUG is defined.
1123 //
1124 inline void print(const Quat &quat);
1125 
1126 // Print a quaternion and an associated string identifier
1127 // NOTE:
1128 // Function is only defined when _VECTORMATH_DEBUG is defined.
1129 //
1130 inline void print(const Quat &quat, const char *name);
1131 
1132 #endif
1133 
1134 // A 3x3 matrix in array-of-structures format
1135 //
1136 class Matrix3
1137 {
1138 	Vector3 mCol0;
1139 	Vector3 mCol1;
1140 	Vector3 mCol2;
1141 
1142 public:
1143 	// Default constructor; does no initialization
1144 	//
Matrix3()1145 	inline Matrix3(){};
1146 
1147 	// Copy a 3x3 matrix
1148 	//
1149 	inline Matrix3(const Matrix3 &mat);
1150 
1151 	// Construct a 3x3 matrix containing the specified columns
1152 	//
1153 	inline Matrix3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2);
1154 
1155 	// Construct a 3x3 rotation matrix from a unit-length quaternion
1156 	//
1157 	explicit inline Matrix3(const Quat &unitQuat);
1158 
1159 	// Set all elements of a 3x3 matrix to the same scalar value
1160 	//
1161 	explicit inline Matrix3(float scalar);
1162 
1163 	// Assign one 3x3 matrix to another
1164 	//
1165 	inline Matrix3 &operator=(const Matrix3 &mat);
1166 
1167 	// Set column 0 of a 3x3 matrix
1168 	//
1169 	inline Matrix3 &setCol0(const Vector3 &col0);
1170 
1171 	// Set column 1 of a 3x3 matrix
1172 	//
1173 	inline Matrix3 &setCol1(const Vector3 &col1);
1174 
1175 	// Set column 2 of a 3x3 matrix
1176 	//
1177 	inline Matrix3 &setCol2(const Vector3 &col2);
1178 
1179 	// Get column 0 of a 3x3 matrix
1180 	//
1181 	inline const Vector3 getCol0() const;
1182 
1183 	// Get column 1 of a 3x3 matrix
1184 	//
1185 	inline const Vector3 getCol1() const;
1186 
1187 	// Get column 2 of a 3x3 matrix
1188 	//
1189 	inline const Vector3 getCol2() const;
1190 
1191 	// Set the column of a 3x3 matrix referred to by the specified index
1192 	//
1193 	inline Matrix3 &setCol(int col, const Vector3 &vec);
1194 
1195 	// Set the row of a 3x3 matrix referred to by the specified index
1196 	//
1197 	inline Matrix3 &setRow(int row, const Vector3 &vec);
1198 
1199 	// Get the column of a 3x3 matrix referred to by the specified index
1200 	//
1201 	inline const Vector3 getCol(int col) const;
1202 
1203 	// Get the row of a 3x3 matrix referred to by the specified index
1204 	//
1205 	inline const Vector3 getRow(int row) const;
1206 
1207 	// Subscripting operator to set or get a column
1208 	//
1209 	inline Vector3 &operator[](int col);
1210 
1211 	// Subscripting operator to get a column
1212 	//
1213 	inline const Vector3 operator[](int col) const;
1214 
1215 	// Set the element of a 3x3 matrix referred to by column and row indices
1216 	//
1217 	inline Matrix3 &setElem(int col, int row, float val);
1218 
1219 	// Get the element of a 3x3 matrix referred to by column and row indices
1220 	//
1221 	inline float getElem(int col, int row) const;
1222 
1223 	// Add two 3x3 matrices
1224 	//
1225 	inline const Matrix3 operator+(const Matrix3 &mat) const;
1226 
1227 	// Subtract a 3x3 matrix from another 3x3 matrix
1228 	//
1229 	inline const Matrix3 operator-(const Matrix3 &mat) const;
1230 
1231 	// Negate all elements of a 3x3 matrix
1232 	//
1233 	inline const Matrix3 operator-() const;
1234 
1235 	// Multiply a 3x3 matrix by a scalar
1236 	//
1237 	inline const Matrix3 operator*(float scalar) const;
1238 
1239 	// Multiply a 3x3 matrix by a 3-D vector
1240 	//
1241 	inline const Vector3 operator*(const Vector3 &vec) const;
1242 
1243 	// Multiply two 3x3 matrices
1244 	//
1245 	inline const Matrix3 operator*(const Matrix3 &mat) const;
1246 
1247 	// Perform compound assignment and addition with a 3x3 matrix
1248 	//
1249 	inline Matrix3 &operator+=(const Matrix3 &mat);
1250 
1251 	// Perform compound assignment and subtraction by a 3x3 matrix
1252 	//
1253 	inline Matrix3 &operator-=(const Matrix3 &mat);
1254 
1255 	// Perform compound assignment and multiplication by a scalar
1256 	//
1257 	inline Matrix3 &operator*=(float scalar);
1258 
1259 	// Perform compound assignment and multiplication by a 3x3 matrix
1260 	//
1261 	inline Matrix3 &operator*=(const Matrix3 &mat);
1262 
1263 	// Construct an identity 3x3 matrix
1264 	//
1265 	static inline const Matrix3 identity();
1266 
1267 	// Construct a 3x3 matrix to rotate around the x axis
1268 	//
1269 	static inline const Matrix3 rotationX(float radians);
1270 
1271 	// Construct a 3x3 matrix to rotate around the y axis
1272 	//
1273 	static inline const Matrix3 rotationY(float radians);
1274 
1275 	// Construct a 3x3 matrix to rotate around the z axis
1276 	//
1277 	static inline const Matrix3 rotationZ(float radians);
1278 
1279 	// Construct a 3x3 matrix to rotate around the x, y, and z axes
1280 	//
1281 	static inline const Matrix3 rotationZYX(const Vector3 &radiansXYZ);
1282 
1283 	// Construct a 3x3 matrix to rotate around a unit-length 3-D vector
1284 	//
1285 	static inline const Matrix3 rotation(float radians, const Vector3 &unitVec);
1286 
1287 	// Construct a rotation matrix from a unit-length quaternion
1288 	//
1289 	static inline const Matrix3 rotation(const Quat &unitQuat);
1290 
1291 	// Construct a 3x3 matrix to perform scaling
1292 	//
1293 	static inline const Matrix3 scale(const Vector3 &scaleVec);
1294 };
1295 // Multiply a 3x3 matrix by a scalar
1296 //
1297 inline const Matrix3 operator*(float scalar, const Matrix3 &mat);
1298 
1299 // Append (post-multiply) a scale transformation to a 3x3 matrix
1300 // NOTE:
1301 // Faster than creating and multiplying a scale transformation matrix.
1302 //
1303 inline const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec);
1304 
1305 // Prepend (pre-multiply) a scale transformation to a 3x3 matrix
1306 // NOTE:
1307 // Faster than creating and multiplying a scale transformation matrix.
1308 //
1309 inline const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat);
1310 
1311 // Multiply two 3x3 matrices per element
1312 //
1313 inline const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1);
1314 
1315 // Compute the absolute value of a 3x3 matrix per element
1316 //
1317 inline const Matrix3 absPerElem(const Matrix3 &mat);
1318 
1319 // Transpose of a 3x3 matrix
1320 //
1321 inline const Matrix3 transpose(const Matrix3 &mat);
1322 
1323 // Compute the inverse of a 3x3 matrix
1324 // NOTE:
1325 // Result is unpredictable when the determinant of mat is equal to or near 0.
1326 //
1327 inline const Matrix3 inverse(const Matrix3 &mat);
1328 
1329 // Determinant of a 3x3 matrix
1330 //
1331 inline float determinant(const Matrix3 &mat);
1332 
1333 // Conditionally select between two 3x3 matrices
1334 //
1335 inline const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1);
1336 
1337 #ifdef _VECTORMATH_DEBUG
1338 
1339 // Print a 3x3 matrix
1340 // NOTE:
1341 // Function is only defined when _VECTORMATH_DEBUG is defined.
1342 //
1343 inline void print(const Matrix3 &mat);
1344 
1345 // Print a 3x3 matrix and an associated string identifier
1346 // NOTE:
1347 // Function is only defined when _VECTORMATH_DEBUG is defined.
1348 //
1349 inline void print(const Matrix3 &mat, const char *name);
1350 
1351 #endif
1352 
1353 // A 4x4 matrix in array-of-structures format
1354 //
1355 class Matrix4
1356 {
1357 	Vector4 mCol0;
1358 	Vector4 mCol1;
1359 	Vector4 mCol2;
1360 	Vector4 mCol3;
1361 
1362 public:
1363 	// Default constructor; does no initialization
1364 	//
Matrix4()1365 	inline Matrix4(){};
1366 
1367 	// Copy a 4x4 matrix
1368 	//
1369 	inline Matrix4(const Matrix4 &mat);
1370 
1371 	// Construct a 4x4 matrix containing the specified columns
1372 	//
1373 	inline Matrix4(const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3);
1374 
1375 	// Construct a 4x4 matrix from a 3x4 transformation matrix
1376 	//
1377 	explicit inline Matrix4(const Transform3 &mat);
1378 
1379 	// Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector
1380 	//
1381 	inline Matrix4(const Matrix3 &mat, const Vector3 &translateVec);
1382 
1383 	// Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector
1384 	//
1385 	inline Matrix4(const Quat &unitQuat, const Vector3 &translateVec);
1386 
1387 	// Set all elements of a 4x4 matrix to the same scalar value
1388 	//
1389 	explicit inline Matrix4(float scalar);
1390 
1391 	// Assign one 4x4 matrix to another
1392 	//
1393 	inline Matrix4 &operator=(const Matrix4 &mat);
1394 
1395 	// Set the upper-left 3x3 submatrix
1396 	// NOTE:
1397 	// This function does not change the bottom row elements.
1398 	//
1399 	inline Matrix4 &setUpper3x3(const Matrix3 &mat3);
1400 
1401 	// Get the upper-left 3x3 submatrix of a 4x4 matrix
1402 	//
1403 	inline const Matrix3 getUpper3x3() const;
1404 
1405 	// Set translation component
1406 	// NOTE:
1407 	// This function does not change the bottom row elements.
1408 	//
1409 	inline Matrix4 &setTranslation(const Vector3 &translateVec);
1410 
1411 	// Get the translation component of a 4x4 matrix
1412 	//
1413 	inline const Vector3 getTranslation() const;
1414 
1415 	// Set column 0 of a 4x4 matrix
1416 	//
1417 	inline Matrix4 &setCol0(const Vector4 &col0);
1418 
1419 	// Set column 1 of a 4x4 matrix
1420 	//
1421 	inline Matrix4 &setCol1(const Vector4 &col1);
1422 
1423 	// Set column 2 of a 4x4 matrix
1424 	//
1425 	inline Matrix4 &setCol2(const Vector4 &col2);
1426 
1427 	// Set column 3 of a 4x4 matrix
1428 	//
1429 	inline Matrix4 &setCol3(const Vector4 &col3);
1430 
1431 	// Get column 0 of a 4x4 matrix
1432 	//
1433 	inline const Vector4 getCol0() const;
1434 
1435 	// Get column 1 of a 4x4 matrix
1436 	//
1437 	inline const Vector4 getCol1() const;
1438 
1439 	// Get column 2 of a 4x4 matrix
1440 	//
1441 	inline const Vector4 getCol2() const;
1442 
1443 	// Get column 3 of a 4x4 matrix
1444 	//
1445 	inline const Vector4 getCol3() const;
1446 
1447 	// Set the column of a 4x4 matrix referred to by the specified index
1448 	//
1449 	inline Matrix4 &setCol(int col, const Vector4 &vec);
1450 
1451 	// Set the row of a 4x4 matrix referred to by the specified index
1452 	//
1453 	inline Matrix4 &setRow(int row, const Vector4 &vec);
1454 
1455 	// Get the column of a 4x4 matrix referred to by the specified index
1456 	//
1457 	inline const Vector4 getCol(int col) const;
1458 
1459 	// Get the row of a 4x4 matrix referred to by the specified index
1460 	//
1461 	inline const Vector4 getRow(int row) const;
1462 
1463 	// Subscripting operator to set or get a column
1464 	//
1465 	inline Vector4 &operator[](int col);
1466 
1467 	// Subscripting operator to get a column
1468 	//
1469 	inline const Vector4 operator[](int col) const;
1470 
1471 	// Set the element of a 4x4 matrix referred to by column and row indices
1472 	//
1473 	inline Matrix4 &setElem(int col, int row, float val);
1474 
1475 	// Get the element of a 4x4 matrix referred to by column and row indices
1476 	//
1477 	inline float getElem(int col, int row) const;
1478 
1479 	// Add two 4x4 matrices
1480 	//
1481 	inline const Matrix4 operator+(const Matrix4 &mat) const;
1482 
1483 	// Subtract a 4x4 matrix from another 4x4 matrix
1484 	//
1485 	inline const Matrix4 operator-(const Matrix4 &mat) const;
1486 
1487 	// Negate all elements of a 4x4 matrix
1488 	//
1489 	inline const Matrix4 operator-() const;
1490 
1491 	// Multiply a 4x4 matrix by a scalar
1492 	//
1493 	inline const Matrix4 operator*(float scalar) const;
1494 
1495 	// Multiply a 4x4 matrix by a 4-D vector
1496 	//
1497 	inline const Vector4 operator*(const Vector4 &vec) const;
1498 
1499 	// Multiply a 4x4 matrix by a 3-D vector
1500 	//
1501 	inline const Vector4 operator*(const Vector3 &vec) const;
1502 
1503 	// Multiply a 4x4 matrix by a 3-D point
1504 	//
1505 	inline const Vector4 operator*(const Point3 &pnt) const;
1506 
1507 	// Multiply two 4x4 matrices
1508 	//
1509 	inline const Matrix4 operator*(const Matrix4 &mat) const;
1510 
1511 	// Multiply a 4x4 matrix by a 3x4 transformation matrix
1512 	//
1513 	inline const Matrix4 operator*(const Transform3 &tfrm) const;
1514 
1515 	// Perform compound assignment and addition with a 4x4 matrix
1516 	//
1517 	inline Matrix4 &operator+=(const Matrix4 &mat);
1518 
1519 	// Perform compound assignment and subtraction by a 4x4 matrix
1520 	//
1521 	inline Matrix4 &operator-=(const Matrix4 &mat);
1522 
1523 	// Perform compound assignment and multiplication by a scalar
1524 	//
1525 	inline Matrix4 &operator*=(float scalar);
1526 
1527 	// Perform compound assignment and multiplication by a 4x4 matrix
1528 	//
1529 	inline Matrix4 &operator*=(const Matrix4 &mat);
1530 
1531 	// Perform compound assignment and multiplication by a 3x4 transformation matrix
1532 	//
1533 	inline Matrix4 &operator*=(const Transform3 &tfrm);
1534 
1535 	// Construct an identity 4x4 matrix
1536 	//
1537 	static inline const Matrix4 identity();
1538 
1539 	// Construct a 4x4 matrix to rotate around the x axis
1540 	//
1541 	static inline const Matrix4 rotationX(float radians);
1542 
1543 	// Construct a 4x4 matrix to rotate around the y axis
1544 	//
1545 	static inline const Matrix4 rotationY(float radians);
1546 
1547 	// Construct a 4x4 matrix to rotate around the z axis
1548 	//
1549 	static inline const Matrix4 rotationZ(float radians);
1550 
1551 	// Construct a 4x4 matrix to rotate around the x, y, and z axes
1552 	//
1553 	static inline const Matrix4 rotationZYX(const Vector3 &radiansXYZ);
1554 
1555 	// Construct a 4x4 matrix to rotate around a unit-length 3-D vector
1556 	//
1557 	static inline const Matrix4 rotation(float radians, const Vector3 &unitVec);
1558 
1559 	// Construct a rotation matrix from a unit-length quaternion
1560 	//
1561 	static inline const Matrix4 rotation(const Quat &unitQuat);
1562 
1563 	// Construct a 4x4 matrix to perform scaling
1564 	//
1565 	static inline const Matrix4 scale(const Vector3 &scaleVec);
1566 
1567 	// Construct a 4x4 matrix to perform translation
1568 	//
1569 	static inline const Matrix4 translation(const Vector3 &translateVec);
1570 
1571 	// Construct viewing matrix based on eye position, position looked at, and up direction
1572 	//
1573 	static inline const Matrix4 lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec);
1574 
1575 	// Construct a perspective projection matrix
1576 	//
1577 	static inline const Matrix4 perspective(float fovyRadians, float aspect, float zNear, float zFar);
1578 
1579 	// Construct a perspective projection matrix based on frustum
1580 	//
1581 	static inline const Matrix4 frustum(float left, float right, float bottom, float top, float zNear, float zFar);
1582 
1583 	// Construct an orthographic projection matrix
1584 	//
1585 	static inline const Matrix4 orthographic(float left, float right, float bottom, float top, float zNear, float zFar);
1586 };
1587 // Multiply a 4x4 matrix by a scalar
1588 //
1589 inline const Matrix4 operator*(float scalar, const Matrix4 &mat);
1590 
1591 // Append (post-multiply) a scale transformation to a 4x4 matrix
1592 // NOTE:
1593 // Faster than creating and multiplying a scale transformation matrix.
1594 //
1595 inline const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec);
1596 
1597 // Prepend (pre-multiply) a scale transformation to a 4x4 matrix
1598 // NOTE:
1599 // Faster than creating and multiplying a scale transformation matrix.
1600 //
1601 inline const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat);
1602 
1603 // Multiply two 4x4 matrices per element
1604 //
1605 inline const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1);
1606 
1607 // Compute the absolute value of a 4x4 matrix per element
1608 //
1609 inline const Matrix4 absPerElem(const Matrix4 &mat);
1610 
1611 // Transpose of a 4x4 matrix
1612 //
1613 inline const Matrix4 transpose(const Matrix4 &mat);
1614 
1615 // Compute the inverse of a 4x4 matrix
1616 // NOTE:
1617 // Result is unpredictable when the determinant of mat is equal to or near 0.
1618 //
1619 inline const Matrix4 inverse(const Matrix4 &mat);
1620 
1621 // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix
1622 // NOTE:
1623 // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.  The result is unpredictable when the determinant of mat is equal to or near 0.
1624 //
1625 inline const Matrix4 affineInverse(const Matrix4 &mat);
1626 
1627 // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix
1628 // NOTE:
1629 // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions.
1630 //
1631 inline const Matrix4 orthoInverse(const Matrix4 &mat);
1632 
1633 // Determinant of a 4x4 matrix
1634 //
1635 inline float determinant(const Matrix4 &mat);
1636 
1637 // Conditionally select between two 4x4 matrices
1638 //
1639 inline const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1);
1640 
1641 #ifdef _VECTORMATH_DEBUG
1642 
1643 // Print a 4x4 matrix
1644 // NOTE:
1645 // Function is only defined when _VECTORMATH_DEBUG is defined.
1646 //
1647 inline void print(const Matrix4 &mat);
1648 
1649 // Print a 4x4 matrix and an associated string identifier
1650 // NOTE:
1651 // Function is only defined when _VECTORMATH_DEBUG is defined.
1652 //
1653 inline void print(const Matrix4 &mat, const char *name);
1654 
1655 #endif
1656 
1657 // A 3x4 transformation matrix in array-of-structures format
1658 //
1659 class Transform3
1660 {
1661 	Vector3 mCol0;
1662 	Vector3 mCol1;
1663 	Vector3 mCol2;
1664 	Vector3 mCol3;
1665 
1666 public:
1667 	// Default constructor; does no initialization
1668 	//
Transform3()1669 	inline Transform3(){};
1670 
1671 	// Copy a 3x4 transformation matrix
1672 	//
1673 	inline Transform3(const Transform3 &tfrm);
1674 
1675 	// Construct a 3x4 transformation matrix containing the specified columns
1676 	//
1677 	inline Transform3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3);
1678 
1679 	// Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector
1680 	//
1681 	inline Transform3(const Matrix3 &tfrm, const Vector3 &translateVec);
1682 
1683 	// Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector
1684 	//
1685 	inline Transform3(const Quat &unitQuat, const Vector3 &translateVec);
1686 
1687 	// Set all elements of a 3x4 transformation matrix to the same scalar value
1688 	//
1689 	explicit inline Transform3(float scalar);
1690 
1691 	// Assign one 3x4 transformation matrix to another
1692 	//
1693 	inline Transform3 &operator=(const Transform3 &tfrm);
1694 
1695 	// Set the upper-left 3x3 submatrix
1696 	//
1697 	inline Transform3 &setUpper3x3(const Matrix3 &mat3);
1698 
1699 	// Get the upper-left 3x3 submatrix of a 3x4 transformation matrix
1700 	//
1701 	inline const Matrix3 getUpper3x3() const;
1702 
1703 	// Set translation component
1704 	//
1705 	inline Transform3 &setTranslation(const Vector3 &translateVec);
1706 
1707 	// Get the translation component of a 3x4 transformation matrix
1708 	//
1709 	inline const Vector3 getTranslation() const;
1710 
1711 	// Set column 0 of a 3x4 transformation matrix
1712 	//
1713 	inline Transform3 &setCol0(const Vector3 &col0);
1714 
1715 	// Set column 1 of a 3x4 transformation matrix
1716 	//
1717 	inline Transform3 &setCol1(const Vector3 &col1);
1718 
1719 	// Set column 2 of a 3x4 transformation matrix
1720 	//
1721 	inline Transform3 &setCol2(const Vector3 &col2);
1722 
1723 	// Set column 3 of a 3x4 transformation matrix
1724 	//
1725 	inline Transform3 &setCol3(const Vector3 &col3);
1726 
1727 	// Get column 0 of a 3x4 transformation matrix
1728 	//
1729 	inline const Vector3 getCol0() const;
1730 
1731 	// Get column 1 of a 3x4 transformation matrix
1732 	//
1733 	inline const Vector3 getCol1() const;
1734 
1735 	// Get column 2 of a 3x4 transformation matrix
1736 	//
1737 	inline const Vector3 getCol2() const;
1738 
1739 	// Get column 3 of a 3x4 transformation matrix
1740 	//
1741 	inline const Vector3 getCol3() const;
1742 
1743 	// Set the column of a 3x4 transformation matrix referred to by the specified index
1744 	//
1745 	inline Transform3 &setCol(int col, const Vector3 &vec);
1746 
1747 	// Set the row of a 3x4 transformation matrix referred to by the specified index
1748 	//
1749 	inline Transform3 &setRow(int row, const Vector4 &vec);
1750 
1751 	// Get the column of a 3x4 transformation matrix referred to by the specified index
1752 	//
1753 	inline const Vector3 getCol(int col) const;
1754 
1755 	// Get the row of a 3x4 transformation matrix referred to by the specified index
1756 	//
1757 	inline const Vector4 getRow(int row) const;
1758 
1759 	// Subscripting operator to set or get a column
1760 	//
1761 	inline Vector3 &operator[](int col);
1762 
1763 	// Subscripting operator to get a column
1764 	//
1765 	inline const Vector3 operator[](int col) const;
1766 
1767 	// Set the element of a 3x4 transformation matrix referred to by column and row indices
1768 	//
1769 	inline Transform3 &setElem(int col, int row, float val);
1770 
1771 	// Get the element of a 3x4 transformation matrix referred to by column and row indices
1772 	//
1773 	inline float getElem(int col, int row) const;
1774 
1775 	// Multiply a 3x4 transformation matrix by a 3-D vector
1776 	//
1777 	inline const Vector3 operator*(const Vector3 &vec) const;
1778 
1779 	// Multiply a 3x4 transformation matrix by a 3-D point
1780 	//
1781 	inline const Point3 operator*(const Point3 &pnt) const;
1782 
1783 	// Multiply two 3x4 transformation matrices
1784 	//
1785 	inline const Transform3 operator*(const Transform3 &tfrm) const;
1786 
1787 	// Perform compound assignment and multiplication by a 3x4 transformation matrix
1788 	//
1789 	inline Transform3 &operator*=(const Transform3 &tfrm);
1790 
1791 	// Construct an identity 3x4 transformation matrix
1792 	//
1793 	static inline const Transform3 identity();
1794 
1795 	// Construct a 3x4 transformation matrix to rotate around the x axis
1796 	//
1797 	static inline const Transform3 rotationX(float radians);
1798 
1799 	// Construct a 3x4 transformation matrix to rotate around the y axis
1800 	//
1801 	static inline const Transform3 rotationY(float radians);
1802 
1803 	// Construct a 3x4 transformation matrix to rotate around the z axis
1804 	//
1805 	static inline const Transform3 rotationZ(float radians);
1806 
1807 	// Construct a 3x4 transformation matrix to rotate around the x, y, and z axes
1808 	//
1809 	static inline const Transform3 rotationZYX(const Vector3 &radiansXYZ);
1810 
1811 	// Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector
1812 	//
1813 	static inline const Transform3 rotation(float radians, const Vector3 &unitVec);
1814 
1815 	// Construct a rotation matrix from a unit-length quaternion
1816 	//
1817 	static inline const Transform3 rotation(const Quat &unitQuat);
1818 
1819 	// Construct a 3x4 transformation matrix to perform scaling
1820 	//
1821 	static inline const Transform3 scale(const Vector3 &scaleVec);
1822 
1823 	// Construct a 3x4 transformation matrix to perform translation
1824 	//
1825 	static inline const Transform3 translation(const Vector3 &translateVec);
1826 };
1827 // Append (post-multiply) a scale transformation to a 3x4 transformation matrix
1828 // NOTE:
1829 // Faster than creating and multiplying a scale transformation matrix.
1830 //
1831 inline const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec);
1832 
1833 // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix
1834 // NOTE:
1835 // Faster than creating and multiplying a scale transformation matrix.
1836 //
1837 inline const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm);
1838 
1839 // Multiply two 3x4 transformation matrices per element
1840 //
1841 inline const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1);
1842 
1843 // Compute the absolute value of a 3x4 transformation matrix per element
1844 //
1845 inline const Transform3 absPerElem(const Transform3 &tfrm);
1846 
1847 // Inverse of a 3x4 transformation matrix
1848 // NOTE:
1849 // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0.
1850 //
1851 inline const Transform3 inverse(const Transform3 &tfrm);
1852 
1853 // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix
1854 // NOTE:
1855 // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions.
1856 //
1857 inline const Transform3 orthoInverse(const Transform3 &tfrm);
1858 
1859 // Conditionally select between two 3x4 transformation matrices
1860 //
1861 inline const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1);
1862 
1863 #ifdef _VECTORMATH_DEBUG
1864 
1865 // Print a 3x4 transformation matrix
1866 // NOTE:
1867 // Function is only defined when _VECTORMATH_DEBUG is defined.
1868 //
1869 inline void print(const Transform3 &tfrm);
1870 
1871 // Print a 3x4 transformation matrix and an associated string identifier
1872 // NOTE:
1873 // Function is only defined when _VECTORMATH_DEBUG is defined.
1874 //
1875 inline void print(const Transform3 &tfrm, const char *name);
1876 
1877 #endif
1878 
1879 }  // namespace Aos
1880 }  // namespace Vectormath
1881 
1882 #include "vec_aos.h"
1883 #include "quat_aos.h"
1884 #include "mat_aos.h"
1885 
1886 #endif
1887