e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <math.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <stdio.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_matrix.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifndef M_PI
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define M_PI 3.14159265358979323846
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic const CRmatrix identity_matrix = {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 1.0, 0.0, 0.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 1.0, 0.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 0.0, 1.0, 0.0,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync 0.0, 0.0, 0.0, 1.0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync};
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Initialize the given matrix to the identity.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixInit(CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *m = identity_matrix;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Parse a string of 16 floats to initialize a matrix (row major order).
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * If there's a parsing error, initialize the matrix to the identity.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixInitFromString(CRmatrix *m, const char *s)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *fmt = "%f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const char *fmtb = "[ %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f, %f ]";
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int n = sscanf(s, (s[0] == '[' ? fmtb : fmt),
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &m->m00, &m->m01, &m->m02, &m->m03,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &m->m10, &m->m11, &m->m12, &m->m13,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &m->m20, &m->m21, &m->m22, &m->m23,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync &m->m30, &m->m31, &m->m32, &m->m33);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (n != 16) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* insufficient parameters */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixInit(m);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Initialize a matrix from an array of 16 values.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixInitFromFloats(CRmatrix *m, const float *v)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m00 = v[0];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m01 = v[1];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m02 = v[2];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m03 = v[3];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m10 = v[4];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m11 = v[5];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m12 = v[6];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m13 = v[7];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m20 = v[8];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m21 = v[9];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m22 = v[10];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m23 = v[11];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m30 = v[12];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m31 = v[13];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m32 = v[14];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m33 = v[15];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixInitFromDoubles(CRmatrix *m, const double *v)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m00 = (float) v[0];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m01 = (float) v[1];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m02 = (float) v[2];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m03 = (float) v[3];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m10 = (float) v[4];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m11 = (float) v[5];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m12 = (float) v[6];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m13 = (float) v[7];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m20 = (float) v[8];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m21 = (float) v[9];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m22 = (float) v[10];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m23 = (float) v[11];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m30 = (float) v[12];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m31 = (float) v[13];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m32 = (float) v[14];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m33 = (float) v[15];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* useful for debugging */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixPrint(const char *msg, const CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync printf("%s\n", msg);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync printf(" %f %f %f %f\n", m->m00, m->m10, m->m20, m->m30);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync printf(" %f %f %f %f\n", m->m01, m->m11, m->m21, m->m31);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync printf(" %f %f %f %f\n", m->m02, m->m12, m->m22, m->m32);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync printf(" %f %f %f %f\n", m->m03, m->m13, m->m23, m->m33);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixGetFloats(float *values, const CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[0] = m->m00;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[1] = m->m01;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[2] = m->m02;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[3] = m->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[4] = m->m10;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[5] = m->m11;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[6] = m->m12;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[7] = m->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[8] = m->m20;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[9] = m->m21;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[10] = m->m22;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[11] = m->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[12] = m->m30;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[13] = m->m31;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[14] = m->m32;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync values[15] = m->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Return 1 if the matrices are equal, return 0 otherwise.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixIsEqual(const CRmatrix *m, const CRmatrix *n)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return crMemcmp(m, n, sizeof(CRmatrix)) == 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Test if matrix is identity
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixIsIdentity(const CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return crMemcmp(m, &identity_matrix, sizeof(CRmatrix)) == 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Test if matrix is orthographic projection matrix.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixIsOrthographic(const CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return m->m33 != 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixCopy(CRmatrix *dest, const CRmatrix *src)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMemcpy(dest, src, sizeof(CRmatrix));
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Compute p = a * b
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixMultiply(CRmatrix *p, const CRmatrix *a, const CRmatrix *b)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmatrix t; /* temporary result, in case p = a or p = b */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m00 = a->m00 * b->m00 + a->m10 * b->m01 + a->m20 * b->m02 + a->m30 * b->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m01 = a->m01 * b->m00 + a->m11 * b->m01 + a->m21 * b->m02 + a->m31 * b->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m02 = a->m02 * b->m00 + a->m12 * b->m01 + a->m22 * b->m02 + a->m32 * b->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m03 = a->m03 * b->m00 + a->m13 * b->m01 + a->m23 * b->m02 + a->m33 * b->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m10 = a->m00 * b->m10 + a->m10 * b->m11 + a->m20 * b->m12 + a->m30 * b->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m11 = a->m01 * b->m10 + a->m11 * b->m11 + a->m21 * b->m12 + a->m31 * b->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m12 = a->m02 * b->m10 + a->m12 * b->m11 + a->m22 * b->m12 + a->m32 * b->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m13 = a->m03 * b->m10 + a->m13 * b->m11 + a->m23 * b->m12 + a->m33 * b->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m20 = a->m00 * b->m20 + a->m10 * b->m21 + a->m20 * b->m22 + a->m30 * b->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m21 = a->m01 * b->m20 + a->m11 * b->m21 + a->m21 * b->m22 + a->m31 * b->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m22 = a->m02 * b->m20 + a->m12 * b->m21 + a->m22 * b->m22 + a->m32 * b->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m23 = a->m03 * b->m20 + a->m13 * b->m21 + a->m23 * b->m22 + a->m33 * b->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m30 = a->m00 * b->m30 + a->m10 * b->m31 + a->m20 * b->m32 + a->m30 * b->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m31 = a->m01 * b->m30 + a->m11 * b->m31 + a->m21 * b->m32 + a->m31 * b->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m32 = a->m02 * b->m30 + a->m12 * b->m31 + a->m22 * b->m32 + a->m32 * b->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync t.m33 = a->m03 * b->m30 + a->m13 * b->m31 + a->m23 * b->m32 + a->m33 * b->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *p = t;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixTransformPointf(const CRmatrix *m, GLvectorf *p)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float x = p->x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float y = p->y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float z = p->z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float w = p->w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->x = m->m00*x + m->m10*y + m->m20*z + m->m30*w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->y = m->m01*x + m->m11*y + m->m21*z + m->m31*w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->z = m->m02*x + m->m12*y + m->m22*z + m->m32*w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->w = m->m03*x + m->m13*y + m->m23*z + m->m33*w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixTransformPointd(const CRmatrix *m, GLvectord *p)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync double x = p->x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync double y = p->y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync double z = p->z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync double w = p->w;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->x = (double) (m->m00*x + m->m10*y + m->m20*z + m->m30*w);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->y = (double) (m->m01*x + m->m11*y + m->m21*z + m->m31*w);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->z = (double) (m->m02*x + m->m12*y + m->m22*z + m->m32*w);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync p->w = (double) (m->m03*x + m->m13*y + m->m23*z + m->m33*w);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixInvertTranspose(CRmatrix *inv, const CRmatrix *mat)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Taken from Pomegranate code, trans.c.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Note: We have our data structures reversed
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m00 = mat->m00;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m01 = mat->m10;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m02 = mat->m20;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m03 = mat->m30;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m10 = mat->m01;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m11 = mat->m11;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m12 = mat->m21;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m13 = mat->m31;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m20 = mat->m02;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m21 = mat->m12;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m22 = mat->m22;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m23 = mat->m32;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m30 = mat->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m31 = mat->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m32 = mat->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float m33 = mat->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3) \
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (a1 * (b2 * c3 - b3 * c2) + \
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync b1 * (c2 * a3 - a2 * c3) + \
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync c1 * (a2 * b3 - a3 * b2))
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof00 = det3x3( m11, m12, m13,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m21, m22, m23,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m31, m32, m33 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof01 = -det3x3( m12, m13, m10,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m22, m23, m20,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m32, m33, m30 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof02 = det3x3( m13, m10, m11,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m23, m20, m21,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m33, m30, m31 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof03 = -det3x3( m10, m11, m12,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m20, m21, m22,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m30, m31, m32 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float inv_det = 1.0f / ( m00 * cof00 + m01 * cof01 +
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m02 * cof02 + m03 * cof03 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof10 = -det3x3( m21, m22, m23,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m31, m32, m33,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m01, m02, m03 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof11 = det3x3( m22, m23, m20,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m32, m33, m30,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m02, m03, m00 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof12 = -det3x3( m23, m20, m21,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m33, m30, m31,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m03, m00, m01 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof13 = det3x3( m20, m21, m22,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m30, m31, m32,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m00, m01, m02 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof20 = det3x3( m31, m32, m33,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m01, m02, m03,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m11, m12, m13 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof21 = -det3x3( m32, m33, m30,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m02, m03, m00,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m12, m13, m10 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof22 = det3x3( m33, m30, m31,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m03, m00, m01,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m13, m10, m11 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof23 = -det3x3( m30, m31, m32,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m00, m01, m02,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m10, m11, m12 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof30 = -det3x3( m01, m02, m03,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m11, m12, m13,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m21, m22, m23 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof31 = det3x3( m02, m03, m00,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m12, m13, m10,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m22, m23, m20 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof32 = -det3x3( m03, m00, m01,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m13, m10, m11,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m23, m20, m21 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float cof33 = det3x3( m00, m01, m02,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m10, m11, m12,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m20, m21, m22 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#undef det3x3
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Perform transpose in asignment */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m00 = cof00 * inv_det; inv->m10 = cof01 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m20 = cof02 * inv_det; inv->m30 = cof03 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m01 = cof10 * inv_det; inv->m11 = cof11 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m21 = cof12 * inv_det; inv->m31 = cof13 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m02 = cof20 * inv_det; inv->m12 = cof21 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m22 = cof22 * inv_det; inv->m32 = cof23 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m03 = cof30 * inv_det; inv->m13 = cof31 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync inv->m23 = cof32 * inv_det; inv->m33 = cof33 * inv_det;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixTranspose(CRmatrix *t, const CRmatrix *m)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmatrix c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync c.m00 = m->m00; c.m10 = m->m01; c.m20 = m->m02; c.m30 = m->m03;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync c.m01 = m->m10; c.m11 = m->m11; c.m21 = m->m12; c.m31 = m->m13;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync c.m02 = m->m20; c.m12 = m->m21; c.m22 = m->m22; c.m32 = m->m23;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync c.m03 = m->m30; c.m13 = m->m31; c.m23 = m->m32; c.m33 = m->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *t = c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Apply a translation to the given matrix.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixTranslate(CRmatrix *m, float x, float y, float z)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m30 = m->m00 * x + m->m10 * y + m->m20 * z + m->m30;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m31 = m->m01 * x + m->m11 * y + m->m21 * z + m->m31;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m32 = m->m02 * x + m->m12 * y + m->m22 * z + m->m32;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m33 = m->m03 * x + m->m13 * y + m->m23 * z + m->m33;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Apply a rotation to the given matrix.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixRotate(CRmatrix *m, float angle, float x, float y, float z)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float c = (float) cos(angle * M_PI / 180.0f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float one_minus_c = 1.0f - c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float s = (float) sin(angle * M_PI / 180.0f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync const float v_len = (float) sqrt (x*x + y*y + z*z);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float x_one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float y_one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float z_one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmatrix rot;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Begin/end Checking and flushing will be done by MultMatrix. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (v_len == 0.0f)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Normalize the vector */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (v_len != 1.0f) {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync x /= v_len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync y /= v_len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync z /= v_len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* compute some common values */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync x_one_minus_c = x * one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync y_one_minus_c = y * one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync z_one_minus_c = z * one_minus_c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* Generate the terms of the rotation matrix
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ** from pg 325 OGL 1.1 Blue Book.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m00 = x * x_one_minus_c + c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m01 = x * y_one_minus_c + z * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m02 = x * z_one_minus_c - y * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m03 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m10 = y * x_one_minus_c - z * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m11 = y * y_one_minus_c + c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m12 = y * z_one_minus_c + x * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m13 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m20 = z * x_one_minus_c + y * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m21 = z * y_one_minus_c - x * s;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m22 = z * z_one_minus_c + c;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m23 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m30 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m31 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m32 = 0.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync rot.m33 = 1.0f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixMultiply(m, m, &rot);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Apply a scale to the given matrix.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixScale(CRmatrix *m, float x, float y, float z)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m00 *= x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m01 *= x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m02 *= x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m03 *= x;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m10 *= y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m11 *= y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m12 *= y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m13 *= y;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m20 *= z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m21 *= z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m22 *= z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync m->m23 *= z;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/*
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * Make a projection matrix from frustum parameters.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixFrustum(CRmatrix *m,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float left, float right,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float bottom, float top,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float zNear, float zFar)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmatrix f;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m00 = (2.0f * zNear) / (right - left);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m01 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m02 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m03 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m10 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m11 = (2.0f * zNear) / (top - bottom);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m12 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m13 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m20 = (right + left) / (right - left);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m21 = (top + bottom) / (top - bottom);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m22 = (-zNear - zFar) / (zFar - zNear);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m23 = -1.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m30 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m31 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m32 = (2.0f * zFar * zNear) / (zNear - zFar);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync f.m33 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixMultiply(m, m, &f);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrMatrixOrtho(CRmatrix *m,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float left, float right,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float bottom, float top,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync float znear, float zfar)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmatrix ortho;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m00 = 2.0f / (right - left);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m01 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m02 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m03 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m10 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m11 = 2.0f / (top - bottom);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m12 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m13 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m20 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m21 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m22 = -2.0f / (zfar - znear);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m23 = 0.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m30 = -(right + left) / (right - left);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m31 = -(top + bottom) / (top - bottom);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m32= -(zfar + znear) / (zfar - znear);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync ortho.m33 = 1.0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMatrixMultiply(m, m, &ortho);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync