matrix.c 3.74 KB

#include "graphic.h"
#include <stdio.h>

/*------------------------------------*/
projection_matrix( pr, ma)
struct Projection *pr;
struct Matrix *ma;
{
    int		i, j;

    ident( ma->m);
/* oldest (column major):
ma->m[0][0] = (pr->n * 2) / (pr->r - pr->l);
ma->m[1][1] = (pr->n * 2) / (pr->t - pr->b);
ma->m[2][0] = (pr->r + pr->l) / (pr->r - pr->l);
ma->m[2][1] = (pr->t + pr->b) / (pr->t - pr->b);
ma->m[2][2] = -(pr->f + pr->n) / (pr->f - pr->n);
ma->m[2][3] = -1;
ma->m[3][2] = -2*pr->f*pr->n/(pr->f - pr->n);
ma->m[3][3] = 0;
 */

/* OpenGL (with z-buffer scaling):
ma->m[0][0] = (pr->n * 2) / (pr->r - pr->l);
ma->m[1][1] = (pr->n * 2) / (pr->t - pr->b);
ma->m[0][2] = (pr->r + pr->l) / (pr->r - pr->l);
ma->m[1][2] = (pr->t + pr->b) / (pr->t - pr->b);
ma->m[2][2] = -(pr->f + pr->n) / (pr->f - pr->n);
ma->m[3][2] = -1;
ma->m[2][3] = -2*pr->f*pr->n/(pr->f - pr->n);
ma->m[3][3] = 0;
 */

/* foley-van dam, simplest: (no z-scaling)
    ma->m[0][0] = 1.0;
    ma->m[1][1] = (pr->r - pr->l) / (pr->t - pr->b);
    ma->m[2][2] = 1.0 / (1.0 + pr->n);
    ma->m[3][2] = -1.0;
    ma->m[2][3] = -pr->n / (1.0 + pr->n);
    ma->m[3][3] = 0.0;
 */

/* blinn, IEEE CG&A May 1993:
 * (with z-buffer scaling & assumes fixed fov of 90 degrees)
 */
    ma->m[0][0] = 1.0;
    ma->m[1][1] = (pr->r - pr->l) / (pr->t - pr->b);
    ma->m[2][2] = -0.5 / (1.0 - pr->n/pr->f);
    ma->m[3][2] = -(pr->n * ma->m[2][2] + 2.0);
    ma->m[2][3] = -0.5;
    ma->m[3][3] = 0.0;

/*
    fprintf(stdout,"projection matrix:\n\t");
    for (i=0; i<4; i++) {
	for (j=0; j<4; j++) {
	    fprintf(stdout,"%10f ",ma->m[i][j]);
	}
	fprintf(stdout,"\n\t");
    }
    fprintf(stdout,"\n");
*/
}
/*------------------------------------*/
image_space( xsize, ysize, zsize, is)
int xsize, ysize, zsize;
struct Image_space *is;
{
float a, b;
/* scale up X and Y for SU_XY_FRAC_SHFT bits of subpixel position */
	if (en_su_subpix) b = (float)SU_XY_FRAC_ONE;
		else b = (float)1;
	a = (float)(xsize) * (float)0.5 * b;
	is->sx = a;
	is->tx = a;
	a = (float)(ysize) * (float)0.5 * b;
	is->sy = a;
	is->ty = a;
	a = (float)zsize;
	is->sz = a;
	is->tz = 0;
}
/*------------------------------------*/
transform_matrix( tr, ma, it)
struct Transform *tr;
struct Matrix *ma;
struct Matrix *it;
{
float m[4][4];
float mit[4][4];	/* inverse transpose */
float t[4][4];
float ra, rs, rc;
int i, j;

	/* XXX assume uniform scaling to void doing a inverse transpose */
	ident( m);
	ident( mit);
	m[0][0] = tr->sx; m[1][1] = tr->sy; m[2][2] = tr->sz; 

	ident( t);
	ra = DEG2RAD( tr->rx);
	rc = cos( ra);
	rs = sin( ra);
	t[1][1] = rc;	t[1][2] = rs;
	t[2][1] = -rs;	t[2][2] = rc;
	concat( m, t, m);
	concat( mit, t, mit);

	ident( t);
	ra = DEG2RAD( tr->ry);
	rc = cos( ra);
	rs = sin( ra);
	t[0][0] = rc;	t[0][2] = -rs;
	t[2][0] = rs;	t[2][2] = rc;
	concat( m, t, m);
	concat( mit, t, mit);

	ident( t);
	ra = DEG2RAD( tr->rz);
	rc = cos( ra);
	rs = sin( ra);
	t[0][0] = rc;	t[0][1] = rs;
	t[1][0] = -rs;	t[1][1] = rc;
	concat( m, t, m);
	concat( mit, t, mit);

	m[3][0] = tr->tx; m[3][1] = tr->ty; m[3][2] = tr->tz; 
	for (i=0; i<4; i++)
	for (j=0; j<4; j++) {
		ma->m[i][j] = m[i][j];
		it->m[i][j] = mit[i][j];
	}
}
/*------------------------------------*/
concat_matrix( m, n, o)
struct Matrix *m, *n, *o;
{
concat( m->m, n->m, o->m);
}
/*------------------------------------*/
concat( m, n, o)
float m[4][4], n[4][4], o[4][4];
{
float t[4][4];	/* temp in case output is input */
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
	t[i][j] =	m[i][0] * n[0][j] +
			m[i][1] * n[1][j] +
			m[i][2] * n[2][j] +
			m[i][3] * n[3][j];
for (i=0; i<4; i++)
for (j=0; j<4; j++)
	o[i][j] = t[i][j];
}
/*------------------------------------*/
ident( m)
float m[4][4];
{
int i, j;
for (i=0; i<4; i++)
for (j=0; j<4; j++)
	m[i][j] = (float)0.0;
for (i=0; i<4; i++)
	m[i][i] = (float)1.0;
}