view dmvecmat.c @ 96:6bf5220fa47e

Urgh .. use memset to silence some bogus GCC warnings about using potentially uninitialized values, while that will not actually be possible. In any case, it is annoying.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 02 Oct 2012 18:52:28 +0300
parents 32250b436bca
children 07c4f1a7ddc6
line wrap: on
line source

/*
 * DMLib
 * -- Vector and matrix functions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (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.
 */
void dm_vector_mul_by_mat_n(DMVector *list, const int nlist, const DMMatrix *mat)
{
    int i;

    for (i = 0; i < nlist; i++)
    {
        DMVector q;
        memcpy(&q, &list[i], sizeof(DMVector));

        list[i].x = (q.x * mat->m[0][0]) + (q.y * mat->m[1][0]) + (q.z * mat->m[2][0]);
        list[i].y = (q.x * mat->m[0][1]) + (q.y * mat->m[1][1]) + (q.z * mat->m[2][1]);
        list[i].z = (q.x * mat->m[0][2]) + (q.y * mat->m[1][2]) + (q.z * mat->m[2][2]);
    }
}


/* Set matrix to unit-matrix
 */
void dm_matrix_unit(DMMatrix *mat)
{
    memset(mat, 0, sizeof(DMMatrix));
    mat->m[0][0] = 1.0f;
    mat->m[1][1] = 1.0f;
    mat->m[2][2] = 1.0f;
}


/* Transpose the matrix mat2 to mat1
 */
void dm_matrix_transpose(DMMatrix *mat1, const DMMatrix *mat2)
{
    int i, j;

    for (i = 0; i < DM_MATRIX_SIZE; i++)
        for (j = 0; j < DM_MATRIX_SIZE; j++)
            mat1->m[i][j] = mat2->m[j][i];
}


/* Multiply matrices mat1 and mat2, putting result into mat1
 */
void dm_matrix_mul(DMMatrix *mat1, const DMMatrix *mat2)
{
    int i, j;
    DMMatrix tmpM;

    for (i = 0; i < DM_MATRIX_SIZE; i++)
        for (j = 0; j < DM_MATRIX_SIZE; j++)
            tmpM.m[i][j] =
                (mat1->m[i][0] * mat2->m[0][j]) +
                (mat1->m[i][1] * mat2->m[1][j]) +
                (mat1->m[i][2] * mat2->m[2][j]);

    memcpy(mat1, &tmpM, sizeof(DMMatrix));
}


/* Multiply given list of matrices (size of nMatrices units) with given matrix.
 */
void dm_matrix_mul_n(DMMatrix * list, const int nlist, const DMMatrix *mat)
{
    int i;
    for (i = 0; i < nlist; i++)
        dm_matrix_mul(&list[i], mat);
}


/* Optimized rotation matrix creation
 */
void dm_matrix_rot(DMMatrix *mat,
    const DMFloat sx, const DMFloat sy, const DMFloat sz,
    const DMFloat cx, const DMFloat cy, const DMFloat cz)
{
    const DMFloat
        q = cx * sz,
        l = cx * cz,
        i = sx * sz,
        j = sx * cz;

    mat->m[0][0] = cy * cz;
    mat->m[0][1] = cy * sz;
    mat->m[0][2] = -sy;


    mat->m[1][0] = (sy * j) - q;
    mat->m[1][1] = (sy * i) + l;
    mat->m[1][2] = sx * cy;


    mat->m[2][0] = (sy * l) + i;
    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));
}