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 / balls.c next >
C/C++ Source or Header  |  1991-01-13  |  5KB  |  182 lines

  1. /*
  2.  * balls.c - Also known as "sphereflake".  Create a set of shiny spheres, with
  3.  *    each sphere blooming sets of 9 more spheres with 1/3rd radius.
  4.  *    A square floor polygon is added.  Three light sources.
  5.  *
  6.  * Author:  Eric Haines, 3D/Eye, Inc.
  7.  *
  8.  * SizeFactor determines the number of objects output.
  9.  *    Total spheres = sum of n=0,SF of (9**SF).
  10.  *
  11.  *    SizeFactor    # spheres    # squares
  12.  *         1            10             1
  13.  *         2            91             1
  14.  *         3           820             1
  15.  *
  16.  *         4          7381             1
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include "def.h"
  22. #include "lib.h"
  23.  
  24. static    int    SizeFactor = 4 ;
  25.  
  26. #define    OUTPUT_FORMAT        OUTPUT_CURVES
  27.  
  28. /* radius of sphere enclosing all balls (a scale factor) */
  29. #define    BV_RADIUS        1.0
  30.  
  31. main(argc,argv)
  32. int    argc ;
  33. char    *argv[] ;
  34. {
  35. COORD3    back_color, obj_color ;
  36. COORD3    from, at, up ;
  37. COORD3    ground[4], bvec, light, objset[9] ;
  38. COORD4    center_pt, direction ;
  39.  
  40.     if ( !lib_get_size( argc, argv, &SizeFactor ) ) {
  41.     fprintf( stderr, "usage: %s [size]\n", *argv ) ;
  42.     exit(EXIT_FAIL) ;
  43.     }
  44.  
  45.     /* output viewpoint */
  46.     SET_COORD3( from, 2.1, 1.3, 1.7 ) ;
  47.     SET_COORD3( at, 0.0, 0.0, 0.0 ) ;
  48.     SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
  49.     lib_output_viewpoint( from, at, up, 45.0, 1.0, 512, 512 ) ;
  50.  
  51.     /* output background color - UNC sky blue */
  52.     SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
  53.     lib_output_background_color( back_color ) ;
  54.  
  55.     /* output light sources */
  56.     SET_COORD3( light, 4.0, 3.0, 2.0 ) ;
  57.     lib_output_light( light ) ;
  58.     SET_COORD3( light, 1.0, -4.0, 4.0 ) ;
  59.     lib_output_light( light ) ;
  60.     SET_COORD3( light, -3.0, 1.0, 5.0 ) ;
  61.     lib_output_light( light ) ;
  62.  
  63.     /* output floor polygon - beige */
  64.     SET_COORD3( back_color, 1.0, 0.75, 0.33 ) ;
  65.     lib_output_color( back_color, 1.0, 0.0, 0.0, 0.0, 0.0 ) ;
  66.     SET_COORD3( bvec, 12.0 * BV_RADIUS, 12.0 * BV_RADIUS, -BV_RADIUS / 2.0 ) ;
  67.     SET_COORD3( ground[0],  bvec[X],  bvec[Y], bvec[Z] ) ;
  68.     SET_COORD3( ground[1], -bvec[X],  bvec[Y], bvec[Z] ) ;
  69.     SET_COORD3( ground[2], -bvec[X], -bvec[Y], bvec[Z] ) ;
  70.     SET_COORD3( ground[3],  bvec[X], -bvec[Y], bvec[Z] ) ;
  71.     lib_output_polygon( 4, ground ) ;
  72.  
  73.     /* set up object color - off white */
  74.     SET_COORD3( obj_color, 1.0, 0.9, 0.7 ) ;
  75.     lib_output_color( obj_color, 0.5, 0.5, 3.0, 0.0, 0.0 ) ;
  76.  
  77.     /* create set of spawned points */
  78.     create_objset( objset ) ;
  79.  
  80.     /* compute and output object */
  81.     SET_COORD4( center_pt, 0.0, 0.0, 0.0, BV_RADIUS / 2.0 ) ;
  82.     SET_COORD4( direction, 0.0, 0.0, 1.0, 1.0/3.0 ) ;
  83.     output_object( SizeFactor, center_pt, direction, objset ) ;
  84.  
  85.     exit(EXIT_SUCCESS) ;
  86. }
  87.  
  88. /* Create the set of 9 vectors needed to generate the sphere set. */
  89. create_objset( objset )
  90. COORD3    objset[9] ;
  91. {
  92. int    num_set, num_vert ;
  93. double    dist ;
  94. COORD3    axis, temp_pt, trio_dir[3] ;
  95. MATRIX    mx ;
  96.  
  97.     dist = 1.0 / sqrt( (double)2.0 ) ;
  98.  
  99.     SET_COORD3( trio_dir[0], dist, dist,   0.0 ) ;
  100.     SET_COORD3( trio_dir[1], dist,  0.0, -dist ) ;
  101.     SET_COORD3( trio_dir[2],  0.0, dist, -dist ) ;
  102.  
  103.     SET_COORD3( axis, 1.0, -1.0, 0.0 ) ;
  104.     (void)lib_normalize_vector( axis ) ;
  105.     lib_create_axis_rotate_matrix(
  106.         mx
  107.       , axis
  108.       , asin( (double) ( 2.0 / sqrt( (double)6.0 ) ) ) ) ;
  109.  
  110.     for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  111.     lib_transform_vector( temp_pt, trio_dir[num_vert], mx ) ;
  112.     COPY_COORD3( trio_dir[num_vert], temp_pt ) ;
  113.     }
  114.  
  115.     for ( num_set = 0 ; num_set < 3 ; ++num_set ) {
  116.     lib_create_rotate_matrix( mx, Z_AXIS, num_set*2.0*PI/3.0 ) ;
  117.     for ( num_vert = 0 ; num_vert < 3 ; ++num_vert ) {
  118.         lib_transform_vector( objset[num_set*3+num_vert],
  119.             trio_dir[num_vert], mx ) ;
  120.     }
  121.     }
  122. }
  123.  
  124.  
  125. /*
  126.  * Output the parent sphere, then output the children of the sphere.
  127.  */
  128. output_object( depth, center, direction, objset )
  129. int    depth ;
  130. COORD4    center ;
  131. COORD4    direction ;
  132. COORD3    objset[9] ;
  133. {
  134. int    num_vert ;
  135. double    angle, scale ;
  136. COORD3    axis, z_axis ;
  137. COORD4    child_pt, child_dir ;
  138. MATRIX    mx ;
  139.  
  140.     /* output sphere at location & radius defined by center */
  141.     lib_output_sphere( center, OUTPUT_FORMAT ) ;
  142.  
  143.     /* check if children should be generated */
  144.     if ( depth > 0 ) {
  145.     --depth ;
  146.  
  147.     /* rotation matrix to new axis from +Z axis */
  148.     if ( direction[Z] >= 1.0 ) {
  149.         /* identity matrix */
  150.         lib_create_identity_matrix( mx ) ;
  151.     }
  152.     else if ( direction[Z] <= -1.0 ) {
  153.         lib_create_rotate_matrix( mx, Y_AXIS, PI ) ;
  154.     }
  155.     else {
  156.         SET_COORD3( z_axis, 0.0, 0.0, 1.0 ) ;
  157.         CROSS( axis, z_axis, direction ) ;
  158.         (void)lib_normalize_vector( axis ) ;
  159.         angle = acos( (double)DOT_PRODUCT( z_axis, direction ) ) ;
  160.         lib_create_axis_rotate_matrix( mx, axis, angle ) ;
  161.     }
  162.  
  163.     /* scale down location of new spheres */
  164.     scale = center[W] * (1.0 + direction[W] ) ;
  165.  
  166.     for ( num_vert = 0 ; num_vert < 9 ; ++num_vert ) {
  167.         lib_transform_vector( child_pt, objset[num_vert], mx ) ;
  168.         child_pt[X] = child_pt[X] * scale + center[X] ;
  169.         child_pt[Y] = child_pt[Y] * scale + center[Y] ;
  170.         child_pt[Z] = child_pt[Z] * scale + center[Z] ;
  171.         /* scale down radius */
  172.         child_pt[W] = center[W] * direction[W] ;
  173.         SUB3_COORD3( child_dir, child_pt, center ) ;
  174.         child_dir[X] /= scale ;
  175.         child_dir[Y] /= scale ;
  176.         child_dir[Z] /= scale ;
  177.         child_dir[W] = direction[W] ;
  178.         output_object( depth, child_pt, child_dir, objset ) ;
  179.     }
  180.     }
  181. }
  182.