rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 32de987f38ce71b0478738fd9c7632f0dc3f15a5
parent fad8dd101e4a5e72f36e6cd7e32a96ab25646660
Author: vaplv <vaplv@free.fr>
Date:   Mon,  4 Jul 2016 17:00:11 +0200

Make the float<22|33|44> types generic to the data type

Diffstat:
Mcmake/CMakeLists.txt | 6+++++-
Msrc/float22.h | 48+-----------------------------------------------
Msrc/float33.h | 155+------------------------------------------------------------------------------
Dsrc/float44.c | 84-------------------------------------------------------------------------------
Msrc/float44.h | 61++-----------------------------------------------------------
Msrc/math.h | 1-
Asrc/real22.h | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/real33.h | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/real44.h | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/realX.h | 5-----
Msrc/realXY.h | 52----------------------------------------------------
Asrc/realXY_begin.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/realXY_end.h | 29+++++++++++++++++++++++++++++
Msrc/realX_begin.h | 6++----
Msrc/realX_end.h | 3++-
15 files changed, 520 insertions(+), 408 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -42,7 +42,6 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) set(RSYS_FILES_SRC clock_time.c cstr.c - float44.c image.c library.c logger.c @@ -100,7 +99,12 @@ set(RSYS_FILES_INC_API realX.h realX_begin.h realX_end.h + real22.h + real33.h + real44.h realXY.h + realXY_begin.h + realXY_end.h ref_count.h rsys.h signal.h diff --git a/src/float22.h b/src/float22.h @@ -18,54 +18,8 @@ #include "float2.h" -/* Generate common floatXY funcs */ -#define REALX_DIMENSION__ 2 -#define REALY_DIMENSION__ 2 #define REAL_TYPE__ float -#include "realXY.h" - -/* Specific float22 funcs */ -static FINLINE float* -f22(float* dst, const float a, const float b, const float c, const float d) -{ - ASSERT(dst); - dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d; - return dst; -} - -static FINLINE float -f22_det(const float* mat) -{ - return mat[0] * mat[3] - mat[2] * mat[1]; -} - -static FINLINE float -f22_inverse(float* dst, const float* mat) -{ - float det, rcp_det, mat0; - ASSERT(dst && mat); - det = f22_det(mat); - rcp_det = 1.f / det; - mat0 = mat[0]; - dst[0] = mat[3] * rcp_det; - dst[1] = -mat[1] * rcp_det; - dst[2] = -mat[2] * rcp_det; - dst[3] = mat0 * rcp_det; - return det; -} - -static FINLINE float -f22_invtrans(float* dst, const float* mat) -{ - float det, dst1, dst2; - ASSERT(dst && mat); - det = f22_inverse(dst, mat); - dst1 = dst[1]; - dst2 = dst[2]; - dst[1] = dst2; - dst[2] = dst1; - return det; -} +#include "real22.h" #endif /* FLOAT22_H */ diff --git a/src/float33.h b/src/float33.h @@ -17,162 +17,9 @@ #define FLOAT33_H #include "float3.h" -#include <math.h> -/* Generate common floatXY funcs */ -#define REALX_DIMENSION__ 3 -#define REALY_DIMENSION__ 3 #define REAL_TYPE__ float -#include "realXY.h" - -/* Specific float33 funcs */ -static FINLINE float* -f33 - (float* dst, - const float a, const float b, const float c, - const float d, const float e, const float f, - const float g, const float h, const float i) -{ - ASSERT(dst); - dst[0] = a; dst[1] = b; dst[2] = c; - dst[3] = d; dst[4] = e; dst[5] = f; - dst[6] = g; dst[7] = h; dst[8] = i; - return dst; -} - -static FINLINE float -f33_det(const float* mat) -{ - float tmp[3]; - f3_cross(tmp, f33_col_cptr(mat, 0), f33_col_cptr(mat, 1)); - return f3_dot(f33_col_cptr(mat, 2), tmp); -} - -static FINLINE float -f33_invtrans(float* dst, const float* src) -{ - float f33[9]; - float det; - f3_cross(f33_col_ptr(f33, 0), f33_col_cptr(src, 1), f33_col_cptr(src, 2)); - f3_cross(f33_col_ptr(f33, 1), f33_col_cptr(src, 2), f33_col_cptr(src, 0)); - f3_cross(f33_col_ptr(f33, 2), f33_col_cptr(src, 0), f33_col_cptr(src, 1)); - - det = f3_dot(f33_col_cptr(f33, 2), f33_col_cptr(src, 2)); - f33_mul(dst, f33, 1.f / det); - return det; -} - -static FINLINE float -f33_inverse(float* dst, const float* src) -{ - float f33[9]; - const float det = f33_invtrans(f33, src); - f33_transpose(dst, f33); - return det; -} - -static INLINE float* -f33_rotation /* XYZ norm */ - (float* dst, - /* In radian */ - const float pitch, - const float yaw, - const float roll) -{ - const float c1 = (float)cos((double)pitch); - const float c2 = (float)cos((double)yaw); - const float c3 = (float)cos((double)roll); - const float s1 = (float)sin((double)pitch); - const float s2 = (float)sin((double)yaw); - const float s3 = (float)sin((double)roll); - ASSERT(dst); - dst[0] = c2*c3; dst[1] = c1*s3 + c3*s1*s2; dst[2] = s1*s3 - c1*c3*s2; - dst[3] =-c2*s3; dst[4] = c1*c3 - s1*s2*s3; dst[5] = c1*s2*s3 + c3*s1; - dst[6] = s2; dst[7] =-c2*s1; dst[8] = c1*c2; - return dst; -} - -static INLINE float* -f33_rotation_axis_angle - (float* dst, - const float axis[3], /* Should be normalized */ - const float angle) /* In radian */ -{ - const float c = (float)cos((double)angle); - const float s = (float)sin((double)angle); - const float C = 1 - c; - ASSERT(dst && axis && f3_is_normalized(axis)); - - dst[0] = axis[0] * axis[0] * C + c; - dst[1] = axis[0] * axis[1] * C + s * axis[2]; - dst[2] = axis[0] * axis[2] * C - s * axis[1]; - - dst[3] = axis[1] * axis[0] * C - s * axis[2]; - dst[4] = axis[1] * axis[1] * C + c; - dst[5] = axis[1] * axis[2] * C + s * axis[0]; - - dst[6] = axis[2] * axis[0] * C + s * axis[1]; - dst[7] = axis[2] * axis[1] * C - s * axis[0]; - dst[8] = axis[2] * axis[2] * C + c; - return dst; -} - -static INLINE float* -f33_rotation_pitch(float dst[9], const float pitch/* in radian */) -{ - const float c = (float)cos((double)pitch); - const float s = (float)sin((double)pitch); - ASSERT(dst); - dst[0] = 1.f; dst[1] = 0.f; dst[2] = 0.f; - dst[3] = 0.f; dst[4] = c; dst[5] = s; - dst[6] = 0.f; dst[7] =-s; dst[8] = c; - return dst; -} - -static INLINE float* -f33_rotation_yaw(float dst[9], const float yaw/* in radian */) -{ - const float c = (float)cos((double)yaw); - const float s = (float)sin((double)yaw); - ASSERT(dst); - dst[0] = c; dst[1] = 0.f; dst[2] =-s; - dst[3] = 0.f; dst[4] = 1.f; dst[5] = 0.f; - dst[6] = s; dst[7] = 0.f; dst[8] = c; - return dst; -} - -static INLINE float* -f33_rotation_roll(float dst[9], const float roll/* in radian */) -{ - const float c = (float)cos((double)roll); - const float s = (float)sin((double)roll); - ASSERT(dst); - dst[0] = c; dst[1] = s; dst[2] = 0.f; - dst[3] =-s; dst[4] = c; dst[5] = 0.f; - dst[6] = 0.f; dst[7] = 0.f; dst[8] = 1.f; - return dst; -} - -static INLINE float* -f33_basis(float dst[9], const float N[3]) -{ - float a[3], b[3], x[3], y[3], normal[3], len; - ASSERT(N); - f3_set(normal, N); - f3_cross(a, f3(a, 1.f, 0.f, 0.f), normal); - f3_cross(b, f3(b, 0.f, 1.f, 0.f), normal); - len = f3_normalize(x, f3_dot(a, a) > f3_dot(b, b) ? a : b); - if(len <= 0.f) { - ASSERT(0 && "Degenerated normal"); - return f33_splat(dst, 0.f); - } - len = f3_normalize(y, f3_cross(y, normal, x)); - ASSERT(len > 0); - f3_set(dst + 0, x); - f3_set(dst + 3, y); - f3_set(dst + 6, normal); - return dst; -} +#include "real33.h" #endif /* FLOAT33_H */ diff --git a/src/float44.c b/src/float44.c @@ -1,84 +0,0 @@ -/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) - * - * The RSys library is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * The RSys 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 - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ - -#include "float44.h" - -float -f44_inverse(float* dst, const float* m) -{ - float tmp[9]; - float det_012[4], det_023[4], det_123[4], det_013[4]; - float cofacts[4]; - float det, rcp_det, mpmp_rcp_det[4], pmpm_rcp_det[4]; - ASSERT( dst && m ); - - /* Define the 3x3 sub matrices and compute their determinants */ - #define C3( Dst, Mat, ICol, X, Y, Z ) \ - (Dst)[0] = Mat[ICol*4+X], (Dst)[1] = Mat[ICol*4+Y], (Dst)[2] = Mat[ICol*4+Z] - C3(tmp+0 ,m, 1, 0, 1, 2); C3(tmp+3, m, 2, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); - det_012[0] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 2, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); - det_012[1] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 1, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); - det_012[2] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 1, 0, 1, 2); C3(tmp+6, m, 2, 0, 1, 2); - det_012[3] = f33_det(tmp); - - C3(tmp+0 ,m, 1, 0, 2, 3); C3(tmp+3, m, 2, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); - det_023[0] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 2, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); - det_023[1] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 1, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); - det_023[2] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 1, 0, 2, 3); C3(tmp+6, m, 2, 0, 2, 3); - det_023[3] = f33_det(tmp); - - C3(tmp+0 ,m, 1, 1, 2, 3); C3(tmp+3, m, 2, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); - det_123[0] = f33_det(tmp); - C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 2, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); - det_123[1] = f33_det(tmp); - C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 1, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); - det_123[2] = f33_det(tmp); - C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 1, 1, 2, 3); C3(tmp+6, m, 2, 1, 2, 3); - det_123[3] = f33_det(tmp); - - C3(tmp+0 ,m, 1, 0, 1, 3); C3(tmp+3, m, 2, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); - det_013[0] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 2, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); - det_013[1] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 1, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); - det_013[2] = f33_det(tmp); - C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 1, 0, 1, 3); C3(tmp+6, m, 2, 0, 1, 3); - det_013[3] = f33_det(tmp); - #undef C3 - - f4_set(cofacts, f4(tmp, -det_012[0], det_012[1], -det_012[2], det_012[3])); - - /* Compute the determinant of src */ - det = f4_dot(cofacts, f4(tmp, m[3], m[7], m[11], m[15])); - - /* Invert the matrix */ - if( det == 0.f ) - return det; - - rcp_det = 1.f / det; - f4_set(mpmp_rcp_det, f4(tmp,-rcp_det, rcp_det,-rcp_det, rcp_det)); - f4_set(pmpm_rcp_det, f4(tmp, rcp_det,-rcp_det, rcp_det,-rcp_det)); - f4_mul(f44_col_ptr(dst, 0), det_123, pmpm_rcp_det); - f4_mul(f44_col_ptr(dst, 1), det_023, mpmp_rcp_det); - f4_mul(f44_col_ptr(dst, 2), det_013, pmpm_rcp_det); - f4_mul(f44_col_ptr(dst, 3), det_012, mpmp_rcp_det); - return det; -} diff --git a/src/float44.h b/src/float44.h @@ -16,68 +16,11 @@ #ifndef FLOAT44_H #define FLOAT44_H -#include "float33.h" #include "float4.h" +#include "float33.h" -/* Generate common floatXY funcs */ -#define REALX_DIMENSION__ 4 -#define REALY_DIMENSION__ 4 #define REAL_TYPE__ float -#include "realXY.h" - -/* Specific float44 funcs*/ -static FINLINE float* -f44 - (float* dst, - const float a, const float b, const float c, const float d, - const float e, const float f, const float g, const float h, - const float i, const float j, const float k, const float l, - const float m, const float n, const float o, const float p) -{ - ASSERT(dst); - dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d; - dst[4] = e; dst[5] = f; dst[6] = g; dst[7] = h; - dst[8] = i; dst[9] = j; dst[10] = k; dst[11] = l; - dst[12] = m; dst[13] = n; dst[14] = o; dst[15] = p; - return dst; -} - -static FINLINE float -f44_det(const float* mat) -{ - float f33[9]; - float row3[4], tmp[4]; - ASSERT( mat ); - - #define C3( Dst, Mat, ICol ) \ - (Dst)[0] = Mat[ICol*4], (Dst)[1] = Mat[ICol*4+1], (Dst)[2] = Mat[ICol*4+2] - C3(f33 + 0, mat, 1); C3(f33 + 3, mat, 2); C3(f33 + 6, mat, 3); - tmp[0] = -f33_det(f33); - C3(f33 + 0, mat, 0); C3(f33 + 3, mat, 2); C3(f33 + 6, mat, 3); - tmp[1] = f33_det(f33); - C3(f33 + 0, mat, 0); C3(f33 + 3, mat, 1); C3(f33 + 6, mat, 3); - tmp[2] = -f33_det(f33); - C3(f33 + 0, mat, 0); C3(f33 + 3, mat, 1); C3(f33 + 6, mat, 2); - #undef C3 - tmp[3] = f33_det(f33); - f44_row(row3, mat, 3); - return f4_dot(tmp, row3); -} - -BEGIN_DECLS - -RSYS_API float -f44_inverse(float* dst, const float* mat); - -END_DECLS - -static FINLINE float -f44_invtrans(float* dst, const float* mat) -{ - const float det = f44_inverse(dst, mat); - f44_transpose(dst, dst); - return det; -} +#include "real44.h" #endif /* FLOAT44_H */ diff --git a/src/math.h b/src/math.h @@ -32,7 +32,6 @@ #define MDEG2RAD(Deg) ((Deg)*PI/180.0) #define MRAD2DEG(Rad) ((Rad)*180.0/PI) - static FINLINE size_t round_up_pow2(const size_t i) { diff --git a/src/real22.h b/src/real22.h @@ -0,0 +1,75 @@ +/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) + * + * The RSys library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The RSys 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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef REAL_TYPE__ + #error Missing arguments +#endif + +/* Generate common realXY funcs */ +#define REALX_DIMENSION__ 2 +#define REALY_DIMENSION__ 2 +#include "realXY_begin.h" +#include "realXY.h" + +/* Specific real22 funcs */ +static FINLINE REAL_TYPE__* +CONCAT(REAL_LETTER__, 22) + (REAL_TYPE__* dst, + const REAL_TYPE__ a, + const REAL_TYPE__ b, + const REAL_TYPE__ c, + const REAL_TYPE__ d) +{ + ASSERT(dst); + dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d; + return dst; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(det)(const REAL_TYPE__* mat) +{ + return mat[0] * mat[3] - mat[2] * mat[1]; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(inverse)(REAL_TYPE__* dst, const REAL_TYPE__* mat) +{ + REAL_TYPE__ det, rcp_det, mat0; + ASSERT(dst && mat); + det = REALXY_FUNC__(det)(mat); + rcp_det = 1.f / det; + mat0 = mat[0]; + dst[0] = mat[3] * rcp_det; + dst[1] = -mat[1] * rcp_det; + dst[2] = -mat[2] * rcp_det; + dst[3] = mat0 * rcp_det; + return det; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(invtrans)(REAL_TYPE__* dst, const REAL_TYPE__* mat) +{ + REAL_TYPE__ det, dst1, dst2; + ASSERT(dst && mat); + det = REALXY_FUNC__(inverse)(dst, mat); + dst1 = dst[1]; + dst2 = dst[2]; + dst[1] = dst2; + dst[2] = dst1; + return det; +} + +#include "realXY_end.h" + diff --git a/src/real33.h b/src/real33.h @@ -0,0 +1,194 @@ +/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) + * + * The RSys library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The RSys 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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef REAL_TYPE__ + #error Missing arguments +#endif + +/* Generate common realXY funcs */ +#define REALX_DIMENSION__ 3 +#define REALY_DIMENSION__ 3 +#include "realXY_begin.h" +#include "realXY.h" + +/* Specific real33 funcs */ +static FINLINE REAL_TYPE__* +CONCAT(REAL_LETTER__, 33) + (REAL_TYPE__* dst, + const REAL_TYPE__ a, const REAL_TYPE__ b, const REAL_TYPE__ c, + const REAL_TYPE__ d, const REAL_TYPE__ e, const REAL_TYPE__ f, + const REAL_TYPE__ g, const REAL_TYPE__ h, const REAL_TYPE__ i) +{ + ASSERT(dst); + dst[0] = a; dst[1] = b; dst[2] = c; + dst[3] = d; dst[4] = e; dst[5] = f; + dst[6] = g; dst[7] = h; dst[8] = i; + return dst; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(det)(const REAL_TYPE__* mat) +{ + REAL_TYPE__ tmp[3]; + REALX_FUNC__(cross) + (tmp, REALXY_FUNC__(col_cptr)(mat, 0), REALXY_FUNC__(col_cptr)(mat, 1)); + return REALX_FUNC__(dot)(REALXY_FUNC__(col_cptr)(mat, 2), tmp); +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(invtrans)(REAL_TYPE__* dst, const REAL_TYPE__* src) +{ + REAL_TYPE__ f33[9]; + REAL_TYPE__ det; + REALX_FUNC__(cross) + (REALXY_FUNC__(col_ptr)(f33, 0), + REALXY_FUNC__(col_cptr)(src, 1), + REALXY_FUNC__(col_cptr)(src, 2)); + REALX_FUNC__(cross) + (REALXY_FUNC__(col_ptr)(f33, 1), + REALXY_FUNC__(col_cptr)(src, 2), + REALXY_FUNC__(col_cptr)(src, 0)); + REALX_FUNC__(cross) + (REALXY_FUNC__(col_ptr)(f33, 2), + REALXY_FUNC__(col_cptr)(src, 0), + REALXY_FUNC__(col_cptr)(src, 1)); + + det = REALX_FUNC__(dot) + (REALXY_FUNC__(col_cptr)(f33, 2), + REALXY_FUNC__(col_cptr)(src, 2)); + REALXY_FUNC__(mul)(dst, f33, 1.f / det); + return det; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(inverse)(REAL_TYPE__* dst, const REAL_TYPE__* src) +{ + REAL_TYPE__ f33[9]; + const REAL_TYPE__ det = REALXY_FUNC__(invtrans)(f33, src); + REALXY_FUNC__(transpose)(dst, f33); + return det; +} + +static INLINE REAL_TYPE__* +f33_rotation /* XYZ norm */ + (REAL_TYPE__* dst, + /* In radian */ + const REAL_TYPE__ pitch, + const REAL_TYPE__ yaw, + const REAL_TYPE__ roll) +{ + const REAL_TYPE__ c1 = (REAL_TYPE__)cos((double)pitch); + const REAL_TYPE__ c2 = (REAL_TYPE__)cos((double)yaw); + const REAL_TYPE__ c3 = (REAL_TYPE__)cos((double)roll); + const REAL_TYPE__ s1 = (REAL_TYPE__)sin((double)pitch); + const REAL_TYPE__ s2 = (REAL_TYPE__)sin((double)yaw); + const REAL_TYPE__ s3 = (REAL_TYPE__)sin((double)roll); + ASSERT(dst); + dst[0] = c2*c3; dst[1] = c1*s3 + c3*s1*s2; dst[2] = s1*s3 - c1*c3*s2; + dst[3] =-c2*s3; dst[4] = c1*c3 - s1*s2*s3; dst[5] = c1*s2*s3 + c3*s1; + dst[6] = s2; dst[7] =-c2*s1; dst[8] = c1*c2; + return dst; +} + +static INLINE REAL_TYPE__* +f33_rotation_axis_angle + (REAL_TYPE__* dst, + const REAL_TYPE__ axis[3], /* Should be normalized */ + const REAL_TYPE__ angle) /* In radian */ +{ + const REAL_TYPE__ c = (REAL_TYPE__)cos((double)angle); + const REAL_TYPE__ s = (REAL_TYPE__)sin((double)angle); + const REAL_TYPE__ C = 1 - c; + ASSERT(dst && axis && REALX_FUNC__(is_normalized)(axis)); + + dst[0] = axis[0] * axis[0] * C + c; + dst[1] = axis[0] * axis[1] * C + s * axis[2]; + dst[2] = axis[0] * axis[2] * C - s * axis[1]; + + dst[3] = axis[1] * axis[0] * C - s * axis[2]; + dst[4] = axis[1] * axis[1] * C + c; + dst[5] = axis[1] * axis[2] * C + s * axis[0]; + + dst[6] = axis[2] * axis[0] * C + s * axis[1]; + dst[7] = axis[2] * axis[1] * C - s * axis[0]; + dst[8] = axis[2] * axis[2] * C + c; + return dst; +} + +static INLINE REAL_TYPE__* +REALXY_FUNC__(rotation_pitch) + (REAL_TYPE__ dst[9], const REAL_TYPE__ pitch/* in radian */) +{ + const REAL_TYPE__ c = (REAL_TYPE__)cos((double)pitch); + const REAL_TYPE__ s = (REAL_TYPE__)sin((double)pitch); + ASSERT(dst); + dst[0] = 1.f; dst[1] = 0.f; dst[2] = 0.f; + dst[3] = 0.f; dst[4] = c; dst[5] = s; + dst[6] = 0.f; dst[7] =-s; dst[8] = c; + return dst; +} + +static INLINE REAL_TYPE__* +REALXY_FUNC__(rotation_yaw) + (REAL_TYPE__ dst[9], const REAL_TYPE__ yaw/* in radian */) +{ + const REAL_TYPE__ c = (REAL_TYPE__)cos((double)yaw); + const REAL_TYPE__ s = (REAL_TYPE__)sin((double)yaw); + ASSERT(dst); + dst[0] = c; dst[1] = 0.f; dst[2] =-s; + dst[3] = 0.f; dst[4] = 1.f; dst[5] = 0.f; + dst[6] = s; dst[7] = 0.f; dst[8] = c; + return dst; +} + +static INLINE REAL_TYPE__* +REALXY_FUNC__(rotation_roll) + (REAL_TYPE__ dst[9], const REAL_TYPE__ roll/* in radian */) +{ + const REAL_TYPE__ c = (REAL_TYPE__)cos((double)roll); + const REAL_TYPE__ s = (REAL_TYPE__)sin((double)roll); + ASSERT(dst); + dst[0] = c; dst[1] = s; dst[2] = 0.f; + dst[3] =-s; dst[4] = c; dst[5] = 0.f; + dst[6] = 0.f; dst[7] = 0.f; dst[8] = 1.f; + return dst; +} + +static INLINE REAL_TYPE__* +REALXY_FUNC__(basis)(REAL_TYPE__ dst[9], const REAL_TYPE__ N[3]) +{ + REAL_TYPE__ a[3], b[3], x[3], y[3], normal[3], len; + ASSERT(N); + REALX_FUNC__(set)(normal, N); + a[0] = 1.f, a[1] = 0.f, a[2] = 0.f; + b[0] = 0.f, b[1] = 1.f, b[2] = 0.f; + REALX_FUNC__(cross)(a, a, normal); + REALX_FUNC__(cross)(b, b, normal); + len = REALX_FUNC__(normalize) + (x, REALX_FUNC__(dot)(a, a) > REALX_FUNC__(dot)(b, b) ? a : b); + if(len <= 0.f) { + ASSERT(0 && "Degenerated normal"); + return REALXY_FUNC__(splat)(dst, 0.f); + } + len = REALX_FUNC__(normalize)(y, REALX_FUNC__(cross)(y, normal, x)); + ASSERT(len > 0); + REALX_FUNC__(set)(dst + 0, x); + REALX_FUNC__(set)(dst + 3, y); + REALX_FUNC__(set)(dst + 6, normal); + return dst; +} + +#include "realXY_end.h" + diff --git a/src/real44.h b/src/real44.h @@ -0,0 +1,158 @@ +/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) + * + * The RSys library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The RSys 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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ + +#include "rsys.h" + +#ifndef REAL_TYPE__ + #error Missing arguments +#endif + +#ifdef REAL33_FUNC__ + #error Unexpected macro definition +#endif + +#define REAL33_FUNC__(Func) CONCAT(CONCAT(CONCAT(REAL_LETTER__, 33), _), Func) + +/* Generate common realXY funcs */ +#define REALX_DIMENSION__ 4 +#define REALY_DIMENSION__ 4 +#include "realXY_begin.h" +#include "realXY.h" + +/* Specific REAL_TYPE__44 funcs*/ +static FINLINE REAL_TYPE__* +CONCAT(REAL_LETTER__, 44) + (REAL_TYPE__* dst, + const REAL_TYPE__ a, const REAL_TYPE__ b, const REAL_TYPE__ c, const REAL_TYPE__ d, + const REAL_TYPE__ e, const REAL_TYPE__ f, const REAL_TYPE__ g, const REAL_TYPE__ h, + const REAL_TYPE__ i, const REAL_TYPE__ j, const REAL_TYPE__ k, const REAL_TYPE__ l, + const REAL_TYPE__ m, const REAL_TYPE__ n, const REAL_TYPE__ o, const REAL_TYPE__ p) +{ + ASSERT(dst); + dst[0] = a; dst[1] = b; dst[2] = c; dst[3] = d; + dst[4] = e; dst[5] = f; dst[6] = g; dst[7] = h; + dst[8] = i; dst[9] = j; dst[10] = k; dst[11] = l; + dst[12] = m; dst[13] = n; dst[14] = o; dst[15] = p; + return dst; +} + +static FINLINE REAL_TYPE__ +REALXY_FUNC__(det)(const REAL_TYPE__* mat) +{ + REAL_TYPE__ m33[9]; + REAL_TYPE__ row3[4], tmp[4]; + ASSERT(mat); + + #define C3( Dst, Mat, ICol ) \ + (Dst)[0] = Mat[ICol*4], (Dst)[1] = Mat[ICol*4+1], (Dst)[2] = Mat[ICol*4+2] + C3(m33 + 0, mat, 1); C3(m33 + 3, mat, 2); C3(m33 + 6, mat, 3); + tmp[0] = -REAL33_FUNC__(det)(m33); + C3(m33 + 0, mat, 0); C3(m33 + 3, mat, 2); C3(m33 + 6, mat, 3); + tmp[1] = REAL33_FUNC__(det)(m33); + C3(m33 + 0, mat, 0); C3(m33 + 3, mat, 1); C3(m33 + 6, mat, 3); + tmp[2] = -REAL33_FUNC__(det)(m33); + C3(m33 + 0, mat, 0); C3(m33 + 3, mat, 1); C3(m33 + 6, mat, 2); + #undef C3 + tmp[3] = REAL33_FUNC__(det)(m33); + REALXY_FUNC__(row)(row3, mat, 3); + return REALX_FUNC__(dot)(tmp, row3); +} + +static INLINE REAL_TYPE__ +REALXY_FUNC__(inverse)(REAL_TYPE__* dst, const REAL_TYPE__* m) +{ + REAL_TYPE__ tmp[9]; + REAL_TYPE__ det_012[4], det_023[4], det_123[4], det_013[4]; + REAL_TYPE__ cofacts[4]; + REAL_TYPE__ det, rcp_det, mpmp_rcp_det[4], pmpm_rcp_det[4]; + ASSERT( dst && m ); + + /* Define the 3x3 sub matrices and compute their determinants */ + #define C3( Dst, Mat, ICol, X, Y, Z ) \ + (Dst)[0] = Mat[ICol*4+X], (Dst)[1] = Mat[ICol*4+Y], (Dst)[2] = Mat[ICol*4+Z] + C3(tmp+0 ,m, 1, 0, 1, 2); C3(tmp+3, m, 2, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); + det_012[0] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 2, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); + det_012[1] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 1, 0, 1, 2); C3(tmp+6, m, 3, 0, 1, 2); + det_012[2] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 2); C3(tmp+3, m, 1, 0, 1, 2); C3(tmp+6, m, 2, 0, 1, 2); + det_012[3] = REAL33_FUNC__(det)(tmp); + + C3(tmp+0 ,m, 1, 0, 2, 3); C3(tmp+3, m, 2, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); + det_023[0] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 2, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); + det_023[1] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 1, 0, 2, 3); C3(tmp+6, m, 3, 0, 2, 3); + det_023[2] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 2, 3); C3(tmp+3, m, 1, 0, 2, 3); C3(tmp+6, m, 2, 0, 2, 3); + det_023[3] = REAL33_FUNC__(det)(tmp); + + C3(tmp+0 ,m, 1, 1, 2, 3); C3(tmp+3, m, 2, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); + det_123[0] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 2, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); + det_123[1] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 1, 1, 2, 3); C3(tmp+6, m, 3, 1, 2, 3); + det_123[2] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 1, 2, 3); C3(tmp+3, m, 1, 1, 2, 3); C3(tmp+6, m, 2, 1, 2, 3); + det_123[3] = REAL33_FUNC__(det)(tmp); + + C3(tmp+0 ,m, 1, 0, 1, 3); C3(tmp+3, m, 2, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); + det_013[0] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 2, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); + det_013[1] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 1, 0, 1, 3); C3(tmp+6, m, 3, 0, 1, 3); + det_013[2] = REAL33_FUNC__(det)(tmp); + C3(tmp+0 ,m, 0, 0, 1, 3); C3(tmp+3, m, 1, 0, 1, 3); C3(tmp+6, m, 2, 0, 1, 3); + det_013[3] = REAL33_FUNC__(det)(tmp); + #undef C3 + + cofacts[0] = -det_012[0]; + cofacts[1] = det_012[1]; + cofacts[2] = -det_012[2]; + cofacts[3] = det_012[3]; + + /* Compute the determinant of src */ + tmp[0] = m[3], tmp[1] = m[7], tmp[2] = m[11], tmp[3] = m[15]; + det = REALX_FUNC__(dot)(cofacts, tmp); + + /* Invert the matrix */ + if(det == 0.f) + return det; + + rcp_det = 1.f / det; + + mpmp_rcp_det[0] = mpmp_rcp_det[2] = -rcp_det; + mpmp_rcp_det[1] = mpmp_rcp_det[3] = rcp_det; + pmpm_rcp_det[0] = pmpm_rcp_det[2] = rcp_det; + pmpm_rcp_det[1] = pmpm_rcp_det[3] = -rcp_det; + REALX_FUNC__(mul)(REALXY_FUNC__(col_ptr)(dst, 0), det_123, pmpm_rcp_det); + REALX_FUNC__(mul)(REALXY_FUNC__(col_ptr)(dst, 1), det_023, mpmp_rcp_det); + REALX_FUNC__(mul)(REALXY_FUNC__(col_ptr)(dst, 2), det_013, pmpm_rcp_det); + REALX_FUNC__(mul)(REALXY_FUNC__(col_ptr)(dst, 3), det_012, mpmp_rcp_det); + return det; +} +static FINLINE REAL_TYPE__ +REALXY_FUNC__(invtrans)(REAL_TYPE__* dst, const REAL_TYPE__* mat) +{ + const REAL_TYPE__ det = REALXY_FUNC__(inverse)(dst, mat); + REALXY_FUNC__(transpose)(dst, dst); + return det; +} + +#undef REAL33_FUNC__ + +#include "realXY_end.h" + diff --git a/src/realX.h b/src/realX.h @@ -19,10 +19,6 @@ #include "math.h" #include <math.h> -#ifndef REALX_BEGIN_H - #error The realX_begin.h header must be included -#endif - #ifdef COMPILER_GCC #pragma GCC push_options #pragma GCC optimize("unroll-loops") @@ -349,4 +345,3 @@ REALX_FUNC__(min) #ifdef COMPILER_GCC #pragma GCC pop_options #endif - diff --git a/src/realXY.h b/src/realXY.h @@ -17,20 +17,6 @@ * Internal header used to generate funcs on column major REAL_TYPE__ matrix * of X x Y dimensions */ -#if !defined(REALX_DIMENSION__) \ - || !defined(REALY_DIMENSION__) \ - || !defined(REAL_TYPE__) - #error Missing arguments -#endif - -#if defined(REALXY_FUNC__) \ - || defined(REALX_FUNC__) \ - || defined(REALY_FUNC__) \ - || defined(REAL_EPSILON__) \ - || defined(REAL_LETTER__) \ - || defined(SIZEOF_REALXY__) - #error Unexpected macro defintion -#endif #include "math.h" #include "rsys.h" @@ -40,31 +26,6 @@ #pragma GCC optimize("unroll-loops") #endif -STATIC_ASSERT - (REALX_DIMENSION__ > 1 && REALY_DIMENSION__ > 1, Unexpected_value); - -/* Define the epsilon for each real type */ -#define REAL_EPSILON_double 1.e-8 -#define REAL_EPSILON_float 1.e-6f -#define REAL_EPSILON__ CONCAT(REAL_EPSILON_, REAL_TYPE__) - -/* Define the suffix/prefix letter for each real type */ -#define REAL_LETTER_float f -#define REAL_LETTER_double d -#define REAL_LETTER__ CONCAT(REAL_LETTER_, REAL_TYPE__) - -#define REALXY_FUNC__(Func) \ - CONCAT(CONCAT(CONCAT(CONCAT \ - (REAL_LETTER__, REALX_DIMENSION__), REALY_DIMENSION__), _), Func) - -#define REALX_FUNC__(Func) \ - CONCAT(CONCAT(CONCAT(f, REALX_DIMENSION__), _), Func) -#define REALY_FUNC__(Func) \ - CONCAT(CONCAT(CONCAT(f, REALY_DIMENSION__), _), Func) - -/* Helper macro */ -#define SIZEOF_REALXY__ sizeof(REAL_TYPE__[REALX_DIMENSION__*REALY_DIMENSION__]) - static FINLINE REAL_TYPE__* REALXY_FUNC__(splat)(REAL_TYPE__* dst, const REAL_TYPE__ val) { @@ -331,19 +292,6 @@ REALXY_FUNC__(CONCAT(CONCAT(mulf, REALX_DIMENSION__), REALY_DIMENSION__)) } #endif /* REALX_DIMENSION__ == REALY_DIMENSION__ */ -#undef REAL_EPSILON__ -#undef REAL_EPSILON_float -#undef REAL_EPSILON_double -#undef REAL_LETTER__ -#undef REAL_LETTER_float -#undef REAL_LETTER_double -#undef REALX_FUNC__ -#undef REALY_FUNC__ -#undef REALXY_FUNC__ -#undef REALX_DIMENSION__ -#undef REALY_DIMENSION__ -#undef SIZEOF_REALXY__ - #ifdef COMPILER_GCC #pragma GCC pop_options #endif diff --git a/src/realXY_begin.h b/src/realXY_begin.h @@ -0,0 +1,51 @@ +/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) + * + * The RSys library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The RSys 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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ + +/* This file can be included once */ +#if defined(REALXY_BEGIN_H) + #error The realXY_begin.h header is already included +#endif +#define REALXY_BEGIN_H + + +/* Check that the expected arguments are defined */ +#if !defined(REALX_DIMENSION__) \ + || !defined(REALY_DIMENSION__) \ + || !defined(REAL_TYPE__) + #error Missing arguments +#endif + +#if defined(REALXY_FUNC__) \ + || defined(REALY_FUNC__) \ + || defined(SIZEOF_REALXY__) + #error Unexpected macro definition +#endif + +/* Define the function name generators */ +#define REALXY_FUNC__(Func) \ + CONCAT(CONCAT(CONCAT(CONCAT \ + (REAL_LETTER__, REALX_DIMENSION__), REALY_DIMENSION__), _), Func) +#define REALY_FUNC__(Func) \ + CONCAT(CONCAT(CONCAT(f, REALY_DIMENSION__), _), Func) + +#define SIZEOF_REALXY__ sizeof(REAL_TYPE__[REALX_DIMENSION__*REALY_DIMENSION__]) + +/* Check the validity of the dimensions */ +#include "rsys.h" +STATIC_ASSERT + (REALX_DIMENSION__ > 1 && REALY_DIMENSION__ > 1, Unexpected_value); + +#include "realX_begin.h" + diff --git a/src/realXY_end.h b/src/realXY_end.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2013-2016 Vincent Forest (vaplv@free.fr) + * + * The RSys library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The RSys 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 + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef REALXY_BEGIN_H + #error The realXY_begin.h header must be included +#endif + +#undef REALY_DIMENSION__ + +#undef REALY_FUNC__ +#undef REALXY_FUNC__ +#undef SIZEOF_REALXY__ + +#undef REALXY_BEGIN_H + +#include "realX_end.h" + diff --git a/src/realX_begin.h b/src/realX_begin.h @@ -13,15 +13,13 @@ * You should have received a copy of the GNU Lesser General Public License * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ -/* Check that the expected arguments are defined */ - /* This file can be included once */ #if defined(REALX_BEGIN_H) - #error The realX_begin.h header is already defined + #error The realX_begin.h header is already included #endif #define REALX_BEGIN_H -/* Check the the file arguments are defined */ +/* Check that the expected arguments are defined */ #if !defined(REALX_DIMENSION__) || !defined(REAL_TYPE__) #error Missing arguments #endif diff --git a/src/realX_end.h b/src/realX_end.h @@ -18,13 +18,14 @@ #endif #undef REAL_TYPE__ +#undef REALX_DIMENSION__ + #undef REAL_LETTER__ #undef REAL_LETTER_float #undef REAL_LETTER_double #undef REAL_EPSILON__ #undef REAL_EPSILON_float #undef REAL_EPSILON_double -#undef REALX_DIMENSION__ #undef REALX_FUNC__ #undef SIZEOF_REALX__