rsalz@uunet.uu.net (Rich Salz) (02/08/90)
Submitted-by: Craig Kolb <craig@weedeater.math.yale.edu> Posting-number: Volume 21, Issue 9 Archive-name: rayshade/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 2 (of 8)." # Contents: Examples/pool.ray nff2shade.awk src/datatypes.h # src/funcdefs.h src/input.c src/list.c src/main.c src/outputp.c # src/primobj.h src/setup.c src/sphere.c src/superq.c src/surface.c PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Examples/pool.ray' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Examples/pool.ray'\" else echo shar: Extracting \"'Examples/pool.ray'\" \(3579 characters\) sed "s/^X//" >'Examples/pool.ray' <<'END_OF_FILE' X/* X * Example rayshade input file X * X * pool table from "Reds' Nightmare" X * X * Warning: this will take a while to render, as it uses 9 rays/pixel X * and makes heavy use of texturing routines. X * X * To speed rendering, use -P or -S options. X * X * C. Kolb 2/88 X */ Xup 0.0 0.0 1. Xfov 45 Xscreen 512 512 Xmaxdepth 2 Xbackground 0 0 0 Xlight 1.4 point 20.0 0.0 66.0 Xsurface blacktile 0.01 0.01 0.01 0.01 0.01 0.01 0. 0. 0. 0. 0. 0 0 Xsurface s0 0.862745 0.862745 0.862745 0.039216 0.039216 0.039216 0. 0. 0. X 7. 0. 0. 1. Xsurface s1 0.470588 0.156863 0.392157 0.470588 0.156863 0.392157 0. 0. 0. X 25. 1. 0. 1. Xsurface s2 0.117647 0.117647 0.392157 0.117647 0.117647 0.392157 0. 0. 0. X 25. 0. 0. 1. Xsurface s3 0.784314 0.078431 0.078431 0.470588 0.039216 0.039216 0. 0. 0. X 25. 0. 0. 1. Xsurface s4 0 .2235 .145 0 .2235 .145 0 0 0 0.0 0. 0. 1. Xsurface mirror 0.04 0.04 0.04 0.05 0.05 0.05 1. 1. 1. 60. 0.95 0. 1. Xsurface s5 0.196078 0.392157 0.117647 0.196078 0.392157 0.117647 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. Xsurface s6 0.588235 0.392157 0.117647 0.196078 0.392157 0.117647 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. Xsurface s7 0.196078 0.392157 0.509804 0.196078 0.392157 0.117647 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. Xsurface s8 0.980392 0.196078 0.117647 0.196078 0.392157 0.117647 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. Xsurface s9 0.196078 0.392157 0.901961 0.196078 0. 0.117647 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. Xsurface s10 0.411765 0.411765 0.176471 0.411765 0.411765 0.176471 0. 0. 0. X 0. 0. 0. 1. Xsurface floor .1 .1 .1 .5 .5 .45 0.8 0.8 0.8 18 0.0 0 0 X/*surface floor 0.5 0.5 0.5 0.8 0.78 0.78 X 0.8 0.76 0.76 10. 0.0 0. 1. */ Xsurface s12 0.313725 0.313725 0.313725 0.745098 0.745098 0.745098 X 0. 0. 0. 0. 0. 0. 1. Xsurface s13 0.078431 0.862745 0.078431 0.039216 0.039216 0.039216 X 0.156863 0.156863 0.156863 7. 0. 0. 1. Xsurface s14 0.784314 0.078431 0.078431 0.470588 0.039216 0.039216 X 0. 0. 0. 25. 0. 0. 1. Xsurface s15 0.392157 0.098039 0.047059 0.392157 0.098039 0.047059 X 0.039216 0.039216 0.039216 3. 0. 0. 1. Xsurface s16 0.509804 0.509804 0.509804 0.509804 0.509804 0.509804 X 0.156863 0.156863 0.156863 7. 0.1 0. 1. X X sphere s5 1.5 0.0 -21. 1.5 X sphere s6 1.5 1.5 -23.598026 1.5 X sphere s7 1.5 -1.5 -23.598026 1.5 X sphere s8 1.5 3.0 -26.196152 1.5 X sphere s9 1.5 0.0 -26.196152 1.5 X sphere s5 1.5 -3.0 -26.196152 1.5 X sphere s6 1.5 4.5 -28.794229 1.5 X sphere s7 1.5 1.5 -28.794229 1.5 X sphere s8 1.5 -1.5 -28.794229 1.5 X sphere s9 1.5 -4.5 -28.794229 1.5 X sphere s5 1.5 6.0 -31.392305 1.5 X sphere s6 1.5 3.0 -31.392305 1.5 X sphere s7 1.5 0.0 -31.392305 1.5 X sphere s8 1.5 -3.0 -31.392305 1.5 X sphere s9 1.5 -6.0 -31.392305 1.5 X X box s4 0. 0. -1. 30. 57. 1. X box s15 30. 0. 0. 3. 54. 1.5 texture wood scale 5. 5. 5. X box s15 -30. 0. 0. 3. 54. 1.5 texture wood scale 5. 5. 5. X box s15 0. 57. 0. 33. 3. 1.5 texture wood scale 5. 5. 5. X box s15 0. -57. 0. 33. 3. 1.5 texture wood scale 5. 5. 5. X sphere s16 1.5 0. 0. 0. translate 0. 21. 1.5 X box mirror 10. -144. 30. 21.3333 .1 20. /* was 40. -144 30. */ X /* X * Walls X */ X plane s10 0. 1. 0. 0. -144. 0. X plane s10 1. 0. 0. -180. 0. 0. X plane s10 -1. 0. 0. 180. 0. 0. X plane s10 0. -1. 0. 0. 144. 0. X /* X * Floor X */ X plane floor 0. 0. 1. 0. 0. -30. X texture marble scale 4. 4. 4. translate 0. 0. -4.376 X texture checker blacktile scale 12.3 12.3 12.3 X /* X * Ceiling X */ X plane s12 0. 0. -1. 0. 0. 72. X Xeyep 38. 100. 43. Xlookp 0. 0. 0. Xgrid 20 20 10 Xjittered Xsamples 3 END_OF_FILE if test 3579 -ne `wc -c <'Examples/pool.ray'`; then echo shar: \"'Examples/pool.ray'\" unpacked with wrong size! fi # end of 'Examples/pool.ray' fi if test -f 'nff2shade.awk' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nff2shade.awk'\" else echo shar: Extracting \"'nff2shade.awk'\" \(3223 characters\) sed "s/^X//" >'nff2shade.awk' <<'END_OF_FILE' X# X# This awk script will convert an NFF-format input file (as output by X# Eric Haines' SPD) to something rayshade can understand. X# The World object will be enclosed in a single grid of 22*22*22 voxels. X# X# Example usage: X# mountains | awk -f nff2shade.awk | rayshade > mountains.rle X# X# For best results, one should modify the output for all but the tetra X# and mountain databases to provide a tighter bounding box around the X# object of interest (tree, gears, etc.). This is done by placing X# all primitives but the ground pologon into an object stored as a Grid, X# and then instantiating that object once. This will decrease ray-tracing X# time dramatically. X# X# $Id: nff2shade.awk,v 3.0 89/10/27 01:30:24 craig Exp $ X# X# $Log: nff2shade.awk,v $ X# Revision 3.0 89/10/27 01:30:24 craig X# Baseline for first official release. X# X# C. Kolb 9/21/89 X# Fixed comment bug; check first character rather than first field for "#". X# Keep track of defined surfaces in associative array so if one is used X# again we don't create another copy. X# Halved ambient intensity of surfaces. X# C. Kolb 10/12/89 X# Added "adaptive 0" and "cutoff 0" to BEGIN and removed "endfile" from END. X# C. Kolb 2/89 X# First version. X# XBEGIN{ X lights = 0; X surfs = 0; X print "maxdepth 4" X print "adaptive 0" X print "cutoff 0." X} Xsubstr($1, 1, 1) == "#" { print "/* " $0 " */"; next;} X$1 == "v" { next;} X$1 == "from" { print "eyep " $2 " "$3 " " $4; next;} X$1 == "at" {print "lookp " $2 " "$3 " "$4; next;} X$1 == "up" {print; next;} X$1 == "angle" { print "fov " $2; next;} X$1 == "hither" {next;} X$1 == "resolution" {print "screen " $2 " "$3; next;} X X$1 == "l" { lightd[lights] = $2 " "$3 " "$4; lights++; next; } X$1 == "b" {print "background " $2 " "$3 " "$4; next; } X$1 == "f" { X if (surfaces[$2 $3 $4 $5 $6 $7 $8] != 0) { X cursurf = surfaces[$2 $3 $4 $5 $6 $7 $8]; X next; X } X surfs++; X surfaces[$2 $3 $4 $5 $6 $7 $8] = surfs; X cursurf = surfs; X aintens = sqrt(lights) / (4*lights); X dr = $2*$5; X dg = $3*$5; X db = $4*$5; X# this is a good guess.... X ar = aintens*dr; X ag = aintens*dg; X ab = aintens*db; X# X# We set "reflectance" to the minimum of Ks and 1. - T, as X# Eric Haines' SPD includes several objects which have Ks + T > 1. X# X if ($6 < 1. - $8) X reflect = $6; X else X reflect = 1. - $8; X printf("surface s%d %f %f %f %f %f %f %f %f %f %f %f %f %f\n", \ X cursurf, ar, ag, ab, dr, dg, db, $6, $6, $6, $7, reflect, $8, $9); X next; X} X X$1 == "c" { X getline; X x1 = $1; X y1 = $2; X z1 = $3; X br = $4; X getline; X printf("cone s%d %f %f %f %f %f %f %f %f\n", \ X cursurf, x1, y1, z1, $1, $2, $3, br, $4); X next; X} X$1 == "s" { X print "sphere s"cursurf " "$5 " "$2 " "$3 " "$4; X next; X} X$1 == "pp" { X if ($2 == 3) X print "triangle s"cursurf; X else X print "poly s"cursurf; X next; X} X$1 == "p" { X# X# Polygon -- the vertices will print out in the default statement. X# If there are three vertices, make it a triangle. X# X if ($2 == 3) X print "triangle s"cursurf; X else X print "poly s"cursurf; X next; X} X{ X# Matched nothing (or is a vertex data) -- print it. X print; X next; X} XEND{ X# X# Output light definitions. X# X intens = sqrt(lights) / (lights); X for (i = 0; i < lights; i++) { X print "light " intens " point " lightd[i] X } X print "grid 22 22 22" X} END_OF_FILE if test 3223 -ne `wc -c <'nff2shade.awk'`; then echo shar: \"'nff2shade.awk'\" unpacked with wrong size! fi # end of 'nff2shade.awk' fi if test -f 'src/datatypes.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/datatypes.h'\" else echo shar: Extracting \"'src/datatypes.h'\" \(3914 characters\) sed "s/^X//" >'src/datatypes.h' <<'END_OF_FILE' X/* X * datatypes.h X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: datatypes.h,v 3.0 89/10/27 02:05:49 craig Exp $ X * X * $Log: datatypes.h,v $ X * Revision 3.0 89/10/27 02:05:49 craig X * Baseline for first official release. X * X */ X X#ifdef NOVOID Xtypedef int void; X#endif X Xtypedef struct { X double u, v; /* 2D point */ X} Vec2d; X Xtypedef struct Vector { X double x, y, z; /* 3D point */ X} Vector; X Xtypedef struct Ray { X Vector pos; /* Origin */ X Vector dir; /* Direction */ X char shadow; X struct SurfaceList *media; /* Medium ray is passing through */ X} Ray; X Xtypedef struct Color { X double r, g, b; /* Red, green, blue. */ X} Color; X Xtypedef struct { X double matrix[3][3]; /* Rotation matrix */ X Vector translate; /* Translation */ X} TransInfo; X Xtypedef struct Trans { X TransInfo world2obj, /* worldspace --> object space */ X obj2world; /* object space --> world space */ X} Trans; X Xtypedef struct { X struct ObjList *list; /* List of prims/objs. in object */ X struct ObjList *unbounded; /* List of unbounded prims. */ X double bounds[2][3]; /* Bounding box of object */ X} List; X Xtypedef struct { X short xsize, ysize, zsize; /* # of voxels along each axis */ X double bounds[2][3]; /* bounding box */ X double voxsize[3]; /* size of a voxel */ X struct ObjList ****cells; /* Voxels */ X struct ObjList *unbounded; /* Unbounded objects */ X} Grid; X X/* X * Surface definition. X */ Xtypedef struct Surface { X char *name; /* Name */ X struct Color amb; /* Ambient color */ X struct Color diff; /* Diffuse color */ X struct Color spec; /* Specular color */ X double coef; /* Phong shading coef. */ X double refl; /* Reflectivity (0-1) */ X double transp; /* Transparency (0-1) */ X double kref; /* Index of refraction */ X double translucency; /* translucency (0-1) */ X double stcoef; /* Phong coef. for transmitted light */ X} Surface; X Xtypedef struct SurfaceList { X Surface *surf; X struct SurfaceList *next; X} SurfaceList; X Xtypedef struct ObjList { X struct Object *data; /* Pointer to object data */ X struct ObjList *next; /* Next in list */ X} ObjList; X Xtypedef struct PointList { X Vector vec; /* Vector data */ X struct PointList *next; /* Next in list */ X} PointList; X X/* X * Data about point of intersection. X * (May be modified by texture mapping.) X */ Xtypedef struct HitInfo { X Vector pos, /* Location of intersection */ X norm; /* Normal to surface at int. point */ X struct Primitive *prim; /* Pointer to primitive hit. */ X struct Surface surf; /* Surface to be used. */ X TransInfo *totaltrans; X} HitInfo; X X/* X * General-purpose texture structure. The (bad) idea is to X * have one structure which every texturing function will use. X */ Xtypedef struct Texture { X char type; /* Texture type */ X Surface *surf1; /* Alternate surface */ X double size; /* Scale/size factor */ X double *args; /* Random arguments. */ X Color *colormap; /* Colormap */ X Trans *trans; /* Transformation matrices. */ X struct Texture *next; /* Pointer to next texture. */ X} Texture; X Xtypedef struct { X Color color; X double trans; X} Fog; X Xtypedef struct { X Color color; /* Mist color */ X Color trans; /* R, G, B trans. */ X double scale, zero; /* Height scale, start Z */ X} Mist; END_OF_FILE if test 3914 -ne `wc -c <'src/datatypes.h'`; then echo shar: \"'src/datatypes.h'\" unpacked with wrong size! fi # end of 'src/datatypes.h' fi if test -f 'src/funcdefs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/funcdefs.h'\" else echo shar: Extracting \"'src/funcdefs.h'\" \(4762 characters\) sed "s/^X//" >'src/funcdefs.h' <<'END_OF_FILE' X/* X * funcdefs.h X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: funcdefs.h,v 3.0 89/10/27 02:05:50 craig Exp $ X * X * $Log: funcdefs.h,v $ X * Revision 3.0 89/10/27 02:05:50 craig X * Baseline for first official release. X * X */ X X/* X * This file should eventually disappear; function declarations should X * appear as externs where needed. Macros should be moved to a separate file. X */ X/* X * Normal routines X */ Xint nrmsph(), nrmbox(), nrmtri(), nrmsup(),nrmplane(), nrmcyl(), X nrmpoly(), nrmcone(), nrmhf(); X/* X * Intersection routines X */ Xdouble intsph(), intbox(), inttri(), intsup(),intplane(), crossp(), intcyl(), X intpoly(), intcone(), inthf(); X/* X * Extent-box finding routines X */ Xint sphextent(),boxextent(),triextent(),supextent(),planeextent(), X cylextent(), polyextent(), coneextent(), hfextent(); X X/* X * Object creation routines X */ XObject *maksph(), *makbox(), *maktri(), *maksup(), *makplane(), *makcyl(), X *makpoly(), *makcone(), *makhf(), *new_object(); X/* X * Intersection routines. X */ Xdouble int_grid(), int_list(), int_primitive(), IntBounds(); X X/* X * Misc. X */ Xchar *Malloc(), *Calloc(), *strsave(); Xdouble normalize(), Noise(); X X/* X * Transformations X */ XTrans *new_trans(); XTransInfo *new_transinfo(); X X/* X * Surfaces X */ XSurface *find_surface(), *make_surface(), *get_surface(); XSurfaceList *add_surface(); X/* X * Objects X */ XObject *add_child_named(), *add_child(), *get_object_named(); X Xextern double ftmp; /* Yick -- keeps us from evaluating twice during fabs. */ X X/* X * Macros X */ X X/* X * Absolute value -- uses "ftmp" to store value of argument, which X * keeps us from evaluating expressions more than once. X */ X#define fabs(x) ((ftmp=(x)) < 0. ? -(ftmp) : (ftmp)) X#define abs(x) ((x) < 0 ? -(x) : (x)) X X#ifdef SYSV Xdouble drand48(); X/* X * nrand() returns a uniformly distributed random variable between 0 and 1. X */ X#define nrand() (drand48()) X#else Xlong random(); X#define nrand() ((double)random() / (double)((1 << 31) - 1)) X#endif X X#ifdef MULTIMAX X/* X * On the multimax, allocate large pieces of memory as shared memory. X */ Xextern char *share_malloc(), *share_calloc(); X#define mallocprim() (Primitive *)share_malloc(sizeof(Primitive)) X#else X/* X * Otherwise, malloc is malloc, etc. X */ X#define share_malloc(x) Malloc(x) X#define share_calloc(x,y) Calloc(x,y) X#define mallocprim() (Primitive *)Malloc(sizeof(Primitive)) X#endif X X/* X * Return a uniformly distributed random variable between -s/2 and s/2. X */ X#define jitter(s) ((nrand() * (s)) - (s)/2.) X/* X * Dot product X */ X#define dotp(a, b) (((a)->x*(b)->x)+((a)->y*(b)->y)+((a)->z*(b)->z)) X/* X * Close enough for us. X */ X#define equal(a, b) (fabs((a) - (b)) < EPSILON) X/* X * Maximum/Minimum functions X */ X#define max(a, b) ((a) > (b) ? (a) : (b)) X#define min(a, b) ((a) < (b) ? (a) : (b)) X/* X * Convert from voxel number along X/Y/Z to corresponding coordinate. X */ X#define voxel2x(g,x) ((x) * g->voxsize[0]+ g->bounds[0][0]) X#define voxel2y(g,y) ((y) * g->voxsize[1] + g->bounds[0][1]) X#define voxel2z(g,z) ((z) * g->voxsize[2] + g->bounds[0][2]) X/* X * And vice-versa. X */ X#define x2voxel(g,x) (((x) - g->bounds[0][0]) / g->voxsize[0]) X#define y2voxel(g,y) (((y) - g->bounds[0][1]) / g->voxsize[1]) X#define z2voxel(g,z) (((z) - g->bounds[0][2]) / g->voxsize[2]) X/* X * Is the point "p" outisde of the bounding box "b"? X */ X#define OutOfBounds(p,b) ((p)->x < b[0][0] || (p)->x > b[1][0] ||\ X (p)->y < b[0][1] || (p)->y > b[1][1] ||\ X (p)->z < b[0][2] || (p)->z > b[1][2]) X X#ifndef DUMB_CPP X X#define vecsub(a,b,r) (r)->x= (a).x-(b).x;(r)->y= (a).y-(b).y;(r)->z= (a).z-(b).z X#define vecadd(a,b,r) (r)->x= (a).x+(b).x;(r)->y= (a).y+(b).y;(r)->z= (a).z+(b).z X#define scalar_prod(s,a,r) (r)->x= s*(a).x;(r)->y= s*(a).y;(r)->z= s*(a).z X#define veccomb(s1,v1,s2,v2,r) (r)->x = s1*(v1).x + s2*(v2).x; \ X (r)->y = s1*(v1).y + s2*(v2).y; \ X (r)->z = s1*(v1).z + s2*(v2).z; X#define addscaledvec(v1,s,v2,r) (r)->x = (v1).x + s*(v2).x; \ X (r)->y = (v1).y + s*(v2).y; \ X (r)->z = (v1).z + s*(v2).z; X#endif END_OF_FILE if test 4762 -ne `wc -c <'src/funcdefs.h'`; then echo shar: \"'src/funcdefs.h'\" unpacked with wrong size! fi # end of 'src/funcdefs.h' fi if test -f 'src/input.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/input.c'\" else echo shar: Extracting \"'src/input.c'\" \(3342 characters\) sed "s/^X//" >'src/input.c' <<'END_OF_FILE' X/* X * input.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: input.c,v 3.0 89/10/27 02:05:51 craig Exp $ X * X * $Log: input.c,v $ X * Revision 3.0 89/10/27 02:05:51 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#ifdef SYSV X#include <string.h> X#else X#ifndef AZTEC_C X#include <strings.h> X#else /* AZTEC_C */ X Xgetpid() X{ X return 123; X} X#endif X#endif X#include "constants.h" X#include "typedefs.h" X X#define INCLUDE_STR "#include " X Xchar *infilename; /* Name of input file. NULL signifies stdin. */ Xchar tmpname[BUFSIZ]; /* name of temporary file */ Xextern FILE *yyin; /* lex/yacc file pointer */ X Xread_input_file() X{ X extern char *infilename; X X /* X * Open temporary file. X */ X sprintf(tmpname,"%s/raytmp.%d",TMPDIR, getpid()); X yyin = fopen(tmpname, "w"); X X if (yyin == (FILE *)NULL) { X fprintf(stderr,"Cannot write to temp file %s\n",tmpname); X exit(1); X } X X if (!process_file(infilename)) { X /* X * Some kind of error occurred -- unlink X * temporary file and exit. X */ X fclose(yyin); X unlink(tmpname); X exit(1); X } X /* X * File processed okay. Close the file, open it again for X * reading, and call lex/yacc. X */ X fclose(yyin); X yyin = fopen(tmpname, "r"); X yyparse(); X /* X * All done -- unlink temporary file. X */ X unlink(tmpname); X} X X/* X * Open the named file and copy its contents into the temporary file. X * If we run across a #include directive, recurse on the desired X * file. Note that *no checking is performed* -- a file could, X * for example, include itself. Rayshade will happily go on X * copying data into the temporary file until it runs out X * of file pointers (an fopen will fail), or you run out of disk space... X */ Xprocess_file(filename) Xchar *filename; X{ X FILE *fp; X char buf[BUFSIZ], *name, *np; X extern int yylineno; X X if (filename == (char *)NULL) X fp = stdin; X else { X fp = fopen(filename, "r"); X if (fp == (FILE *)NULL) { X fprintf(stderr,"Cannot open %s for reading.\n",filename); X return FALSE; X } X } X X while(fgets(buf, BUFSIZ, fp) != NULL) { X if (strncmp(buf, INCLUDE_STR, strlen(INCLUDE_STR)) == 0) { X /* X * Got an "#include "... X */ X#ifdef SYSV X name = strchr(buf, '"'); X np = strrchr(buf, '"'); X#else X name = index(buf, '"'); X np = rindex(buf, '"'); X#endif X /* X * Get name between quotes. If no or X * one quote, complain. X */ X if (name == (char *)0 || name == np) { X fprintf(stderr,"Invalid include directive (line %d)\n", yylineno); X return FALSE; X } X name++; X *np = (char)NULL; X if (process_file(name) == FALSE) X return FALSE; X } else X fputs(buf, yyin); X } X return TRUE; X} END_OF_FILE if test 3342 -ne `wc -c <'src/input.c'`; then echo shar: \"'src/input.c'\" unpacked with wrong size! fi # end of 'src/input.c' fi if test -f 'src/list.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/list.c'\" else echo shar: Extracting \"'src/list.c'\" \(3185 characters\) sed "s/^X//" >'src/list.c' <<'END_OF_FILE' X/* X * list.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: list.c,v 3.0 89/10/27 02:05:54 craig Exp $ X * X * $Log: list.c,v $ X * Revision 3.0 89/10/27 02:05:54 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#include "constants.h" X#include "typedefs.h" X#include "funcdefs.h" X/* X * Take a list whose DATA field points to a linked list of objects and X * turn it into a List. X */ Xmake_list(obj) XObject *obj; X{ X int i; X List *list; X extern ObjList *find_bounds(); X X list = (List *)Malloc(sizeof(List)); X /* X * Find the unbounded objects on the list as well as the X * bounding box of the list. X */ X list->unbounded = find_bounds((ObjList **)&obj->data, obj->bounds); X /* X * Transform bounding box if necessary. X */ X if (obj->trans) X transform_bounds(&obj->trans->obj2world, obj->bounds); X for (i = 0; i < 3; i++) { X list->bounds[LOW][i] = obj->bounds[LOW][i]; X list->bounds[HIGH][i] = obj->bounds[HIGH][i]; X } X /* X * obj->data now holds list of bounded objects. X */ X list->list = (ObjList *)obj->data; X obj->data = (char *)list; X} X X/* X * Intersect ray & list of objects. X */ Xdouble Xint_list(list, source, ray, hitinfo) XList *list; XPrimitive *source; XRay *ray; XHitInfo *hitinfo; X{ X register ObjList *objlist; X double offset; X HitInfo hittmp; X double dist, mindist; X extern double intersect(); X X mindist = FAR_AWAY; X hittmp.totaltrans = hitinfo->totaltrans; X /* X * Intersect with unbounded objects. X */ X for (objlist = list->unbounded; objlist ; objlist = objlist->next) { X dist = intersect((Object *)objlist->data, source, ray, X &hittmp); X if (dist > EPSILON && dist < mindist) { X mindist = dist; X *hitinfo = hittmp; X } X } X /* X * Check for intersection with bounding box. X */ X if (OutOfBounds(&ray->pos, list->bounds)) { X offset = IntBounds(ray, list->bounds); X if (offset < EPSILON) X /* X * Ray never hit list. X */ X return (mindist == FAR_AWAY ? 0. : mindist); X else if (mindist < offset) X /* X * Ray hit unbounded object closer than bounding box. X */ X return mindist; X /* X * Else the ray enters list-space before it hits an X * unbounded object. X */ X } X /* X * Intersect with objects on list. X */ X for (objlist = list->list; objlist ; objlist = objlist->next) { X dist = intersect((Object *)objlist->data, source, ray, X &hittmp); X if (dist > EPSILON && dist < mindist) { X mindist = dist; X *hitinfo = hittmp; X } X } X X return (mindist == FAR_AWAY ? 0. : mindist); X} END_OF_FILE if test 3185 -ne `wc -c <'src/list.c'`; then echo shar: \"'src/list.c'\" unpacked with wrong size! fi # end of 'src/list.c' fi if test -f 'src/main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/main.c'\" else echo shar: Extracting \"'src/main.c'\" \(4705 characters\) sed "s/^X//" >'src/main.c' <<'END_OF_FILE' Xchar rcsid[] = X "$Id: main.c,v 3.0 89/10/27 17:05:45 craig Exp $"; X/* X * main.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Log: main.c,v $ X * Revision 3.0 89/10/27 17:05:45 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#include <signal.h> X#ifdef SYSV X#include <sys/types.h> X#include <sys/times.h> X#include <sys/param.h> X#else X#ifndef AZTEC_C X#include <sys/time.h> X#include <sys/resource.h> X#endif X#endif X#include "constants.h" X#include "typedefs.h" X#include "defaults.h" X Xunsigned long EyeRays, /* # of eye rays spawned */ X ShadowRays, /* # of shadow rays spawned */ X ReflectRays, /* # of reflected rays */ X RefractRays, /* # of refracted rays */ X HitRays, /* # of rays which hit something. */ X BVTests, /* # of bounding volume tests. */ X SuperSampled; /* # of supersampled pixels. */ Xdouble ftmp; /* Used by fabs() macro. */ XFILE *fstats; /* Statistics file */ X X/* X * LINDA silliness. X */ X#ifdef LINDA Xrayshade_main(argc, argv) X#else Xmain(argc, argv) X#endif Xint argc; Xchar **argv; X{ X double utime, stime; X unsigned long TotalRays; X extern int Verbose, Cache; X extern unsigned long CacheWorked, CacheFailed, ShadowHits; X X /* X * Initialize variables, etc. X */ X setup(); X /* X * Parse options from command line. X */ X parse_options(argc, argv); X /* X * Process input file. X */ X if (Verbose) { X print_version(); X fprintf(fstats,"Reading input file...\n"); X fflush(fstats); X } X read_input_file(); X /* X * Set variables which weren't set on command line X * or in input file. X */ X cleanup(); X /* X * Start new picture. X */ X startpic(); X /* X * Set up viewing parameters. X */ X viewing(); X /* X * Set up world. X */ X if (Verbose) X fprintf(fstats,"Setting up voxels...\n"); X SetupWorld(); X get_cpu_time(&utime, &stime); X fprintf(fstats,"Preprocessing time:\t"); X fprintf(fstats,"%2.2lfu %2.2lfs\n",utime, stime); X fprintf(fstats,"Starting trace.\n"); X fflush(fstats); X /* X * Trace the image. X */ X raytrace(); X /* X * Close the image file. X */ X endpic(); X X get_cpu_time(&utime, &stime); X X#ifndef LINDA X TotalRays = EyeRays + ShadowRays + ReflectRays + RefractRays; X ShadowHits += CacheWorked; X HitRays += ShadowHits; X fprintf(fstats,"Eye rays:\t\t\t%ld\n", EyeRays); X fprintf(fstats,"Shadow rays:\t\t\t%ld\n",ShadowRays); X fprintf(fstats,"Reflected rays:\t\t\t%ld\n",ReflectRays); X fprintf(fstats,"Refracted rays:\t\t\t%ld\n",RefractRays); X fprintf(fstats,"Total rays:\t\t\t%ld\n", TotalRays); X if (TotalRays != 0.) X fprintf(fstats,"Intersecting rays:\t\t%ld (%3.3f%%)\n", X HitRays, 100. * (float)HitRays / (float)TotalRays); X if (ShadowRays != 0) { X if (Cache) X fprintf(fstats,"Shadow cache hits:\t\t%ld (%ld misses)\n", X CacheWorked, CacheFailed); X fprintf(fstats,"Total shadow hits:\t\t%ld (%3.3f%%)\n", X ShadowHits, 100.*(float)ShadowHits / (float)ShadowRays); X } X fprintf(fstats,"Supersampled pixels:\t\t%ld\n",SuperSampled); X fprintf(fstats,"B.V. intersection tests:\t%ld\n", BVTests); X print_prim_stats(); X#endif X fprintf(fstats,"Total CPU time (sec):\t\t"); X fprintf(fstats,"%2.2lf (%2.2lfu + %2.2lfs)\n",utime+stime, utime, stime); X#ifndef LINDA X if (TotalRays != 0.) X fprintf(fstats,"Seconds / ray:\t\t\t%4.4lf\n", X (utime + stime) / (double)TotalRays); X if (HitRays != 0.) X fprintf(fstats, "Seconds / intersecting ray:\t%4.4lf\n", X (utime + stime) / (double)HitRays); X#endif X PrintMemoryStats(); X exit(0); X} X X#ifdef SYSV Xget_cpu_time(utime, stime) Xdouble *utime, *stime; X{ X struct tms time; X long times(); X X (void)times(&time); X *utime = (double)time.tms_utime / (double)HZ; X *stime = (double)time.tms_stime / (double)HZ; X} X#else X#ifdef AZTEC_C Xget_cpu_time() X{ X} X#else /* !SYSV && !AZTEC_C */ Xget_cpu_time(utime, stime) Xdouble *utime, *stime; X{ X struct rusage usage; X X getrusage(RUSAGE_SELF, &usage); X X *utime = (double)usage.ru_utime.tv_sec + X (double)usage.ru_utime.tv_usec / 1000000.; X *stime = (double)usage.ru_stime.tv_sec + X (double)usage.ru_stime.tv_usec / 1000000.; X} X#endif X#endif END_OF_FILE if test 4705 -ne `wc -c <'src/main.c'`; then echo shar: \"'src/main.c'\" unpacked with wrong size! fi # end of 'src/main.c' fi if test -f 'src/outputp.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/outputp.c'\" else echo shar: Extracting \"'src/outputp.c'\" \(4181 characters\) sed "s/^X//" >'src/outputp.c' <<'END_OF_FILE' X/* X * outputp.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: outputp.c,v 3.0 89/10/27 02:05:58 craig Exp $ X * X * $Log: outputp.c,v $ X * Revision 3.0 89/10/27 02:05:58 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#include "typedefs.h" X#include "constants.h" X#include "funcdefs.h" X#ifndef NORLE X#include "svfb_global.h" Xunsigned char *buffer[3]; /* Output buffer */ X#endif X XFILE *imgfile; /* Raster output file */ Xchar outfilename[BUFSIZ]; /* Name of output file */ Xint Appending; /* Appending to output file? */ X X/* X * Convert floating-point to unsigned char (0-255). X * This could easily be a macro, but the old SGI compilers dump core X * on it for some reason. X */ Xunsigned char Xcorrect(x) Xdouble x; X{ X if (x < 0) X return 0; X if (x > 255) X return 255; X return x; X} X X#ifndef NORLE X/* X * Open image file and write RLE header. X */ Xstartpic() X{ X extern int Xres, Yres; X X if (*outfilename) { X if (Appending) { X /* X * If we're appending, we *still* have to write X * the Utah Raster header to the file. This is X * due to strangeness in the Utah Raster toolkit, X * which does some vital initialization in sv_setup(). X */ X imgfile = fopen(outfilename, "r+"); X } else X imgfile = fopen(outfilename, "w"); X if (imgfile == (FILE *)NULL) { X fprintf(stderr,"Cannot open %s for writing.\n", X outfilename); X exit(2); X } X } else X imgfile = stdout; X sv_globals.svfb_fd = imgfile; X sv_globals.sv_xmax = Xres -1; X sv_globals.sv_ymax = Yres -1; X sv_globals.sv_xmin = sv_globals.sv_ymin = 0; X sv_globals.sv_ncolors = 3; X sv_globals.sv_alpha = 0; X sv_setup(RUN_DISPATCH, &sv_globals); X /* X * Flush the header. If we don't, and LINDA forks off X * a bunch of workers, strange things will happen (they'll X * all flush the buffer when they die, and you end up with X * lots of headers at the end of the file). X */ X fflush(sv_globals.svfb_fd); X buffer[0]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres); X buffer[1]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres); X buffer[2]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres); X if (Appending) X fseek(imgfile, 0L, 2); /* Go to end of file */ X} X X X/* X * Write a scanline of output. X * "buf" is an array of Color structures of size Xres. Each color X * component is normalized to [0, 1.]. X */ Xoutline(buf) XColor *buf; X{ X register int i; X extern int Xres; X X for(i = 0;i < Xres;i++) { X /* X * Scale colors to fit unsigned char and check for X * over/underflow. X */ X buffer[0][i] = correct(255 * buf[i].r); X buffer[1][i] = correct(255 * buf[i].g); X buffer[2][i] = correct(255 * buf[i].b); X } X sv_putrow(buffer, Xres, &sv_globals); X} X X/* X * Close image file. X */ Xendpic() X{ X sv_puteof(&sv_globals); X fclose(imgfile); X} X X#else /* NORLE */ X Xstartpic() X{ X extern int Xres, Yres; X X if (*outfilename) { X if (Appending) X imgfile = fopen(outfilename, "a"); X else X imgfile = fopen(outfilename, "w"); X if (imgfile == (FILE *)NULL) { X fprintf(stderr,"Cannot open %s for writing.\n", X outfilename); X exit(2); X } X } else X imgfile = stdout; X X fprintf(imgfile,"%d %d\n",Xres, Yres); X fflush(imgfile); X} X Xoutline(buf) XColor *buf; X{ X register int i; X extern int Xres; X X for (i = 0; i < Xres; i++) { X fputc(correct(255.*buf[i].r), imgfile); X fputc(correct(255.*buf[i].g), imgfile); X fputc(correct(255.*buf[i].b), imgfile); X } X fflush(imgfile); X} X Xendpic() X{ X fclose(imgfile); X} X#endif /* NORLE */ X END_OF_FILE if test 4181 -ne `wc -c <'src/outputp.c'`; then echo shar: \"'src/outputp.c'\" unpacked with wrong size! fi # end of 'src/outputp.c' fi if test -f 'src/primobj.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/primobj.h'\" else echo shar: Extracting \"'src/primobj.h'\" \(3420 characters\) sed "s/^X//" >'src/primobj.h' <<'END_OF_FILE' X/* X * primobj.h X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: primobj.h,v 3.0 89/10/27 02:06:00 craig Exp $ X * X * $Log: primobj.h,v $ X * Revision 3.0 89/10/27 02:06:00 craig X * Baseline for first official release. X * X */ X X/* X * Cylinder X */ Xtypedef struct cylinder { X double rad, len; /* Radius and length. */ X} Cylinder; X Xtypedef struct cone { X double start_pos, end_pos, apex_rad; /* End cap Z positions */ X double tantheta; /* "slope" */ X} Cone; X X/* X * Sphere X */ Xtypedef struct { X double r; /* radius */ X double x, y, z; /* position */ X} Sphere; X X/* X * Box X */ Xtypedef struct { X double bounds[2][3]; /* Box corners */ X} Box; X X/* X * Triangle X */ Xtypedef struct { X Vector nrm; /* triangle normal */ X Vector p1, p2, p3; /* vertices */ X double d; /* plane constant */ X char index; /* Flag used for shading/intersection test. */ X Vector *vnorm; /* Array of vertex normals */ X double *b; /* Array of barycentric coordinates */ X Vector e1, e2, e3; /* edge vectors */ X} Triangle; X X/* X * Polygon X */ Xtypedef struct { X Vector norm; /* Normal to polygon */ X double d; /* Plane constant */ X char index; /* Which normal coord is "dominant"? */ X Vector *points; /* Array of vertices */ X int npoints; /* Number of vertices */ X} Polygon; X X/* X * Superquadric X */ Xtypedef struct { X double bounds[2][3]; /* bounding box */ X double x, y, z; /* Center */ X double pow; /* Superquadric power */ X double a, b, c, r; X double err; /* Error constant */ X} Superq; X X/* X * Plane X */ Xtypedef struct { X Vector norm; /* Plane normal. */ X double d; /* Plane constant. */ X} Plane; X X/* X * Height field gunk. X */ Xtypedef struct hfTri { X Vector v1, v2, v3, norm; X double d; X char type; X struct hfTri *next, *prev; X} hfTri; X Xtypedef struct { X int len; X hfTri *head, *tail; X} TriQueue; X Xtypedef struct { X float **data; /* Altitude points */ X float minz, maxz; X int size, *lsize; /* # of points/side */ X int BestSize; /* "best" division size */ X float iBestSize; /* inverse of above (for faster computation) */ X int levels; /* log base BestSize of size */ X float ***boundsmax; /* high data values at various resolutions. */ X float ***boundsmin; X float *spacing; X hfTri hittri, **q; /* hit triangle and triangle cache */ X int qtail, qsize; /* end and length of cache */ X double boundbox[2][3]; /* bounding box of HF */ X} Hf; X X/* X * Primitive object. X */ Xtypedef struct Primitive { X char type; /* object type */ X struct Surface *surf; /* default surface */ X union { X Sphere *p_sphere; X Box *p_box; X Triangle *p_triangle; X Superq *p_superq; X Plane *p_plane; X Cylinder *p_cylinder; X Polygon *p_poly; X Cone *p_cone; X Hf *p_hf; X } objpnt; /* Pointer to primitive */ X} Primitive; END_OF_FILE if test 3420 -ne `wc -c <'src/primobj.h'`; then echo shar: \"'src/primobj.h'\" unpacked with wrong size! fi # end of 'src/primobj.h' fi if test -f 'src/setup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/setup.c'\" else echo shar: Extracting \"'src/setup.c'\" \(4525 characters\) sed "s/^X//" >'src/setup.c' <<'END_OF_FILE' X/* X * setup.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: setup.c,v 3.0 89/10/27 02:06:03 craig Exp $ X * X * $Log: setup.c,v $ X * Revision 3.0 89/10/27 02:06:03 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#include "constants.h" X#include "defaults.h" X#include "typedefs.h" X#include "funcdefs.h" X X#ifdef MULTIMAX X#include <parallel.h> X#define SHARED_BYTES 23 /* 2^23 bytes of shared memory */ X#endif X/* X * Set default parameters X */ Xsetup() X{ X extern int maxlevel; X extern double hfov, vfov; X extern Vector eyep, lookp, up; X extern Object *World; X extern ObjList *CurObj; X#ifdef MULTIMAX X unsigned int bytes; X X /* X * Initialize shared memory stuff. X */ X bytes = 1 << SHARED_BYTES; X if (share_malloc_init(bytes) == -1) { X fprintf(stderr,"Cannot share_malloc %d bytes.\n",bytes); X exit(10); X } else X fprintf(stderr,"Malloced %d bytes of shared memory.\n", X bytes); X#endif X /* X * Like every other object, the objects that make up X * "World" are stored in a simple linked list until it X * has been completely defined. Once the definition is X * complete we convert the linked list into a Grid or List X * as per the user's wishes. X */ X World = new_object("world", LIST, (char *)NULL, (Trans *)NULL); X X maxlevel = MAXLEVEL; X hfov = HFOV; X vfov = UNSET; X eyep.x = EYEX; X eyep.y = EYEY; X eyep.z = EYEZ; X lookp.x = LOOKX; X lookp.y = LOOKY; X lookp.z = LOOKZ; X up.x = UPX; X up.y = UPY; X up.z = UPZ; X X /* X * Kinda yicky, but compatible. X */ X CurObj = (ObjList *)Malloc(sizeof(ObjList)); X CurObj->next = (ObjList *)0; X CurObj->data = (Object *)0; X InitRTable(); /* Initialize values for Noise() */ X} X X/* X * cleanup() X * X * Initialize variables not set on command line or in input file. X */ Xcleanup() X{ X int i; X extern int nlight, maxlevel; X extern int Xres, Yres, StartLine, Jittered, JitSamples, pixel_div; X extern double RedContrast, GreenContrast, BlueContrast, TreeCutoff; X extern double vfov, hfov; X extern Light light[]; X extern FILE *fstats; X X /* X * Because we want the user to be able to override the input file X * through the command line, we have to initialize some variables to X * bogus values so that when the file is being parsed, it is X * possible to tell if a given variable has been set on the X * command line. X * X * If such variables are not set to legal values on the command X * line or in the input file, we must do it here. X */ X if (Xres == UNSET) X Xres = XRESOLUTION; X if (Yres == UNSET) X Yres = YRESOLUTION; X X if (StartLine == UNSET) X StartLine = Yres -1; X else X fprintf(fstats,"Starting on line %d\n",StartLine); X X /* X * If not defined in the input file, calculate VFOV X * by hand. This assumes that pixels are square, which is X * probably a bad idea. ("aspect" option?) X */ X if (vfov == UNSET) X vfov = hfov * Yres / Xres; X X if (!Jittered && pixel_div == UNSET) X pixel_div = PIXEL_DIV; X X if (JitSamples == UNSET) X JitSamples = DEFLIGHTSAMPLES; X X if (Jittered && JitSamples > 5) { X fprintf(stderr,"Sorry, %d rays/pixel not supported.\n", X JitSamples*JitSamples); X exit(2); X } X if (!Jittered && JitSamples < 3) { X fprintf(stderr,"Samples (-S) value must be at least 3.\n"); X exit(2); X } X X if (TreeCutoff == UNSET) X TreeCutoff = DEFCUTOFF; X X if (RedContrast == UNSET) X RedContrast = DEFREDCONT; X if (GreenContrast == UNSET) X GreenContrast = DEFGREENCONT; X if (BlueContrast == UNSET) X BlueContrast = DEFBLUECONT; X X /* X * Now that we've parsed the input file, we know what X * maxlevel is, so we can allocate the right amount of X * space for each light source's cache and related X * transformation. X */ X for (i = 0; i < nlight; i++) { X light[i].cache = (Primitive **)Calloc(maxlevel+1, X sizeof(Primitive *)); X light[i].trans = (TransInfo *)Malloc((maxlevel+1)* X sizeof(TransInfo)); X } X} END_OF_FILE if test 4525 -ne `wc -c <'src/setup.c'`; then echo shar: \"'src/setup.c'\" unpacked with wrong size! fi # end of 'src/setup.c' fi if test -f 'src/sphere.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/sphere.c'\" else echo shar: Extracting \"'src/sphere.c'\" \(3346 characters\) sed "s/^X//" >'src/sphere.c' <<'END_OF_FILE' X/* X * sphere.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: sphere.c,v 3.0 89/10/27 02:06:04 craig Exp $ X * X * $Log: sphere.c,v $ X * Revision 3.0 89/10/27 02:06:04 craig X * Baseline for first official release. X * X */ X#include <math.h> X#include <stdio.h> X#include "constants.h" X#include "typedefs.h" X#include "funcdefs.h" X X/* X * Create & return reference to a sphere. X */ XObject * Xmaksph(surf, r, pos) Xchar *surf; Xdouble r; XVector *pos; X{ X Sphere *sphere; X Object *newobj; X Primitive *prim; X extern int Quiet, yylineno; X X if (r < EPSILON) { X if (!Quiet) X fprintf(stderr,"Degenerate sphere (line %d)\n", X yylineno); X return (Object *)0; X } X X prim = mallocprim(); X newobj = new_object(NULL, SPHERE, (char *)prim, (Trans *)NULL); X prim->type = SPHERE; X prim->surf = find_surface(surf); X sphere = (Sphere *)Malloc(sizeof(Sphere)); X prim->objpnt.p_sphere = sphere; X /* X * sphere->r really holds the square of the radius. X */ X sphere->r = r*r; X sphere->x = pos->x; X sphere->y = pos->y; X sphere->z = pos->z; X X return newobj; X} X X/* X * Ray/sphere intersection test. X */ Xdouble Xintsph(pos, ray, obj) Xregister Vector *pos, *ray; XPrimitive *obj; X{ X Sphere *sph; X double xadj, yadj, zadj; X double b, t, s; X extern unsigned long primtests[]; X X primtests[SPHERE]++; X sph = obj->objpnt.p_sphere; X /* X * Translate ray origin to object space and negate everything. X * (Thus, we translate the sphere into ray space, which saves X * us a couple of negations below.) X */ X xadj = sph->x - pos->x; X yadj = sph->y - pos->y; X zadj = sph->z - pos->z; X X /* X * Solve quadratic equiation. Recall that sph->r is the square of r. X */ X b = xadj * ray->x + yadj * ray->y + zadj * ray->z; X t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->r; X if (t < 0) X return 0.; X t = sqrt(t); X s = b - t; X if (s > EPSILON) X return s; X s = b + t; X if (s > EPSILON) X return s; X return 0.; X} X Xnrmsph(pos, obj, nrm) XVector *pos, *nrm; XPrimitive *obj; X{ X /* X * Don't bother dividing by by sphere->r -- the normal will be X * normalized later. X */ X nrm->x = (pos->x - obj->objpnt.p_sphere->x); X nrm->y = (pos->y - obj->objpnt.p_sphere->y); X nrm->z = (pos->z - obj->objpnt.p_sphere->z); X} X Xsphextent(o, bounds) XPrimitive *o; Xdouble bounds[2][3]; X{ X Sphere *s = o->objpnt.p_sphere; X double r; X X /* X * Could store both r*r and r, but sphextent is only X * called in preprocessing, so... X */ X r = sqrt(s->r); X bounds[LOW][X] = s->x - r; X bounds[HIGH][X] = s->x + r; X bounds[LOW][Y] = s->y - r; X bounds[HIGH][Y] = s->y + r; X bounds[LOW][Z] = s->z - r; X bounds[HIGH][Z] = s->z + r; X} END_OF_FILE if test 3346 -ne `wc -c <'src/sphere.c'`; then echo shar: \"'src/sphere.c'\" unpacked with wrong size! fi # end of 'src/sphere.c' fi if test -f 'src/superq.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/superq.c'\" else echo shar: Extracting \"'src/superq.c'\" \(3390 characters\) sed "s/^X//" >'src/superq.c' <<'END_OF_FILE' X/* X * superq.c X * X * Slightly modified version of Kuchkuda's superquadric code. X * X * $Id: superq.c,v 3.0 89/10/27 02:06:05 craig Exp $ X * X * $Log: superq.c,v $ X * Revision 3.0 89/10/27 02:06:05 craig X * Baseline for first official release. X * X */ X#include <math.h> X#include "constants.h" X#include "typedefs.h" X#include "funcdefs.h" X X#define ERRCONST 1.006 X X/* X * Create and return reference to a superquadric. X */ XObject * Xmaksup(surf, x, y, z, xs, ys, zs, power) Xchar *surf; Xdouble x, y, z, xs, ys, zs, power; X{ X double maxval; X Superq *super; X Primitive *prim; X Object *newobj; X X prim = mallocprim(); X prim->surf = find_surface(surf); X newobj = new_object(NULL, SUPERQ, (char *)prim, (Trans *)NULL); X prim->type = SUPERQ; X super = (Superq *) Malloc((unsigned)sizeof(Superq)); X prim->objpnt.p_superq = super; X super->x = x; X super->y = y; X super->z = z; X super->bounds[LOW][X] = x - xs; X super->bounds[HIGH][X] = x + xs; X super->bounds[LOW][Y] = y - ys; X super->bounds[HIGH][Y] = y + ys; X super->bounds[LOW][Z] = z - zs; X super->bounds[HIGH][Z] = z + zs; X X super->pow = power; X maxval = xs; X if (ys > maxval) X maxval = ys; X if (zs > maxval) X maxval = zs; X super->a = xs / maxval; X super->b = ys / maxval; X super->c = zs / maxval; X super->r = pow(maxval, power); X super->err = pow((ERRCONST * maxval), power) - super->r; X X return newobj; X} X Xdouble Xintsup(pos, ray, obj) XVector *pos, *ray; XPrimitive *obj; X{ X double s, si, t; X double xadj, yadj, zadj; X double old, result, p; X Ray tmpray; X Superq *super; X extern unsigned long primtests[]; X X primtests[SUPERQ]++; X super = obj->objpnt.p_superq; X /* find box intersection */ X if (OutOfBounds(pos, super->bounds)) { X tmpray.pos = *pos; X tmpray.dir = *ray; X s = IntBounds(&tmpray, super->bounds); X if (s <= 0.) X return 0; X } X else X s = 0.; X X xadj = pos->x - super->x; X yadj = pos->y - super->y; X zadj = pos->z - super->z; X X /* initial solution */ X p = super->pow; X result = pow(fabs((xadj + ray->x * s) / super->a), p) X + pow(fabs((yadj + ray->y * s) / super->b), p) X + pow(fabs((zadj + ray->z * s) / super->c), p) X - super->r; X X si = s; X s = s + 0.001; X /* iterative refinement */ X while (result > super->err) { X old = result; X result = pow(fabs((xadj + ray->x * s) / super->a), p) X + pow(fabs((yadj + ray->y * s) / super->b), p) X + pow(fabs((zadj + ray->z * s) / super->c), p) X - super->r; X X if (result >= old) X return (0.0); X t = (result * (s - si)) / (result - old); X si = s; X s -= t; X } X X return (s); X} X Xnrmsup(pos, obj, nrm) XVector *pos, *nrm; XPrimitive *obj; X{ X double k; X Superq *super; X X super = obj->objpnt.p_superq; X nrm->x = (pos->x - super->x) / super->a; X nrm->y = (pos->y - super->y) / super->b; X nrm->z = (pos->z - super->z) / super->c; X k = super->pow - 1; X if (nrm->x > 0) X nrm->x = pow(nrm->x, k); X else X nrm->x = -pow(-nrm->x, k); X if (nrm->y > 0) X nrm->y = pow(nrm->y, k); X else X nrm->y = -pow(-nrm->y, k); X if (nrm->z > 0) X nrm->z = pow(nrm->z, k); X else X nrm->z = -pow(-nrm->z, k); X} X X Xsupextent(o, bounds) XPrimitive *o; Xdouble bounds[2][3]; X{ X Superq *s = o->objpnt.p_superq; X X bounds[LOW][X] = s->bounds[LOW][X]; X bounds[HIGH][X] = s->bounds[HIGH][X]; X bounds[LOW][Y] = s->bounds[LOW][Y]; X bounds[HIGH][Y] = s->bounds[HIGH][Y]; X bounds[LOW][Z] = s->bounds[LOW][Z]; X bounds[HIGH][Z] = s->bounds[HIGH][Z]; X} END_OF_FILE if test 3390 -ne `wc -c <'src/superq.c'`; then echo shar: \"'src/superq.c'\" unpacked with wrong size! fi # end of 'src/superq.c' fi if test -f 'src/surface.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/surface.c'\" else echo shar: Extracting \"'src/surface.c'\" \(3946 characters\) sed "s/^X//" >'src/surface.c' <<'END_OF_FILE' X/* X * surface.c X * X * Copyright (C) 1989, Craig E. Kolb X * X * This software may be freely copied, modified, and redistributed, X * provided that this copyright notice is preserved on all copies. X * X * There is no warranty or other guarantee of fitness for this software, X * it is provided solely . Bug reports or fixes may be sent X * to the author, who may or may not act on them as he desires. X * X * You may not include this software in a program or other software product X * without supplying the source, or without informing the end-user that the X * source is available for no extra charge. X * X * If you modify this software, you should include a notice giving the X * name of the person performing the modification, the date of modification, X * and the reason for such modification. X * X * $Id: surface.c,v 3.0 89/10/27 02:06:05 craig Exp $ X * X * $Log: surface.c,v $ X * Revision 3.0 89/10/27 02:06:05 craig X * Baseline for first official release. X * X */ X#include <stdio.h> X#include "constants.h" X#include "typedefs.h" X#include "funcdefs.h" X X#define blend(a, b, p, q) (a * p + b * q) X#define NORMCONST (1. / 255.) X XSurfaceList *Surfaces; /* Linked list of defined surfaces */ X X/* X * Create and return pointer to surface with given properties. X */ XSurface * Xmake_surface(name, amb, diff, spec, coef, refl, refr, k, translu, stcoef) Xchar *name; XColor *amb, *diff, *spec; Xdouble coef, refl, refr, k, translu, stcoef; X{ X Surface *stmp; X X /* X * Complain if named surface already exists. X */ X if ((stmp = get_surface(name)) != (Surface *)0) X yyerror("Surface redefined."); X X stmp = (Surface *)Malloc(sizeof(Surface)); X stmp->name = strsave(name); X X stmp->amb = *amb; X stmp->diff = *diff; X stmp->spec = *spec; X X stmp->coef = coef; stmp->refl = refl; stmp->transp = refr; X stmp->kref = k; stmp->translucency = translu; X stmp->stcoef = stcoef; X X return stmp; X} X XSurfaceList * Xadd_surface(surf, list) XSurface *surf; XSurfaceList *list; X{ X SurfaceList *res; X X res = (SurfaceList *)Malloc(sizeof(SurfaceList)); X res->surf = surf; X res->next = list; X X return res; X} X X/* X * Search for surface with given name. If not found, complain and exit. X */ XSurface * Xfind_surface(name) Xchar *name; X{ X Surface *stmp; X X stmp = get_surface(name); X if (stmp == (Surface *)0) X yyerror("Undefined surface."); X X return stmp; X} X X/* X * Return pointer to surface with given name, NULL if no such surface. X */ XSurface * Xget_surface(name) Xchar *name; X{ X SurfaceList *stmp; X X for (stmp = Surfaces; stmp ; stmp = stmp->next) X if(strcmp(name, stmp->surf->name) == 0) X return stmp->surf; X /* X * No surface named "name". X */ X return (Surface *)0; X} X X/* X * Compute combination of two surfaces. Resulting surface is copied into surf1. X */ Xblend_surface(surf1, surf2, p, q) XSurface *surf1, *surf2; Xdouble p, q; X{ X /* X * P is weight of surf1. q is weight of surf2. X * Result is placed in surf1. X */ X X blend_color(&surf1->amb, &surf2->amb, p, q); X blend_color(&surf1->diff, &surf2->diff, p, q); X blend_color(&surf1->spec, &surf2->spec, p, q); X X surf1->coef = blend(surf1->coef, surf2->coef, p, q); X surf1->refl = blend(surf1->refl, surf2->refl, p, q); X surf1->transp = blend(surf1->transp, surf2->transp, p, q); X surf1->kref = blend(surf1->kref, surf2->kref, p, q); X} X X/* X * Blend two colors. Result is placed in color1. X */ Xblend_color(color1, color2, p, q) XColor *color1, *color2; Xdouble p, q; X{ X color1->r = blend(color1->r, color2->r, p, q); X color1->g = blend(color1->g, color2->g, p, q); X color1->b = blend(color1->b, color2->b, p, q); X} X X/* X * Scale color by given red, green and blue factors. X */ XScaleColor(scalar, color, res) Xdouble scalar; XColor color, *res; X{ X res->r = color.r * scalar; X res->g = color.g * scalar; X res->b = color.b * scalar; X} X XAddScaledColor(color1, scalar, color2, res) XColor color1, color2, *res; Xdouble scalar; X{ X res->r = color1.r + scalar * color2.r; X res->g = color1.g + scalar * color2.g; X res->b = color1.b + scalar * color2.b; X} END_OF_FILE if test 3946 -ne `wc -c <'src/surface.c'`; then echo shar: \"'src/surface.c'\" unpacked with wrong size! fi # end of 'src/surface.c' fi echo shar: End of archive 2 \(of 8\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.