//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc. //Distributed under the Boost Software License, Version 1.0. (See accompanying //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_QVM_907229FCB3A711DE83C152F855D89593 #define BOOST_QVM_907229FCB3A711DE83C152F855D89593 #include #include #include #include #include namespace test_qvm { namespace detail { inline float sin( float a ) { return ::sinf(a); } inline double sin( double a ) { return ::sin(a); } inline float cos( float a ) { return ::cosf(a); } inline double cos( double a ) { return ::cos(a); } inline float abs( float a ) { return ::fabsf(a); } inline double abs( double a ) { return ::fabs(a); } inline float atan2( float a, float b ) { return ::atan2f(a,b); } inline double atan2( double a, double b ) { return ::atan2(a,b); } template T determinant( T * * a, int n ) { int i,j,j1,j2; T det = 0; T * * m = 0; assert(n>=1); if( n==1 ) det = a[0][0]; else if( n==2 ) det = a[0][0] * a[1][1] - a[1][0] * a[0][1]; else { det = 0; for( j1=0; j1(malloc((n-1)*sizeof(T *))); for( i=0; i(malloc((n-1)*sizeof(T))); for( i=1; i void cofactor( T * * a, T (&b)[N][N] ) { int i,j,ii,jj,i1,j1; T det; T * * c; c = static_cast(malloc((N-1)*sizeof(T *))); for( i=0; i(malloc((N-1)*sizeof(T))); for( j=0; j T determinant( T (&in)[D][D] ) { T * * m = static_cast(malloc(D*sizeof(T *))); for( int i=0; i!=D; ++i ) { m[i] = static_cast(malloc(D*sizeof(T))); for( int j=0; j!=D; ++j ) m[i][j]=in[i][j]; } T det=::test_qvm::detail::determinant(m,D); for( int i=0; i void inverse( T (&out)[D][D], T (&in)[D][D] ) { T * * m = static_cast(malloc(D*sizeof(T *))); for( int i=0; i!=D; ++i ) { m[i] = static_cast(malloc(D*sizeof(T))); for( int j=0; j!=D; ++j ) m[i][j]=in[i][j]; } T det=::test_qvm::detail::determinant(m,D); assert(det!=T(0)); T f=T(1)/det; T b[D][D]; ::test_qvm::detail::cofactor(m,b); for( int i=0; i void init_m( T (&r)[M][N], T start=T(0), T step=T(0) ) { for( int i=0; i void init_v( T (&r)[D], T start=T(0), T step=T(0) ) { for( int i=0; i void zero_mat( T (&r)[M][N] ) { for( int i=0; i void zero_vec( T (&r)[D] ) { for( int i=0; i void identity( T (&r)[D][D] ) { for( int i=0; i void add_m( T (&r)[M][N], U (&a)[M][N], V (&b)[M][N] ) { for( int i=0; i void add_v( T (&r)[D], U (&a)[D], V (&b)[D] ) { for( int i=0; i void subtract_m( T (&r)[M][N], U (&a)[M][N], V (&b)[M][N] ) { for( int i=0; i void subtract_v( T (&r)[D], U (&a)[D], V (&b)[D] ) { for( int i=0; i void rotation_x( T (&r)[D][D], U angle ) { identity(r); T c=::test_qvm::detail::cos(angle); T s=::test_qvm::detail::sin(angle); r[1][1]=c; r[1][2]=-s; r[2][1]=s; r[2][2]=c; } template void rotation_y( T (&r)[D][D], U angle ) { identity(r); T c=::test_qvm::detail::cos(angle); T s=::test_qvm::detail::sin(angle); r[0][0]=c; r[0][2]=s; r[2][0]=-s; r[2][2]=c; } template void rotation_z( T (&r)[D][D], U angle ) { identity(r); T c=::test_qvm::detail::cos(angle); T s=::test_qvm::detail::sin(angle); r[0][0]=c; r[0][1]=-s; r[1][0]=s; r[1][1]=c; } template void translation( T (&r)[D][D], T (&t)[D-1] ) { identity(r); for( int i=0; i!=D-1; ++i ) r[i][D-1]=t[i]; } template void multiply_m( R (&r)[M][P], T (&a)[M][N], U (&b)[N][P] ) { for( int i=0; i void multiply_mv( R (&r)[M], T (&a)[M][N], U (&b)[N] ) { for( int i=0; i void multiply_vm( R (&r)[P], T (&a)[N], U (&b)[N][P] ) { for( int j=0; j void scalar_multiply_m( T (&r)[M][N], U (&a)[M][N], S scalar ) { for( int i=0; i void scalar_multiply_v( T (&r)[D], U (&a)[D], S scalar ) { for( int i=0; i void transpose( T (&r)[M][N], T (&a)[N][M] ) { for( int i=0; i R dot( T (&a)[D], U (&b)[D] ) { R r=R(0); for( int i=0; i T norm_squared( T (&m)[M][N] ) { T f=T(0); for( int i=0; i inline void matrix_perspective_lh( T (&r)[4][4], T fov_y, T aspect_ratio, T zn, T zf ) { T ys=T(1)/::tanf(fov_y/T(2)); T xs=ys/aspect_ratio; zero_mat(r); r[0][0] = xs; r[1][1] = ys; r[2][2] = zf/(zf-zn); r[2][3] = -zn*zf/(zf-zn); r[3][2] = 1; } template inline void matrix_perspective_rh( T (&r)[4][4], T fov_y, T aspect_ratio, T zn, T zf ) { matrix_perspective_lh(r,fov_y,aspect_ratio,zn,zf); r[2][2]=-r[2][2]; r[3][2]=-r[3][2]; } } #endif