gem5/splash2/codes/apps/raytrace/matrix.C
Sanchayan Maity 0f4b39775c Fix splash2 benchmark
During the last commit of splash2 benchmark it seems before committing
when we ran "make clean", it effectively undid what the patch at below
link did
http://www.capsl.udel.edu/splash/Download.html

Fix this since without this it is not possible to build the arcane
splash2 benchmark.
2017-04-26 21:33:02 +05:30

457 lines
7.5 KiB
C

/*************************************************************************/
/* */
/* Copyright (c) 1994 Stanford University */
/* */
/* All rights reserved. */
/* */
/* Permission is given to use, copy, and modify this software for any */
/* non-commercial purpose as long as this copyright notice is not */
/* removed. All other uses, including redistribution in whole or in */
/* part, are forbidden without prior written permission. */
/* */
/* This software is provided with absolutely no warranty and no */
/* support. */
/* */
/*************************************************************************/
/*
* NAME
* matrix.c
*
* DESCRIPTION
* This file contains routines for matrix math, including common graphics
* related matrix operations, and also some vector operations.
*/
#include <stdio.h>
#include <math.h>
#include "rt.h"
typedef REAL GJMATRIX[4][8]; /* Matrix for Gauss-Jordan inversion.*/
/*
* NAME
* VecNorm - normalize vector to unity length
*
* SYNOPSIS
* VOID VecNorm(V)
* Point V; // Vector to normalize.
*
* RETURNS
* Nothing.
*/
VOID VecNorm(POINT V)
{
REAL l;
l = VecLen(V);
if (l > 0.0000001)
{
V[0] /= l;
V[1] /= l;
V[2] /= l;
}
}
/*
* NAME
* VecMatMult - multiply a vector by a matrix
*
* SYNOPSIS
* VOID VecMatMult(Vt, M, V)
* POINT Vt; // Transformed vector.
* MATRIX M; // Transformation matrix.
* POINT V; // Input vector.
*
* RETURNS
* Nothing.
*/
VOID VecMatMult(POINT Vt, MATRIX M, POINT V)
{
INT i, j;
POINT tvec;
/* tvec = M * V */
for (i = 0; i < 4; i++)
{
tvec[i] = 0.0;
for (j = 0; j < 4; j++)
tvec[i] += V[j] * M[j][i];
}
/* copy tvec to Vt */
for (i = 0; i < 4; i++)
Vt[i] = tvec[i];
}
/*
* NAME
* PrintMatrix - print values from matrix to stdout
*
* SYNOPSIS
* VOID PrintMatrix(M, s)
* MATRIX M; // Matrix to print.
* CHAR *s; // Title string.
*
* RETURNS
* Nothing.
*/
VOID PrintMatrix(MATRIX M, CHAR *s)
{
INT i, j;
printf("\n%s\n", s);
for (i = 0; i < 4; i++)
{
printf("\t");
for (j = 0; j < 4; j++)
printf("%f ", M[i][j]);
printf("\n");
}
}
/*
* NAME
* MatrixIdentity - set a matrix to the identity matrix
*
* SYNOPSIS
* VOID MatrixIdentity(M)
* MATRIX M;
*
* RETURNS
* Nothing.
*/
VOID MatrixIdentity(MATRIX M)
{
INT i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
M[i][j] = 0.0;
M[0][0] = 1.0;
M[1][1] = 1.0;
M[2][2] = 1.0;
M[3][3] = 1.0;
}
/*
* NAME
* MatrixCopy - copy one matrix to another
*
* SYNOPSIS
* VOID MatrixCopy(A, B)
* MATRIX A; // Destination matrix.
* MATRIX B; // Source matrix.
*
* RETURNS
* Nothing.
*/
VOID MatrixCopy(MATRIX A, MATRIX B)
{
INT i, j;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
A[i][j] = B[i][j];
}
/*
* NAME
* MatrixTranspose - transpose the elements of a matrix
*
* SYNOPSIS
* VOID MatrixTranspose(MT, M)
* MATRIX MT; // Transposed matrix.
* MATRIX M; // Original matrix.
*
* RETURNS
* Nothing.
*/
VOID MatrixTranspose(MATRIX MT, MATRIX M)
{
INT i, j;
MATRIX tmp;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tmp[j][i] = M[i][j];
MatrixCopy(MT, tmp);
}
/*
* NAME
* MatrixMult - multiply two matrices
*
* SYNOPSIS
* VOID MatrixMult(C, A, B)
* MATRIX C, A, B; // C = A*B
*
* RETURNS
* Nothing.
*/
VOID MatrixMult(MATRIX C, MATRIX A, MATRIX B)
{
INT i, j, k;
MATRIX T; /* Temporary matrix. */
/* T = A*B */
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
{
T[i][j] = 0.0;
for (k = 0; k < 4; k++)
T[i][j] += A[i][k] * B[k][j];
}
/* copy T to C */
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
C[i][j] = T[i][j];
}
/*
* NAME
* MatrixInverse - invert matrix using Gaussian elimination with partial pivoting
*
* SYNOPSIS
* VOID MatrixInverse(Minv, Mat)
* MATRIX Minv; // Inverted matrix.
* MATRIX Mat; // Original matrix.
*
* RETURNS
* Nothing.
*/
VOID MatrixInverse(MATRIX Minv, MATRIX Mat)
{
INT i, j, k; /* Indices. */
GJMATRIX gjmat; /* Inverse calculator. */
REAL tbuf[8]; /* Row holder. */
REAL pval, aval; /* Pivot candidates. */
INT prow; /* Pivot row number. */
REAL c; /* Pivot scale factor. */
MATRIX tmp;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
gjmat[i][j] = Mat[i][j];
k = 0;
for (i = 4; i < 8; i++)
{
for (j = 4; j < 8; j++)
if (i == j)
gjmat[k][j] = 1.0;
else
gjmat[k][j] = 0.0;
k++ ;
}
/* Gaussian elimination. */
for (i = 0; i < 3; i++)
{
pval = ABS(gjmat[i][i]);
prow = i;
for (j = i + 1; j < 4; j++)
{
aval = ABS(gjmat[j][i]);
if (aval > pval)
{
pval = aval;
prow = j;
}
}
if (i != prow)
{
for (k = 0; k < 8; k++)
tbuf[k] = gjmat[i][k];
for (k = 0; k < 8; k++)
gjmat[i][k] = gjmat[prow][k];
for (k = 0; k < 8; k++)
gjmat[prow][k] = tbuf[k];
}
for (j = i + 1; j < 4; j++)
{
c = gjmat[j][i] / gjmat[i][i];
gjmat[j][i] = 0.0;
for (k = i + 1; k < 8; k++)
gjmat[j][k] = gjmat[j][k] - c * gjmat[i][k];
}
}
/* Zero columns */
for (i = 0; i < 3; i++)
for (j = i + 1; j < 4; j++)
{
c = gjmat[i][j] / gjmat[j][j];
gjmat[i][j] = 0.0;
for (k = j + 1; k < 8; k++)
gjmat[i][k] = gjmat[i][k] - c * gjmat[j][k];
}
for (i = 0; i < 4; i++)
for (k = 4; k < 8; k++) /* normalize row */
gjmat[i][k] /= gjmat[i][i];
/* Generate inverse matrix. */
for (i = 0; i < 4; i++)
for (j = 4; j < 8; j++)
Minv[i][j - 4] = gjmat[i][j];
MatrixMult(tmp, Mat, Minv);
}
/*
* NAME
* Translate - build translation matrix
*
* SYNOPSIS
* VOID Translate(M, dx, dy, dz)
* MATRIX M; // New matrix.
* REAL dx, dy, dz; // Translation values.
*
* RETURNS
* Nothing.
*/
VOID Translate(MATRIX M, REAL dx, REAL dy, REAL dz)
{
MatrixIdentity(M);
M[3][0] = dx;
M[3][1] = dy;
M[3][2] = dz;
}
/*
* NAME
* Scale - build scaling matrix
*
* SYNOPSIS
* VOID Scale(M, sx, sy, sz)
* MATRIX M; // New matrix.
* REAL sx, sy, sz; // Scaling factors.
*
* RETURNS
* Nothing.
*/
VOID Scale(MATRIX M, REAL sx, REAL sy, REAL sz)
{
MatrixIdentity(M);
M[0][0] = sx;
M[1][1] = sy;
M[2][2] = sz;
}
/*
* NAME
* Rotate - build rotation matrix
*
* SYNOPSIS
* VOID Rotate(axis, M, angle)
* INT axis; // Axis of rotation.
* MATRIX M; // New matrix.
* REAL angle; // Angle of rotation.
*
* RETURNS
* Nothing.
*/
VOID Rotate(INT axis, MATRIX M, REAL angle)
{
REAL cosangle;
REAL sinangle;
MatrixIdentity(M);
cosangle = cos(angle);
sinangle = sin(angle);
switch (axis)
{
case X_AXIS:
M[1][1] = cosangle;
M[1][2] = sinangle;
M[2][1] = -sinangle;
M[2][2] = cosangle;
break;
case Y_AXIS:
M[0][0] = cosangle;
M[0][2] = -sinangle;
M[2][0] = sinangle;
M[2][2] = cosangle;
break;
case Z_AXIS:
M[0][0] = cosangle;
M[0][1] = sinangle;
M[1][0] = -sinangle;
M[1][1] = cosangle;
break;
default:
printf("Unknown rotation axis %ld.\n", axis);
exit(5);
break;
}
}