home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Graphics / SPD / Sources / tree.c < prev   
Encoding:
C/C++ Source or Header  |  1994-05-10  |  5.5 KB  |  206 lines  |  [TEXT/R*ch]

  1. /*
  2.  * tree.c - Creates a tree using Aono & Kunii's generation method.
  3.  *    (See IEEE CG&A May 1984).  A square polygon is placed beneath the
  4.  *    tree to act as a field.  Seven light sources.
  5.  *
  6.  * Author:  Eric Haines, 3D/Eye, Inc.
  7.  *
  8.  * size_factor determines the number of objects output.
  9.  *    Total objects = 2**(SF+1)-1 cones and spheres + 1 square polygon.
  10.  *
  11.  *    size_factor    # spheres       # cones    # squares
  12.  *         1             3               3         1
  13.  *         2             7               7         1
  14.  *         3            15              15         1
  15.  *
  16.  *        11          4095            4095         1
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <stdlib.h>    /* atoi */
  22. #include "def.h"
  23. #include "drv.h"    /* display_close() */
  24. #include "lib.h"
  25.  
  26. /* These may be read from the command line */
  27. static int size_factor       = 11;
  28. static int raytracer_format = OUTPUT_RT_DEFAULT;
  29. static int output_format    = OUTPUT_CURVES;
  30.  
  31. #ifdef OUTPUT_TO_FILE
  32. static FILE * stdout_file = NULL;
  33. #else
  34. #define stdout_file stdout
  35. #endif /* OUTPUT_TO_FILE */
  36.  
  37. /* the following affect the shape of the tree */
  38. #define    BR_ANGLE_0        40.0
  39. #define    BR_ANGLE_1        25.0
  40. #define    BR_CONTR_0        0.65
  41. #define    BR_CONTR_1        0.70
  42. #define    BR_DIAMETER        0.67
  43. #define    DIV_ANGLE        140.0
  44. #define    WIDTH_HEIGHTH_RATIO    0.15
  45.  
  46. static    MATRIX    Rst_mx[2] ;
  47.  
  48. /* grow tree branches recursively */
  49. void
  50. grow_tree(cur_mx, scale, depth)
  51.     MATRIX cur_mx;
  52.     double scale;
  53.     int depth;
  54. {
  55.     int i;
  56.     COORD3 vec;
  57.     COORD4 apex, base;
  58.     MATRIX new_mx;
  59.  
  60.     PLATFORM_MULTITASK();
  61.  
  62.     /* output branch */
  63.     SET_COORD3( vec, 0.0, 0.0, 0.0 ) ;
  64.     lib_transform_point( base, vec, cur_mx ) ;
  65.     base[W] = scale * WIDTH_HEIGHTH_RATIO ;
  66.  
  67.     SET_COORD3( vec, 0.0, 0.0, 1.0 ) ;
  68.     lib_transform_point( apex, vec, cur_mx ) ;
  69.     apex[W] = base[W] * BR_DIAMETER ;
  70.  
  71.     lib_output_cylcone( base, apex, output_format ) ;
  72.     lib_output_sphere( apex, output_format ) ;
  73.  
  74.     if ( depth > 0 ) {
  75.     --depth ;
  76.  
  77.     for ( i = 0 ; i < 2 ; ++i ) {
  78.         lib_matrix_multiply( new_mx, Rst_mx[i], cur_mx ) ;
  79.         grow_tree( new_mx, scale * BR_DIAMETER, depth ) ;
  80.     }
  81.     }
  82. }
  83.  
  84. /*
  85.  * Set up matrices for growth of each branch with respect to the
  86.  * parent branch, then grow each branch.
  87.  */
  88. void
  89. create_tree()
  90. {
  91.     int    i;
  92.     double branch_angle, branch_contraction, divergence;
  93.     MATRIX ident_mx, temp1_mx, temp2_mx, tempr_mx, tempst_mx;
  94.  
  95.     for ( i = 0 ; i < 2 ; ++i ) {
  96.     if ( i == 0 ) {
  97.         branch_angle = BR_ANGLE_0 ;
  98.         divergence = 90.0 ;
  99.         branch_contraction = BR_CONTR_0 ;
  100.     } else {
  101.         branch_angle = BR_ANGLE_1 ;
  102.         divergence = DIV_ANGLE + 90.0 ;
  103.         branch_contraction = BR_CONTR_1 ;
  104.     }
  105.  
  106.     /* rotate along X axis by branching angle */
  107.     lib_create_rotate_matrix( temp1_mx, X_AXIS, branch_angle*PI/180.0 ) ;
  108.  
  109.     /* rotate along Z axis by divergence angle */
  110.     lib_create_rotate_matrix( temp2_mx, Z_AXIS, divergence*PI/180.0 ) ;
  111.  
  112.     lib_matrix_multiply( tempr_mx, temp1_mx, temp2_mx ) ;
  113.  
  114.     /* include translation of branch, scaled */
  115.     lib_create_identity_matrix( tempst_mx ) ;
  116.     tempst_mx[0][0] = branch_contraction;
  117.     tempst_mx[1][1] = branch_contraction;
  118.     tempst_mx[2][2] = branch_contraction;
  119.     tempst_mx[3][2] = 1.0;
  120.  
  121.     /* concatenate */
  122.     lib_matrix_multiply( Rst_mx[i], tempr_mx, tempst_mx ) ;
  123.     }
  124.  
  125.     /* set up initial matrix */
  126.     lib_create_identity_matrix( ident_mx ) ;
  127.     grow_tree( ident_mx, 1.0, size_factor ) ;
  128. }
  129.  
  130. int
  131. main(argc,argv)
  132.     int argc;
  133.     char *argv[];
  134. {
  135.     COORD3 field[4];
  136.     COORD3 from, at, up;
  137.     COORD3 back_color, tree_color;
  138.     COORD4 light;
  139.     double lscale;
  140.  
  141.     PLATFORM_INIT(SPD_TREE);
  142.  
  143.     /* Start by defining which raytracer we will be using */
  144.     if ( lib_gen_get_opts( argc, argv,
  145.             &size_factor, &raytracer_format, &output_format ) ) {
  146.     return EXIT_FAIL;
  147.     }
  148.     if ( lib_open( raytracer_format, "Tree.out" ) ) {
  149.     return EXIT_FAIL;
  150.     }
  151.  
  152.     /* output background color - UNC sky blue */
  153.     /* NOTE: Do this BEFORE lib_output_viewpoint(), for display_init() */
  154.     SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
  155.     lib_output_background_color( back_color ) ;
  156.  
  157.     /* output viewpoint */
  158.     SET_COORD3( from, 4.5, 0.4, 2.0 ) ;
  159.     SET_COORD3( at, 0.0, 0.0, 1.5 ) ;
  160.     SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
  161.     lib_output_viewpoint(from, at, up, 45.0, 1.0, 1.0, 512, 512);
  162.  
  163.     /* output light sources */
  164.     if (raytracer_format == OUTPUT_NFF || raytracer_format == OUTPUT_RTRACE)
  165.     lscale = 1.0;
  166.     else
  167.     lscale = 1.0 / sqrt(7.0);
  168.  
  169.     /* output light source */
  170.     SET_COORD4( light, -5.0, 5.0, 50.0, lscale ) ;
  171.     lib_output_light( light ) ;
  172.     SET_COORD4( light, 30.0, -30.0, 30.0, lscale ) ;
  173.     lib_output_light( light ) ;
  174.     SET_COORD4( light, -40.0, -30.0, 20.0, lscale ) ;
  175.     lib_output_light( light ) ;
  176.     SET_COORD4( light, 10.0, 30.0, 40.0, lscale ) ;
  177.     lib_output_light( light ) ;
  178.     SET_COORD4( light, -30.0, 40.0, 10.0, lscale ) ;
  179.     lib_output_light( light ) ;
  180.     SET_COORD4( light, 50.0, 25.0, 20.0, lscale ) ;
  181.     lib_output_light( light ) ;
  182.     SET_COORD4( light, -10.0, -60.0, 30.0, lscale ) ;
  183.     lib_output_light( light ) ;
  184.  
  185.     /* output field polygon - green */
  186.     SET_COORD3( back_color, 0.2, 0.7, 0.2 ) ;
  187.     lib_output_color(NULL, back_color, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  188.     SET_COORD3( field[0],  50.0,  50.0, 0.0 ) ;
  189.     SET_COORD3( field[1], -50.0,  50.0, 0.0 ) ;
  190.     SET_COORD3( field[2], -50.0, -50.0, 0.0 ) ;
  191.     SET_COORD3( field[3],  50.0, -50.0, 0.0 ) ;
  192.     lib_output_polygon( 4, field ) ;
  193.  
  194.     /* set up tree color - brown */
  195.     SET_COORD3( tree_color, 0.55, 0.4, 0.2 ) ;
  196.     lib_output_color(NULL, tree_color, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  197.  
  198.     /* create tree */
  199.     create_tree();
  200.  
  201.     lib_close();
  202.  
  203.     PLATFORM_SHUTDOWN();
  204.     return EXIT_SUCCESS;
  205. }
  206.