#ifndef GIM_LINEAR_H_INCLUDED #define GIM_LINEAR_H_INCLUDED /*! \file gim_linear_math.h *\author Francisco Leon Najera Type Independant Vector and matrix operations. */ /* ----------------------------------------------------------------------------- This source file is part of GIMPACT Library. For the latest info, see http://gimpact.sourceforge.net/ Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. email: projectileman@yahoo.com This library is free software; you can redistribute it and/or modify it under the terms of EITHER: (1) The GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The text of the GNU Lesser General Public License is included with this library in the file GIMPACT-LICENSE-LGPL.TXT. (2) The BSD-style license that is included with this library in the file GIMPACT-LICENSE-BSD.TXT. (3) The zlib/libpng license that is included with this library in the file GIMPACT-LICENSE-ZLIB.TXT. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. ----------------------------------------------------------------------------- */ #include "gim_math.h" #include "gim_geom_types.h" //! Zero out a 2D vector #define VEC_ZERO_2(a) \ { \ (a)[0] = (a)[1] = 0.0f; \ }\ //! Zero out a 3D vector #define VEC_ZERO(a) \ { \ (a)[0] = (a)[1] = (a)[2] = 0.0f; \ }\ /// Zero out a 4D vector #define VEC_ZERO_4(a) \ { \ (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \ }\ /// Vector copy #define VEC_COPY_2(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ }\ /// Copy 3D vector #define VEC_COPY(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ (b)[2] = (a)[2]; \ }\ /// Copy 4D vector #define VEC_COPY_4(b,a) \ { \ (b)[0] = (a)[0]; \ (b)[1] = (a)[1]; \ (b)[2] = (a)[2]; \ (b)[3] = (a)[3]; \ }\ /// VECTOR SWAP #define VEC_SWAP(b,a) \ { \ GIM_SWAP_NUMBERS((b)[0],(a)[0]);\ GIM_SWAP_NUMBERS((b)[1],(a)[1]);\ GIM_SWAP_NUMBERS((b)[2],(a)[2]);\ }\ /// Vector difference #define VEC_DIFF_2(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ }\ /// Vector difference #define VEC_DIFF(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ (v21)[2] = (v2)[2] - (v1)[2]; \ }\ /// Vector difference #define VEC_DIFF_4(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] - (v1)[0]; \ (v21)[1] = (v2)[1] - (v1)[1]; \ (v21)[2] = (v2)[2] - (v1)[2]; \ (v21)[3] = (v2)[3] - (v1)[3]; \ }\ /// Vector sum #define VEC_SUM_2(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ }\ /// Vector sum #define VEC_SUM(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ (v21)[2] = (v2)[2] + (v1)[2]; \ }\ /// Vector sum #define VEC_SUM_4(v21,v2,v1) \ { \ (v21)[0] = (v2)[0] + (v1)[0]; \ (v21)[1] = (v2)[1] + (v1)[1]; \ (v21)[2] = (v2)[2] + (v1)[2]; \ (v21)[3] = (v2)[3] + (v1)[3]; \ }\ /// scalar times vector #define VEC_SCALE_2(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ }\ /// scalar times vector #define VEC_SCALE(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ (c)[2] = (a)*(b)[2]; \ }\ /// scalar times vector #define VEC_SCALE_4(c,a,b) \ { \ (c)[0] = (a)*(b)[0]; \ (c)[1] = (a)*(b)[1]; \ (c)[2] = (a)*(b)[2]; \ (c)[3] = (a)*(b)[3]; \ }\ /// accumulate scaled vector #define VEC_ACCUM_2(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ }\ /// accumulate scaled vector #define VEC_ACCUM(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ (c)[2] += (a)*(b)[2]; \ }\ /// accumulate scaled vector #define VEC_ACCUM_4(c,a,b) \ { \ (c)[0] += (a)*(b)[0]; \ (c)[1] += (a)*(b)[1]; \ (c)[2] += (a)*(b)[2]; \ (c)[3] += (a)*(b)[3]; \ }\ /// Vector dot product #define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1]) /// Vector dot product #define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]) /// Vector dot product #define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3]) /// vector impact parameter (squared) #define VEC_IMPACT_SQ(bsq,direction,position) {\ GREAL _llel_ = VEC_DOT(direction, position);\ bsq = VEC_DOT(position, position) - _llel_*_llel_;\ }\ /// vector impact parameter #define VEC_IMPACT(bsq,direction,position) {\ VEC_IMPACT_SQ(bsq,direction,position); \ GIM_SQRT(bsq,bsq); \ }\ /// Vector length #define VEC_LENGTH_2(a,l)\ {\ GREAL _pp = VEC_DOT_2(a,a);\ GIM_SQRT(_pp,l);\ }\ /// Vector length #define VEC_LENGTH(a,l)\ {\ GREAL _pp = VEC_DOT(a,a);\ GIM_SQRT(_pp,l);\ }\ /// Vector length #define VEC_LENGTH_4(a,l)\ {\ GREAL _pp = VEC_DOT_4(a,a);\ GIM_SQRT(_pp,l);\ }\ /// Vector inv length #define VEC_INV_LENGTH_2(a,l)\ {\ GREAL _pp = VEC_DOT_2(a,a);\ GIM_INV_SQRT(_pp,l);\ }\ /// Vector inv length #define VEC_INV_LENGTH(a,l)\ {\ GREAL _pp = VEC_DOT(a,a);\ GIM_INV_SQRT(_pp,l);\ }\ /// Vector inv length #define VEC_INV_LENGTH_4(a,l)\ {\ GREAL _pp = VEC_DOT_4(a,a);\ GIM_INV_SQRT(_pp,l);\ }\ /// distance between two points #define VEC_DISTANCE(_len,_va,_vb) {\ vec3f _tmp_; \ VEC_DIFF(_tmp_, _vb, _va); \ VEC_LENGTH(_tmp_,_len); \ }\ /// Vector length #define VEC_CONJUGATE_LENGTH(a,l)\ {\ GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\ GIM_SQRT(_pp,l);\ }\ /// Vector length #define VEC_NORMALIZE(a) { \ GREAL len;\ VEC_INV_LENGTH(a,len); \ if(lenA[1]?(A[0]>A[2]?0:2):(A[1]>A[2]?1:2);\ }\ //! Finds the 2 smallest cartesian coordinates from a vector #define VEC_MINOR_AXES(vec, i0, i1)\ {\ VEC_MAYOR_COORD(vec,i0);\ i0 = (i0+1)%3;\ i1 = (i0+1)%3;\ }\ #define VEC_EQUAL(v1,v2) (v1[0]==v2[0]&&v1[1]==v2[1]&&v1[2]==v2[2]) #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])) /// Vector cross #define X_AXIS_CROSS_VEC(dst,src)\ { \ dst[0] = 0.0f; \ dst[1] = -src[2]; \ dst[2] = src[1]; \ }\ #define Y_AXIS_CROSS_VEC(dst,src)\ { \ dst[0] = src[2]; \ dst[1] = 0.0f; \ dst[2] = -src[0]; \ }\ #define Z_AXIS_CROSS_VEC(dst,src)\ { \ dst[0] = -src[1]; \ dst[1] = src[0]; \ dst[2] = 0.0f; \ }\ /// initialize matrix #define IDENTIFY_MATRIX_3X3(m) \ { \ m[0][0] = 1.0; \ m[0][1] = 0.0; \ m[0][2] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = 1.0; \ m[1][2] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = 0.0; \ m[2][2] = 1.0; \ }\ /*! initialize matrix */ #define IDENTIFY_MATRIX_4X4(m) \ { \ m[0][0] = 1.0; \ m[0][1] = 0.0; \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = 1.0; \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = 0.0; \ m[2][2] = 1.0; \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ }\ /*! initialize matrix */ #define ZERO_MATRIX_4X4(m) \ { \ m[0][0] = 0.0; \ m[0][1] = 0.0; \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = 0.0; \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = 0.0; \ m[2][2] = 0.0; \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 0.0; \ }\ /*! matrix rotation X */ #define ROTX_CS(m,cosine,sine) \ { \ /* rotation about the x-axis */ \ \ m[0][0] = 1.0; \ m[0][1] = 0.0; \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = (cosine); \ m[1][2] = (sine); \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = -(sine); \ m[2][2] = (cosine); \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ }\ /*! matrix rotation Y */ #define ROTY_CS(m,cosine,sine) \ { \ /* rotation about the y-axis */ \ \ m[0][0] = (cosine); \ m[0][1] = 0.0; \ m[0][2] = -(sine); \ m[0][3] = 0.0; \ \ m[1][0] = 0.0; \ m[1][1] = 1.0; \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = (sine); \ m[2][1] = 0.0; \ m[2][2] = (cosine); \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ }\ /*! matrix rotation Z */ #define ROTZ_CS(m,cosine,sine) \ { \ /* rotation about the z-axis */ \ \ m[0][0] = (cosine); \ m[0][1] = (sine); \ m[0][2] = 0.0; \ m[0][3] = 0.0; \ \ m[1][0] = -(sine); \ m[1][1] = (cosine); \ m[1][2] = 0.0; \ m[1][3] = 0.0; \ \ m[2][0] = 0.0; \ m[2][1] = 0.0; \ m[2][2] = 1.0; \ m[2][3] = 0.0; \ \ m[3][0] = 0.0; \ m[3][1] = 0.0; \ m[3][2] = 0.0; \ m[3][3] = 1.0; \ }\ /*! matrix copy */ #define COPY_MATRIX_2X2(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[0][1]; \ \ b[1][0] = a[1][0]; \ b[1][1] = a[1][1]; \ \ }\ /*! matrix copy */ #define COPY_MATRIX_2X3(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[0][1]; \ b[0][2] = a[0][2]; \ \ b[1][0] = a[1][0]; \ b[1][1] = a[1][1]; \ b[1][2] = a[1][2]; \ }\ /*! matrix copy */ #define COPY_MATRIX_3X3(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[0][1]; \ b[0][2] = a[0][2]; \ \ b[1][0] = a[1][0]; \ b[1][1] = a[1][1]; \ b[1][2] = a[1][2]; \ \ b[2][0] = a[2][0]; \ b[2][1] = a[2][1]; \ b[2][2] = a[2][2]; \ }\ /*! matrix copy */ #define COPY_MATRIX_4X4(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[0][1]; \ b[0][2] = a[0][2]; \ b[0][3] = a[0][3]; \ \ b[1][0] = a[1][0]; \ b[1][1] = a[1][1]; \ b[1][2] = a[1][2]; \ b[1][3] = a[1][3]; \ \ b[2][0] = a[2][0]; \ b[2][1] = a[2][1]; \ b[2][2] = a[2][2]; \ b[2][3] = a[2][3]; \ \ b[3][0] = a[3][0]; \ b[3][1] = a[3][1]; \ b[3][2] = a[3][2]; \ b[3][3] = a[3][3]; \ }\ /*! matrix transpose */ #define TRANSPOSE_MATRIX_2X2(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[1][0]; \ \ b[1][0] = a[0][1]; \ b[1][1] = a[1][1]; \ }\ /*! matrix transpose */ #define TRANSPOSE_MATRIX_3X3(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[1][0]; \ b[0][2] = a[2][0]; \ \ b[1][0] = a[0][1]; \ b[1][1] = a[1][1]; \ b[1][2] = a[2][1]; \ \ b[2][0] = a[0][2]; \ b[2][1] = a[1][2]; \ b[2][2] = a[2][2]; \ }\ /*! matrix transpose */ #define TRANSPOSE_MATRIX_4X4(b,a) \ { \ b[0][0] = a[0][0]; \ b[0][1] = a[1][0]; \ b[0][2] = a[2][0]; \ b[0][3] = a[3][0]; \ \ b[1][0] = a[0][1]; \ b[1][1] = a[1][1]; \ b[1][2] = a[2][1]; \ b[1][3] = a[3][1]; \ \ b[2][0] = a[0][2]; \ b[2][1] = a[1][2]; \ b[2][2] = a[2][2]; \ b[2][3] = a[3][2]; \ \ b[3][0] = a[0][3]; \ b[3][1] = a[1][3]; \ b[3][2] = a[2][3]; \ b[3][3] = a[3][3]; \ }\ /*! multiply matrix by scalar */ #define SCALE_MATRIX_2X2(b,s,a) \ { \ b[0][0] = (s) * a[0][0]; \ b[0][1] = (s) * a[0][1]; \ \ b[1][0] = (s) * a[1][0]; \ b[1][1] = (s) * a[1][1]; \ }\ /*! multiply matrix by scalar */ #define SCALE_MATRIX_3X3(b,s,a) \ { \ b[0][0] = (s) * a[0][0]; \ b[0][1] = (s) * a[0][1]; \ b[0][2] = (s) * a[0][2]; \ \ b[1][0] = (s) * a[1][0]; \ b[1][1] = (s) * a[1][1]; \ b[1][2] = (s) * a[1][2]; \ \ b[2][0] = (s) * a[2][0]; \ b[2][1] = (s) * a[2][1]; \ b[2][2] = (s) * a[2][2]; \ }\ /*! multiply matrix by scalar */ #define SCALE_MATRIX_4X4(b,s,a) \ { \ b[0][0] = (s) * a[0][0]; \ b[0][1] = (s) * a[0][1]; \ b[0][2] = (s) * a[0][2]; \ b[0][3] = (s) * a[0][3]; \ \ b[1][0] = (s) * a[1][0]; \ b[1][1] = (s) * a[1][1]; \ b[1][2] = (s) * a[1][2]; \ b[1][3] = (s) * a[1][3]; \ \ b[2][0] = (s) * a[2][0]; \ b[2][1] = (s) * a[2][1]; \ b[2][2] = (s) * a[2][2]; \ b[2][3] = (s) * a[2][3]; \ \ b[3][0] = s * a[3][0]; \ b[3][1] = s * a[3][1]; \ b[3][2] = s * a[3][2]; \ b[3][3] = s * a[3][3]; \ }\ /*! multiply matrix by scalar */ #define SCALE_VEC_MATRIX_2X2(b,svec,a) \ { \ b[0][0] = svec[0] * a[0][0]; \ b[1][0] = svec[0] * a[1][0]; \ \ b[0][1] = svec[1] * a[0][1]; \ b[1][1] = svec[1] * a[1][1]; \ }\ /*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */ #define SCALE_VEC_MATRIX_3X3(b,svec,a) \ { \ b[0][0] = svec[0] * a[0][0]; \ b[1][0] = svec[0] * a[1][0]; \ b[2][0] = svec[0] * a[2][0]; \ \ b[0][1] = svec[1] * a[0][1]; \ b[1][1] = svec[1] * a[1][1]; \ b[2][1] = svec[1] * a[2][1]; \ \ b[0][2] = svec[2] * a[0][2]; \ b[1][2] = svec[2] * a[1][2]; \ b[2][2] = svec[2] * a[2][2]; \ }\ /*! multiply matrix by scalar */ #define SCALE_VEC_MATRIX_4X4(b,svec,a) \ { \ b[0][0] = svec[0] * a[0][0]; \ b[1][0] = svec[0] * a[1][0]; \ b[2][0] = svec[0] * a[2][0]; \ b[3][0] = svec[0] * a[3][0]; \ \ b[0][1] = svec[1] * a[0][1]; \ b[1][1] = svec[1] * a[1][1]; \ b[2][1] = svec[1] * a[2][1]; \ b[3][1] = svec[1] * a[3][1]; \ \ b[0][2] = svec[2] * a[0][2]; \ b[1][2] = svec[2] * a[1][2]; \ b[2][2] = svec[2] * a[2][2]; \ b[3][2] = svec[2] * a[3][2]; \ \ b[0][3] = svec[3] * a[0][3]; \ b[1][3] = svec[3] * a[1][3]; \ b[2][3] = svec[3] * a[2][3]; \ b[3][3] = svec[3] * a[3][3]; \ }\ /*! multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ { \ b[0][0] += (s) * a[0][0]; \ b[0][1] += (s) * a[0][1]; \ \ b[1][0] += (s) * a[1][0]; \ b[1][1] += (s) * a[1][1]; \ }\ /*! multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ { \ b[0][0] += (s) * a[0][0]; \ b[0][1] += (s) * a[0][1]; \ b[0][2] += (s) * a[0][2]; \ \ b[1][0] += (s) * a[1][0]; \ b[1][1] += (s) * a[1][1]; \ b[1][2] += (s) * a[1][2]; \ \ b[2][0] += (s) * a[2][0]; \ b[2][1] += (s) * a[2][1]; \ b[2][2] += (s) * a[2][2]; \ }\ /*! multiply matrix by scalar */ #define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ { \ b[0][0] += (s) * a[0][0]; \ b[0][1] += (s) * a[0][1]; \ b[0][2] += (s) * a[0][2]; \ b[0][3] += (s) * a[0][3]; \ \ b[1][0] += (s) * a[1][0]; \ b[1][1] += (s) * a[1][1]; \ b[1][2] += (s) * a[1][2]; \ b[1][3] += (s) * a[1][3]; \ \ b[2][0] += (s) * a[2][0]; \ b[2][1] += (s) * a[2][1]; \ b[2][2] += (s) * a[2][2]; \ b[2][3] += (s) * a[2][3]; \ \ b[3][0] += (s) * a[3][0]; \ b[3][1] += (s) * a[3][1]; \ b[3][2] += (s) * a[3][2]; \ b[3][3] += (s) * a[3][3]; \ }\ /*! matrix product */ /*! 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];*/ #define MATRIX_PRODUCT_2X2(c,a,b) \ { \ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \ \ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \ \ }\ /*! matrix product */ /*! 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];*/ #define MATRIX_PRODUCT_3X3(c,a,b) \ { \ c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \ c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \ c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \ \ c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \ c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \ c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \ \ c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \ c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \ c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \ }\ /*! matrix product */ /*! 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];*/ #define MATRIX_PRODUCT_4X4(c,a,b) \ { \ 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];\ 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];\ 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];\ 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];\ \ 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];\ 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];\ 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];\ 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];\ \ 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];\ 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];\ 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];\ 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];\ \ 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];\ 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];\ 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];\ 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];\ }\ /*! matrix times vector */ #define MAT_DOT_VEC_2X2(p,m,v) \ { \ p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \ p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \ }\ /*! matrix times vector */ #define MAT_DOT_VEC_3X3(p,m,v) \ { \ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \ }\ /*! matrix times vector v is a vec4f */ #define MAT_DOT_VEC_4X4(p,m,v) \ { \ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \ p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \ }\ /*! matrix times vector v is a vec3f and m is a mat4f
Last column is added as the position */ #define MAT_DOT_VEC_3X4(p,m,v) \ { \ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \ p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \ }\ /*! vector transpose times matrix */ /*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */ #define VEC_DOT_MAT_3X3(p,v,m) \ { \ p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \ p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \ p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \ }\ /*! affine matrix times vector */ /** The matrix is assumed to be an affine matrix, with last two * entries representing a translation */ #define MAT_DOT_VEC_2X3(p,m,v) \ { \ p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \ p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \ }\ //! Transform a plane #define MAT_TRANSFORM_PLANE_4X4(pout,m,plane)\ { \ pout[0] = m[0][0]*plane[0] + m[0][1]*plane[1] + m[0][2]*plane[2];\ pout[1] = m[1][0]*plane[0] + m[1][1]*plane[1] + m[1][2]*plane[2];\ pout[2] = m[2][0]*plane[0] + m[2][1]*plane[1] + m[2][2]*plane[2];\ pout[3] = m[0][3]*pout[0] + m[1][3]*pout[1] + m[2][3]*pout[2] + plane[3];\ }\ /** inverse transpose of matrix times vector * * This macro computes inverse transpose of matrix m, * and multiplies vector v into it, to yeild vector p * * DANGER !!! Do Not use this on normal vectors!!! * It will leave normals the wrong length !!! * See macro below for use on normals. */ #define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \ { \ GREAL det; \ \ det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ \ /* if matrix not singular, and not orthonormal, then renormalize */ \ if ((det!=1.0f) && (det != 0.0f)) { \ det = 1.0f / det; \ p[0] *= det; \ p[1] *= det; \ } \ }\ /** transform normal vector by inverse transpose of matrix * and then renormalize the vector * * This macro computes inverse transpose of matrix m, * and multiplies vector v into it, to yeild vector p * Vector p is then normalized. */ #define NORM_XFORM_2X2(p,m,v) \ { \ GREAL len; \ \ /* do nothing if off-diagonals are zero and diagonals are \ * equal */ \ if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \ p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ \ len = p[0]*p[0] + p[1]*p[1]; \ GIM_INV_SQRT(len,len); \ p[0] *= len; \ p[1] *= len; \ } else { \ VEC_COPY_2 (p, v); \ } \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_2X2(m,v,t) \ { \ m[0][0] = v[0] * t[0]; \ m[0][1] = v[0] * t[1]; \ \ m[1][0] = v[1] * t[0]; \ m[1][1] = v[1] * t[1]; \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_3X3(m,v,t) \ { \ m[0][0] = v[0] * t[0]; \ m[0][1] = v[0] * t[1]; \ m[0][2] = v[0] * t[2]; \ \ m[1][0] = v[1] * t[0]; \ m[1][1] = v[1] * t[1]; \ m[1][2] = v[1] * t[2]; \ \ m[2][0] = v[2] * t[0]; \ m[2][1] = v[2] * t[1]; \ m[2][2] = v[2] * t[2]; \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define OUTER_PRODUCT_4X4(m,v,t) \ { \ m[0][0] = v[0] * t[0]; \ m[0][1] = v[0] * t[1]; \ m[0][2] = v[0] * t[2]; \ m[0][3] = v[0] * t[3]; \ \ m[1][0] = v[1] * t[0]; \ m[1][1] = v[1] * t[1]; \ m[1][2] = v[1] * t[2]; \ m[1][3] = v[1] * t[3]; \ \ m[2][0] = v[2] * t[0]; \ m[2][1] = v[2] * t[1]; \ m[2][2] = v[2] * t[2]; \ m[2][3] = v[2] * t[3]; \ \ m[3][0] = v[3] * t[0]; \ m[3][1] = v[3] * t[1]; \ m[3][2] = v[3] * t[2]; \ m[3][3] = v[3] * t[3]; \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \ { \ m[0][0] += v[0] * t[0]; \ m[0][1] += v[0] * t[1]; \ \ m[1][0] += v[1] * t[0]; \ m[1][1] += v[1] * t[1]; \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \ { \ m[0][0] += v[0] * t[0]; \ m[0][1] += v[0] * t[1]; \ m[0][2] += v[0] * t[2]; \ \ m[1][0] += v[1] * t[0]; \ m[1][1] += v[1] * t[1]; \ m[1][2] += v[1] * t[2]; \ \ m[2][0] += v[2] * t[0]; \ m[2][1] += v[2] * t[1]; \ m[2][2] += v[2] * t[2]; \ }\ /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ #define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \ { \ m[0][0] += v[0] * t[0]; \ m[0][1] += v[0] * t[1]; \ m[0][2] += v[0] * t[2]; \ m[0][3] += v[0] * t[3]; \ \ m[1][0] += v[1] * t[0]; \ m[1][1] += v[1] * t[1]; \ m[1][2] += v[1] * t[2]; \ m[1][3] += v[1] * t[3]; \ \ m[2][0] += v[2] * t[0]; \ m[2][1] += v[2] * t[1]; \ m[2][2] += v[2] * t[2]; \ m[2][3] += v[2] * t[3]; \ \ m[3][0] += v[3] * t[0]; \ m[3][1] += v[3] * t[1]; \ m[3][2] += v[3] * t[2]; \ m[3][3] += v[3] * t[3]; \ }\ /** determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_2X2(d,m) \ { \ d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ }\ /** determinant of matrix * * Computes determinant of matrix m, returning d */ #define DETERMINANT_3X3(d,m) \ { \ d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \ d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \ d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \ }\ /** i,j,th cofactor of a 4x4 matrix * */ #define COFACTOR_4X4_IJ(fac,m,i,j) \ { \ GUINT __ii[4], __jj[4], __k; \ \ for (__k=0; __k */ #define INV_MAT_DOT_VEC_3X3(p,m,v) \ { \ p[0] = MAT_DOT_COL(m,v,0); \ p[1] = MAT_DOT_COL(m,v,1); \ p[2] = MAT_DOT_COL(m,v,2); \ }\ #endif // GIM_VECTOR_H_INCLUDED