CCL Home Page
Up Directory CCL Part07
#! /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 'Doc/Guide/preface.tex' <<'END_OF_FILE'
X\chapter*{Preface}
X\addcontentsline{toc}{chapter}{Preface}
X
X{\Rayshade} is a program for creating ray-traced images.
XIt reads a description of a scene to be
Xrendered and produces a color image corresponding to the
Xdescription.
X{\Rayshade} was designed to make it easy to
Xcreate nice pictures.
XIt was also meant to be flexible, easy to modify,
Xand relatively fast.
X
XThe first version of {\rayshade} was written in 1987-1988 at
XPrinceton University with help and encouragement from David Dobkin
Xand David Hoffman.  That version was heavily based on a public-domain
X``introductory'' ray tracer written by Roman Kuchkuda.
XChanges to {\rayshade} from that point until version 4.0 were
Xevolutionary in nature.
XThe current version is to a large extent a re-write,
Xand an attempt has been made to remove some of the fundamental
Xproblems present in previous incarnations.
X
XI wish to thank the many people who have made
Xcontributions to the development of {\rayshade} during the past four years.
XThanks to Marc Andreessen, Ray Bellis, Dominique Boisvert, William Bouma,
XAllen Braunsdorf, Jeff Butterworth, Nick Carriero, Nancy Everson, Tom Friedel,
XRobert Funchess, David Gelernter, Mike Gigante, Ed Herderick, John Knuston,
XRaphael Manfredi, Lee Moore, Dietmar Saupe, Brian Wyvill,
Xand the hundreds of others who have provided
Xbug-fixes, suggestions, input files,
Xencouragement, support, and other feedback.
X
XDavid Dobkin first suggested that an extensible
Xray tracer would be a worthwhile project.  Gavin Bell, David
XHoffman, Lefteris Koutsofios, and Steven North
Xwere the first users of the original {\rayshade}, and their feedback
Xshowed that the project might indeed have a future.
XIn the Fall of 1988,
XPrzemyslaw Prusinkiewicz encouraged me
Xto develop {\rayshade} further, and was, as always, full of ``insanely
Xgreat'' ideas.  The resulting version of {\rayshade} was released
Xon Usenet in 1989.  Allan Snider was particularly helpful in
Xfinding bugs in version 3.0 and in making valuable suggestions
Xas to how the program might be improved.
X
X{\Rayshade} version 4.0
Xwas written by Craig Kolb and Rod Bogart during 1990-1991, with contributions
Xof ideas and code made by many others.
XPat Hanrahan's {\em OOGL} provided the spirit, if not the letter, of the
Xmodularity of the version 4.0.  Thanks to Pat and to Mark VandeWettering
Xfor the ``net tracer'' conversations and for the inspiration to do something
Xto clean up {\rayshade}.
XEric Haines saved the day on more than one occasion by suggesting
Ximprovements, finding bugs, and saying nice things about {\rayshade}
Xwhen I was all but ready to throw in the towel.
XRobert Skinner was kind enough to provide the {\em Noise()}, {\em DNoise()},
Xand other texturing functions and to allow them to be redistributed.
XMark Podlipec provided the blob object and torus object, which uses
XJochen Schwarze's cubic and quartic root-finding functions.
XMajor Thanks to Rod Bogart for being willing to take the plunge and
Xplay such a large role in the development of version 4.0.
XI am most grateful to Benoit Mandelbrot for his support of this
Xproject and the inspiration he provided.
X
X\begin{flushright}
X\parbox[t]{1.5in}{
XC. Kolb \\
XJanuary 10, 1992
X}
X\end{flushright}
END_OF_FILE
if test 3203 -ne `wc -c <'Doc/Guide/preface.tex'`; then
    echo shar: \"'Doc/Guide/preface.tex'\" unpacked with wrong size!
fi
# end of 'Doc/Guide/preface.tex'
fi
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'\" \(3791 characters\)
sed "s/^X//" >'Examples/pool.ray' <<'END_OF_FILE'
X/* Converted by rsconvert */
X/*
X * Example rayshade input file
X *
X * pool table from "Reds' Nightmare"
X *
X * C. Kolb 2/88
X *
X * $Id: pool.ray,v 4.0 91/07/17 14:26:36 kolb Exp Locker: kolb $
X *
X * $Log:	pool.ray,v $
X * Revision 4.0  91/07/17  14:26:36  kolb
X * Initial version.
X * 
X */
Xup 0 0 1 
Xfov 45 
Xscreen 512 512 
Xmaxdepth 2 
Xbackground 0 0 0 
Xlight 1.4 point 20 0 66 
Xsurface blacktile 
X	ambient 0.01 0.01 0.01 
X	diffuse 0.01 0.01 0.01 
Xsurface s0 
X	ambient 0.862745 0.862745 0.862745 
X	diffuse 0.039216 0.039216 0.039216 
Xsurface s1 
X		
X	ambient 0.470588 0.156863 0.392157 
X	diffuse 0.470588 0.156863 0.392157 
X	specular 1 1 1
Xsurface s2 
X		
X	ambient 0.117647 0.117647 0.392157 
X	diffuse 0.117647 0.117647 0.392157 
Xsurface s3 
X		
X	ambient 0.784314 0.078431 0.078431 
X	diffuse 0.470588 0.039216 0.039216 
Xsurface s4 
X	ambient 0 0.2235 0.145 
X	diffuse 0 0.2235 0.145 
Xsurface mirror 
X	ambient 0.04 0.04 0.04 
X	diffuse 0.05 0.05 0.05 
X	specular .8 .8 .8
X	specpow 60 
X	reflect 1.
Xsurface s5 
X	ambient 0.196078 0.392157 0.117647 
X	diffuse 0.196078 0.392157 0.117647 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsurface s6 
X		
X	ambient 0.588235 0.392157 0.117647 
X	diffuse 0.196078 0.392157 0.117647 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsurface s7 
X	ambient 0.196078 0.392157 0.509804 
X	diffuse 0.196078 0.392157 0.117647 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsurface s8 
X	ambient 0.980392 0.196078 0.117647 
X	diffuse 0.196078 0.392157 0.117647 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsurface s9 
X		
X	ambient 0.196078 0.392157 0.901961 
X	diffuse 0.196078 0 0.117647 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsurface s10 
X	ambient 0.411765 0.411765 0.176471 
X	diffuse 0.411765 0.411765 0.176471 
Xsurface floor 
X	ambient 0.1 0.1 0.1 
X	diffuse 0.5 0.5 0.45 
X	specular 0.8 0.8 0.8 
X	specpow 18 
Xsurface s12 
X	ambient 0.313725 0.313725 0.313725 
X	diffuse 0.745098 0.745098 0.745098 
Xsurface s13 
X	ambient 0.078431 0.862745 0.078431 
X	diffuse 0.039216 0.039216 0.039216 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
Xsurface s14 
X	ambient 0.784314 0.078431 0.078431 
X	diffuse 0.470588 0.039216 0.039216 
Xsurface s15 
X	ambient 0.392157 0.098039 0.047059 
X	diffuse 0.392157 0.098039 0.047059 
X	specular 0.039216 0.039216 0.039216 
X	specpow 3 
Xsurface s16 
X	ambient 0.509804 0.509804 0.509804 
X	diffuse 0.509804 0.509804 0.509804 
X	specular 0.156863 0.156863 0.156863 
X	specpow 7 
X	reflect 1.
Xsphere s5 1.5 0 	-21 		1.5 
X	sphere s6 1.5 1.5 	-23.598 	1.5 
X	sphere s7 1.5 -1.5 	-23.598 	1.5 
X	sphere s8 1.5 3 	-26.1962 	1.5 
X	sphere s9 1.5 0 	-26.1962 	1.5 
X	sphere s5 1.5 -3 	-26.1962 	1.5 
X	sphere s6 1.5 4.5 	-28.7942 	1.5 
X	sphere s7 1.5 1.5 	-28.7942 	1.5 
X	sphere s8 1.5 -1.5 	-28.7942 	1.5 
X	sphere s9 1.5 -4.5 	-28.7942 	1.5 
X	sphere s5 1.5 6 	-31.3923 	1.5 
X	sphere s6 1.5 3 	-31.3923 	1.5 
X	sphere s7 1.5 0 	-31.3923 	1.5 
X	sphere s8 1.5 -3 	-31.3923 	1.5 
X	sphere s9 1.5 -6 	-31.3923 	1.5 
X
X	box s4 -30 -57 -2 30 57 0 
X	box s15 27 -54 -1.5 33 54 1.5 texture wood scale 15 10 15 
X	box s15 -33 -54 -1.5 -27 54 1.5 texture wood scale 15 10 15 
X	box s15 -33 54 -1.5 33 60 1.5 texture wood scale 10 15 15 
X	box s15 -33 -60 -1.5 33 -54 1.5 texture wood scale 10 15 15 
X	sphere s16 1.5 0 0 0 translate 0 21 1.5 
X	box mirror -11.3333 -144.1 10 31.3333 -143.9 50 	/* was 40. -144 30. */
X	/*
X	 * Walls
X	 */
X	plane s10 					0 -144 0 0 1 0 
X	plane s10 				-180 0 0 1 0 0 
X	plane s10 			180 0 0 -1 0 0 
X	plane s10 			0 144 0 0 -1 0 
X	/*
X	 * Floor
X	 */
X	plane floor 				0 0 -30 0 0 1 
X		texture marble scale 6 6 6 rotate 1 0 0 90 
X				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 72 0 0 -1 
X
Xeyep 38 100 43 
Xlookp 0 0 0 
END_OF_FILE
if test 3791 -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 'etc/nff2shade.awk' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'etc/nff2shade.awk'\"
else
echo shar: Extracting \"'etc/nff2shade.awk'\" \(3477 characters\)
sed "s/^X//" >'etc/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#	mount | awk -f sped2shade.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 moving
X# ground polygons and the like outside of the topmost grid object.
X# This will decrease ray-tracing time dramatically.
X#
X# Note that we have to make sure that the viewing paramters are output
X# outside of the object definition block.  We do this by printing
X# the eye position, etc., at the very end of the output.
X#
XBEGIN{
X	init = 0;
X	lights = 0;
X	print "maxdepth 4"
X	print "sample 1 nojitter"
X	print "cutoff 0."
X	print "report verbose"
X}
Xsubstr($1, 1, 1) == "#" { print "/* " $0 " */"; next;}
X$1 == "v" { next;}
X$1 == "from" { eyex = $2; eyey = $3; eyez = $4; next;}
X$1 == "at" { atx = $2; aty = $3; atz = $4; next;}
X$1 == "up" { upx = $2; upy = $3; upz = $4; next;}
X$1 == "angle" { fov = $2; next;}
X$1 == "hither" {next;}
X$1 == "resolution" {screenx = $2; screeny = $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 (init == 0) {
X		print "grid 22 22 22";
X		init = 1;
X	}
X	printf("applysurf ");
X	if (lights != 0)
X		aintens = sqrt(lights) / (4*lights);
X	else
X		aintens = .1;
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	if (ar != 0 || ag != 0 || ab != 0)
X		printf("\tambient %f %f %f\n", ar, ag, ab);
X	if (dr != 0 || dg != 0 || db != 0)
X		printf("\tdiffuse %f %f %f\n", dr, dg, db);
X#
X# This gets a little strange.  We're given a color, Ks, and T.
X# We need a specular color, a specular reflectivity (for reflected
X# rays), and a transparency (for transmitted rays).
X# In rayshade, reflected rays have intensity proportional to
X# specular_color*reflectivity, transmitted proportaional to
X# specular_color*transparency, and specular hilights to
X# specular_color.  Also, Ks + T >1 for some SPDs.
X#
X	if ($6) {
X		sr = $2*$6;
X		sg = $3*$6;
X		sb = $4*$6;
X		printf("\tspecular %f %f %f specpow %f\n", sr, sg, sb, $7);
X	}
X	if ($6 < 1. - $8)
X		printf("\treflect 1.0\n");
X	else
X		printf("\treflect %f\n", 1. - $8);
X
X	if ($8 || $9)
X		printf("\ttransp %f index %f\n", $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 %f %f %f %f %f %f %f %f\n", \
X		br, x1, y1, z1, $4, $1, $2, $3);
X	next;
X}
X$1 == "s" {
X	print "sphere "$5 " "$2 " "$3 " "$4;
X	next;
X}
X$1 == "pp" {
X	if ($2 == 3)
X		print "triangle ";
X	else
X		print "poly ";
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 ";
X	else
X		print "poly ";
X	next;
X}
X{
X# Matched nothing (or is a vertex data) -- print it.
X	print;
X	next;
X}
XEND{
X	print "end"
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	printf("eyep %g %g %g\n", eyex, eyey, eyez);
X	printf("lookp %g %g %g\n", atx, aty, atz);
X	printf("up %g %g %g\n", upx, upy, upz);
X	printf("fov %g\n", fov);
X	printf("screen %d %d\n", screenx, screeny);
X}
END_OF_FILE
if test 3477 -ne `wc -c <'etc/nff2shade.awk'`; then
    echo shar: \"'etc/nff2shade.awk'\" unpacked with wrong size!
fi
# end of 'etc/nff2shade.awk'
fi
if test -f 'libray/libcommon/sampling.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libcommon/sampling.c'\"
else
echo shar: Extracting \"'libray/libcommon/sampling.c'\" \(3298 characters\)
sed "s/^X//" >'libray/libcommon/sampling.c' <<'END_OF_FILE'
X/*
X * sampling.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: sampling.c,v 4.0 91/07/17 14:31:55 kolb Exp Locker: kolb $
X *
X * $Log:	sampling.c,v $
X * Revision 4.0  91/07/17  14:31:55  kolb
X * Initial version.
X * 
X */
X#include "common.h"
X#include "sampling.h"
X
XSampleInfo	Sampling;	/* sampling information */
X
X/*
X * Set sampling options.
X */
Xvoid
XSamplingSetOptions(n, gaussian, width)
Xint n, gaussian;
XFloat width;
X{
X	Float norm, u, v;
X	int x, y;
X
X	Sampling.sidesamples = n;
X	Sampling.totsamples = n*n;
X	Sampling.weight = 1. / (Float)Sampling.totsamples;
X	Sampling.spacing = 1. / (Float)Sampling.sidesamples;
X	Sampling.filterwidth = width;
X	Sampling.filterdelta = Sampling.filterwidth * Sampling.spacing;
X	Sampling.gaussian = gaussian;
X
X	Sampling.filter = (Float **)Malloc(Sampling.sidesamples
X		*sizeof(Float *));
X	for (y = 0; y < Sampling.sidesamples; y++) {
X		Sampling.filter[y] = (Float *)Malloc(Sampling.sidesamples *
X			sizeof(Float));
X	}
X	if (Sampling.gaussian) {
X		norm = 0.;
X		u = -0.5*Sampling.filterwidth + 
X		     0.5*Sampling.filterwidth*Sampling.spacing;
X		for (x = 0; x < Sampling.sidesamples; x++) {
X			v = -0.5*Sampling.filterwidth +
X			     0.5*Sampling.filterwidth*Sampling.spacing;
X			for (y = 0; y < Sampling.sidesamples; y++) {
X				Sampling.filter[x][y] = exp(-0.5*(u*u+v*v));
X				norm += Sampling.filter[x][y];
X				v += Sampling.spacing *
X					Sampling.filterwidth;
X			}
X			u += Sampling.spacing * Sampling.filterwidth;
X		}
X		
X		for (x = 0; x < Sampling.sidesamples; x++)
X			for (y = 0; y < Sampling.sidesamples; y++)
X				Sampling.filter[x][y] /= norm;
X	} else {
X		/* Box filter.  Yawn. */
X		for (x = 0; x < Sampling.sidesamples; x++)
X			for (y = 0; y < Sampling.sidesamples; y++)
X				Sampling.filter[x][y] = Sampling.weight;
X	}
X}
X
X/*
X * Set start time and duration of frame.
X */
Xvoid
XSamplingSetTime(starttime, shutter, frame)
XFloat starttime, shutter;
Xint frame;
X{
X	Sampling.starttime = starttime;
X	Sampling.shutter = shutter;
X	Sampling.framenum = frame;
X	TimeSet(Sampling.starttime);
X	FrameSet((Float)frame);
X}
X
X/*
X * Find a point on a unit circle that is separated from other random
X * points by some jitter spacing.
X *
X * It should do the above, but the temporary hack below just finds a
X * jittered point in a unit square.
X */
Xvoid
XUnitCirclePoint(pnt, sample)
XVector *pnt;
X{
X	/*
X	 * This picks a random point on a -1 to 1 square.  The jitter stuff
X	 * is correct enough to avoid excessive noise.  An extremely blurry
X	 * bright highlight will look squarish, not roundish.  Sorry.
X	 */
X	Float jit;
X
X	if (sample >= 0) {
X		jit = 2. * Sampling.spacing;
X
X		pnt->x = nrand()*jit - 1.0 +
X			(sample % Sampling.sidesamples) * jit;
X		pnt->y = nrand()*jit - 1.0 +
X			(sample / Sampling.sidesamples) * jit;
X		pnt->z = 0.0;
X	} else {
X		pnt->x = nrand() * 2.0 - 1.0;
X		pnt->y = nrand() * 2.0 - 1.0;
X		pnt->z = 0.0;
X	}
X}
END_OF_FILE
if test 3298 -ne `wc -c <'libray/libcommon/sampling.c'`; then
    echo shar: \"'libray/libcommon/sampling.c'\" unpacked with wrong size!
fi
# end of 'libray/libcommon/sampling.c'
fi
if test -f 'libray/libcommon/vecmath.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libcommon/vecmath.c'\"
else
echo shar: Extracting \"'libray/libcommon/vecmath.c'\" \(3857 characters\)
sed "s/^X//" >'libray/libcommon/vecmath.c' <<'END_OF_FILE'
X/*
X * vecmath.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: vecmath.c,v 4.0.1.2 91/11/26 21:36:15 cek Exp Locker: cek $
X *
X * $Log:	vecmath.c,v $
X * Revision 4.0.1.2  91/11/26  21:36:15  cek
X * patch3: Potential roundoff problems.
X * 
X * Revision 4.0.1.1  91/09/29  15:38:41  cek
X * patch1: Fixed floating-point compare in normalization code.
X *
X * Revision 4.0  91/07/17  14:33:02  kolb
X * Initial version.
X * 
X */
X#include "common.h"
X
X/*
X * Normalize a vector, return original length.
X */
XFloat
XVecNormalize(a)
Xregister Vector *a;
X{
X	Float d;
X
X	d = sqrt(a->x*a->x + a->y*a->y + a->z*a->z);
X	if (equal(d, 0.))
X		return 0.;
X	a->x /= d;
X	a->y /= d;
X	a->z /= d;
X#ifdef CRAY
X	/*
X	 * The Cray Research Inc. math functional units don't work in the IEEE
X	 * standard way, so when we get here, we just might have an x,y or z
X	 * that is not in the range  -1.0 <= J <= 1.0 Yes, I know that that
X	 * can't happen, but it does. So since we know we just normalized this
X	 * vector, we'll just force x,y and z into the range -1.0 to 1.0 O.K?
X	 */
X	if (a->x >= 1.0) a->x = 1.0;
X	else if (a->x <= -1.0) a->x = -1.0;
X	if (a->y >= 1.0) a->y = 1.0;
X	else if (a->y <= -1.0) a->y = -1.0;
X	if (a->z >= 1.0) a->z = 1.0;
X	else if (a->z <= -1.0) a->z = -1.0;
X#endif /* CRAY */
X
X	return d;
X}
X
X/*
X * Compute cross-product of a and b, place normalized result in o.  Returns
X * length of result before normalization.
X */
XFloat
XVecNormCross(a, b, r)
XVector *a, *b, *r;
X{
X	VecCross(a, b, r);
X	return VecNormalize(r);
X}
X
X/*
X * Compute cross-product of a and b, place result in o.
X */
Xvoid
XVecCross(a, b, r)
XVector *a, *b, *r;
X{
X	r->x = (a->y * b->z) - (a->z * b->y);
X	r->y = (a->z * b->x) - (a->x * b->z);
X	r->z = (a->x * b->y) - (a->y * b->x);
X}
X
X/*
X * Calculate direction of refracted ray using Heckbert's formula.  Returns TRUE
X * if a total internal reflection occurs.
X */
Xint
XRefract(dir, from_index, to_index, I, N, cos1)
XFloat from_index, to_index, cos1;
XVector *dir, *I, *N;
X{
X	double kn, cos2, k;
X	Vector nrm;
X
X	if (cos1 < 0.) {
X		/*
X		 * Hit the 'backside' of a surface -- flip the normal.
X		 */
X		nrm.x = -N->x;
X		nrm.y = -N->y;
X		nrm.z = -N->z;
X		cos1 = -cos1;
X	} else
X		nrm = *N;
X
X	kn = from_index / to_index;
X	cos2 = 1. - kn*kn*(1. - cos1*cos1);
X	if (cos2 < 0.)
X		return TRUE;		/* Total internal reflection. */
X	k = kn * cos1 - sqrt((double)cos2);
X	VecComb(kn, *I, k, nrm, dir);
X	return FALSE;
X}
X
X/*
X * Given a vector, find two additional vectors such that all three
X * are mutually perpendicular and uaxis X vaxis = vector.  The given
X * vector need not be normalized. uaxis and vaxis are normalized.
X */
Xvoid
XVecCoordSys(vector, uaxis, vaxis)
XVector *vector, *uaxis, *vaxis;
X{
X	uaxis->x = -vector->y;
X	uaxis->y = vector->x;
X	uaxis->z = 0.;
X	if (VecNormalize(uaxis) == 0.) {
X		uaxis->x = vector->z;
X		uaxis->y = 0.;
X		uaxis->z = -vector->x;
X		if (VecNormalize(uaxis) == 0.)
X			RLerror(RL_WARN,
X				"VecCoordSys passed degenerate vector.\n");
X	}
X	(void)VecNormCross(vector, uaxis, vaxis);
X}
X
X/*
X * Modify given normal by "bumping" it.
X */
Xvoid
XMakeBump(norm, dpdu, dpdv, fu, fv)
XVector *norm, *dpdu, *dpdv;	/* normal, surface derivatives */
XFloat fu, fv;			/* bump function partial derivatives in uv */
X{
X	Vector tmp1, tmp2;
X
X	VecCross(norm, dpdv, &tmp1);
X	VecScale(fu, tmp1, &tmp1);
X	VecCross(norm, dpdu, &tmp2);
X	VecScale(fv, tmp2, &tmp2);
X	VecSub(tmp1, tmp2, &tmp1);
X	VecAdd(*norm, tmp1, norm);
X	(void)VecNormalize(norm);
X}
END_OF_FILE
if test 3857 -ne `wc -c <'libray/libcommon/vecmath.c'`; then
    echo shar: \"'libray/libcommon/vecmath.c'\" unpacked with wrong size!
fi
# end of 'libray/libcommon/vecmath.c'
fi
if test -f 'libray/liblight/spot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/liblight/spot.c'\"
else
echo shar: Extracting \"'libray/liblight/spot.c'\" \(3312 characters\)
sed "s/^X//" >'libray/liblight/spot.c' <<'END_OF_FILE'
X/*
X * spot.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: spot.c,v 4.0 91/07/17 14:35:42 kolb Exp Locker: kolb $
X *
X * $Log:	spot.c,v $
X * Revision 4.0  91/07/17  14:35:42  kolb
X * Initial version.
X * 
X */
X#include "light.h"
X#include "spot.h"
X
Xstatic LightMethods *iSpotMethods = NULL;
X
XSpotlight *
XSpotCreate(from, to, coef, in, out)
XVector *from, *to;
XFloat coef, in, out;
X{
X	Spotlight *spot;
X
X	spot = (Spotlight *)share_malloc(sizeof(Spotlight));
X	spot->pos = *from;
X	VecSub(*to, *from, &spot->dir);
X	if (VecNormalize(&spot->dir) == 0. || in > out) {
X		RLerror(RL_ABORT,"Invalid spotlight specification.\n");
X		return (Spotlight *)NULL;
X	}
X	spot->coef = coef;
X	spot->radius = cos(deg2rad(in));
X	spot->falloff = cos(deg2rad(out));
X
X	return spot;
X}
X
XLightMethods *
XSpotMethods()
X{
X	if (iSpotMethods == (LightMethods *)NULL) {
X		iSpotMethods = LightMethodsCreate();
X		iSpotMethods->intens = SpotIntens;
X		iSpotMethods->dir = SpotDirection;
X	}
X	return iSpotMethods;
X}
X
X/*
X * Calculate intensity ('color') of light reaching 'pos' from light 'lp'.
X * The spotlight is 'dist' units from 'pos' along 'dir'.
X *
X * Returns TRUE if non-zero illumination, FALSE otherwise.
X */
Xint
XSpotIntens(spot, lcolor, cache, ray, dist, noshadow, color)
XSpotlight *spot;
XShadowCache *cache;
XRay *ray;
XColor *lcolor, *color;
Xint noshadow;
XFloat dist;
X{
X	Float atten;
X	extern Float SpotAtten();
X
X	/*
X	 * Compute spotlight color
X	 */
X	atten = SpotAtten(spot, &ray->dir);
X	/*
X	 * If outside of spot, return FALSE.
X	 */
X	if (atten == 0.)
X		return FALSE;
X	if (Shadowed(color, lcolor, cache, ray, dist, noshadow))
X		return FALSE;
X	ColorScale(atten, *color, color);
X	return TRUE;
X}
X
X/*
X * Compute intensity of spotlight along 'dir'.
X */
XFloat
XSpotAtten(lp, dir)
XSpotlight *lp;
XVector *dir;
X{
X	Float costheta, atten;
X	extern Float rampup();
X
X	costheta = -dotp(dir, &lp->dir);
X	/*
X	 * Behind spotlight.
X	 */
X	if (costheta <= 0.)
X		return 0.;
X	/*
X	 * Intensity is the product of costheta raised to lp->coef and
X	 * a function that smoothly interpolates from 0 at
X	 * costheta=lp->falloff to 1 at costheta=lp->radius.
X	 */
X	atten = pow(costheta, lp->coef);
X	if (lp->radius > 0.)
X		atten *= rampup(lp->falloff, lp->radius, costheta);
X	return atten;
X}
X
X/*
X * Cubic interpolation between 0 at left and 1 at right, sampled at 'at'
X * It is assumed that right >= left.
X */
XFloat
Xrampup(left, right, at)
XFloat left, right, at;
X{
X	if (at < left)
X		return 0.;
X	else if (at > right)
X		return 1.;
X
X	if (right == left)
X		return 0.;
X
X	at = (at - left) / (right - left);
X	return (3 - 2*at)*at*at;
X}
X
Xvoid
XSpotDirection(lp, pos, dir, dist)
XSpotlight *lp;
XVector *pos, *dir;
XFloat *dist;
X{
X	/*
X	 * Calculate dir from position to center of light source.
X	 */
X	VecSub(lp->pos, *pos, dir);
X	*dist = VecNormalize(dir);
X}
X
XSpotMethodRegister(meth)
XUserMethodType meth;
X{
X	if (iSpotMethods)
X		iSpotMethods->user = meth;
X}
END_OF_FILE
if test 3312 -ne `wc -c <'libray/liblight/spot.c'`; then
    echo shar: \"'libray/liblight/spot.c'\" unpacked with wrong size!
fi
# end of 'libray/liblight/spot.c'
fi
if test -f 'libray/libobj/box.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libobj/box.c'\"
else
echo shar: Extracting \"'libray/libobj/box.c'\" \(3201 characters\)
sed "s/^X//" >'libray/libobj/box.c' <<'END_OF_FILE'
X/*
X * box.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: box.c,v 4.0 91/07/17 14:36:32 kolb Exp Locker: kolb $
X *
X * $Log:	box.c,v $
X * Revision 4.0  91/07/17  14:36:32  kolb
X * Initial version.
X * 
X */
X#include "geom.h"
X#include "box.h"
X
Xstatic Methods *iBoxMethods = NULL;
Xstatic char boxName[] = "box";
X
Xunsigned long BoxTests, BoxHits;
X
XBox *
XBoxCreate(v1, v2)
XVector *v1, *v2;
X{
X	Box *box;
X	Vector size;
X
X	VecSub(*v1, *v2, &size);
X
X	if (equal(size.x, 0.) || equal(size.y, 0.) || equal(size.z, 0.)) {
X		RLerror(RL_WARN, "Degenerate box.\n");
X		return (Box *)NULL;
X	}
X
X	box = (Box *)share_malloc(sizeof(Box));
X	box->bounds[LOW][X] = min(v1->x, v2->x);
X	box->bounds[HIGH][X] = max(v1->x, v2->x);
X	box->bounds[LOW][Y] = min(v1->y, v2->y);
X	box->bounds[HIGH][Y] = max(v1->y, v2->y);
X	box->bounds[LOW][Z] = min(v1->z, v2->z);
X	box->bounds[HIGH][Z] = max(v1->z, v2->z);
X	return box;
X}
X
XMethods *
XBoxMethods()
X{
X	if (iBoxMethods == (Methods *)NULL) {
X		iBoxMethods = MethodsCreate();
X		iBoxMethods->create = (GeomCreateFunc *)BoxCreate;
X		iBoxMethods->methods = BoxMethods;
X		iBoxMethods->name = BoxName;
X		iBoxMethods->intersect = BoxIntersect;
X		iBoxMethods->normal = BoxNormal;
X		iBoxMethods->enter = BoxEnter;
X		iBoxMethods->bounds = BoxBounds;
X		iBoxMethods->stats = BoxStats;
X		iBoxMethods->checkbounds = FALSE;
X		iBoxMethods->closed = TRUE;
X	}
X	return iBoxMethods;
X}
X
Xint
XBoxIntersect(box, ray, mindist, maxdist)
XBox *box;
XRay *ray;
XFloat mindist, *maxdist;
X{
X	BoxTests++;
X	if (BoundsIntersect(ray, box->bounds, mindist, maxdist)) {
X		BoxHits++;
X		return TRUE;
X	}
X	return FALSE;
X}
X
Xint
XBoxNormal(box, pos, nrm, gnrm)
XVector *pos, *nrm, *gnrm;	/* point of intersection */
XBox *box;
X{
X	nrm->x = nrm->y = nrm->z = 0.;
X
X	if (equal(pos->x, box->bounds[HIGH][X]))
X		nrm->x = 1.;
X	else if (equal(pos->x, box->bounds[LOW][X]))
X		nrm->x = -1.;
X	else if (equal(pos->y, box->bounds[HIGH][Y]))
X		nrm->y = 1.;
X	else if (equal(pos->y, box->bounds[LOW][Y]))
X		nrm->y = -1.;
X	else if (equal(pos->z, box->bounds[HIGH][Z]))
X		nrm->z = 1.;
X	else if (equal(pos->z, box->bounds[LOW][Z]))
X		nrm->z = -1.;
X	else
X		RLerror(RL_WARN, "Confusion in nrmbox!\n");
X	*gnrm = *nrm;
X	return FALSE;
X}
X
X/*
X * Determine if ray enters (TRUE) or leaves (FALSE) box at pos
X */
Xint
XBoxEnter(box, ray, mind, hitd)
XBox *box;
XRay *ray;
XFloat mind, hitd;
X{
X	Vector pos;
X
X	VecAddScaled(ray->pos, mind, ray->dir, &pos);
X	return OutOfBounds(&pos, box->bounds);
X}
X
Xvoid
XBoxBounds(box, bounds)
XBox *box;
XFloat bounds[2][3];
X{
X	BoundsCopy(box->bounds, bounds);
X}
X
Xchar *
XBoxName()
X{
X	return boxName;
X}
X
Xvoid
XBoxStats(tests, hits)
Xunsigned long *tests, *hits;
X{
X	*tests = BoxTests;
X	*hits = BoxHits;
X}
X
Xvoid
XBoxMethodRegister(meth)
XUserMethodType meth;
X{
X	if (iBoxMethods)
X		iBoxMethods->user = meth;
X}
END_OF_FILE
if test 3201 -ne `wc -c <'libray/libobj/box.c'`; then
    echo shar: \"'libray/libobj/box.c'\" unpacked with wrong size!
fi
# end of 'libray/libobj/box.c'
fi
if test -f 'libray/libobj/list.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libobj/list.c'\"
else
echo shar: Extracting \"'libray/libobj/list.c'\" \(3113 characters\)
sed "s/^X//" >'libray/libobj/list.c' <<'END_OF_FILE'
X/*
X * list.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: list.c,v 4.0 91/07/17 14:38:42 kolb Exp Locker: kolb $
X *
X * $Log:	list.c,v $
X * Revision 4.0  91/07/17  14:38:42  kolb
X * Initial version.
X * 
X */
X#include "geom.h"
X#include "list.h"
X
Xstatic Methods *iListMethods = NULL;
Xstatic char listName[] = "list";
X
XList *
XListCreate()
X{
X	return (List *)share_calloc(1, sizeof(List));
X}
X
Xchar *
XListName()
X{
X	return listName;
X}
X
X/*
X * Take a list whose DATA field points to a linked list of objects and
X * turn it into a List.
X */
Xint
XListConvert(list, objlist)
XList *list;
XGeom *objlist;
X{
X	int num;
X
X	/*
X	 * Find the unbounded objects on the list as well as the
X	 * bounding box of the list.
X	 */
X	list->list = objlist;
X	for (num = 0; objlist; objlist = objlist->next)
X		num += objlist->prims;
X	return num;
X}
X
X/*
X * Intersect ray & list of objects.
X */
Xint
XListIntersect(list, ray, hitlist, mindist, maxdist)
XList *list;
XRay *ray;
XHitList *hitlist;
XFloat mindist, *maxdist;
X{
X	Geom *objlist;
X	Vector vtmp;
X	Float s;
X	int hit;
X
X	hit = FALSE;
X	/*
X	 * Intersect with unbounded objects.
X	 */
X	for (objlist = list->unbounded; objlist ; objlist = objlist->next) {
X		if (intersect(objlist, ray, hitlist, mindist, maxdist))
X			hit = TRUE;
X	}
X
X	/*
X	 * Check for intersection with bounding box.
X	 */
X	s = *maxdist;	/* So maxdist won't be reset. */
X	VecAddScaled(ray->pos, mindist, ray->dir, &vtmp);
X	if (OutOfBounds(&vtmp, list->bounds) &&
X	    !BoundsIntersect(ray, list->bounds, mindist, &s))
X		/*
X		 * Ray never hit list.
X		 */
X		return hit;
X	/*
X	 * Else the ray enters list-space before it hits an
X	 * unbounded object. Intersect with objects on list.
X	 */
X	for (objlist = list->list; objlist ; objlist = objlist->next) {
X		if (intersect(objlist, ray, hitlist, mindist, maxdist))
X			hit = TRUE;
X	}
X
X	return hit;
X}
X
XMethods *
XListMethods()
X{
X	if (iListMethods == (Methods *)NULL) {
X		iListMethods = MethodsCreate();
X		iListMethods->methods = ListMethods;
X		iListMethods->create = (GeomCreateFunc *)ListCreate;
X		iListMethods->name = ListName;
X		iListMethods->intersect = ListIntersect;
X		iListMethods->bounds = ListBounds;
X		iListMethods->convert = ListConvert;
X		iListMethods->checkbounds = FALSE;
X		iListMethods->closed = TRUE;
X	}
X	return iListMethods;
X}
X
Xvoid
XListBounds(list, bounds)
XList *list;
XFloat bounds[2][3];
X{
X	Geom *obj, *next;
X
X	BoundsInit(list->bounds);
X	/*
X	 * For each object on the list,
X	 * compute its bounds...
X	 */
X	list->unbounded  = GeomComputeAggregateBounds(&list->list, 
X				list->unbounded, list->bounds);
X	BoundsCopy(list->bounds, bounds);
X}
X
Xvoid
XListMethodRegister(meth)
XUserMethodType meth;
X{
X	if (iListMethods)
X		iListMethods->user = meth;
X}
END_OF_FILE
if test 3113 -ne `wc -c <'libray/libobj/list.c'`; then
    echo shar: \"'libray/libobj/list.c'\" unpacked with wrong size!
fi
# end of 'libray/libobj/list.c'
fi
if test -f 'libray/libobj/plane.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libobj/plane.c'\"
else
echo shar: Extracting \"'libray/libobj/plane.c'\" \(2991 characters\)
sed "s/^X//" >'libray/libobj/plane.c' <<'END_OF_FILE'
X/*
X * plane.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: plane.c,v 4.0 91/07/17 14:38:51 kolb Exp Locker: kolb $
X *
X * $Log:	plane.c,v $
X * Revision 4.0  91/07/17  14:38:51  kolb
X * Initial version.
X * 
X */
X#include "geom.h"
X#include "plane.h"
X
Xstatic Methods *iPlaneMethods = NULL;
Xstatic char planeName[] = "plane";
X
Xunsigned long PlaneTests, PlaneHits;
X
X/*
X * create plane primitive
X */
XPlane *
XPlaneCreate(pos, norm)
XVector *pos, *norm;
X{
X	Plane *plane;
X	Vector tmpnrm;
X
X	tmpnrm = *norm;
X	if (VecNormalize(&tmpnrm) == 0.) {
X		RLerror(RL_WARN, "Degenerate plane normal.\n");
X		return (Plane *)NULL;
X	}
X	plane = (Plane *)share_malloc(sizeof(Plane));
X	plane->norm = tmpnrm;
X	plane->pos = *pos;
X	plane->d = dotp(&plane->norm, pos);
X
X	return plane;
X}
X
XMethods *
XPlaneMethods()
X{
X	if (iPlaneMethods == (Methods *)NULL) {
X		iPlaneMethods = MethodsCreate();
X		iPlaneMethods->name = PlaneName;
X		iPlaneMethods->create = (GeomCreateFunc *)PlaneCreate;
X		iPlaneMethods->methods = PlaneMethods;
X		iPlaneMethods->intersect = PlaneIntersect;
X		iPlaneMethods->normal = PlaneNormal;
X		iPlaneMethods->uv = PlaneUV;
X		iPlaneMethods->bounds = PlaneBounds;
X		iPlaneMethods->stats = PlaneStats;
X		iPlaneMethods->checkbounds = FALSE;
X		iPlaneMethods->closed = FALSE;
X	}
X	return iPlaneMethods;
X}
X
Xint
XPlaneIntersect(plane, ray, mindist, maxdist)
XPlane *plane;
XRay *ray;
XFloat mindist, *maxdist;
X{
X	Float d;
X
X	PlaneTests++;
X
X	d = dotp(&plane->norm, &ray->dir);
X	if (fabs(d) < EPSILON)
X		return FALSE;
X	d = (plane->d - dotp(&plane->norm, &ray->pos)) / d;
X
X	if (d > mindist && d < *maxdist) {
X		*maxdist = d;
X		PlaneHits++;
X		return TRUE;
X	}
X	return FALSE;
X}
X
X/*ARGSUSED*/
Xint
XPlaneNormal(plane, pos, nrm, gnrm)
XPlane *plane;
XVector *pos, *nrm, *gnrm;
X{
X	*gnrm = *nrm = plane->norm;
X	return FALSE;
X}
X
Xvoid
XPlaneUV(plane, pos, norm, uv, dpdu, dpdv)
XPlane *plane;
XVector *pos, *norm, *dpdu, *dpdv;
XVec2d *uv;
X{
X	Vector vec, du, dv;
X
X	VecCoordSys(norm, &du, &dv);
X	VecSub(*pos, plane->pos, &vec);
X
X	uv->u = dotp(&vec, &du);
X	uv->v = dotp(&vec, &dv);
X
X	if (dpdu)
X		*dpdu = du;
X	if (dpdv)
X		*dpdv = dv;
X}
X	
X/*ARGSUSED*/
Xvoid
XPlaneBounds(plane, bounds)
XPlane *plane;
XFloat bounds[2][3];
X{
X	/*
X	 * Planes are unbounded by nature.  minx > maxx signifies
X	 * this.
X	 */
X	bounds[LOW][X] = 1.0;
X	bounds[HIGH][X] = -1.0;
X}
X
Xchar *
XPlaneName()
X{
X	return planeName;
X}
X
Xvoid
XPlaneStats(tests, hits)
Xunsigned long *tests, *hits;
X{
X	*tests = PlaneTests;
X	*hits = PlaneHits;
X}
X
Xvoid
XPlaneMethodRegister(meth)
XUserMethodType meth;
X{
X	if (iPlaneMethods)
X		iPlaneMethods->user = meth;
X}
END_OF_FILE
if test 2991 -ne `wc -c <'libray/libobj/plane.c'`; then
    echo shar: \"'libray/libobj/plane.c'\" unpacked with wrong size!
fi
# end of 'libray/libobj/plane.c'
fi
if test -f 'libray/libsurf/surface.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libsurf/surface.c'\"
else
echo shar: Extracting \"'libray/libsurf/surface.c'\" \(3304 characters\)
sed "s/^X//" >'libray/libsurf/surface.c' <<'END_OF_FILE'
X/*
X * surface.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: surface.c,v 4.0 91/07/17 14:40:55 kolb Exp Locker: kolb $
X *
X * $Log:	surface.c,v $
X * Revision 4.0  91/07/17  14:40:55  kolb
X * Initial version.
X * 
X */
X#include "atmosphere.h"
X#include "surface.h"
X
X#define blend(a, b, p, q)	(a * p + b * q)
X
XColor	Black = {0., 0., 0.},
X	White = {1., 1., 1.};
X
X/*
X * Create and return pointer to surface with given properties.
X */
XSurface *
XSurfaceCreate()
X{
X	Surface *stmp;
X
X	stmp = (Surface *)Malloc(sizeof(Surface));
X
X	stmp->amb = stmp->diff = stmp->spec =
X		stmp->translu = Black;
X
X	stmp->body = White;
X
X	stmp->srexp = stmp->stexp = DEFAULT_PHONGPOW;
X	stmp->statten = 1.;	/* No attenuation by default */
X
X	stmp->reflect = stmp->transp = 0.;
X
X	stmp->noshadow = FALSE;
X
X	stmp->index = DEFAULT_INDEX;
X
X	stmp->name = (char *)NULL;
X	stmp->next = (Surface *)NULL;
X
X	return stmp;
X}
X
XSurface *
XSurfaceCopy(surf)
XSurface *surf;
X{
X	Surface *res;
X
X	if (!surf)
X		return (Surface *)NULL;
X
X	res = SurfaceCreate();
X	*res = *surf;
X	res->next = (Surface *)NULL;
X	res->name = (char *)NULL;
X	return res;
X}
X
X/*
X * Compute combination of two surfaces. Resulting surface is copied into surf1.
X */
Xvoid
XSurfaceBlend(surf1, surf2, p, q)
XSurface *surf1, *surf2;
XFloat p, q;
X{
X	/*
X 	 * P is weight of surf1.  q is weight of surf2.
X	 * Result is placed in surf1.
X	 */
X	if (q < EPSILON)
X		return;	/* keep surf1 as-is */
X
X	ColorBlend(&surf1->amb, &surf2->amb, p, q);
X	ColorBlend(&surf1->diff, &surf2->diff, p, q);
X	ColorBlend(&surf1->spec, &surf2->spec, p, q);
X	ColorBlend(&surf1->translu, &surf2->translu, p, q);
X	ColorBlend(&surf1->body, &surf2->body, p, q);
X
X	surf1->srexp = blend(surf1->srexp, surf2->srexp, p, q);
X	surf1->stexp = blend(surf1->stexp, surf2->stexp, p, q);
X
X	surf1->reflect = blend(surf1->reflect, surf2->reflect, p, q);
X	surf1->transp  = blend(surf1->transp,  surf2->transp,  p, q);
X	surf1->translucency = blend(surf1->translucency, surf2->translucency,
X			p, q);
X	/*
X	 * Questionable...
X	 */
X	surf1->statten = blend(surf1->statten, surf2->statten, p, q);
X	surf1->index = blend(surf1->index, surf2->index, p, q);
X
X	if (p < EPSILON) {
X		surf1->noshadow = surf2->noshadow;
X	} else {
X		/* else there's a blend of some kind... */
X		surf1->noshadow = (surf1->noshadow && surf2->noshadow);
X	}
X}
X
X/*
X * Blend two colors.  Result is placed in color1.
X */
Xvoid
XColorBlend(color1, color2, p, q)
XColor *color1, *color2;
XFloat 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
XSurfList *
XSurfPop(list)
XSurfList *list;
X{
X	SurfList *stmp = list->next;
X
X	free((voidstar)list);
X	return stmp;
X}
X
XSurfList *
XSurfPush(surf, list)
XSurface *surf;
XSurfList *list;
X{
X	SurfList *stmp;
X
X	stmp = (SurfList *)Malloc(sizeof(SurfList));
X	stmp->surf = surf;
X	stmp->next = list;
X	return stmp;
X}
END_OF_FILE
if test 3304 -ne `wc -c <'libray/libsurf/surface.c'`; then
    echo shar: \"'libray/libsurf/surface.c'\" unpacked with wrong size!
fi
# end of 'libray/libsurf/surface.c'
fi
if test -f 'libshade/lightdef.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/lightdef.c'\"
else
echo shar: Extracting \"'libshade/lightdef.c'\" \(3547 characters\)
sed "s/^X//" >'libshade/lightdef.c' <<'END_OF_FILE'
X/*
X * lightdef.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: lightdef.c,v 4.0 91/07/17 14:46:25 kolb Exp Locker: kolb $
X *
X * $Log:	lightdef.c,v $
X * Revision 4.0  91/07/17  14:46:25  kolb
X * Initial version.
X * 
X */
X#include "rayshade.h"
X#include "options.h"
X#include "liblight/light.h"
X#include "liblight/infinite.h"	/* to create default infinite light */
X#include "liblight/jittered.h"	/* to create jittered light sources */
X
XLight *Lights = NULL;		/* Linked list of defined lights */
X
Xvoid
XLightAddToDefined(light)
XLight *light;
X{
X	if (light) {
X		light->next = Lights;
X		Lights = light;
X	}
X}
X
Xvoid
XLightSetup()
X{
X	long shadowopts;
X	Light *ltmp;
X
X	/*
X	 * Set shadowing options.
X	 */
X	shadowopts = 0;
X	if (Options.no_shadows)
X		shadowopts |= SHADOW_NONE;
X	if (Options.shadowtransp)
X		shadowopts |= SHADOW_TRANSP;
X	if (Options.csg)
X		shadowopts |= SHADOW_CSG;
X	if (Options.cache)
X		shadowopts |= SHADOW_CACHE;
X	if (Options.shutterspeed > 0.)
X		shadowopts |= SHADOW_BLUR;
X	ShadowSetOptions(shadowopts);
X
X	/*
X	 * If no light sources were defined, add a default.
X	 */
X	if (Lights == (Light *)NULL) {
X		Color ctmp;
X		Vector vtmp;
X		vtmp.x = vtmp.z = 1.;
X		vtmp.y = -1;
X		ctmp.r = ctmp.g = ctmp.b = 1.;
X
X		LightAddToDefined(LightInfiniteCreate(&ctmp, &vtmp));
X	}
X	/*
X	 * Now that we've parsed the input file, we know what
X	 * maxlevel is, and we can allocate the correct amount of
X	 * space for each light source's cache.
X	 */
X	for (ltmp = Lights; ltmp; ltmp = ltmp->next) {
X		ltmp->cache = (ShadowCache *)Calloc(
X			(unsigned)Options.maxdepth + 1, sizeof(ShadowCache));
X	}
X}
X
Xvoid
XAreaLightCreate(color, corner, u, usamp, v, vsamp, shadow)
XColor *color;
XVector *corner, *u, *v;
Xint usamp, vsamp, shadow;
X{
X	Vector vpos, curpos;
X	int i, j, numlight;
X	Float ulen, vlen;
X	Color intens;
X	Light *ltmp;
X
X	if (usamp < 1 || vsamp < 1)
X		RLerror(RL_ABORT, "Invalid area light specification.\n");
X
X	numlight = usamp * vsamp;	/* Total number of jittered sources */
X
X	/*
X	 * Sum of all intensities is equal to specified intensity.
X	 */
X	intens.r = color->r / (Float)numlight;
X	intens.g = color->g / (Float)numlight;
X	intens.b = color->b / (Float)numlight;
X
X	VecSub(*u, *corner, u);
X	VecSub(*v, *corner, v);
X	/*
X	 * Make sure that u and v are not degenerate.
X	 */
X	ulen = VecNormalize(u);
X	vlen = VecNormalize(v);
X	if (ulen < EPSILON || vlen < EPSILON)
X		RLerror(RL_ABORT, "Degenerate area light source.\n");
X	/*
X	 * Scale u and v such that they define the area covered by a
X	 * single sample.
X	 */
X	VecScale(ulen / (Float)usamp, *u, u); 
X	VecScale(vlen / (Float)vsamp, *v, v);
X	/*
X	 * For each sample...
X	 */
X	vpos = *corner;
X	for (i = 0; i < vsamp; i++) {
X		curpos = vpos;
X		for (j = 0; j < usamp; j++) {
X			/*
X			 * current pos is the "corner" of a new light
X			 * source.  A jittered position based on
X			 * the "corner" and the two edge vectors
X			 * is used as the position for the
X			 * light source in lighting calculations.
X			 */
X			ltmp = LightJitteredCreate(&intens, &curpos, u, v);
X			ltmp->shadow = shadow;
X			LightAddToDefined(ltmp);
X			VecAdd(curpos, *u, &curpos);
X		}
X		VecAdd(vpos, *v, &vpos);
X	}
X}
END_OF_FILE
if test 3547 -ne `wc -c <'libshade/lightdef.c'`; then
    echo shar: \"'libshade/lightdef.c'\" unpacked with wrong size!
fi
# end of 'libshade/lightdef.c'
fi
if test -f 'libshade/options.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/options.h'\"
else
echo shar: Extracting \"'libshade/options.h'\" \(3457 characters\)
sed "s/^X//" >'libshade/options.h' <<'END_OF_FILE'
X/*
X * options.h
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: options.h,v 4.0.1.2 92/01/14 18:29:14 cek Exp Locker: cek $
X *
X * $Log:	options.h,v $
X * Revision 4.0.1.2  92/01/14  18:29:14  cek
X * patch3: Added "cpp" option.
X * 
X * Revision 4.0.1.1  91/09/29  15:51:17  cek
X * patch1: Added window and crop options.
X * 
X * Revision 4.0  91/07/17  14:46:54  kolb
X * Initial version.
X * 
X */
X#ifndef OPTIONS_H
X#define OPTIONS_H
X
X/*
X * Constants for Stereo mode
X */
X#define LEFT		1
X#define RIGHT		2
X
X/*
X * Options
X */
Xtypedef struct RSOptions {
X	int	stereo,			/* Stereo mode? */
X		verbose,		/* Babbling mode? */
X		quiet,			/* Don't complain? */
X		jitter,			/* use jittered sampling? */
X		samples,		/* Sqrt of # of samples */
X		maxdepth,		/* Maximum ray tree depth */
X		report_freq,		/* Frequency, in lines, of report */
X		no_shadows,		/* Trace shadow rays? */
X		shadowtransp,		/* ... through transparent objects? */
X		cache,			/* Cache shadowing info? */
X		appending,		/* Append to image file? */
X		resolution_set,		/* resolution set on command line */
X		contrast_set,		/* contrast overridden ... */
X		samples_set,		/* samples overridden ... */
X		cutoff_set,		/* cutoff ... */
X		maxdepth_set,		/* adaptive depth ... */
X		window_set,		/* subwindow ... */
X		crop_set,		/* crop window ... */
X		freq_set,		/* report frequency ... */
X		jitter_set,		/* use jittering */
X		eyesep_set,		/* eye separation ... */
X		csg,			/* CSG object someplace in world */
X		flipnorm,		/* flip normals of polygonal objs */
X		samplemap,		/* output sample map? */
X		gaussian,		/* Use gaussian pixel filter? */
X		framenum,		/* current frame number */
X		startframe,		/* Starting frame number. */
X		endframe,		/* ending frame number */
X		totalframes,		/* total # of frames */
X		totalframes_set,	/* set on command line? */
X		cpp;			/* run CPP? */
X#ifdef URT
X	int	alpha;			/* Write alpha channel? */
X	int	exp_output;		/* Write exponential RLE file? */
X#endif
X	Float	eyesep,			/* Eye separation (for Stereo mode) */
X		gamma,			/* Gamma value (0 == no correction) */
X		starttime,		/* Think about it ... */
X		shutterspeed,		/* time shutter is open */
X		framestart,		/* start time of the current frame */
X		framelength,		/* length of the current frame */
X		filterwidth;		/* Pixel filter width. */
X	Color	contrast,		/* Max. allowable contrast */
X		cutoff,			/* Ray tree depth control */
X		ambient;		/* Ambient light multiplier */
X	char	*progname,		/* argv[0] */
X		*statsname,		/* Name of stats file. */
X		*imgname,		/* Name of output image file */
X		*inputname,		/* Name of input file, NULL == stdin */
X		*cppargs;		/* arguments to pass to cpp */
X	int	window[2][2];		/* Subwindow corners */
X	Float	crop[2][2];		/* Crop window, lo/hi normalized */
X#ifdef LINDA
X	int	workers,		/* # of worker processes */
X		workernum,		/* worker #, 0 == supervisor */
X		verbose_worker;		/* Babble while you work? */
X#endif
X	FILE	*pictfile;		/* output file pointer */
X} RSOptions;
X
Xextern RSOptions Options;
Xextern void OptionsList(), OptionsSet();
X
X#endif /* OPTIONS_H */
END_OF_FILE
if test 3457 -ne `wc -c <'libshade/options.h'`; then
    echo shar: \"'libshade/options.h'\" unpacked with wrong size!
fi
# end of 'libshade/options.h'
fi
if test -f 'libshade/symtab.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/symtab.c'\"
else
echo shar: Extracting \"'libshade/symtab.c'\" \(3809 characters\)
sed "s/^X//" >'libshade/symtab.c' <<'END_OF_FILE'
X/*
X * symtab.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X * 
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose.  It is provided solely "as is".
X *
X * $Id: symtab.c,v 4.0.1.1 91/10/05 18:24:29 cek Exp Locker: cek $
X *
X * $Log:	symtab.c,v $
X * Revision 4.0.1.1  91/10/05  18:24:29  cek
X * patch1: Added casts for builtin functions.
X * 
X * Revision 4.0  91/07/17  14:48:02  kolb
X * Initial version.
X * 
X */
X
X#include "rayshade.h"
X#include "symtab.h"
X#include "builtin.h"
X
Xstatic struct SymtabPredefinedEntry SymtabPredefined[] = {
X	{"pi", 3.141592, NULL, FLOAT_EXPR, FALSE, 0},
X	{"dtor", 0.017453, NULL, FLOAT_EXPR, FALSE, 0},
X	{"rtod", 57.29578, NULL, FLOAT_EXPR, FALSE, 0},
X	{"cos", 0.0, (Float (*)())cos, BUILTIN_EXPR, FALSE, 1},
X	{"sin", 0.0, (Float (*)())sin, BUILTIN_EXPR, FALSE, 1},
X	{"tan", 0.0, (Float (*)())tan, BUILTIN_EXPR, FALSE, 1},
X	{"sqrt", 0.0, (Float (*)())sqrt, BUILTIN_EXPR, FALSE, 1},
X	{"acos", 0.0, (Float (*)())acos, BUILTIN_EXPR, FALSE, 1},
X	{"asin", 0.0, (Float (*)())asin, BUILTIN_EXPR, FALSE, 1},
X	{"atan", 0.0, (Float (*)())atan, BUILTIN_EXPR, FALSE, 1},
X	{"hypot", 0.0, (Float (*)())hypot, BUILTIN_EXPR, FALSE, 2},
X	{"time", 0.0, NULL, FLOAT_EXPR, TRUE, 0},
X	{"frame", 0.0, NULL, FLOAT_EXPR, TRUE, 0},
X	{"linear", 0.0, LinearTime, BUILTIN_EXPR, TRUE, 4},
X	{NULL, 0.0, NULL, 0, 0}
X};
X
XSymtabEntry *Symtab = (SymtabEntry *) NULL;
X
Xvoid SymtabAddEntry();
X
Xvoid
XSymtabInit()
X{
X	int i;
X
X	for(i=0; SymtabPredefined[i].name; i++) {
X		if (SymtabPredefined[i].type == BUILTIN_EXPR)
X			SymtabAddEntry(SymtabPredefined[i].name,
X				       SymtabPredefined[i].type,
X				       NULL,
X				       SymtabPredefined[i].fp,
X					SymtabPredefined[i].timevary,	
X				       SymtabPredefined[i].params);
X		else
X			SymtabAddEntry(SymtabPredefined[i].name,
X				       SymtabPredefined[i].type,
X				       ExprFloatCreate(SymtabPredefined[i].f,
X						SymtabPredefined[i].timevary),
X				       NULL, SymtabPredefined[i].timevary, 0);
X	}
X	TimeExpr = ExprFloatSymtabFind("time");
X	FrameExpr = ExprFloatSymtabFind("frame");
X}
X
Xvoid
XSymtabAddEntry(name, type, expr, fp, timevary, params)
Xchar *name;
XExpr *expr;
XFloat (*fp)();
Xint type, timevary, params;
X{
X	SymtabEntry *res;
X
X	if (SymtabFind(name) != (SymtabEntry *)NULL)
X		RLerror(RL_ABORT, "Symbol %s redefined.\n", name);
X
X	res = (SymtabEntry *) Malloc( sizeof(SymtabEntry));
X	res->name = strsave(name);
X	res->type = type;
X	res->timevary = timevary;
X	switch (type) {
X	case FLOAT_EXPR:
X		res->value.expr = expr;
X		expr->symtab = TRUE;
X		break;
X	case BUILTIN_EXPR:
X		res->value.fp = fp;
X		break;
X	default:
X		RLerror(RL_WARN,
X			"Type %d not implemented!!!",type);
X	}
X	res->params = params;
X	res->next = Symtab;
X	Symtab = res;
X}
X
XSymtabEntry *
XSymtabFind(name)
Xchar *name;
X{
X	SymtabEntry *res;
X	for(res=Symtab; res; res=res->next) {
X		if (!strcmp(res->name,name))
X			return res;
X	}
X	/*error*/
X	return NULL;
X}
X
XExpr *
XExprFloatSymtabFind(name)
Xchar *name;
X{
X	SymtabEntry *res;
X
X	if ((res = SymtabFind(name)) == NULL) 
X		RLerror(RL_PANIC,
X			"Symbol %s not defined!\n", name);
X	if (res->type != FLOAT_EXPR)
X		RLerror(RL_PANIC,
X			"Symbol %s is not a float expression!\n", name);
X	return res->value.expr;
X}
X
X
XSymtabEntry *
XSymtabBuiltinFind(name)
Xchar *name;
X{
X	SymtabEntry *res;
X
X	if ((res = SymtabFind(name)) == NULL) 
X		RLerror(RL_PANIC,
X			"Symbol %s not defined!\n", name);
X	if (res->type != BUILTIN_EXPR)
X		RLerror(RL_PANIC,
X			"Symbol %s is not a built in function!\n", name);
X	return res;
X}
END_OF_FILE
if test 3809 -ne `wc -c <'libshade/symtab.c'`; then
    echo shar: \"'libshade/symtab.c'\" unpacked with wrong size!
fi
# end of 'libshade/symtab.c'
fi
echo shar: End of archive 7 \(of 19\).
cp /dev/null ark7isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 19 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
Modified: Wed Dec 11 17:00:00 1996 GMT
Page accessed 1240 times since Sat Apr 17 21:59:31 1999 GMT