view dmvecmat.c @ 0:32250b436bca

Initial re-import.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 28 Sep 2012 01:54:23 +0300
parents
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));
}