#include #include #include #include #include "cloud.h" /* * The QAEB procedural ray tracing routine. * * Initialization routine. * * Copyright 1998 F. Kenton Musgrave * All rights reserved */ extern Color *scanline; extern FILE *outfile; extern unsigned long samples; extern unsigned long hits; /* * Initialize the various variables needed for the rendering. */ Init( int argc, char *argv[], OptionsType *options, CameraType *camera, Light *light, Color *background, double *octaves_scalar ) { int i; double frequency; if ( argc < 2 ) { fprintf(stderr, "usage: %s outfile\n", argv[0]); exit (-1); } if ( (outfile = fopen(argv[1], "w")) == NULL ) { fprintf(stderr, "%s: fatal error: cannot open file %s\n", argv[0], argv[1]); exit (-1); } /* set default variable values */ Set_Defaults( options, camera, light, background ); /* get user input */ Read_Input( argc, argv, options, camera, light ); /* initialize viewing parameters */ Init_Camera( camera ); /* initialize tables for Noise2() and Noise3() functions */ Init_Noise(); /* allocate memory for scanline */ scanline = (Color *)calloc( (size_t)camera->hres, (size_t)sizeof( Color ) ); /* Initialize the magic number that relates distance to octaves */ *octaves_scalar = -LOG2(tan(DEGTORAD(0.5*camera->hfov / camera->hres))) - 3.0; /* relates Noise() to Nyquist limit */ #ifdef PPM /* Write the PPM image file header */ fprintf( outfile, "P6 %d %d %d\n", camera->hres, camera->vres, 255 ); fflush( outfile ); #endif } /* Init() */ /* * Initialize default variable values. */ Set_Defaults( OptionsType *options, CameraType *camera, Light *light, Color *background ) { camera->eyep.x = 0.0; /* position the camera */ camera->eyep.x = 0.25; /* right eye */ camera->eyep.x = -.25; /* left eye */ camera->eyep.y = 0.0; camera->eyep.z = 0.0; camera->look_pt.x = 0.0; /* looking at... */ camera->look_pt.y = 6.0; camera->look_pt.z = 0.0; camera->up_dir.x = 0.0; /* camera "up" vector */ camera->up_dir.y = 0.0; camera->up_dir.z = 1.0; camera->hfov = 25.0; /* set horizontal field of view */ camera->vfov = 20.0; /* set vertical field of view */ /* for cumulus cloud experiment */ camera->hres = 256; /* set horizontal resolution */ camera->vres = 208; /* set vertical resolution */ camera->near_clip= 4.25; /* set near clipping distance */ camera->far_clip= 7.0; /* set far clipping distance */ options->shad_clip_dist = 1.5; /* slow but accurate */ options->shad_clip_dist = 1.0; /* pretty accurate */ options->threshold = 0.0; /* crossover from air to cloud */ options->density_scale = 100.0; /* for volcanic cloud */ options->density_scale = 35.0; /* scales cloud density */ options->step_scale = 3.0; /* scalar for the increments */ options->shadstep_scale = 2.0; /* scalar for the shadow ray steps */ options->gamma = 1.9; /* for film recorder */ options->gamma = 2.4; /* set image gamma */ options->noise = 1./255.; /* amount of noise to add to pixels */ light->direction.x = 1.0; /* set up some fixed light direction */ light->direction.y = -1.0; light->direction.z = 1.0; Normalize( &light->direction ); light->color.r = 1.10; /* determine light color */ light->color.g = 1.05; light->color.b = 1.00; background->r = 0.0; /* set background color */ background->g = 0.0; background->b = 1.0; hits = 0; /* initialize statistics storage */ samples = 0; } /* Set_Defaults() */ /* * Read input to initialize the various variables needed for the rendering. * * (Current a straw-horse routine.) */ Read_Input( int argc, char *argv[], OptionsType *options, CameraType *camera, Light *light ) { return; } /* Read_Input() */ Init_Camera( CameraType *camera ) { /* point the camera */ camera->view_dir.x = camera->look_pt.x - camera->eyep.x; camera->view_dir.y = camera->look_pt.y - camera->eyep.y; camera->view_dir.z = camera->look_pt.z - camera->eyep.z; NORM( (&camera->view_dir) ); /* calculate the lateral screeen dir */ CROSS( camera->view_dir, camera->up_dir, (&camera->right_dir) ); NORM( (&camera->right_dir) ); /* recalculate the screeen "up" dir */ CROSS( camera->right_dir, camera->view_dir, (&camera->up_dir) ); NORM( (&camera->up_dir) ); /* calculate pixel dimensions at unit distance */ camera->pix_width = 2 * tan(DEGTORAD(0.5*camera->hfov)) / camera->hres; camera->pix_height = 2 * tan(DEGTORAD(0.5*camera->vfov)) / camera->vres; /* * Calculate the dir of ray through pixel [0,0], * from which all other screen rays are offset. */ camera->corner_ray.x = camera->view_dir.x - 0.5*camera->hres * camera->pix_width * camera->right_dir.x - 0.5*camera->vres * camera->pix_height * camera->up_dir.x; camera->corner_ray.y = camera->view_dir.y - 0.5*camera->hres * camera->pix_width * camera->right_dir.y - 0.5*camera->vres * camera->pix_height * camera->up_dir.y; camera->corner_ray.z = camera->view_dir.z - 0.5*camera->hres * camera->pix_width * camera->right_dir.z - 0.5*camera->vres * camera->pix_height * camera->up_dir.z; } /* Init_Camera() */ /* * Take care of whatever hideous nonsense is required before we exit main(). */ Cleanup( Color *scanline, FILE *outfile ) { /* free scanline memory */ free( scanline ); /* close up the image file */ fflush( outfile ); /* flush the buffer first */ fclose( outfile ); } /* Cleanup() */