home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
gondwana.ecr.mu.oz.au/pub/
/
Graphics.tar
/
Graphics
/
SPD.3.0.shar.gz
/
SPD.3.0.shar
/
tetra.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-13
|
4KB
|
149 lines
/*
* tetra.c - Create a tetrahedral pyramid. This environment is based on the
* scene used by Glassner ("Space Subdivision for Fast Ray Tracing," IEEE
* CG&A, October 1984) and Kay & Kajiya ("Ray Tracing Complex Scenes,"
* SIGGRAPH '86 Proceedings) for testing their ray tracers.
* One light source.
*
* Author: Eric Haines, 3D/Eye, Inc.
*
* Note: the view and light positions are the same (after transformation to
* a different set of world coordinates) as used by Kay & Kajiya,
* courtesy of Tim Kay. For some reason, the number of shadow rays
* generated is different (Kay gets 34K, I get 46K). One light source.
*
* SizeFactor determines the number of polygons output.
* Total triangular polygons = 4**SF
*
* SizeFactor # triangles
* 1 4
* 2 16
* 3 64
*
* 6 4096
*/
#include <stdio.h>
#include <math.h>
#include "def.h"
#include "lib.h"
static int SizeFactor = 6 ;
main(argc,argv)
int argc ;
char *argv[] ;
{
COORD3 back_color, tetra_color, light ;
COORD3 from, at, up ;
COORD4 center_pt ;
if ( !lib_get_size( argc, argv, &SizeFactor ) ) {
fprintf( stderr, "usage: %s [size]\n", *argv ) ;
exit(EXIT_FAIL) ;
}
/* output viewpoint */
SET_COORD3( from, 1.022846, -3.177154, -2.174512 ) ;
SET_COORD3( at, -0.004103, -0.004103, 0.216539 ) ;
SET_COORD3( up, -0.816497, -0.816497, 0.816497 ) ;
lib_output_viewpoint( from, at, up, 45.0, 1.0, 512, 512 ) ;
/* output background color - UNC sky blue */
SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
lib_output_background_color( back_color ) ;
/* output light source */
SET_COORD3( light, 1.876066, -18.123936, -5.000422 ) ;
lib_output_light( light ) ;
/* output tetrahedron color - red */
SET_COORD3( tetra_color, 1.0, 0.2, 0.2 ) ;
lib_output_color( tetra_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
/* compute and output tetrahedral object */
SET_COORD4( center_pt, 0.0, 0.0, 0.0, 1.0 ) ;
create_tetra( SizeFactor, center_pt ) ;
exit(EXIT_SUCCESS) ;
}
/* Create tetrahedrons recursively */
create_tetra( depth, center )
int depth ;
COORD4 center ;
{
int num_face, num_vert, swap, vert_ord[3] ;
int x_dir, y_dir, z_dir ;
COORD3 face_pt[3], obj_pt[4] ;
COORD4 sub_center ;
if ( depth <= 1 ) {
/* Output tetrahedron */
/* find opposite corners of a cube which form a tetrahedron */
for ( num_vert = 0, x_dir = -1 ; x_dir <= 1 ; x_dir += 2 ) {
for ( y_dir = -1 ; y_dir <= 1 ; y_dir += 2 ) {
for ( z_dir = -1 ; z_dir <= 1 ; z_dir += 2 ) {
if ( x_dir*y_dir*z_dir == 1 ) {
obj_pt[num_vert][X] =
center[X] + (double)x_dir * center[W] ;
obj_pt[num_vert][Y] =
center[Y] + (double)y_dir * center[W] ;
obj_pt[num_vert][Z] =
center[Z] + (double)z_dir * center[W] ;
++num_vert ;
}
}
}
}
/* find faces and output */
for ( num_face = 0 ; num_face < 4 ; ++num_face ) {
/* output order:
* face 0: points 0 1 2
* face 1: points 3 2 1
* face 2: points 2 3 0
* face 3: points 1 0 3
*/
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
vert_ord[num_vert] = (num_face + num_vert) % 4 ;
}
if ( num_face%2 == 1 ) {
swap = vert_ord[0] ;
vert_ord[0] = vert_ord[2] ;
vert_ord[2] = swap ;
}
for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
COPY_COORD3( face_pt[num_vert], obj_pt[vert_ord[num_vert]] ) ;
}
lib_output_polygon( 3, face_pt ) ;
}
}
else {
/* Create sub-tetrahedra */
/* find opposite corners of a cube to form sub-tetrahedra */
for ( x_dir = -1 ; x_dir <= 1 ; x_dir += 2 ) {
for ( y_dir = -1 ; y_dir <= 1 ; y_dir += 2 ) {
for ( z_dir = -1 ; z_dir <= 1 ; z_dir += 2 ) {
if ( x_dir*y_dir*z_dir == 1 ) {
sub_center[X] =
center[X] + (double)x_dir * center[W] / 2.0 ;
sub_center[Y] =
center[Y] + (double)y_dir * center[W] / 2.0 ;
sub_center[Z] =
center[Z] + (double)z_dir * center[W] / 2.0 ;
sub_center[W] = center[W] / 2.0 ;
create_tetra( depth-1, sub_center ) ;
}
}
}
}
}
}