v21i009: A ray tracing program, Part02/08

Rich Salz rsalz at uunet.uu.net
Thu Feb 8 07:49:11 AEST 1990


Submitted-by: Craig Kolb <craig at 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 at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list