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 >
C/C++ Source or Header  |  1991-01-13  |  4KB  |  149 lines

  1. /*
  2.  * tetra.c - Create a tetrahedral pyramid.  This environment is based on the
  3.  *    scene used by Glassner ("Space Subdivision for Fast Ray Tracing," IEEE
  4.  *    CG&A, October 1984) and Kay & Kajiya ("Ray Tracing Complex Scenes,"
  5.  *    SIGGRAPH '86 Proceedings) for testing their ray tracers.
  6.  *    One light source.
  7.  *
  8.  * Author:  Eric Haines, 3D/Eye, Inc.
  9.  *
  10.  * Note:  the view and light positions are the same (after transformation to
  11.  *    a different set of world coordinates) as used by Kay & Kajiya,
  12.  *    courtesy of Tim Kay.  For some reason, the number of shadow rays
  13.  *    generated is different (Kay gets 34K, I get 46K).  One light source.
  14.  *
  15.  * SizeFactor determines the number of polygons output.
  16.  *    Total triangular polygons = 4**SF
  17.  *
  18.  *    SizeFactor    # triangles
  19.  *         1             4
  20.  *         2            16
  21.  *         3            64
  22.  *
  23.  *         6          4096
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <math.h>
  28. #include "def.h"
  29. #include "lib.h"
  30.  
  31. static    int    SizeFactor = 6 ;
  32.  
  33. main(argc,argv)
  34. int    argc ;
  35. char    *argv[] ;
  36. {
  37. COORD3  back_color, tetra_color, light ;
  38. COORD3  from, at, up ;
  39. COORD4  center_pt ;
  40.  
  41.     if ( !lib_get_size( argc, argv, &SizeFactor ) ) {
  42.     fprintf( stderr, "usage: %s [size]\n", *argv ) ;
  43.     exit(EXIT_FAIL) ;
  44.     }
  45.  
  46.     /* output viewpoint */
  47.     SET_COORD3( from, 1.022846, -3.177154, -2.174512 ) ;
  48.     SET_COORD3( at, -0.004103, -0.004103, 0.216539 ) ;
  49.     SET_COORD3( up, -0.816497, -0.816497, 0.816497 ) ;
  50.     lib_output_viewpoint( from, at, up, 45.0, 1.0, 512, 512 ) ;
  51.  
  52.     /* output background color - UNC sky blue */
  53.     SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
  54.     lib_output_background_color( back_color ) ;
  55.  
  56.     /* output light source */
  57.     SET_COORD3( light, 1.876066, -18.123936, -5.000422 ) ;
  58.     lib_output_light( light ) ;
  59.  
  60.     /* output tetrahedron color - red */
  61.     SET_COORD3( tetra_color, 1.0, 0.2, 0.2 ) ;
  62.     lib_output_color( tetra_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
  63.  
  64.     /* compute and output tetrahedral object */
  65.     SET_COORD4( center_pt, 0.0, 0.0, 0.0, 1.0 ) ;
  66.     create_tetra( SizeFactor, center_pt ) ;
  67.  
  68.     exit(EXIT_SUCCESS) ;
  69. }
  70.  
  71.  
  72. /* Create tetrahedrons recursively */
  73. create_tetra( depth, center )
  74. int    depth ;
  75. COORD4    center ;
  76. {
  77. int    num_face, num_vert, swap, vert_ord[3] ;
  78. int    x_dir, y_dir, z_dir ;
  79. COORD3    face_pt[3], obj_pt[4] ;
  80. COORD4    sub_center ;
  81.  
  82.     if ( depth <= 1 ) {
  83.     /* Output tetrahedron */
  84.  
  85.     /* find opposite corners of a cube which form a tetrahedron */
  86.     for ( num_vert = 0, x_dir = -1 ; x_dir <= 1 ; x_dir += 2 ) {
  87.         for ( y_dir = -1 ; y_dir <= 1 ; y_dir += 2 ) {
  88.         for ( z_dir = -1 ; z_dir <= 1 ; z_dir += 2 ) {
  89.             if ( x_dir*y_dir*z_dir == 1 ) {
  90.             obj_pt[num_vert][X] =
  91.                     center[X] + (double)x_dir * center[W] ;
  92.             obj_pt[num_vert][Y] =
  93.                     center[Y] + (double)y_dir * center[W] ;
  94.             obj_pt[num_vert][Z] =
  95.                     center[Z] + (double)z_dir * center[W] ;
  96.             ++num_vert ;
  97.             }
  98.         }
  99.         }
  100.     }
  101.  
  102.     /* find faces and output */
  103.     for ( num_face = 0 ; num_face < 4 ; ++num_face ) {
  104.         /* output order:
  105.          *   face 0:  points 0 1 2
  106.          *   face 1:  points 3 2 1
  107.          *   face 2:  points 2 3 0
  108.          *   face 3:  points 1 0 3
  109.          */
  110.         for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  111.         vert_ord[num_vert] = (num_face + num_vert) % 4 ;
  112.         }
  113.         if ( num_face%2 == 1 ) {
  114.         swap = vert_ord[0] ;
  115.         vert_ord[0] = vert_ord[2] ;
  116.         vert_ord[2] = swap ;
  117.         }
  118.  
  119.         for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  120.         COPY_COORD3( face_pt[num_vert], obj_pt[vert_ord[num_vert]] ) ;
  121.         }
  122.         lib_output_polygon( 3, face_pt ) ;
  123.     }
  124.     }
  125.  
  126.     else {
  127.     /* Create sub-tetrahedra */
  128.  
  129.     /* find opposite corners of a cube to form sub-tetrahedra */
  130.     for ( x_dir = -1 ; x_dir <= 1 ; x_dir += 2 ) {
  131.         for ( y_dir = -1 ; y_dir <= 1 ; y_dir += 2 ) {
  132.         for ( z_dir = -1 ; z_dir <= 1 ; z_dir += 2 ) {
  133.             if ( x_dir*y_dir*z_dir == 1 ) {
  134.             sub_center[X] =
  135.                 center[X] + (double)x_dir * center[W] / 2.0 ;
  136.             sub_center[Y] =
  137.                 center[Y] + (double)y_dir * center[W] / 2.0 ;
  138.             sub_center[Z] =
  139.                 center[Z] + (double)z_dir * center[W] / 2.0 ;
  140.             sub_center[W] = center[W] / 2.0 ;
  141.  
  142.             create_tetra( depth-1, sub_center ) ;
  143.             }
  144.         }
  145.         }
  146.     }
  147.     }
  148. }
  149.