Mercurial > hg > dmlib
changeset 239:07c4f1a7ddc6
Make DMVector 16 bytes in size (4 floats), add SSE optimizations, move some
functions to dmvecmat.h as static inline for speed, etc.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 09 Oct 2012 12:59:09 +0300 |
parents | 9643c517967d |
children | 61b9cd67cd55 |
files | dmvecmat.c dmvecmat.h vecmattest.c |
diffstat | 3 files changed, 154 insertions(+), 133 deletions(-) [+] |
line wrap: on
line diff
--- a/dmvecmat.c Tue Oct 09 06:06:08 2012 +0300 +++ b/dmvecmat.c Tue Oct 09 12:59:09 2012 +0300 @@ -5,109 +5,6 @@ * (C) Copyright 2011 Tecnic Software productions (TNSP) */ #include "dmvecmat.h" -#include <math.h> - - -void dm_vector_copy(DMVector *vd, DMVector *vs) -{ - memcpy(vd, vs, sizeof(DMVector)); -} - - -/* Basic vector operations - */ -void dm_vector_add(DMVector *vr, const DMVector *v2) -{ - vr->x += v2->x; - vr->y += v2->y; - vr->z += v2->z; -} - - -void dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2) -{ - vr->x = v1->x + v2->x; - vr->y = v1->y + v2->y; - vr->z = v1->z + v2->z; -} - - -void dm_vector_sub(DMVector *vr, const DMVector *v2) -{ - vr->x -= v2->x; - vr->y -= v2->y; - vr->z -= v2->z; -} - - -void dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2) -{ - vr->x = v1->x - v2->x; - vr->y = v1->y - v2->y; - vr->z = v1->z - v2->z; -} - - -/* Return vector length - */ -DMFloat dm_vector_length(const DMVector *vs) -{ - return sqrt((vs->x * vs->x) + (vs->y * vs->y) + (vs->z * vs->z)); -} - - -/* Normalize vector - */ -void dm_vector_normalize(DMVector *vec) -{ - DMFloat l = dm_vector_length(vec); - - if (l > 0.0f) - { - l = 1.0f / l; - vec->x *= l; - vec->y *= l; - vec->z *= l; - } -} - - -/* Scale given vector - */ -void dm_vector_scale(DMVector * vec, const DMFloat k) -{ - vec->x *= k; - vec->y *= k; - vec->z *= k; -} - - -/* Returns dot-product of two given vectors - */ -DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2) -{ - return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); -} - - -/* Returns cross-product of two given vectors - */ -void dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2) -{ - vr->x = (v1->y * v2->z) - (v1->z * v2->y); - vr->y = (v1->z * v2->x) - (v1->x * v2->z); - vr->z = (v1->x * v2->y) - (v1->y * v2->x); -} - - -/* Multiply given vector with a matrix - */ -void dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat) -{ - vd->x = (vs->x * mat->m[0][0]) + (vs->y * mat->m[1][0]) + (vs->z * mat->m[2][0]); - vd->y = (vs->x * mat->m[0][1]) + (vs->y * mat->m[1][1]) + (vs->z * mat->m[2][1]); - vd->z = (vs->x * mat->m[0][2]) + (vs->y * mat->m[1][2]) + (vs->z * mat->m[2][2]); -} /* Multiply list of given vectors with given matrix. @@ -205,13 +102,3 @@ mat->m[2][1] = (sy * q) - j; mat->m[2][2] = cx * cy; } - - -/* Make rotation matrix from given angles (radians) - */ -void dm_matrix_rot_a(DMMatrix *mat, const DMFloat ax, const DMFloat ay, const DMFloat az) -{ - dm_matrix_rot(mat, sin(ax), sin(ay), sin(az), cos(ax), cos(ay), cos(az)); -} - -
--- a/dmvecmat.h Tue Oct 09 06:06:08 2012 +0300 +++ b/dmvecmat.h Tue Oct 09 12:59:09 2012 +0300 @@ -8,15 +8,17 @@ #define DMVECMAT_H #include "dmlib.h" +#include <math.h> + #ifdef __cplusplus extern "C" { #endif -#define DM_MATRIX_SIZE (3) +#define DM_MATRIX_SIZE (4) typedef struct { - DMFloat x, y, z; + DMFloat x, y, z, W; } DMVector; typedef struct @@ -24,21 +26,6 @@ DMFloat m[DM_MATRIX_SIZE][DM_MATRIX_SIZE]; } DMMatrix; -void dm_vector_copy(DMVector *vd, DMVector *vs); - -void dm_vector_add(DMVector *vr, const DMVector *v2); -void dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2); -void dm_vector_sub(DMVector *vr, const DMVector *v2); -void dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2); - -DMFloat dm_vector_length(const DMVector *vs); -void dm_vector_normalize(DMVector *vs); -void dm_vector_scale(DMVector * vec, const DMFloat k); -DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2); -void dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2); - - -void dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat); void dm_vector_mul_by_mat_n(DMVector *list, const int nlist, const DMMatrix *mat); void dm_matrix_unit(DMMatrix *mat); @@ -51,8 +38,155 @@ const DMFloat sx, const DMFloat sy, const DMFloat sz, const DMFloat cx, const DMFloat cy, const DMFloat cz); -void dm_matrix_rot_a(DMMatrix *mat, - const DMFloat ax, const DMFloat ay, const DMFloat az); + +static inline void dm_vector_copy(DMVector *vd, DMVector *vs) +{ + memcpy(vd, vs, sizeof(DMVector)); +} + + +/* Basic vector operations + */ +static inline void dm_vector_add(DMVector *vr, const DMVector *v2) +{ +#ifdef DM_USE_SIMD + asm("movups %2, %%xmm1\n" + "movups %1, %%xmm2\n" + "addps %%xmm2, %%xmm1\n" + "movups %%xmm1, %0\n" + : "=m" (*vr) + : "m" (*vr), "m" (*v2) + : "memory", "%xmm1", "%xmm2"); +#else + vr->x += v2->x; + vr->y += v2->y; + vr->z += v2->z; +#endif +} + + +static inline void dm_vector_add_r(DMVector *vr, const DMVector *v1, const DMVector *v2) +{ +#ifdef DM_USE_SIMD + asm("movups %2, %%xmm1\n" + "movups %1, %%xmm2\n" + "addps %%xmm2, %%xmm1\n" + "movups %%xmm1, %0\n" + : "=m" (*vr) + : "m" (*v1), "m" (*v2) + : "memory", "%xmm1", "%xmm2"); +#else + vr->x = v1->x + v2->x; + vr->y = v1->y + v2->y; + vr->z = v1->z + v2->z; +#endif +} + + +static inline void dm_vector_sub(DMVector *vr, const DMVector *v2) +{ +#ifdef DM_USE_SIMD + asm("movups %2, %%xmm1\n" + "movups %1, %%xmm2\n" + "subps %%xmm2, %%xmm1\n" + "movups %%xmm1, %0\n" + : "=m" (*vr) + : "m" (*vr), "m" (*v2) + : "memory", "%xmm1", "%xmm2"); +#else + vr->x -= v2->x; + vr->y -= v2->y; + vr->z -= v2->z; +#endif +} + + +static inline void dm_vector_sub_r(DMVector *vr, const DMVector *v1, const DMVector *v2) +{ +#ifdef DM_USE_SIMD + asm("movups %2, %%xmm1\n" + "movups %1, %%xmm2\n" + "subps %%xmm2, %%xmm1\n" + "movups %%xmm1, %0\n" + : "=m" (*vr) + : "m" (*v1), "m" (*v2) + : "memory", "%xmm1", "%xmm2"); +#else + vr->x = v1->x - v2->x; + vr->y = v1->y - v2->y; + vr->z = v1->z - v2->z; +#endif +} + + +/* Returns dot-product of two given vectors + */ +static inline DMFloat dm_vector_dot(const DMVector *v1, const DMVector *v2) +{ + return (v1->x * v2->x) + (v1->y * v2->y) + (v1->z * v2->z); +} + + +/* Return vector length + */ +static inline DMFloat dm_vector_length(const DMVector *vs) +{ + return sqrt((vs->x * vs->x) + (vs->y * vs->y) + (vs->z * vs->z)); +} + + +/* Normalize vector + */ +static inline void dm_vector_normalize(DMVector *vec) +{ + DMFloat l = dm_vector_length(vec); + + if (l > 0.0f) + { + l = 1.0f / l; + vec->x *= l; + vec->y *= l; + vec->z *= l; + } +} + + +/* Scale given vector + */ +static inline void dm_vector_scale(DMVector * vec, const DMFloat k) +{ + vec->x *= k; + vec->y *= k; + vec->z *= k; +} + + +/* Returns cross-product of two given vectors + */ +static inline void dm_vector_cross(DMVector *vr, const DMVector *v1, const DMVector *v2) +{ + vr->x = (v1->y * v2->z) - (v1->z * v2->y); + vr->y = (v1->z * v2->x) - (v1->x * v2->z); + vr->z = (v1->x * v2->y) - (v1->y * v2->x); +} + + +/* Multiply given vector with a matrix + */ +static inline void dm_vector_mul_by_mat(DMVector *vd, const DMVector *vs, const DMMatrix *mat) +{ + vd->x = (vs->x * mat->m[0][0]) + (vs->y * mat->m[1][0]) + (vs->z * mat->m[2][0]); + vd->y = (vs->x * mat->m[0][1]) + (vs->y * mat->m[1][1]) + (vs->z * mat->m[2][1]); + vd->z = (vs->x * mat->m[0][2]) + (vs->y * mat->m[1][2]) + (vs->z * mat->m[2][2]); +} + + +/* Make rotation matrix from given angles (radians) + */ +static inline void dm_matrix_rot_a(DMMatrix *mat, const DMFloat ax, const DMFloat ay, const DMFloat az) +{ + dm_matrix_rot(mat, sin(ax), sin(ay), sin(az), cos(ax), cos(ay), cos(az)); +} #ifdef __cplusplus