1 #ifndef GIM_LINEAR_H_INCLUDED
2 #define GIM_LINEAR_H_INCLUDED
4 /*! \file gim_linear_math.h
5 *\author Francisco Leon Najera
6 Type Independant Vector and matrix operations.
9 -----------------------------------------------------------------------------
10 This source file is part of GIMPACT Library.
12 For the latest info, see http://gimpact.sourceforge.net/
14 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
15 email: projectileman@yahoo.com
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of EITHER:
19 (1) The GNU Lesser General Public License as published by the Free
20 Software Foundation; either version 2.1 of the License, or (at
21 your option) any later version. The text of the GNU Lesser
22 General Public License is included with this library in the
23 file GIMPACT-LICENSE-LGPL.TXT.
24 (2) The BSD-style license that is included with this library in
25 the file GIMPACT-LICENSE-BSD.TXT.
26 (3) The zlib/libpng license that is included with this library in
27 the file GIMPACT-LICENSE-ZLIB.TXT.
29 This library is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files
32 GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
34 -----------------------------------------------------------------------------
38 #include "gim_geom_types.h"
40 //! Zero out a 2D vector
41 #define VEC_ZERO_2(a) \
43 (a)[0] = (a)[1] = 0.0f; \
46 //! Zero out a 3D vector
49 (a)[0] = (a)[1] = (a)[2] = 0.0f; \
52 /// Zero out a 4D vector
53 #define VEC_ZERO_4(a) \
55 (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \
59 #define VEC_COPY_2(b, a) \
66 #define VEC_COPY(b, a) \
74 #define VEC_COPY_4(b, a) \
83 #define VEC_SWAP(b, a) \
85 GIM_SWAP_NUMBERS((b)[0], (a)[0]); \
86 GIM_SWAP_NUMBERS((b)[1], (a)[1]); \
87 GIM_SWAP_NUMBERS((b)[2], (a)[2]); \
91 #define VEC_DIFF_2(v21, v2, v1) \
93 (v21)[0] = (v2)[0] - (v1)[0]; \
94 (v21)[1] = (v2)[1] - (v1)[1]; \
98 #define VEC_DIFF(v21, v2, v1) \
100 (v21)[0] = (v2)[0] - (v1)[0]; \
101 (v21)[1] = (v2)[1] - (v1)[1]; \
102 (v21)[2] = (v2)[2] - (v1)[2]; \
105 /// Vector difference
106 #define VEC_DIFF_4(v21, v2, v1) \
108 (v21)[0] = (v2)[0] - (v1)[0]; \
109 (v21)[1] = (v2)[1] - (v1)[1]; \
110 (v21)[2] = (v2)[2] - (v1)[2]; \
111 (v21)[3] = (v2)[3] - (v1)[3]; \
115 #define VEC_SUM_2(v21, v2, v1) \
117 (v21)[0] = (v2)[0] + (v1)[0]; \
118 (v21)[1] = (v2)[1] + (v1)[1]; \
122 #define VEC_SUM(v21, v2, v1) \
124 (v21)[0] = (v2)[0] + (v1)[0]; \
125 (v21)[1] = (v2)[1] + (v1)[1]; \
126 (v21)[2] = (v2)[2] + (v1)[2]; \
130 #define VEC_SUM_4(v21, v2, v1) \
132 (v21)[0] = (v2)[0] + (v1)[0]; \
133 (v21)[1] = (v2)[1] + (v1)[1]; \
134 (v21)[2] = (v2)[2] + (v1)[2]; \
135 (v21)[3] = (v2)[3] + (v1)[3]; \
138 /// scalar times vector
139 #define VEC_SCALE_2(c, a, b) \
141 (c)[0] = (a) * (b)[0]; \
142 (c)[1] = (a) * (b)[1]; \
145 /// scalar times vector
146 #define VEC_SCALE(c, a, b) \
148 (c)[0] = (a) * (b)[0]; \
149 (c)[1] = (a) * (b)[1]; \
150 (c)[2] = (a) * (b)[2]; \
153 /// scalar times vector
154 #define VEC_SCALE_4(c, a, b) \
156 (c)[0] = (a) * (b)[0]; \
157 (c)[1] = (a) * (b)[1]; \
158 (c)[2] = (a) * (b)[2]; \
159 (c)[3] = (a) * (b)[3]; \
162 /// accumulate scaled vector
163 #define VEC_ACCUM_2(c, a, b) \
165 (c)[0] += (a) * (b)[0]; \
166 (c)[1] += (a) * (b)[1]; \
169 /// accumulate scaled vector
170 #define VEC_ACCUM(c, a, b) \
172 (c)[0] += (a) * (b)[0]; \
173 (c)[1] += (a) * (b)[1]; \
174 (c)[2] += (a) * (b)[2]; \
177 /// accumulate scaled vector
178 #define VEC_ACCUM_4(c, a, b) \
180 (c)[0] += (a) * (b)[0]; \
181 (c)[1] += (a) * (b)[1]; \
182 (c)[2] += (a) * (b)[2]; \
183 (c)[3] += (a) * (b)[3]; \
186 /// Vector dot product
187 #define VEC_DOT_2(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1])
189 /// Vector dot product
190 #define VEC_DOT(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] + (a)[2] * (b)[2])
192 /// Vector dot product
193 #define VEC_DOT_4(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] + (a)[2] * (b)[2] + (a)[3] * (b)[3])
195 /// vector impact parameter (squared)
196 #define VEC_IMPACT_SQ(bsq, direction, position) \
198 GREAL _llel_ = VEC_DOT(direction, position); \
199 bsq = VEC_DOT(position, position) - _llel_ * _llel_; \
202 /// vector impact parameter
203 #define VEC_IMPACT(bsq, direction, position) \
205 VEC_IMPACT_SQ(bsq, direction, position); \
206 GIM_SQRT(bsq, bsq); \
210 #define VEC_LENGTH_2(a, l) \
212 GREAL _pp = VEC_DOT_2(a, a); \
217 #define VEC_LENGTH(a, l) \
219 GREAL _pp = VEC_DOT(a, a); \
224 #define VEC_LENGTH_4(a, l) \
226 GREAL _pp = VEC_DOT_4(a, a); \
230 /// Vector inv length
231 #define VEC_INV_LENGTH_2(a, l) \
233 GREAL _pp = VEC_DOT_2(a, a); \
234 GIM_INV_SQRT(_pp, l); \
237 /// Vector inv length
238 #define VEC_INV_LENGTH(a, l) \
240 GREAL _pp = VEC_DOT(a, a); \
241 GIM_INV_SQRT(_pp, l); \
244 /// Vector inv length
245 #define VEC_INV_LENGTH_4(a, l) \
247 GREAL _pp = VEC_DOT_4(a, a); \
248 GIM_INV_SQRT(_pp, l); \
251 /// distance between two points
252 #define VEC_DISTANCE(_len, _va, _vb) \
255 VEC_DIFF(_tmp_, _vb, _va); \
256 VEC_LENGTH(_tmp_, _len); \
260 #define VEC_CONJUGATE_LENGTH(a, l) \
262 GREAL _pp = 1.0 - a[0] * a[0] - a[1] * a[1] - a[2] * a[2]; \
267 #define VEC_NORMALIZE(a) \
270 VEC_INV_LENGTH(a, len); \
271 if (len < G_REAL_INFINITY) \
280 #define VEC_RENORMALIZE(a, newlen) \
283 VEC_INV_LENGTH(a, len); \
284 if (len < G_REAL_INFINITY) \
294 #define VEC_CROSS(c, a, b) \
296 c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \
297 c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \
298 c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \
301 /*! Vector perp -- assumes that n is of unit length
302 * accepts vector v, subtracts out any component parallel to n */
303 #define VEC_PERPENDICULAR(vp, v, n) \
305 GREAL dot = VEC_DOT(v, n); \
306 vp[0] = (v)[0] - dot * (n)[0]; \
307 vp[1] = (v)[1] - dot * (n)[1]; \
308 vp[2] = (v)[2] - dot * (n)[2]; \
311 /*! Vector parallel -- assumes that n is of unit length */
312 #define VEC_PARALLEL(vp, v, n) \
314 GREAL dot = VEC_DOT(v, n); \
315 vp[0] = (dot) * (n)[0]; \
316 vp[1] = (dot) * (n)[1]; \
317 vp[2] = (dot) * (n)[2]; \
320 /*! Same as Vector parallel -- n can have any length
321 * accepts vector v, subtracts out any component perpendicular to n */
322 #define VEC_PROJECT(vp, v, n) \
324 GREAL scalar = VEC_DOT(v, n); \
325 scalar /= VEC_DOT(n, n); \
326 vp[0] = (scalar) * (n)[0]; \
327 vp[1] = (scalar) * (n)[1]; \
328 vp[2] = (scalar) * (n)[2]; \
331 /*! accepts vector v*/
332 #define VEC_UNPROJECT(vp, v, n) \
334 GREAL scalar = VEC_DOT(v, n); \
335 scalar = VEC_DOT(n, n) / scalar; \
336 vp[0] = (scalar) * (n)[0]; \
337 vp[1] = (scalar) * (n)[1]; \
338 vp[2] = (scalar) * (n)[2]; \
341 /*! Vector reflection -- assumes n is of unit length
342 Takes vector v, reflects it against reflector n, and returns vr */
343 #define VEC_REFLECT(vr, v, n) \
345 GREAL dot = VEC_DOT(v, n); \
346 vr[0] = (v)[0] - 2.0 * (dot) * (n)[0]; \
347 vr[1] = (v)[1] - 2.0 * (dot) * (n)[1]; \
348 vr[2] = (v)[2] - 2.0 * (dot) * (n)[2]; \
352 Takes two vectors a, b, blends them together with two scalars */
353 #define VEC_BLEND_AB(vr, sa, a, sb, b) \
355 vr[0] = (sa) * (a)[0] + (sb) * (b)[0]; \
356 vr[1] = (sa) * (a)[1] + (sb) * (b)[1]; \
357 vr[2] = (sa) * (a)[2] + (sb) * (b)[2]; \
361 Takes two vectors a, b, blends them together with s <=1 */
362 #define VEC_BLEND(vr, a, b, s) VEC_BLEND_AB(vr, (1 - s), a, s, b)
364 #define VEC_SET3(a, b, op, c) \
365 a[0] = b[0] op c[0]; \
366 a[1] = b[1] op c[1]; \
369 //! Finds the bigger cartesian coordinate from a vector
370 #define VEC_MAYOR_COORD(vec, maxc) \
372 GREAL A[] = {fabs(vec[0]), fabs(vec[1]), fabs(vec[2])}; \
373 maxc = A[0] > A[1] ? (A[0] > A[2] ? 0 : 2) : (A[1] > A[2] ? 1 : 2); \
376 //! Finds the 2 smallest cartesian coordinates from a vector
377 #define VEC_MINOR_AXES(vec, i0, i1) \
379 VEC_MAYOR_COORD(vec, i0); \
384 #define VEC_EQUAL(v1, v2) (v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2])
386 #define VEC_NEAR_EQUAL(v1, v2) (GIM_NEAR_EQUAL(v1[0], v2[0]) && GIM_NEAR_EQUAL(v1[1], v2[1]) && GIM_NEAR_EQUAL(v1[2], v2[2]))
389 #define X_AXIS_CROSS_VEC(dst, src) \
396 #define Y_AXIS_CROSS_VEC(dst, src) \
403 #define Z_AXIS_CROSS_VEC(dst, src) \
410 /// initialize matrix
411 #define IDENTIFY_MATRIX_3X3(m) \
426 /*! initialize matrix */
427 #define IDENTIFY_MATRIX_4X4(m) \
450 /*! initialize matrix */
451 #define ZERO_MATRIX_4X4(m) \
474 /*! matrix rotation X */
475 #define ROTX_CS(m, cosine, sine) \
477 /* rotation about the x-axis */ \
485 m[1][1] = (cosine); \
491 m[2][2] = (cosine); \
500 /*! matrix rotation Y */
501 #define ROTY_CS(m, cosine, sine) \
503 /* rotation about the y-axis */ \
505 m[0][0] = (cosine); \
517 m[2][2] = (cosine); \
526 /*! matrix rotation Z */
527 #define ROTZ_CS(m, cosine, sine) \
529 /* rotation about the z-axis */ \
531 m[0][0] = (cosine); \
537 m[1][1] = (cosine); \
553 #define COPY_MATRIX_2X2(b, a) \
563 #define COPY_MATRIX_2X3(b, a) \
575 #define COPY_MATRIX_3X3(b, a) \
591 #define COPY_MATRIX_4X4(b, a) \
614 /*! matrix transpose */
615 #define TRANSPOSE_MATRIX_2X2(b, a) \
624 /*! matrix transpose */
625 #define TRANSPOSE_MATRIX_3X3(b, a) \
640 /*! matrix transpose */
641 #define TRANSPOSE_MATRIX_4X4(b, a) \
664 /*! multiply matrix by scalar */
665 #define SCALE_MATRIX_2X2(b, s, a) \
667 b[0][0] = (s)*a[0][0]; \
668 b[0][1] = (s)*a[0][1]; \
670 b[1][0] = (s)*a[1][0]; \
671 b[1][1] = (s)*a[1][1]; \
674 /*! multiply matrix by scalar */
675 #define SCALE_MATRIX_3X3(b, s, a) \
677 b[0][0] = (s)*a[0][0]; \
678 b[0][1] = (s)*a[0][1]; \
679 b[0][2] = (s)*a[0][2]; \
681 b[1][0] = (s)*a[1][0]; \
682 b[1][1] = (s)*a[1][1]; \
683 b[1][2] = (s)*a[1][2]; \
685 b[2][0] = (s)*a[2][0]; \
686 b[2][1] = (s)*a[2][1]; \
687 b[2][2] = (s)*a[2][2]; \
690 /*! multiply matrix by scalar */
691 #define SCALE_MATRIX_4X4(b, s, a) \
693 b[0][0] = (s)*a[0][0]; \
694 b[0][1] = (s)*a[0][1]; \
695 b[0][2] = (s)*a[0][2]; \
696 b[0][3] = (s)*a[0][3]; \
698 b[1][0] = (s)*a[1][0]; \
699 b[1][1] = (s)*a[1][1]; \
700 b[1][2] = (s)*a[1][2]; \
701 b[1][3] = (s)*a[1][3]; \
703 b[2][0] = (s)*a[2][0]; \
704 b[2][1] = (s)*a[2][1]; \
705 b[2][2] = (s)*a[2][2]; \
706 b[2][3] = (s)*a[2][3]; \
708 b[3][0] = s * a[3][0]; \
709 b[3][1] = s * a[3][1]; \
710 b[3][2] = s * a[3][2]; \
711 b[3][3] = s * a[3][3]; \
714 /*! multiply matrix by scalar */
715 #define SCALE_VEC_MATRIX_2X2(b, svec, a) \
717 b[0][0] = svec[0] * a[0][0]; \
718 b[1][0] = svec[0] * a[1][0]; \
720 b[0][1] = svec[1] * a[0][1]; \
721 b[1][1] = svec[1] * a[1][1]; \
724 /*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */
725 #define SCALE_VEC_MATRIX_3X3(b, svec, a) \
727 b[0][0] = svec[0] * a[0][0]; \
728 b[1][0] = svec[0] * a[1][0]; \
729 b[2][0] = svec[0] * a[2][0]; \
731 b[0][1] = svec[1] * a[0][1]; \
732 b[1][1] = svec[1] * a[1][1]; \
733 b[2][1] = svec[1] * a[2][1]; \
735 b[0][2] = svec[2] * a[0][2]; \
736 b[1][2] = svec[2] * a[1][2]; \
737 b[2][2] = svec[2] * a[2][2]; \
740 /*! multiply matrix by scalar */
741 #define SCALE_VEC_MATRIX_4X4(b, svec, a) \
743 b[0][0] = svec[0] * a[0][0]; \
744 b[1][0] = svec[0] * a[1][0]; \
745 b[2][0] = svec[0] * a[2][0]; \
746 b[3][0] = svec[0] * a[3][0]; \
748 b[0][1] = svec[1] * a[0][1]; \
749 b[1][1] = svec[1] * a[1][1]; \
750 b[2][1] = svec[1] * a[2][1]; \
751 b[3][1] = svec[1] * a[3][1]; \
753 b[0][2] = svec[2] * a[0][2]; \
754 b[1][2] = svec[2] * a[1][2]; \
755 b[2][2] = svec[2] * a[2][2]; \
756 b[3][2] = svec[2] * a[3][2]; \
758 b[0][3] = svec[3] * a[0][3]; \
759 b[1][3] = svec[3] * a[1][3]; \
760 b[2][3] = svec[3] * a[2][3]; \
761 b[3][3] = svec[3] * a[3][3]; \
764 /*! multiply matrix by scalar */
765 #define ACCUM_SCALE_MATRIX_2X2(b, s, a) \
767 b[0][0] += (s)*a[0][0]; \
768 b[0][1] += (s)*a[0][1]; \
770 b[1][0] += (s)*a[1][0]; \
771 b[1][1] += (s)*a[1][1]; \
774 /*! multiply matrix by scalar */
775 #define ACCUM_SCALE_MATRIX_3X3(b, s, a) \
777 b[0][0] += (s)*a[0][0]; \
778 b[0][1] += (s)*a[0][1]; \
779 b[0][2] += (s)*a[0][2]; \
781 b[1][0] += (s)*a[1][0]; \
782 b[1][1] += (s)*a[1][1]; \
783 b[1][2] += (s)*a[1][2]; \
785 b[2][0] += (s)*a[2][0]; \
786 b[2][1] += (s)*a[2][1]; \
787 b[2][2] += (s)*a[2][2]; \
790 /*! multiply matrix by scalar */
791 #define ACCUM_SCALE_MATRIX_4X4(b, s, a) \
793 b[0][0] += (s)*a[0][0]; \
794 b[0][1] += (s)*a[0][1]; \
795 b[0][2] += (s)*a[0][2]; \
796 b[0][3] += (s)*a[0][3]; \
798 b[1][0] += (s)*a[1][0]; \
799 b[1][1] += (s)*a[1][1]; \
800 b[1][2] += (s)*a[1][2]; \
801 b[1][3] += (s)*a[1][3]; \
803 b[2][0] += (s)*a[2][0]; \
804 b[2][1] += (s)*a[2][1]; \
805 b[2][2] += (s)*a[2][2]; \
806 b[2][3] += (s)*a[2][3]; \
808 b[3][0] += (s)*a[3][0]; \
809 b[3][1] += (s)*a[3][1]; \
810 b[3][2] += (s)*a[3][2]; \
811 b[3][3] += (s)*a[3][3]; \
814 /*! matrix product */
815 /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
816 #define MATRIX_PRODUCT_2X2(c, a, b) \
818 c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0]; \
819 c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1]; \
821 c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0]; \
822 c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1]; \
825 /*! matrix product */
826 /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
827 #define MATRIX_PRODUCT_3X3(c, a, b) \
829 c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0]; \
830 c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1]; \
831 c[0][2] = a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2]; \
833 c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0]; \
834 c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1]; \
835 c[1][2] = a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2]; \
837 c[2][0] = a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0]; \
838 c[2][1] = a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1]; \
839 c[2][2] = a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2]; \
842 /*! matrix product */
843 /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
844 #define MATRIX_PRODUCT_4X4(c, a, b) \
846 c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0]; \
847 c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1]; \
848 c[0][2] = a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2]; \
849 c[0][3] = a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3]; \
851 c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0]; \
852 c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1]; \
853 c[1][2] = a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2]; \
854 c[1][3] = a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3]; \
856 c[2][0] = a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0]; \
857 c[2][1] = a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1]; \
858 c[2][2] = a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2]; \
859 c[2][3] = a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3]; \
861 c[3][0] = a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0]; \
862 c[3][1] = a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1]; \
863 c[3][2] = a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2]; \
864 c[3][3] = a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3]; \
867 /*! matrix times vector */
868 #define MAT_DOT_VEC_2X2(p, m, v) \
870 p[0] = m[0][0] * v[0] + m[0][1] * v[1]; \
871 p[1] = m[1][0] * v[0] + m[1][1] * v[1]; \
874 /*! matrix times vector */
875 #define MAT_DOT_VEC_3X3(p, m, v) \
877 p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2]; \
878 p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2]; \
879 p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]; \
882 /*! matrix times vector
885 #define MAT_DOT_VEC_4X4(p, m, v) \
887 p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3]; \
888 p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3]; \
889 p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3]; \
890 p[3] = m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]; \
893 /*! matrix times vector
896 Last column is added as the position
898 #define MAT_DOT_VEC_3X4(p, m, v) \
900 p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3]; \
901 p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3]; \
902 p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3]; \
905 /*! vector transpose times matrix */
906 /*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
907 #define VEC_DOT_MAT_3X3(p, v, m) \
909 p[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0]; \
910 p[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1]; \
911 p[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2]; \
914 /*! affine matrix times vector */
915 /** The matrix is assumed to be an affine matrix, with last two
916 * entries representing a translation */
917 #define MAT_DOT_VEC_2X3(p, m, v) \
919 p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2]; \
920 p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2]; \
923 //! Transform a plane
924 #define MAT_TRANSFORM_PLANE_4X4(pout, m, plane) \
926 pout[0] = m[0][0] * plane[0] + m[0][1] * plane[1] + m[0][2] * plane[2]; \
927 pout[1] = m[1][0] * plane[0] + m[1][1] * plane[1] + m[1][2] * plane[2]; \
928 pout[2] = m[2][0] * plane[0] + m[2][1] * plane[1] + m[2][2] * plane[2]; \
929 pout[3] = m[0][3] * pout[0] + m[1][3] * pout[1] + m[2][3] * pout[2] + plane[3]; \
932 /** inverse transpose of matrix times vector
934 * This macro computes inverse transpose of matrix m,
935 * and multiplies vector v into it, to yeild vector p
937 * DANGER !!! Do Not use this on normal vectors!!!
938 * It will leave normals the wrong length !!!
939 * See macro below for use on normals.
941 #define INV_TRANSP_MAT_DOT_VEC_2X2(p, m, v) \
945 det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
946 p[0] = m[1][1] * v[0] - m[1][0] * v[1]; \
947 p[1] = -m[0][1] * v[0] + m[0][0] * v[1]; \
949 /* if matrix not singular, and not orthonormal, then renormalize */ \
950 if ((det != 1.0f) && (det != 0.0f)) \
958 /** transform normal vector by inverse transpose of matrix
959 * and then renormalize the vector
961 * This macro computes inverse transpose of matrix m,
962 * and multiplies vector v into it, to yeild vector p
963 * Vector p is then normalized.
965 #define NORM_XFORM_2X2(p, m, v) \
969 /* do nothing if off-diagonals are zero and diagonals are \
971 if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) \
973 p[0] = m[1][1] * v[0] - m[1][0] * v[1]; \
974 p[1] = -m[0][1] * v[0] + m[0][0] * v[1]; \
976 len = p[0] * p[0] + p[1] * p[1]; \
977 GIM_INV_SQRT(len, len); \
987 /** outer product of vector times vector transpose
989 * The outer product of vector v and vector transpose t yeilds
992 #define OUTER_PRODUCT_2X2(m, v, t) \
994 m[0][0] = v[0] * t[0]; \
995 m[0][1] = v[0] * t[1]; \
997 m[1][0] = v[1] * t[0]; \
998 m[1][1] = v[1] * t[1]; \
1001 /** outer product of vector times vector transpose
1003 * The outer product of vector v and vector transpose t yeilds
1006 #define OUTER_PRODUCT_3X3(m, v, t) \
1008 m[0][0] = v[0] * t[0]; \
1009 m[0][1] = v[0] * t[1]; \
1010 m[0][2] = v[0] * t[2]; \
1012 m[1][0] = v[1] * t[0]; \
1013 m[1][1] = v[1] * t[1]; \
1014 m[1][2] = v[1] * t[2]; \
1016 m[2][0] = v[2] * t[0]; \
1017 m[2][1] = v[2] * t[1]; \
1018 m[2][2] = v[2] * t[2]; \
1021 /** outer product of vector times vector transpose
1023 * The outer product of vector v and vector transpose t yeilds
1026 #define OUTER_PRODUCT_4X4(m, v, t) \
1028 m[0][0] = v[0] * t[0]; \
1029 m[0][1] = v[0] * t[1]; \
1030 m[0][2] = v[0] * t[2]; \
1031 m[0][3] = v[0] * t[3]; \
1033 m[1][0] = v[1] * t[0]; \
1034 m[1][1] = v[1] * t[1]; \
1035 m[1][2] = v[1] * t[2]; \
1036 m[1][3] = v[1] * t[3]; \
1038 m[2][0] = v[2] * t[0]; \
1039 m[2][1] = v[2] * t[1]; \
1040 m[2][2] = v[2] * t[2]; \
1041 m[2][3] = v[2] * t[3]; \
1043 m[3][0] = v[3] * t[0]; \
1044 m[3][1] = v[3] * t[1]; \
1045 m[3][2] = v[3] * t[2]; \
1046 m[3][3] = v[3] * t[3]; \
1049 /** outer product of vector times vector transpose
1051 * The outer product of vector v and vector transpose t yeilds
1054 #define ACCUM_OUTER_PRODUCT_2X2(m, v, t) \
1056 m[0][0] += v[0] * t[0]; \
1057 m[0][1] += v[0] * t[1]; \
1059 m[1][0] += v[1] * t[0]; \
1060 m[1][1] += v[1] * t[1]; \
1063 /** outer product of vector times vector transpose
1065 * The outer product of vector v and vector transpose t yeilds
1068 #define ACCUM_OUTER_PRODUCT_3X3(m, v, t) \
1070 m[0][0] += v[0] * t[0]; \
1071 m[0][1] += v[0] * t[1]; \
1072 m[0][2] += v[0] * t[2]; \
1074 m[1][0] += v[1] * t[0]; \
1075 m[1][1] += v[1] * t[1]; \
1076 m[1][2] += v[1] * t[2]; \
1078 m[2][0] += v[2] * t[0]; \
1079 m[2][1] += v[2] * t[1]; \
1080 m[2][2] += v[2] * t[2]; \
1083 /** outer product of vector times vector transpose
1085 * The outer product of vector v and vector transpose t yeilds
1088 #define ACCUM_OUTER_PRODUCT_4X4(m, v, t) \
1090 m[0][0] += v[0] * t[0]; \
1091 m[0][1] += v[0] * t[1]; \
1092 m[0][2] += v[0] * t[2]; \
1093 m[0][3] += v[0] * t[3]; \
1095 m[1][0] += v[1] * t[0]; \
1096 m[1][1] += v[1] * t[1]; \
1097 m[1][2] += v[1] * t[2]; \
1098 m[1][3] += v[1] * t[3]; \
1100 m[2][0] += v[2] * t[0]; \
1101 m[2][1] += v[2] * t[1]; \
1102 m[2][2] += v[2] * t[2]; \
1103 m[2][3] += v[2] * t[3]; \
1105 m[3][0] += v[3] * t[0]; \
1106 m[3][1] += v[3] * t[1]; \
1107 m[3][2] += v[3] * t[2]; \
1108 m[3][3] += v[3] * t[3]; \
1111 /** determinant of matrix
1113 * Computes determinant of matrix m, returning d
1115 #define DETERMINANT_2X2(d, m) \
1117 d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \
1120 /** determinant of matrix
1122 * Computes determinant of matrix m, returning d
1124 #define DETERMINANT_3X3(d, m) \
1126 d = m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
1127 d -= m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]); \
1128 d += m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
1131 /** i,j,th cofactor of a 4x4 matrix
1134 #define COFACTOR_4X4_IJ(fac, m, i, j) \
1136 GUINT __ii[4], __jj[4], __k; \
1138 for (__k = 0; __k < i; __k++) __ii[__k] = __k; \
1139 for (__k = i; __k < 3; __k++) __ii[__k] = __k + 1; \
1140 for (__k = 0; __k < j; __k++) __jj[__k] = __k; \
1141 for (__k = j; __k < 3; __k++) __jj[__k] = __k + 1; \
1143 (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]] * m[__ii[2]][__jj[2]] - m[__ii[1]][__jj[2]] * m[__ii[2]][__jj[1]]); \
1144 (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]] * m[__ii[2]][__jj[2]] - m[__ii[1]][__jj[2]] * m[__ii[2]][__jj[0]]); \
1145 (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]] * m[__ii[2]][__jj[1]] - m[__ii[1]][__jj[1]] * m[__ii[2]][__jj[0]]); \
1148 if (__k != (__k / 2) * 2) \
1154 /** determinant of matrix
1156 * Computes determinant of matrix m, returning d
1158 #define DETERMINANT_4X4(d, m) \
1161 COFACTOR_4X4_IJ(cofac, m, 0, 0); \
1162 d = m[0][0] * cofac; \
1163 COFACTOR_4X4_IJ(cofac, m, 0, 1); \
1164 d += m[0][1] * cofac; \
1165 COFACTOR_4X4_IJ(cofac, m, 0, 2); \
1166 d += m[0][2] * cofac; \
1167 COFACTOR_4X4_IJ(cofac, m, 0, 3); \
1168 d += m[0][3] * cofac; \
1171 /** cofactor of matrix
1173 * Computes cofactor of matrix m, returning a
1175 #define COFACTOR_2X2(a, m) \
1177 a[0][0] = (m)[1][1]; \
1178 a[0][1] = -(m)[1][0]; \
1179 a[1][0] = -(m)[0][1]; \
1180 a[1][1] = (m)[0][0]; \
1183 /** cofactor of matrix
1185 * Computes cofactor of matrix m, returning a
1187 #define COFACTOR_3X3(a, m) \
1189 a[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; \
1190 a[0][1] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]); \
1191 a[0][2] = m[1][0] * m[2][1] - m[1][1] * m[2][0]; \
1192 a[1][0] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]); \
1193 a[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0]; \
1194 a[1][2] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]); \
1195 a[2][0] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; \
1196 a[2][1] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]); \
1197 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1200 /** cofactor of matrix
1202 * Computes cofactor of matrix m, returning a
1204 #define COFACTOR_4X4(a, m) \
1208 for (i = 0; i < 4; i++) \
1210 for (j = 0; j < 4; j++) \
1212 COFACTOR_4X4_IJ(a[i][j], m, i, j); \
1217 /** adjoint of matrix
1219 * Computes adjoint of matrix m, returning a
1220 * (Note that adjoint is just the transpose of the cofactor matrix)
1222 #define ADJOINT_2X2(a, m) \
1224 a[0][0] = (m)[1][1]; \
1225 a[1][0] = -(m)[1][0]; \
1226 a[0][1] = -(m)[0][1]; \
1227 a[1][1] = (m)[0][0]; \
1230 /** adjoint of matrix
1232 * Computes adjoint of matrix m, returning a
1233 * (Note that adjoint is just the transpose of the cofactor matrix)
1235 #define ADJOINT_3X3(a, m) \
1237 a[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1]; \
1238 a[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]); \
1239 a[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0]; \
1240 a[0][1] = -(m[0][1] * m[2][2] - m[0][2] * m[2][1]); \
1241 a[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0]; \
1242 a[2][1] = -(m[0][0] * m[2][1] - m[0][1] * m[2][0]); \
1243 a[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1]; \
1244 a[1][2] = -(m[0][0] * m[1][2] - m[0][2] * m[1][0]); \
1245 a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]); \
1248 /** adjoint of matrix
1250 * Computes adjoint of matrix m, returning a
1251 * (Note that adjoint is just the transpose of the cofactor matrix)
1253 #define ADJOINT_4X4(a, m) \
1257 for (_i_ = 0; _i_ < 4; _i_++) \
1259 for (_j_ = 0; _j_ < 4; _j_++) \
1261 COFACTOR_4X4_IJ(a[_j_][_i_], m, _i_, _j_); \
1266 /** compute adjoint of matrix and scale
1268 * Computes adjoint of matrix m, scales it by s, returning a
1270 #define SCALE_ADJOINT_2X2(a, s, m) \
1272 a[0][0] = (s)*m[1][1]; \
1273 a[1][0] = -(s)*m[1][0]; \
1274 a[0][1] = -(s)*m[0][1]; \
1275 a[1][1] = (s)*m[0][0]; \
1278 /** compute adjoint of matrix and scale
1280 * Computes adjoint of matrix m, scales it by s, returning a
1282 #define SCALE_ADJOINT_3X3(a, s, m) \
1284 a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \
1285 a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]); \
1286 a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \
1288 a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]); \
1289 a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]); \
1290 a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]); \
1292 a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]); \
1293 a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]); \
1294 a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]); \
1297 /** compute adjoint of matrix and scale
1299 * Computes adjoint of matrix m, scales it by s, returning a
1301 #define SCALE_ADJOINT_4X4(a, s, m) \
1304 for (_i_ = 0; _i_ < 4; _i_++) \
1306 for (_j_ = 0; _j_ < 4; _j_++) \
1308 COFACTOR_4X4_IJ(a[_j_][_i_], m, _i_, _j_); \
1314 /** inverse of matrix
1316 * Compute inverse of matrix a, returning determinant m and
1319 #define INVERT_2X2(b, det, a) \
1322 DETERMINANT_2X2(det, a); \
1323 _tmp_ = 1.0 / (det); \
1324 SCALE_ADJOINT_2X2(b, _tmp_, a); \
1327 /** inverse of matrix
1329 * Compute inverse of matrix a, returning determinant m and
1332 #define INVERT_3X3(b, det, a) \
1335 DETERMINANT_3X3(det, a); \
1336 _tmp_ = 1.0 / (det); \
1337 SCALE_ADJOINT_3X3(b, _tmp_, a); \
1340 /** inverse of matrix
1342 * Compute inverse of matrix a, returning determinant m and
1345 #define INVERT_4X4(b, det, a) \
1348 DETERMINANT_4X4(det, a); \
1349 _tmp_ = 1.0 / (det); \
1350 SCALE_ADJOINT_4X4(b, _tmp_, a); \
1353 //! Get the triple(3) row of a transform matrix
1354 #define MAT_GET_ROW(mat, vec3, rowindex) \
1356 vec3[0] = mat[rowindex][0]; \
1357 vec3[1] = mat[rowindex][1]; \
1358 vec3[2] = mat[rowindex][2]; \
1361 //! Get the tuple(2) row of a transform matrix
1362 #define MAT_GET_ROW2(mat, vec2, rowindex) \
1364 vec2[0] = mat[rowindex][0]; \
1365 vec2[1] = mat[rowindex][1]; \
1368 //! Get the quad (4) row of a transform matrix
1369 #define MAT_GET_ROW4(mat, vec4, rowindex) \
1371 vec4[0] = mat[rowindex][0]; \
1372 vec4[1] = mat[rowindex][1]; \
1373 vec4[2] = mat[rowindex][2]; \
1374 vec4[3] = mat[rowindex][3]; \
1377 //! Get the triple(3) col of a transform matrix
1378 #define MAT_GET_COL(mat, vec3, colindex) \
1380 vec3[0] = mat[0][colindex]; \
1381 vec3[1] = mat[1][colindex]; \
1382 vec3[2] = mat[2][colindex]; \
1385 //! Get the tuple(2) col of a transform matrix
1386 #define MAT_GET_COL2(mat, vec2, colindex) \
1388 vec2[0] = mat[0][colindex]; \
1389 vec2[1] = mat[1][colindex]; \
1392 //! Get the quad (4) col of a transform matrix
1393 #define MAT_GET_COL4(mat, vec4, colindex) \
1395 vec4[0] = mat[0][colindex]; \
1396 vec4[1] = mat[1][colindex]; \
1397 vec4[2] = mat[2][colindex]; \
1398 vec4[3] = mat[3][colindex]; \
1401 //! Get the triple(3) col of a transform matrix
1402 #define MAT_GET_X(mat, vec3) \
1404 MAT_GET_COL(mat, vec3, 0); \
1407 //! Get the triple(3) col of a transform matrix
1408 #define MAT_GET_Y(mat, vec3) \
1410 MAT_GET_COL(mat, vec3, 1); \
1413 //! Get the triple(3) col of a transform matrix
1414 #define MAT_GET_Z(mat, vec3) \
1416 MAT_GET_COL(mat, vec3, 2); \
1419 //! Get the triple(3) col of a transform matrix
1420 #define MAT_SET_X(mat, vec3) \
1422 mat[0][0] = vec3[0]; \
1423 mat[1][0] = vec3[1]; \
1424 mat[2][0] = vec3[2]; \
1427 //! Get the triple(3) col of a transform matrix
1428 #define MAT_SET_Y(mat, vec3) \
1430 mat[0][1] = vec3[0]; \
1431 mat[1][1] = vec3[1]; \
1432 mat[2][1] = vec3[2]; \
1435 //! Get the triple(3) col of a transform matrix
1436 #define MAT_SET_Z(mat, vec3) \
1438 mat[0][2] = vec3[0]; \
1439 mat[1][2] = vec3[1]; \
1440 mat[2][2] = vec3[2]; \
1443 //! Get the triple(3) col of a transform matrix
1444 #define MAT_GET_TRANSLATION(mat, vec3) \
1446 vec3[0] = mat[0][3]; \
1447 vec3[1] = mat[1][3]; \
1448 vec3[2] = mat[2][3]; \
1451 //! Set the triple(3) col of a transform matrix
1452 #define MAT_SET_TRANSLATION(mat, vec3) \
1454 mat[0][3] = vec3[0]; \
1455 mat[1][3] = vec3[1]; \
1456 mat[2][3] = vec3[2]; \
1459 //! Returns the dot product between a vec3f and the row of a matrix
1460 #define MAT_DOT_ROW(mat, vec3, rowindex) (vec3[0] * mat[rowindex][0] + vec3[1] * mat[rowindex][1] + vec3[2] * mat[rowindex][2])
1462 //! Returns the dot product between a vec2f and the row of a matrix
1463 #define MAT_DOT_ROW2(mat, vec2, rowindex) (vec2[0] * mat[rowindex][0] + vec2[1] * mat[rowindex][1])
1465 //! Returns the dot product between a vec4f and the row of a matrix
1466 #define MAT_DOT_ROW4(mat, vec4, rowindex) (vec4[0] * mat[rowindex][0] + vec4[1] * mat[rowindex][1] + vec4[2] * mat[rowindex][2] + vec4[3] * mat[rowindex][3])
1468 //! Returns the dot product between a vec3f and the col of a matrix
1469 #define MAT_DOT_COL(mat, vec3, colindex) (vec3[0] * mat[0][colindex] + vec3[1] * mat[1][colindex] + vec3[2] * mat[2][colindex])
1471 //! Returns the dot product between a vec2f and the col of a matrix
1472 #define MAT_DOT_COL2(mat, vec2, colindex) (vec2[0] * mat[0][colindex] + vec2[1] * mat[1][colindex])
1474 //! Returns the dot product between a vec4f and the col of a matrix
1475 #define MAT_DOT_COL4(mat, vec4, colindex) (vec4[0] * mat[0][colindex] + vec4[1] * mat[1][colindex] + vec4[2] * mat[2][colindex] + vec4[3] * mat[3][colindex])
1477 /*!Transpose matrix times vector
1479 and m is a mat4f<br>
1481 #define INV_MAT_DOT_VEC_3X3(p, m, v) \
1483 p[0] = MAT_DOT_COL(m, v, 0); \
1484 p[1] = MAT_DOT_COL(m, v, 1); \
1485 p[2] = MAT_DOT_COL(m, v, 2); \
1488 #endif // GIM_VECTOR_H_INCLUDED