Sanchayan Maity
0f4b39775c
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.
408 lines
13 KiB
C
408 lines
13 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. */
|
|
/* */
|
|
/*************************************************************************/
|
|
|
|
/******************************************************************************
|
|
* *
|
|
* view.c: Compute viewing direction. *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
#include "incl.h"
|
|
|
|
#define XAXIS 1 /* Positive X-axis points rightwards */
|
|
#define YAXIS 2 /* Positive Y-axis points upwards */
|
|
#define ZAXIS 3 /* Positive Z-axis points into screen */
|
|
|
|
float transformation_matrix[4][4];/* current transformation matrix of floats */
|
|
float out_invvertex[2][2][2][NM]; /* Image and object space centers */
|
|
/* of outer voxels in output map */
|
|
float uout_invvertex[2][2][2][NM];/* Image and object space vertices */
|
|
/* of output map unit voxel */
|
|
|
|
long frust_len; /* Size of clipping frustum */
|
|
/* (mins will be 0 in this program, */
|
|
/* {x,y}len will be <= IK{X,Y}SIZE) */
|
|
float out_diag_len[NM]; /* Per-axis lengths and combined length of */
|
|
float out_diag_length; /* diagonal of input map in image space */
|
|
float depth_cueing[MAX_OUTLEN]; /* Pre-computed table of depth cueing */
|
|
long image_zlen; /* number of samples along viewing ray */
|
|
float in_max[NM]; /* Pre-computed clipping aids */
|
|
long opc_xlen,opc_xylen;
|
|
long norm_xlen,norm_xylen;
|
|
|
|
float invmatrix[4][4]; /* Inverse of viewing matrix: */
|
|
/* 4 x 4 viewing transformation matrix */
|
|
/* (orthographic projection used, so */
|
|
/* matrix[][3] = 0, matrix[3][3] = 1) */
|
|
|
|
EXTERN_ENV
|
|
|
|
void Compute_Pre_View()
|
|
{
|
|
long i, outz;
|
|
|
|
for (i=0; i<NM; i++)
|
|
out_diag_len[i] = opc_len[i]-1;
|
|
out_diag_length = out_diag_len[X]*out_diag_len[X] +
|
|
out_diag_len[Y]*out_diag_len[Y] +
|
|
out_diag_len[Z]*out_diag_len[Z];
|
|
out_diag_length = sqrt(out_diag_length);
|
|
frust_len = NINT(out_diag_length)+1;
|
|
image_zlen = frust_len - 1;
|
|
|
|
/* Pre-compute table of depth cueing attenuation fractions as */
|
|
/* exponential falloff from intensity of depth_hither*full at */
|
|
/* hither (outz=0) to depth_yon*full at yon (frust_len-1). */
|
|
/* Exponent > 1.0 falls off slower than linear, < 1.0 falls faster. */
|
|
/* Clip fractions to valid range to allow agressive user */
|
|
/* to set hither or yon outside the range 0.0..1.0. */
|
|
if (image_zlen > MAX_OUTLEN)
|
|
Error ("MAX_OUTLEN exceeded in Ray_Trace.\n");
|
|
for (outz=0; outz<=image_zlen; outz++) {
|
|
depth_cueing[outz] = depth_hither -
|
|
pow((float)(outz)/(float)image_zlen,depth_exponent) *
|
|
(depth_hither - depth_yon);
|
|
depth_cueing[outz] = MIN(MAX(depth_cueing[outz],0.0),1.0);
|
|
}
|
|
|
|
/* Pre-compute clipping aids */
|
|
in_max[X] = (float)(opc_len[X]-1)-SMALL-1.0/(float)MAX_PIXEL;
|
|
in_max[Y] = (float)(opc_len[Y]-1)-SMALL-1.0/(float)MAX_PIXEL;
|
|
in_max[Z] = (float)(opc_len[Z]-1)-SMALL-1.0/(float)MAX_PIXEL;
|
|
|
|
/* Pre-compute subscripting aids */
|
|
opc_xlen = opc_len[X] + 1;
|
|
opc_xylen = opc_len[X] * opc_len[Y] + 1;
|
|
|
|
norm_xlen = norm_len[X] + 1;
|
|
norm_xylen = norm_len[X] * norm_len[Y] + 1;
|
|
}
|
|
|
|
|
|
void Select_View(delta_angle, axis)
|
|
float delta_angle;
|
|
long axis;
|
|
|
|
{
|
|
Load_Identity_Matrix(invmatrix);
|
|
|
|
/* Moves input map from all-positive octant to center of */
|
|
/* coordinate system so subsequent rotations spin object */
|
|
/* in place. Must be first after initialization to work. */
|
|
Inverse_Concatenate_Translation(invmatrix,
|
|
(float)(out_diag_len[X])/2.0,
|
|
(float)(out_diag_len[Y])/2.0,
|
|
(float)(out_diag_len[Z])/2.0);
|
|
|
|
/* scale dataset size in Z-direction for 256x256x113 dataset */
|
|
Inverse_Concatenate_Scaling(invmatrix,1.0,1.0,1.0/(float)ZSCALE);
|
|
|
|
/* rotation about axis by angle */
|
|
if (frame != 0)
|
|
angle[axis] = angle[axis] + delta_angle;
|
|
Inverse_Concatenate_Rotation(invmatrix,XAXIS,-angle[X]);
|
|
Inverse_Concatenate_Rotation(invmatrix,YAXIS,-angle[Y]);
|
|
/* Inverse_Concatenate_Rotation(invmatrix,ZAXIS,-angle[Z]);*/
|
|
Inverse_Concatenate_Rotation(invmatrix,XAXIS,30.0);
|
|
|
|
/* Moves input map from center of coordinate system back */
|
|
/* to within all-positive octant such that any rotation */
|
|
/* (e.g. by using pre-matrix, rotations, and anpost-matrix) */
|
|
/* exactly falls in the octant, preventing low-side clipping.*/
|
|
/* Fails if non-isotropic image space scaling is applied */
|
|
/* (i.e. different scaling in X,Y, or Z after rotations). */
|
|
Inverse_Concatenate_Translation(invmatrix,
|
|
-out_diag_length/2.0,
|
|
-out_diag_length/2.0,
|
|
-out_diag_length/2.0);
|
|
|
|
/* Insures that frustum entirely encloses any rotation of */
|
|
/* map assuming they fall within the all-positive octant */
|
|
/* (e.g. by using pre-matrix, rotations, and anpost-matrix), */
|
|
Load_Transformation_Matrix(invmatrix);
|
|
Compute_Input_Dimensions();
|
|
Compute_Input_Unit_Vector();
|
|
}
|
|
|
|
|
|
void Compute_Input_Dimensions()
|
|
{
|
|
long x,y,z;
|
|
float in_invvertex[2][2][2][NM]; /* Image and object space centers */
|
|
|
|
in_invvertex[0][0][0][X] = 0;
|
|
in_invvertex[0][0][0][Y] = 0;
|
|
in_invvertex[0][0][0][Z] = 0;
|
|
|
|
in_invvertex[0][0][1][X] = frust_len-1;
|
|
in_invvertex[0][0][1][Y] = 0;
|
|
in_invvertex[0][0][1][Z] = 0;
|
|
|
|
in_invvertex[0][1][0][X] = 0;
|
|
in_invvertex[0][1][0][Y] = frust_len-1;
|
|
in_invvertex[0][1][0][Z] = 0;
|
|
|
|
in_invvertex[0][1][1][X] = frust_len-1;
|
|
in_invvertex[0][1][1][Y] = frust_len-1;
|
|
in_invvertex[0][1][1][Z] = 0;
|
|
|
|
in_invvertex[1][0][0][X] = 0;
|
|
in_invvertex[1][0][0][Y] = 0;
|
|
in_invvertex[1][0][0][Z] = frust_len-1;
|
|
|
|
in_invvertex[1][0][1][X] = frust_len-1;
|
|
in_invvertex[1][0][1][Y] = 0;
|
|
in_invvertex[1][0][1][Z] = frust_len-1;
|
|
|
|
in_invvertex[1][1][0][X] = 0;
|
|
in_invvertex[1][1][0][Y] = frust_len-1;
|
|
in_invvertex[1][1][0][Z] = frust_len-1;
|
|
|
|
in_invvertex[1][1][1][X] = frust_len-1;
|
|
in_invvertex[1][1][1][Y] = frust_len-1;
|
|
in_invvertex[1][1][1][Z] = frust_len-1;
|
|
|
|
for (z=0; z<2; z++) {
|
|
for (y=0; y<2; y++) {
|
|
for (x=0; x<2; x++) {
|
|
Transform_Point(in_invvertex[z][y][x][X],
|
|
in_invvertex[z][y][x][Y],
|
|
in_invvertex[z][y][x][Z],
|
|
&out_invvertex[z][y][x][X],
|
|
&out_invvertex[z][y][x][Y],
|
|
&out_invvertex[z][y][x][Z]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Compute_Input_Unit_Vector()
|
|
{
|
|
long x,y,z;
|
|
float uin_invvertex[2][2][2][NM];
|
|
|
|
uin_invvertex[0][0][0][X] = 0;
|
|
uin_invvertex[0][0][0][Y] = 0;
|
|
uin_invvertex[0][0][0][Z] = 0;
|
|
|
|
uin_invvertex[0][0][1][X] = 1.0;
|
|
uin_invvertex[0][0][1][Y] = 0;
|
|
uin_invvertex[0][0][1][Z] = 0;
|
|
|
|
uin_invvertex[0][1][0][X] = 0;
|
|
uin_invvertex[0][1][0][Y] = 1.0;
|
|
uin_invvertex[0][1][0][Z] = 0;
|
|
|
|
uin_invvertex[0][1][1][X] = 1.0;
|
|
uin_invvertex[0][1][1][Y] = 1.0;
|
|
uin_invvertex[0][1][1][Z] = 0;
|
|
|
|
uin_invvertex[1][0][0][X] = 0;
|
|
uin_invvertex[1][0][0][Y] = 0;
|
|
uin_invvertex[1][0][0][Z] = 1.0;
|
|
|
|
uin_invvertex[1][0][1][X] = 1.0;
|
|
uin_invvertex[1][0][1][Y] = 0;
|
|
uin_invvertex[1][0][1][Z] = 1.0;
|
|
|
|
uin_invvertex[1][1][0][X] = 0;
|
|
uin_invvertex[1][1][0][Y] = 1.0;
|
|
uin_invvertex[1][1][0][Z] = 1.0;
|
|
|
|
uin_invvertex[1][1][1][X] = 1.0;
|
|
uin_invvertex[1][1][1][Y] = 1.0;
|
|
uin_invvertex[1][1][1][Z] = 1.0;
|
|
|
|
for (z=0; z<2; z++) {
|
|
for (y=0; y<2; y++) {
|
|
for (x=0; x<2; x++) {
|
|
Transform_Point(uin_invvertex[z][y][x][X],
|
|
uin_invvertex[z][y][x][Y],
|
|
uin_invvertex[z][y][x][Z],
|
|
&uout_invvertex[z][y][x][X],
|
|
&uout_invvertex[z][y][x][Y],
|
|
&uout_invvertex[z][y][x][Z]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Load_Transformation_Matrix(matrix)
|
|
float matrix[4][4];
|
|
{
|
|
Copy_Matrix(matrix,transformation_matrix);
|
|
}
|
|
|
|
|
|
void Transform_Point(xold,yold,zold,xnew,ynew,znew)
|
|
float xold,yold,zold;
|
|
float *xnew,*ynew,*znew;
|
|
{
|
|
*xnew =
|
|
xold * transformation_matrix[0][0] +
|
|
yold * transformation_matrix[1][0] +
|
|
zold * transformation_matrix[2][0] +
|
|
transformation_matrix[3][0];
|
|
|
|
*ynew =
|
|
xold * transformation_matrix[0][1] +
|
|
yold * transformation_matrix[1][1] +
|
|
zold * transformation_matrix[2][1] +
|
|
transformation_matrix[3][1];
|
|
|
|
*znew =
|
|
xold * transformation_matrix[0][2] +
|
|
yold * transformation_matrix[1][2] +
|
|
zold * transformation_matrix[2][2] +
|
|
transformation_matrix[3][2];
|
|
}
|
|
|
|
|
|
void Inverse_Concatenate_Translation(matrix,xoffset,yoffset,zoffset)
|
|
float matrix[4][4],xoffset,yoffset,zoffset;
|
|
{
|
|
float translation_matrix[4][4];
|
|
Load_Translation_Matrix(translation_matrix,xoffset,yoffset,zoffset);
|
|
Inverse_Concatenate_Transform(matrix,translation_matrix);
|
|
}
|
|
|
|
|
|
void Inverse_Concatenate_Scaling(matrix,xscale,yscale,zscale)
|
|
float matrix[4][4],xscale,yscale,zscale;
|
|
{
|
|
float scaling_matrix[4][4];
|
|
Load_Scaling_Matrix(scaling_matrix,xscale,yscale,zscale);
|
|
Inverse_Concatenate_Transform(matrix,scaling_matrix);
|
|
}
|
|
|
|
|
|
void Inverse_Concatenate_Rotation(matrix,axis,angle)
|
|
float matrix[4][4],angle;
|
|
long axis;
|
|
{
|
|
float rotation_matrix[4][4];
|
|
Load_Rotation_Matrix(rotation_matrix,axis,angle);
|
|
Inverse_Concatenate_Transform(matrix,rotation_matrix);
|
|
}
|
|
|
|
|
|
void Load_Identity_Matrix(matrix)
|
|
float matrix[4][4];
|
|
{
|
|
long i,j;
|
|
for (i=0; i<4; i++) {
|
|
for (j=0; j<4; j++) {
|
|
matrix[i][j] = 0;
|
|
}
|
|
matrix[i][i] = 1.0;
|
|
}
|
|
}
|
|
|
|
void Load_Translation_Matrix(matrix,xoffset,yoffset,zoffset)
|
|
float matrix[4][4],xoffset,yoffset,zoffset;
|
|
{
|
|
Load_Identity_Matrix(matrix);
|
|
matrix[3][0] = xoffset;
|
|
matrix[3][1] = yoffset;
|
|
matrix[3][2] = zoffset;
|
|
}
|
|
|
|
|
|
void Load_Scaling_Matrix(matrix,xscale,yscale,zscale)
|
|
float matrix[4][4],xscale,yscale,zscale;
|
|
{
|
|
Load_Identity_Matrix(matrix);
|
|
matrix[0][0] = xscale;
|
|
matrix[1][1] = yscale;
|
|
matrix[2][2] = zscale;
|
|
}
|
|
|
|
|
|
void Load_Rotation_Matrix(matrix,axis,angle)
|
|
float matrix[4][4],angle;
|
|
long axis;
|
|
{
|
|
Load_Identity_Matrix(matrix);
|
|
if (axis == XAXIS) {
|
|
matrix[1][1] = cos(angle/180.0*PI);
|
|
matrix[1][2] = sin(angle/180.0*PI);
|
|
matrix[2][1] = -sin(angle/180.0*PI);
|
|
matrix[2][2] = cos(angle/180.0*PI);
|
|
}
|
|
else if (axis == YAXIS) {
|
|
matrix[0][0] = cos(angle/180.0*PI);
|
|
matrix[0][2] = -sin(angle/180.0*PI);
|
|
matrix[2][0] = sin(angle/180.0*PI);
|
|
matrix[2][2] = cos(angle/180.0*PI);
|
|
}
|
|
else if (axis == ZAXIS) {
|
|
matrix[0][0] = cos(angle/180.0*PI);
|
|
matrix[0][1] = sin(angle/180.0*PI);
|
|
matrix[1][0] = -sin(angle/180.0*PI);
|
|
matrix[1][1] = cos(angle/180.0*PI);
|
|
}
|
|
}
|
|
|
|
|
|
void Concatenate_Transform(composite_matrix,transformation_matrix)
|
|
float composite_matrix[][4],transformation_matrix[][4];
|
|
{
|
|
float temp_matrix[4][4];
|
|
Multiply_Matrices(composite_matrix,transformation_matrix,temp_matrix);
|
|
Copy_Matrix(temp_matrix,composite_matrix);
|
|
}
|
|
|
|
void Inverse_Concatenate_Transform(composite_matrix,transformation_matrix)
|
|
float composite_matrix[][4],transformation_matrix[][4];
|
|
{
|
|
float temp_matrix[4][4];
|
|
Multiply_Matrices(transformation_matrix,composite_matrix,temp_matrix);
|
|
Copy_Matrix(temp_matrix,composite_matrix);
|
|
}
|
|
|
|
|
|
void Multiply_Matrices(input_matrix1,input_matrix2,output_matrix)
|
|
float input_matrix1[][4],input_matrix2[][4],output_matrix[][4];
|
|
{
|
|
long i,j;
|
|
for (i=0; i<4; i++) {
|
|
for (j=0; j<4; j++) {
|
|
output_matrix[i][j] =
|
|
input_matrix1[i][0] *
|
|
input_matrix2[0][j] +
|
|
input_matrix1[i][1] *
|
|
input_matrix2[1][j] +
|
|
input_matrix1[i][2] *
|
|
input_matrix2[2][j] +
|
|
input_matrix1[i][3] *
|
|
input_matrix2[3][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void Copy_Matrix(input_matrix,output_matrix)
|
|
float input_matrix[][4],output_matrix[][4];
|
|
{
|
|
long i,j;
|
|
for (i=0; i<4; i++) {
|
|
for (j=0; j<4; j++) {
|
|
output_matrix[i][j] = input_matrix[i][j];
|
|
}
|
|
}
|
|
}
|