#! /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 9 (of 19)."
# Contents:  config.H libray/libcommon/expr.c libray/libimage/image.c
#   libray/libobj/bounds.c libray/libtext/mapping.c
#   libray/libtext/textaux.c libshade/lex.l libshade/setup.c
# Wrapped by kolb@woody on Wed Jul 17 17:56:49 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'config.H' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'config.H'\"
else
echo shar: Extracting \"'config.H'\" \(6009 characters\)
sed "s/^X//" >'config.H' <<'END_OF_FILE'
X/* config.h
X * This file was produced by running the config.h.SH script, which
X * gets its values from config.sh, which is generally produced by
X * running Configure.
X *
X * Feel free to modify any of this as the need arises.  Note, however,
X * that running config.h.SH again will wipe out any changes you've made.
X * For a more permanent change edit config.sh and rerun config.h.SH.
X */
X
X
X/* EUNICE:
X *	This symbol, if defined, indicates that the program is being compiled
X *	under the EUNICE package under VMS.  The program will need to handle
X *	things like files that don't go away the first time you unlink them,
X *	due to version numbering.  It will also need to compensate for lack
X *	of a respectable link() command.
X */
X/* VMS:
X *	This symbol, if defined, indicates that the program is running under
X *	VMS.  It is currently only set in conjunction with the EUNICE symbol.
X */
X/* XENIX:
X *	This symbol, if defined, indicates thet the program is running under
X *	Xenix (at least 3.0 ?).
X */
X/* BSD:
X *	This symbol, if defined, indicates that the program is running under
X *	a BSD system.
X */
X/*#undef EUNICE		/**/
X/*#undef VMS		/**/
X/*#undef XENIX		/**/
X#define BSD		/**/
X
X/* CPPSTDIN:
X *	This symbol contains the first part of the string which will invoke
X *	the C preprocessor on the standard input and produce to standard
X *	output.	 Typical value of "cc -E" or "/lib/cpp".
X */
X/* CPPMINUS:
X *	This symbol contains the second part of the string which will invoke
X *	the C preprocessor on the standard input and produce to standard
X *	output.  This symbol will have the value "-" if CPPSTDIN needs a minus
X *	to specify standard input, otherwise the value is "".
X */
X#define CPPSTDIN "/usr/lib/cpp"
X#define CPPMINUS ""
X
X/* bzero:
X *	This symbol is maped to memset if the  bzero() routine is not
X *	available to set memory to 0.
X */
X/*#undef	bzero(s,l)	memset((s),0,(l))	;	/* mapped to memset */
X
X/* CBRT:
X *	This symbol, if defined, indicates that the cbrt() (cube root)
X *	function is available.
X */
X#define	CBRT		/**/
X
X/* index:
X *	This preprocessor symbol is defined, along with rindex, if the system
X *	uses the strchr and strrchr routines instead.
X */
X/* rindex:
X *	This preprocessor symbol is defined, along with index, if the system
X *	uses the strchr and strrchr routines instead.
X */
X#define	index strchr	/* cultural */
X#define	rindex strrchr	/*  differences? */
X
X/* MEMSET:
X *	This symbol, if defined, indicates that the memset routine is available
X *	to set blocks of memory. You should always use bzero() instead of
X *	memset() because bzero is remaped to memset if necessary. This means
X *	that a memset() routine must be provided in case MEMSET is not defined
X *	and no bzero() is found.
X */
X#define	MEMSET		/**/
X
X/* POPEN:
X *	This symbol, if defined, indicates that the popen routine is
X *	available to open a pipe from a process.
X */
X#define POPEN		/**/
X
X/* RUSAGE:
X *	This symbol, if defined, indicates that the getrusage() routine exists.
X *	Inclusion of <sys/resource.h> and <sys/time.h> may be necessary.
X */
X#define	RUSAGE		/**/
X
X/* TIMES:
X *	This symbol, if defined, indicates that the times() routine exists.
X *	Note that this became obsolete on some systems (SUNOS), which now
X * use getrusage().
X */
X/* CLOCKTYPE:
X *	This symbol holds the type returned by times(). It can be long,
X *	or clock_t on BSD sites (in which case <sys/types.h> should be
X *	included). Moreover, the Clock_t symbol is defined in common.h
X *	and should be used for easy clean reference.
X */
X#define TIMES		/**/
X#define CLOCKTYPE long		/**/
X
X/* I_STRING:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <string.h> (USG systems) instead of <strings.h> (BSD systems).
X */
X#define I_STRING		/**/
X
X/* I_SYSRESOURCE:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/resource.h>.
X */
X#define	I_SYSRESOURCE		/**/
X
X/* I_SYSTYPES:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/types.h>.
X */
X#define	I_SYSTYPES		/**/
X
X/* I_TIME:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <time.h>.
X */
X/* I_SYSTIME:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/time.h>.
X */
X/* I_SYSTIMEKERNEL:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/time.h> with KERNEL defined.
X */
X/*#undef I_TIME		/**/
X#define I_SYSTIME		/**/
X/*#undef I_SYSTIMEKERNEL		/**/
X
X/* nrand:
X *	This macro is to be used to generate uniformly distributed
X *	random numbers over the range [0., 1.].
X */
X/* seednrand:
X *	This symbol defines the macro to be used in seeding the
X *	random number generator (see nrand).
X */
X#define nrand()		drand48()		/**/
X#define seednrand(x)	srand48(x)	/**/
X
X/* VOIDFLAGS:
X *	This symbol indicates how much support of the void type is given by this
X *	compiler.  What various bits mean:
X *
X *	    1 = supports declaration of void
X *	    2 = supports arrays of pointers to functions returning void
X *	    4 = supports comparisons between pointers to void functions and
X *		    addresses of void functions
X *	    8 = suports declaration of generic void pointers
X *
X *	The package designer should define VOIDUSED to indicate the requirements
X *	of the package.  This can be done either by #defining VOIDUSED before
X *	including config.h, or by defining defvoidused in Myinit.U.  If the
X *	latter approach is taken, only those flags will be tested.  If the
X *	level of void support necessary is not present, defines void to int.
X */
X#ifndef VOIDUSED
X#define VOIDUSED 11
X#endif
X#define VOIDFLAGS 11
X#if (VOIDFLAGS & VOIDUSED) != VOIDUSED
X#define void int		/* is void to be avoided? */
X#define M_VOID		/* Xenix strikes again */
X#endif
X
X/* URT:
X *     This symbol, if defined, indicates that the Utah Raster
X *	Toolkit is being used.
X */
X#define       URT          /**/
X
X/* I_VARARGS:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <stdlib.h>.
X */
X/*#undef I_STDLIB		/**/
X
END_OF_FILE
if test 6009 -ne `wc -c <'config.H'`; then
    echo shar: \"'config.H'\" unpacked with wrong size!
fi
# end of 'config.H'
fi
if test -f 'libray/libcommon/expr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libcommon/expr.c'\"
else
echo shar: Extracting \"'libray/libcommon/expr.c'\" \(5942 characters\)
sed "s/^X//" >'libray/libcommon/expr.c' <<'END_OF_FILE'
X/*
X * expr.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: expr.c,v 4.0 91/07/17 14:30:36 kolb Exp Locker: kolb $
X *
X * $Log:	expr.c,v $
X * Revision 4.0  91/07/17  14:30:36  kolb
X * Initial version.
X * 
X */
X#include "common.h"
X
XExpr *TimeExpr, *FrameExpr;
X
Xstatic Expr *ExprCreate();
Xvoid ExprFree();
X
XExpr *
XExprFloatCreate(val, timevary)
XFloat val;
Xint timevary;
X{
X	Expr *res;
X
X	res = ExprCreate(FLOAT_EXPR, timevary);
X	res->value = val;
X	return res;
X}
X
XExpr *
XExprReuseFloatCreate(val)
XFloat val;
X{
X	Expr *res;
X
X	/* this should get the expr from a magic list
X	 * that will reuse the exprs.
X	 * But not yet...
X	 */
X	res = ExprCreate(FLOAT_EXPR, FALSE);
X	res->value = val;
X	return res;
X}
X
XExpr *
XExprMalloc()
X{
X	return (Expr *)Malloc(sizeof(Expr));
X}
X
Xstatic
XExpr *
XExprCreate(type, timevary)
Xint type, timevary;
X{
X	Expr *res;
X
X	res = ExprMalloc();
X	res->type = type;
X	res->timevary = timevary;
X	res->symtab = FALSE;
X	res->nparams = 0;
X	res->params = (Expr **)NULL;
X	res->function = (Float (*)())NULL;
X	res->value = 0.0;
X	res->timenow = -FAR_AWAY;
X	return res;	
X}
X
XFloat
XExprEval(expr)
XExpr *expr;	/* Expression to evaluate */
X{
X	/*
X	 * If the expression is a time-varying function,
X	 * and its time is incorrect, evaluate at
X	 * the current time.
X	 */
X	if (expr->timevary && expr->nparams && 
X	    !equal(TimeExpr->value, expr->timenow)) {
X		if (expr->nparams == 1) {
X			expr->value = (*expr->function)
X				(ExprEval(expr->params[0]));
X		} else if (expr->nparams == 2) {
X			expr->value = (*expr->function)
X				(ExprEval(expr->params[0]),
X				 ExprEval(expr->params[1]));
X		} else if (expr->nparams == 3) {
X			expr->value = (*expr->function)
X				(ExprEval(expr->params[0]),
X				 ExprEval(expr->params[1]),
X				 ExprEval(expr->params[2]));
X		} else if (expr->nparams == 4) {
X			expr->value = (*expr->function)
X				(ExprEval(expr->params[0]),
X				 ExprEval(expr->params[1]),
X				 ExprEval(expr->params[2]),
X				 ExprEval(expr->params[3]));
X		} else if (expr->nparams == 5) {
X			expr->value = (*expr->function)
X				(ExprEval(expr->params[0]),
X				 ExprEval(expr->params[1]),
X				 ExprEval(expr->params[2]),
X				 ExprEval(expr->params[3]),
X				 ExprEval(expr->params[4]));
X		} else if (expr->nparams > 5)
X			RLerror(RL_PANIC, "Expression with > 5 args?\n");
X		expr->timenow = TimeExpr->value;
X	}
X	return expr->value;
X}
X
XExpr *
XExprFunctionCreate(fp, nparams, params, timevary)
XFloat (*fp)();
Xint nparams, timevary;
XExpr **params;
X{
X	Expr *res;
X
X	res = ExprCreate(FLOAT_EXPR, timevary);
X	res->function = fp;
X	res->nparams = nparams;
X	res->params = params;
X
X	return res;
X}
X
XExpr *
XExprResolve1(a, fp, timevary)
XExpr *a;
XFloat (*fp)();
Xint timevary;
X{
X	Expr **params, *res;
X
X	if (!timevary && !a->timevary) {
X		res = ExprFloatCreate((*fp)(a->value), FALSE);
X		ExprFree(a);
X		return res;
X	} else {
X		params = (Expr **)Malloc(sizeof(Expr *));
X		params[0] = a;
X		return ExprFunctionCreate(fp, 1, params, TRUE);
X	}
X}
X
XExpr *
XExprResolve2(a, b, fp, timevary)
XExpr *a, *b;
XFloat (*fp)();
Xint timevary;
X{
X	Expr **params, *res;
X	if (!timevary && !a->timevary && !b->timevary) {
X		res = ExprFloatCreate((*fp)(a->value, b->value), FALSE);
X		ExprFree(a);
X		ExprFree(b);
X		return res;
X	} else {
X		params = (Expr **)Malloc(2 * sizeof(Expr *));
X		params[0] = a;
X		params[1] = b;
X		return ExprFunctionCreate(fp, 2, params, TRUE);
X	}
X}
X
XExpr *
XExprResolve3(a, b, c, fp, timevary)
XExpr *a, *b, *c;
XFloat (*fp)();
Xint timevary;
X{
X	Expr **params, *res;
X	if (!timevary && !a->timevary && !b->timevary && !c->timevary) {
X		res = ExprFloatCreate((*fp)(a->value, b->value, c->value), 
X				      FALSE);
X		ExprFree(a);
X		ExprFree(b);
X		ExprFree(c);
X		return res;
X	} else {
X		params = (Expr **)Malloc(3 * sizeof(Expr *));
X		params[0] = a;
X		params[1] = b;
X		params[2] = c;
X		return ExprFunctionCreate(fp, 3, params, TRUE);
X	}
X}
X
XExpr *
XExprResolve4(a, b, c, d, fp, timevary)
XExpr *a, *b, *c, *d;
XFloat (*fp)();
Xint timevary;
X{
X	Expr **params, *res;
X	if (!timevary && !a->timevary && !b->timevary && !c->timevary &&
X	    !d->timevary) {
X		res = ExprFloatCreate((*fp)(a->value, b->value, c->value, 
X					    d->value), FALSE);
X		ExprFree(a);
X		ExprFree(b);
X		ExprFree(c);
X		ExprFree(d);
X		return res;
X	} else {
X		params = (Expr **)Malloc(4 * sizeof(Expr *));
X		params[0] = a;
X		params[1] = b;
X		params[2] = c;
X		params[3] = d;
X		return ExprFunctionCreate(fp, 4, params, TRUE);
X	}
X}
X
XExpr *
XExprResolve5(a, b, c, d, e, fp, timevary)
XExpr *a, *b, *c, *d, *e;
XFloat (*fp)();
Xint timevary;
X{
X	Expr **params, *res;
X	if (!timevary && !a->timevary && !b->timevary && !c->timevary &&
X	    !d->timevary && !e->timevary) {
X		res = ExprFloatCreate((*fp)(a->value, b->value, c->value, 
X					    d->value, e->value), FALSE);
X		ExprFree(a);
X		ExprFree(b);
X		ExprFree(c);
X		ExprFree(d);
X		ExprFree(e);
X		return res;
X	} else {
X		params = (Expr **)Malloc(5 * sizeof(Expr *));
X		params[0] = a;
X		params[1] = b;
X		params[2] = c;
X		params[3] = d;
X		params[4] = e;
X		return ExprFunctionCreate(fp, 5, params, TRUE);
X	}
X}
X
XExprAssoc *
XAssocCreate(lhs, expr, next)
XFloat *lhs;
XExpr *expr;
XExprAssoc *next;
X{
X	ExprAssoc *new;
X
X	new = (ExprAssoc *)Malloc(sizeof(ExprAssoc));
X	new->lhs = lhs;
X	new->expr = expr;
X	new->next = next;
X	return new;
X}
X
Xvoid
XTimeSet(time)
XFloat time;
X{
X	TimeExpr->value = time;
X}
X
Xvoid
XFrameSet(frame)
XFloat frame;
X{
X	FrameExpr->value = frame;
X}
X
Xvoid
XExprFree(expr)
XExpr *expr;
X{
X	if (!expr->symtab) {
X		if (expr->type == BUILTIN_EXPR && expr->params)
X			free((voidstar)expr->params);
X		free((voidstar)expr);
X	}
X}
END_OF_FILE
if test 5942 -ne `wc -c <'libray/libcommon/expr.c'`; then
    echo shar: \"'libray/libcommon/expr.c'\" unpacked with wrong size!
fi
# end of 'libray/libcommon/expr.c'
fi
if test -f 'libray/libimage/image.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libimage/image.c'\"
else
echo shar: Extracting \"'libray/libimage/image.c'\" \(5803 characters\)
sed "s/^X//" >'libray/libimage/image.c' <<'END_OF_FILE'
X/*
X * image.c
X *
X * Copyright (C) 1989, 1991, Rod G. Bogart, 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: image.c,v 4.0 91/07/17 14:33:29 kolb Exp Locker: kolb $
X *
X * $Log:	image.c,v $
X * Revision 4.0  91/07/17  14:33:29  kolb
X * Initial version.
X * 
X */
X#include <stdio.h>
X#include "libcommon/common.h"
X#include "image.h"
X#ifdef URT
X#include "rle.h"
X#endif
X
XImage *image_list = NULL;		/* Linked list of images */
X
XImage *
XImageCreate(filename)
Xchar *filename;
X{
X	Image *new;
X
X	new = (Image *)Malloc(sizeof(Image));
X	new->filename = strsave(filename);
X	new->width = 0;
X	new->height = 0;
X	new->chan = 0;
X	new->data = NULL;
X	new->next = image_list;
X	image_list = new;
X	return new;
X}
X
XImage *
XImageFind(name)
Xchar *name;
X{
X	Image *im;
X
X	for (im = image_list; im; im = im->next) {
X		if (strcmp(im->filename, name) == 0)
X			return im;
X	}
X
X	return (Image *)NULL;
X}
X
X#ifdef URT
XImage *
XImageRead(filename)
Xchar *filename;
X{
X	FILE *fp;
X	int i, y, chan;
X	rle_hdr in_hdr;
X	Image *image;
X	rle_pixel **inrows;
X
X	/*
X	 * See if image has been read before.
X	 */
X	image = ImageFind(filename);
X	if (image)
X		return image;
X
X	fp = fopen(filename, "r");
X	if (fp == (FILE *)NULL) {
X		RLerror(RL_ABORT, "Cannot open RLE file %s.\n",filename);
X		return (Image *)NULL;
X	}
X
X	in_hdr.rle_file = fp;
X   
X	/* Try to open the RLE file */
X	if (rle_get_setup(&in_hdr) < 0) {
X		RLerror(RL_ABORT, "Error reading header of %s\n", filename);
X		return (Image *)NULL;
X	}
X
X	/*
X	 * Read new image
X	 */
X	image = ImageCreate(filename);
X
X	in_hdr.xmax -= in_hdr.xmin;
X	in_hdr.xmin = 0;
X	image->width = in_hdr.xmax + 1;
X	image->height = in_hdr.ymax - in_hdr.ymin + 1;
X	image->chan = in_hdr.ncolors;
X	image->has_alpha = in_hdr.alpha ? 1 : 0;
X	image->totalchan = image->chan + image->has_alpha;
X	image->chansize = image->width * image->height;
X
X	image->data = (unsigned char *) Malloc(
X		image->chansize * image->totalchan * sizeof(unsigned char));
X
X	/*
X	 * Allocate array of pointers to pass to rle_getrow.
X	 */
X	inrows = (rle_pixel **)Malloc(image->totalchan *
X			sizeof(rle_pixel *));
X	/*
X	 * Set inrows to point to appropriate initial location in image.
X	 */
X	inrows[0] = (rle_pixel *)image->data;
X	for (i = 1; i < image->totalchan; i++)
X		inrows[i] = inrows[i-1] + image->chansize;
X	if (image->has_alpha)
X		/* Alpha channel lives in channel -1 */
X		inrows++;
X
X	/* Read the image */
X	for ( y = 0; y < image->height; y++ ) {
X		rle_getrow( &in_hdr, inrows );
X		/*
X		 * Update inrows to point to next scanline for
X		 * each channel.
X		 */
X		for (i = 0; i < image->chan; i++)
X			inrows[i] += image->width;
X		if (image->has_alpha)
X			inrows[-1] += image->width;
X	}
X
X	(void)fclose(fp);
X	return image;
X}
X
X#else /* !URT */
X
XImage *
XImageRead(filename)
Xchar *filename;
X{
X	FILE *fp;
X	char buf[80];
X	Image *image;
X	int y, x;
X	unsigned char *rbuf, *gbuf, *bbuf;
X
X	image = ImageFind(filename);
X	if (image)
X		return image;
X
X	fp = fopen(filename, "r");
X	if (fp == (FILE *)NULL) {
X		RLerror(RL_ABORT, "Cannot open image file %s.\n",filename);
X		return (Image *)NULL;
X	}
X
X	image = ImageCreate(filename);
X	/*
X	 * Read image header.
X	 */
X	if (fgets(buf, 100, fp) == (char *)NULL ||
X	    sscanf(buf, "%d %d\n", &image->width, &image->height) != 2) {
X		RLerror(RL_ABORT, "Cannot read header of image file %s.\n",
X			filename);
X		fclose(fp);
X		return (Image *)NULL;
X	}
X	/*
X	 * Generic image files always have 3 channels, no alpha.
X	 */
X	image->chan = image->totalchan = 3;
X	image->has_alpha = 0;
X	image->chansize = image->width * image->height;
X
X	image->data = (unsigned char *) Malloc(
X		image->chansize * image->totalchan * sizeof(unsigned char));
X
X	rbuf = image->data;
X	gbuf = &image->data[image->chansize];
X	bbuf = &image->data[image->chansize+image->chansize];
X	for (y = 0; y < image->height; y++ ) {
X		for (x = 0; x < image->width; x++) {
X			*(rbuf++) = getc(fp);
X			*(gbuf++) = getc(fp);
X			*(bbuf++) = getc(fp);
X			if (feof(fp)) {
X				RLerror(RL_ABORT,
X				"Error reading image %s\n",filename);
X				fclose(fp);
X				return (Image *)NULL;
X			}
X		}
X	}
X
X	(void)fclose(fp);
X	return image;
X}
X#endif
X
Xvoid
XImageIndex(img, ix, iy, fx, fy, smooth, outval)
XImage *img;
Xint ix, iy, smooth;
XFloat fx, fy;
XFloat outval[4];
X{
X	int xplus, yplus, chan, offset;
X	Float x0y0, x1y0, x0y1, x1y1;
X	unsigned char *data;
X
X	if (smooth) {
X		/*
X		 * bi-linear interp of four pixels.  Note this blends
X		 * the top with the bottom, and the left with the right.
X		 */
X		if (ix == img->width - 1)
X			xplus = 1 - img->width;
X		else 
X			xplus = 1;
X		if (iy == img->height - 1)
X			yplus = (1 - img->height) * img->width;
X		else
X			yplus = img->width;
X		data = img->data;
X		/* compute offset into first channel */
X		offset = ix + iy * img->width;
X		for (chan = 0; chan < img->totalchan; chan++) {
X			x0y0 = (Float)data[offset] / 255.0;
X			x1y0 = (Float)data[offset+xplus] / 255.0;
X			x0y1 = (Float)data[offset+yplus] / 255.0;
X			x1y1 = (Float)data[offset+xplus+yplus]/255.0;
X			outval[chan] = (x0y0*(1.0-fx)*(1.0-fy) +
X					x1y0*(fx)*(1.0-fy) +
X					x0y1*(1.0-fx)*(fy) +  x1y1*(fx)*(fy));
X			/* Make offset point to next channel */
X			offset += img->chansize;
X		}
X	} else {
X		/*
X		 * Hard edged image pixels (rectangles)
X		 * Compute offset into first channel
X		 */
X		offset = ix + iy * img->width;
X		for (chan = 0; chan < img->totalchan; chan++) {
X			outval[chan] = (Float)img->data[offset]/255.0;
X			/* Make offset point to next channel */
X			offset += img->chansize;
X		}
X	}
X}
END_OF_FILE
if test 5803 -ne `wc -c <'libray/libimage/image.c'`; then
    echo shar: \"'libray/libimage/image.c'\" unpacked with wrong size!
fi
# end of 'libray/libimage/image.c'
fi
if test -f 'libray/libobj/bounds.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libobj/bounds.c'\"
else
echo shar: Extracting \"'libray/libobj/bounds.c'\" \(5507 characters\)
sed "s/^X//" >'libray/libobj/bounds.c' <<'END_OF_FILE'
X/*
X * bounds.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: bounds.c,v 4.0 91/07/17 14:36:21 kolb Exp Locker: kolb $
X *
X * $Log:	bounds.c,v $
X * Revision 4.0  91/07/17  14:36:21  kolb
X * Initial version.
X * 
X */
X#include "geom.h"
X
X/*
X * Check for intersection between bounding box and the given ray.
X * If there is an intersection between mindist and *maxdist along
X * the ray, *maxdist is replaced with the distance to the point of
X * intersection, and TRUE is returned.  Otherwise, FALSE is returned.
X *
X * If this routine is used to check for intersection with a volume
X * rather than a "hollow" box, one should first determine if
X * (ray->pos + mindist * ray->dir) is inside the bounding volume, and
X * call BoundsIntersect() only if it is not.
X */
Xint
XBoundsIntersect(ray, bounds, mindist, maxdist)
XRay *ray;
XFloat bounds[2][3], mindist, *maxdist;
X{
X	Float t, tmin, tmax;
X	Float dir, pos;
X
X	tmax = *maxdist;
X	tmin = mindist;
X
X	dir = ray->dir.x;
X	pos = ray->pos.x;
X
X	if (dir < 0) {
X		t = (bounds[LOW][X] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[HIGH][X] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (dir > 0.) {
X		t = (bounds[HIGH][X] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[LOW][X] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (pos < bounds[LOW][X] || pos > bounds[HIGH][X])
X		return FALSE;
X
X	dir = ray->dir.y;
X	pos = ray->pos.y;
X
X	if (dir < 0) {
X		t = (bounds[LOW][Y] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[HIGH][Y] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (dir > 0.) {
X		t = (bounds[HIGH][Y] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[LOW][Y] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (pos < bounds[LOW][Y] || pos > bounds[HIGH][Y])
X		return FALSE;
X
X	dir = ray->dir.z;
X	pos = ray->pos.z;
X
X	if (dir < 0) {
X		t = (bounds[LOW][Z] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[HIGH][Z] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (dir > 0.) {
X		t = (bounds[HIGH][Z] - pos) / dir;
X		if (t < tmin)
X			return FALSE;
X		if (t <= tmax)
X			tmax = t;
X		t = (bounds[LOW][Z] - pos) / dir;
X		if (t >= tmin) {
X			if (t > tmax)
X				return FALSE;
X			tmin = t;
X		}
X	} else if (pos < bounds[LOW][Z] || pos > bounds[HIGH][Z])
X		return FALSE;
X
X	if (tmin == mindist) {
X		if (tmax < *maxdist) {
X			*maxdist = tmax;
X			return TRUE;
X		}
X	} else {
X		if (tmin < *maxdist) {
X			*maxdist = tmin;
X			return TRUE;
X		}
X	}
X	return FALSE;	/* hit, but not closer than maxdist */
X}
X
X/*
X * Transform an object's bounding box by the given transformation
X * matrix.
X */
Xvoid
XBoundsTransform(trans, objbounds)
XRSMatrix *trans;
XFloat objbounds[2][3];
X{
X	Vector tmp;
X	Float bounds[2][3];
X	int x, y, z;
X
X	/*
X	 * Can't (and shouldn't) do anything with unbounded objects.
X	 */
X	if (objbounds[LOW][X] > objbounds[HIGH][X])
X		return;
X		
X	BoundsInit(bounds);
X
X	/*
X	 * Find bounding box of transformed corners of bounding box.
X	 */
X	for (x = 0 ; x < 2; x++) {
X		for (y = 0; y < 2; y++) {
X			for (z = 0; z < 2; z++) {
X				tmp.x = objbounds[x][X];
X				tmp.y = objbounds[y][Y];
X				tmp.z = objbounds[z][Z];
X				PointTransform(&tmp, trans);
X				if (tmp.x < bounds[LOW][X])
X					bounds[LOW][X] = tmp.x;
X				if (tmp.x > bounds[HIGH][X])
X					bounds[HIGH][X] = tmp.x;
X				if (tmp.y < bounds[LOW][Y])
X					bounds[LOW][Y] = tmp.y;
X				if (tmp.y > bounds[HIGH][Y])
X					bounds[HIGH][Y] = tmp.y;
X				if (tmp.z < bounds[LOW][Z])
X					bounds[LOW][Z] = tmp.z;
X				if (tmp.z > bounds[HIGH][Z])
X					bounds[HIGH][Z] = tmp.z;
X			}
X		}
X	}
X
X	BoundsCopy(bounds, objbounds);
X}
X
Xvoid
XBoundsInit(bounds)
XFloat bounds[2][3];
X{
X	bounds[LOW][X] = bounds[LOW][Y] = bounds[LOW][Z] = FAR_AWAY;
X	bounds[HIGH][X] = bounds[HIGH][Y] = bounds[HIGH][Z] = -FAR_AWAY;
X}
X
Xvoid
XBoundsCopy(from, into)
XFloat into[2][3], from[2][3];
X{
X	into[LOW][X] = from[LOW][X];
X	into[LOW][Y] = from[LOW][Y];
X	into[LOW][Z] = from[LOW][Z];
X	into[HIGH][X] = from[HIGH][X];
X	into[HIGH][Y] = from[HIGH][Y];
X	into[HIGH][Z] = from[HIGH][Z];
X}
X
X#define SetIfLess(a, b)		(a = ((a) < (b) ? (a) : (b)))
X#define SetIfGreater(a, b)	(a = ((a) > (b) ? (a) : (b)))
X
X/*
X * Find bounding box of the union of two bounding boxes.
X */
Xvoid
XBoundsEnlarge(old, new)
XFloat old[2][3], new[2][3];
X{
X	SetIfLess(old[LOW][X], new[LOW][X]);
X	SetIfLess(old[LOW][Y], new[LOW][Y]);
X	SetIfLess(old[LOW][Z], new[LOW][Z]);
X	SetIfGreater(old[HIGH][X], new[HIGH][X]);
X	SetIfGreater(old[HIGH][Y], new[HIGH][Y]);
X	SetIfGreater(old[HIGH][Z], new[HIGH][Z]);
X}
X
Xvoid
XBoundsPrint(box, fp)
XFloat box[2][3];
XFILE *fp;
X{
X	fprintf(fp,"\tX: %f to %f\n",box[LOW][X], box[HIGH][X]);
X	fprintf(fp,"\tY: %f to %f\n",box[LOW][Y], box[HIGH][Y]);
X	fprintf(fp,"\tZ: %f to %f\n",box[LOW][Z], box[HIGH][Z]);
X}
END_OF_FILE
if test 5507 -ne `wc -c <'libray/libobj/bounds.c'`; then
    echo shar: \"'libray/libobj/bounds.c'\" unpacked with wrong size!
fi
# end of 'libray/libobj/bounds.c'
fi
if test -f 'libray/libtext/mapping.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libtext/mapping.c'\"
else
echo shar: Extracting \"'libray/libtext/mapping.c'\" \(5643 characters\)
sed "s/^X//" >'libray/libtext/mapping.c' <<'END_OF_FILE'
X/*
X * mapping.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: mapping.c,v 4.0 91/07/17 14:42:54 kolb Exp Locker: kolb $
X *
X * $Log:	mapping.c,v $
X * Revision 4.0  91/07/17  14:42:54  kolb
X * Initial version.
X * 
X */
X#include "libobj/geom.h"
X#include "mapping.h"
X
Xvoid UVMapping(), SphereMapping(), CylinderMapping(), LinearMapping();
X
XMapping *
XUVMappingCreate()
X{
X	Mapping *res;
X
X	res = (Mapping *)Malloc(sizeof(Mapping));
X	res->flags = PRIMSPACE;
X	res->method = UVMapping;
X	return res;
X}
X
XMapping *
XSphereMappingCreate(center, norm, uaxis)
XVector *center, *norm, *uaxis;
X{
X	Mapping *res;
X
X	res = (Mapping *)Malloc(sizeof(Mapping));
X	res->flags = OBJSPACE;
X	res->method = SphereMapping;
X	if (center)
X		res->center = *center;
X	else
X		res->center.x = res->center.y = res->center.z = 0.;
X	if (norm && uaxis) {
X		res->norm = *norm;
X		if (VecNormalize(&res->norm) == 0.) {
X			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
X			return (Mapping *)NULL;
X		}
X		if (VecNormCross(norm, uaxis, &res->vaxis) == 0.) {
X			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
X			return (Mapping *)NULL;
X		}
X		(void)VecNormCross(&res->vaxis, norm, &res->uaxis);
X	} else {
X		res->norm.x = res->norm.y = res->uaxis.y = res->uaxis.z =
X			res->vaxis.x = res->vaxis.z = 0.;
X		res->norm.z = res->uaxis.x = res->vaxis.y = 1.;
X	}
X	return res;
X}
X
XMapping *
XCylMappingCreate(center, norm, uaxis)
XVector *center, *norm, *uaxis;
X{
X	Mapping *res;
X
X	res = (Mapping *)Malloc(sizeof(Mapping));
X	res->flags = OBJSPACE;
X	res->method = CylinderMapping;
X	if (center)
X		res->center = *center;
X	else
X		res->center.x = res->center.y = res->center.z = 0.;
X	if (norm && uaxis) {
X		res->norm = *norm;
X		if (VecNormalize(&res->norm) == 0.) {
X			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
X			return (Mapping *)NULL;
X		}
X		/*
X		 * Here, uaxis indicates where theta (u) = 0.
X		 */
X		if (VecNormCross(norm, uaxis, &res->vaxis) == 0.) {
X			RLerror(RL_ABORT, "Degenerate mapping vector.\n");
X			return (Mapping *)NULL;
X		}
X		(void)VecNormCross(&res->vaxis, norm, &res->uaxis);
X	} else {
X		res->norm.x = res->norm.y = res->uaxis.y = res->uaxis.z =
X			res->vaxis.x = res->vaxis.z = 0.;
X		res->norm.z = res->uaxis.x = res->vaxis.y = 1.;
X	}
X	return res;
X}
X
XMapping *
XLinearMappingCreate(center, vaxis, uaxis)
XVector *center, *vaxis, *uaxis;
X{
X	Mapping *res;
X	RSMatrix m;
X	Vector n;
X
X	res = (Mapping *)Malloc(sizeof(Mapping));
X	res->flags = OBJSPACE;
X	res->method= LinearMapping;
X
X	if (center)
X		res->center = *center;
X	else
X		res->center.x = res->center.y = res->center.z = 0.;
X
X	if (uaxis && vaxis) {
X		VecCross(uaxis, vaxis, &n);
X		/* this is wrong, since uaxis and vaxis
X		 * give U and V in world space, and we
X		 * need the inverse.
X		 */
X		ArbitraryMatrix(
X			uaxis->x, uaxis->y, uaxis->z,
X			vaxis->x, vaxis->y, vaxis->z,
X			n.x, n.y, n.z,
X			res->center.x, res->center.y, res->center.z,
X			&m);
X		MatrixInvert(&m, &res->m);
X		res->uaxis = *uaxis;
X		res->vaxis = *vaxis;
X		VecNormalize(&res->uaxis);
X		VecNormalize(&res->vaxis);
X	} else {
X		VecScale(-1., res->center, &n);
X		TranslationMatrix(n.x, n.y, n.z, &res->m);
X		res->uaxis.x = res->vaxis.y = 1.;
X		res->uaxis.y = res->uaxis.z = res->vaxis.x =
X			res->vaxis.z = 0.;
X	}
X	return res;
X}
X
Xvoid
XUVMapping(map, obj, pos, norm, uv, dpdu, dpdv)
XMapping *map;
XGeom *obj;
XVec2d *uv;
XVector *pos, *norm, *dpdu, *dpdv;
X{
X	PrimUV(obj, pos, norm, uv, dpdu, dpdv);
X}
X
Xvoid
XSphereMapping(map, obj, pos, norm, uv, dpdu, dpdv)
XMapping *map;
XGeom *obj;
XVec2d *uv;
XVector *pos, *norm, *dpdu, *dpdv;
X{
X	Vector vtmp;
X	Float nx, ny, nz, phi, theta;
X
X	VecSub(*pos, map->center, &vtmp);
X	if (VecNormalize(&vtmp) == 0.) {
X		/*
X		 * Point is coincident with origin of sphere.  Punt.
X		 */
X		uv->u = uv->v = 0.;
X		return;
X	}
X
X	/*
X	 * Find location of point projected onto unit sphere
X	 * in the sphere's coordinate system.
X	 */
X	nx = dotp(&map->uaxis, &vtmp);
X	ny = dotp(&map->vaxis, &vtmp);
X	nz = dotp(&map->norm, &vtmp);
X
X	if (nz > 1.)	/* roundoff */
X		phi = PI;
X	else if (nz < -1.)
X		phi = 0;
X	else
X		phi = acos(-nz);
X
X	uv->v = phi / PI;
X
X	if (fabs(uv->v) < EPSILON || equal(uv->v, 1.))
X		uv->u = 0.;
X	else {
X		theta = nx / sin(phi);
X		if (theta > 1.)
X			theta = 0.;
X		else if (theta < -1.)
X			theta = 0.5;
X		else
X			theta = acos(theta) / TWOPI;
X
X		if (ny > 0)
X			uv->u = theta;
X		else
X			uv->u = 1 - theta;
X	}
X}
X
Xvoid
XCylinderMapping(map, obj, pos, norm, uv, dpdu, dpdv)
XMapping *map;
XGeom *obj;
XVec2d *uv;
XVector *pos, *norm, *dpdu, *dpdv;
X{
X	Vector vtmp;
X	Float nx, ny, r;
X
X	VecSub(*pos, map->center, &vtmp);
X	nx = dotp(&map->uaxis, &vtmp);
X	ny = dotp(&map->vaxis, &vtmp);
X	uv->v = dotp(&map->norm, &vtmp);
X
X	r = sqrt(nx*nx + ny*ny);
X
X	if (r < EPSILON) {
X		uv->u = 0.;
X		return;
X	}
X
X	nx /= r;
X	ny /= r;
X
X	if (fabs(nx) > 1.)
X		uv->u = 0.5;
X	else
X		uv->u = acos(nx) / TWOPI;
X	if (ny < 0.)
X		uv->u = 1. - uv->u;
X
X	if (dpdv)
X		*dpdv = map->norm;
X	if (dpdu)
X		(void)VecNormCross(&map->norm, pos, dpdu);
X}
X
Xvoid
XLinearMapping(map, obj, pos, norm, uv, dpdu, dpdv)
XMapping *map;
XGeom *obj;
XVec2d *uv;
XVector *pos, *norm, *dpdu, *dpdv;
X{
X	Vector vtmp;
X
X	vtmp = *pos;
X	VecTransform(&vtmp, &map->m);
X	uv->u = vtmp.x; uv->v = vtmp.y;
X
X	if (dpdu) {
X		*dpdu = map->uaxis;
X	}
X	if (dpdv) {
X		*dpdv = map->vaxis;
X	}
X}
END_OF_FILE
if test 5643 -ne `wc -c <'libray/libtext/mapping.c'`; then
    echo shar: \"'libray/libtext/mapping.c'\" unpacked with wrong size!
fi
# end of 'libray/libtext/mapping.c'
fi
if test -f 'libray/libtext/textaux.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libtext/textaux.c'\"
else
echo shar: Extracting \"'libray/libtext/textaux.c'\" \(5697 characters\)
sed "s/^X//" >'libray/libtext/textaux.c' <<'END_OF_FILE'
X/*
X * textaux.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart, Robert F. Skinner
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: textaux.c,v 4.0 91/07/17 14:44:05 kolb Exp Locker: kolb $
X *
X * $Log:	textaux.c,v $
X * Revision 4.0  91/07/17  14:44:05  kolb
X * Initial version.
X * 
X */
X#include "texture.h"
X
XColor *
XColormapRead(filename)
Xchar *filename;
X{
X	FILE *fp;
X	Color *map;
X	char buf[BUFSIZ];
X	int r, g, b, i, num;
X
X	fp = fopen(filename, "r");
X	if (fp == (FILE *)NULL) {
X		RLerror(RL_ABORT, "Cannot open colormap file \"%s\".\n",
X				filename);
X		return (Color *)NULL;
X	}
X
X	map = (Color *)Calloc(256, sizeof(Color));
X
X	for (i = 0; fgets(buf,BUFSIZ,fp) != NULL && i < 256; i++) {
X		num = sscanf(buf,"%d %d %d", &r, &g, &b);
X		if (num != 3) {
X			RLerror(RL_ABORT,
X				"%s, line %d:  Bad color specification.\n",
X				filename, i+1);
X			return (Color *)NULL;
X		}
X		map[i].r = (Float)r;
X		map[i].g = (Float)g;
X		map[i].b = (Float)b;
X		ColorScale(1. / 255., map[i], &map[i]);
X	}
X	(void)fclose(fp);
X	return map;
X}
X
XFloat
XMarble(vec)
XVector *vec;
X{
X	Float i;
X
X	i = sin(8. * Chaos(vec, 6) + 7. * vec->z) + 1;
X	
X	return pow(0.5 * i, 0.77);
X}
X
XFloat
XPAChaos(vec, octaves)
XVector *vec;
Xint octaves;
X{
X	Float s, t, tmp;
X	Vector tp;
X
X	s = 1.0;
X	t = 0.;
X	tp = *vec;
X
X	while (octaves--) {
X		tmp = Noise3(&tp) * s;
X		t += fabs(tmp);
X		s *= 0.5;
X		tp.x *= 2.;
X		tp.y *= 2.;
X		tp.z *= 2.;
X	}
X
X	return t;
X}
X
XFloat
XChaos(vec, octaves)
XVector *vec;
Xint octaves;
X{
X	Float s, t;
X	Vector tp;
X
X	s = 1.0;
X	t = 0.;
X	tp = *vec;
X
X	while (octaves--) {
X		t += Noise3(&tp) * s;
X		s *= 0.5;
X		tp.x *= 2.;
X		tp.y *= 2.;
X		tp.z *= 2.;
X	}
X
X	return t;
X}
X
Xvoid
XVfBm(vec, omega, lambda, octaves, ans)
XVector *vec, *ans;
XFloat omega, lambda;
Xint octaves;
X{
X	Float o;
X	Vector tp, n;
X
X	ans->x = ans->y = ans->z = 0.;
X	tp = *vec;
X	o = 1.;
X
X	while (octaves--) {
X		DNoise3(&tp, &n);
X		ans->x += o * n.x;
X		ans->y += o * n.y;
X		ans->z += o * n.z;
X		o *= omega;
X		if (o < EPSILON)
X			break;
X		tp.x *= lambda;
X		tp.y *= lambda;
X		tp.z *= lambda;
X	}
X}
X
XFloat
XfBm(vec, omega, lambda, octaves)
Xregister Vector *vec;
XFloat omega, lambda;
Xint octaves;
X{
X	Float a, o;
X	Vector tp;
X
X	a = 0; o = 1.;
X	tp = *vec;
X	while (octaves--) {
X		a += o * Noise3(&tp);
X		tp.x *= lambda;
X		tp.y *= lambda;
X		tp.z *= lambda;
X		o *= omega;
X	}
X	return a;
X}
X
Xint
XTileValue(tileu, tilev, u, v)
XFloat tileu, tilev, u, v;
X{
X	/*
X	 * If both tileu and tilev are zero, the pattern is repeated infinitly.
X	 *   XXXXXX
X	 *   XXXXXX   tileu=0  tilev=0
X	 *   XXXXXX
X	 *   XXXXXX
X	 * If one is positive and the other is zero, the pattern is infinite
X	 * in one direction and limited in the other.
X	 *   ++++++
X	 *   XXXXXX   tileu=0  tilev=1
X	 *   ++++++
X	 *   ++++++
X	 * If both are positive, the pattern is limited in both directions.
X	 *   ++++++
X	 *   +++XX+   tileu=2  tilev=1
X	 *   ++++++
X	 *   ++++++
X	 * If one is negative and the other is zero, the pattern is the
X	 * inverse of the positive/zero case.
X	 *   XXXXXX
X	 *   ++++++   tileu=0  tilev=-1
X	 *   XXXXXX
X	 *   XXXXXX
X	 * If one is negative and the other is positive, the pattern is like
X	 * negative/zero, but limited in one direction.
X	 *   +++XX+
X	 *   ++++++   tileu=2  tilev=-1
X	 *   +++XX+
X	 *   +++XX+
X	 * If both are negative, the pattern is the inverse of the 
X	 * positive/positive case (a rectangular hole).
X	 *   XXXXXX
X	 *   XXX++X   tileu=-2  tilev=-1
X	 *   XXXXXX
X	 *   XXXXXX
X	 */
X	if ((tileu < 0.001) && (tileu > -0.001) && 
X	    (tilev < 0.001) && (tilev > -0.001))
X		/* zero/zero */
X		return FALSE;
X	if ((tileu < -0.001) && (tilev < -0.001) &&
X	    ((u > -tileu) || (u < 0) || (v > -tilev) || (v < 0)))
X		/* negative/negative */
X		return FALSE;
X	if ((tileu > 0.001) && ((u > tileu) || (u < 0)))
X		/* positive/whatever */
X		return TRUE;
X	if ((tilev > 0.001) && ((v > tilev) || (v < 0)))
X		/* whatever/positive */
X		return TRUE;
X	if ((tileu < -0.001) && (u < -tileu) && (u > 0))
X		/* negative/whatever */
X		return TRUE;
X	if ((tilev < -0.001) && (v < -tilev) && (v > 0))
X		/* whatever/negative */
X		return TRUE;
X
X	return FALSE;
X}
X
Xvoid
XWrinkled(pos, lambda, omega, octaves, res)
XVector *pos, *res;
XFloat lambda, omega;
Xint octaves;
X{
X	Float s;
X	Vector point, tmp;
X
X	res->x = res->y = res->z = 0.;
X	s = 1.;
X	point = *pos;
X	while (octaves--) {
X		DNoise3(&point, &tmp);
X		point.x *= lambda;
X		point.y *= lambda;
X		point.z *= lambda;
X		res->x += tmp.x * s;
X		res->y += tmp.y * s;
X		res->z += tmp.z * s;
X		s *= omega;
X	}
X}
X
Xvoid
XWindy(pos,windscale,chaoscale,bumpscale,octaves,tscale,hscale,offset,res)
XVector *pos, *res;
XFloat windscale, chaoscale, bumpscale, tscale, hscale, offset;
Xint octaves;
X{
X	Vector spoint, tmp;
X	Float windfield, f, scalar;
X
X	spoint = *pos;
X	spoint.x *= windscale;
X	spoint.y *= windscale;
X	spoint.z *= windscale;
X	if (chaoscale)
X		windfield = chaoscale * Chaos(&spoint, 7);
X	else
X		windfield = 1.;
X
X	DNoise3(pos, &tmp);
X	res->x = bumpscale * tmp.x;
X	res->y = bumpscale * tmp.y;
X	res->z = bumpscale * tmp.z;
X
X	f = 1.;
X	scalar = windfield;
X	while (octaves--) {
X		f *= tscale;
X		spoint.x = f*pos->x;
X		spoint.y = f*pos->y;
X		spoint.z = f*pos->z;
X		DNoise3(&spoint, &tmp);
X		res->x += scalar*tmp.x;
X		res->y += scalar*tmp.y;
X		res->z += scalar*tmp.z;
X		scalar *= hscale;
X	}
X	res->x *= windfield + offset;
X	res->y *= windfield + offset;
X	res->z *= windfield + offset;
X}
END_OF_FILE
if test 5697 -ne `wc -c <'libray/libtext/textaux.c'`; then
    echo shar: \"'libray/libtext/textaux.c'\" unpacked with wrong size!
fi
# end of 'libray/libtext/textaux.c'
fi
if test -f 'libshade/lex.l' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/lex.l'\"
else
echo shar: Extracting \"'libshade/lex.l'\" \(5332 characters\)
sed "s/^X//" >'libshade/lex.l' <<'END_OF_FILE'
X/* lex.l								   */
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: lex.l,v 4.0 91/07/17 14:46:15 kolb Exp Locker: kolb $ */
X%{
X#include "config.h"
X#include "rayshade.h"
X#ifdef I_STRING
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X#include "liblight/light.h"
X#include "libsurf/atmosphere.h"
X#include "libsurf/surface.h"
X#include "libtext/texture.h"
X#include "libobj/geom.h"
X#include "symtab.h"
X#include "y.tab.h"
Xextern char *strsave();
X%}
Xalpha	[a-zA-Z]
Xspecial	[\.\_-]
Xdigit	[0-9]
Xexp	[Ee][-+]?{digit}+
Xstring	{alpha}({alpha}|{digit}|{special})*
Xfilename "/"?"/"?(("."|".."|{string})"/")*{string}
X%p 9400
X%e 1200
X%n 600
X%%
X[ \t\n]			;
X^#			handlehash();
X"/*"			skipcomments();
Xambient			return tAMBIENT;
Xaperture		return tAPERTURE;
Xapplysurf		return tAPPLYSURF;
Xarea			return tAREA;
Xatmosphere		return tATMOSPHERE;
Xbackground		return tBACKGROUND;
Xblob			return tBLOB;
Xblotch			return tBLOTCH;
Xbody			return tBODY;
Xbox			return tBOX;
Xbump			return tBUMP;
Xchecker			return tCHECKER;
Xcloud			return tCLOUD;
Xcone			return tCONE;
Xcomponent		return tCOMPONENT;
Xcontrast		return tCONTRAST;
Xcursurf			return tCURSURF;
Xcutoff			return tCUTOFF;
Xcylinder		return tCYL;
Xcylindrical		return tCYLINDRICAL;
Xdefine			return tDEFINE;
Xdiffuse			return tDIFFUSE;
Xdifference		return tDIFFERENCE;
Xdirectional		return tDIRECTIONAL;
Xdisc			return tDISC;
Xend			return tEND;
Xextended		return tEXTENDED;
Xextinct			return tEXTINCT;
Xeyep			return tEYEP;
Xeyesep			return tEYESEP;
Xfilter			return tFILTER;
Xfbm			return tFBM;
Xfbmbump			return tFBMBUMP;
Xfocaldist		return tFOCALDIST;
Xfog			return tFOG;
Xfogdeck			return tFOGDECK;
Xfov			return tFOV;
Xframelength		return tFRAMELENGTH;
Xframes			return tFRAMES;
Xgauss			return tGAUSS;
Xgloss			return tGLOSS;
Xgrid			return tGRID;
Xheightfield		return tHEIGHTFIELD;
Ximage			return tIMAGE;
Xindex			return tINDEX;
Xintersect		return tINTERSECT;
Xjitter			return tJITTER;
Xlight			return tLIGHT;
Xlist			return tLIST;
Xlookp			return tLOOKP;
Xmap			return tMAP;
Xmarble			return tMARBLE;
Xmaxdepth		return tMAXDEPTH;
Xmount			return tMOUNT;
Xmist			return tMIST;
Xname			return tNAME;
Xnojitter		return tNOJITTER;
Xnoshadow		return tNOSHADOW;
Xobject			return tOBJECT;
Xoutfile			return tOUTFILE;
Xplane			return tPLANE;
Xplanar			return tPLANAR;
Xpoint			return tPOINT;
Xpoly			return tPOLY;
Xpolygon			return tPOLY;
Xprint			return tPRINT;
Xquiet			return tQUIET;
Xrange			return tRANGE;
Xreflect			return tREFLECT;
Xreflective		return tREFLECT;
Xreport			return tREPORT;
Xresolution		return tSCREEN; /* A synonym for screen */
Xrotate			return tROTATE;
Xsample			return tSAMPLE;
Xscale			return tSCALE;
Xscreen			return tSCREEN;
Xshadowtransp		return tSHADOWTRANSP;
Xshutter			return tSHUTTER;
Xsky			return tSKY;
Xsmooth			return tSMOOTH;
Xsphere			return tSPHERE;
Xspherical		return tSPHERICAL;
Xspecular		return tSPECULAR;
Xspecpow			return tSPECPOW;
Xspot			return tSPOT;
Xstarttime		return tSTARTTIME;
Xstripe			return tSTRIPE;
Xsurface			return tSURFACE;
Xtextsurf		return tTEXTSURF;
Xtexture			return tTEXTURE;
Xtile			return tTILE;
Xtorus			return tTORUS;
Xtransform		return tTRANSFORM;
Xtranslate		return tTRANSLATE;
Xtranslu			return tTRANSLU;
Xtranslucency		return tTRANSLU;
Xtransp			return tTRANSP;
Xtransparent		return tTRANSP;
Xtriangle		return tTRIANGLE;
Xtriangleuv		return tTRIANGLEUV;
Xunion			return tUNION;
Xup			return tUP;
Xuv			return tUV;
Xverbose			return tVERBOSE;
Xwindy			return tWINDY;
Xwood			return tWOOD;
X{digit}+ |
X{digit}+"."{digit}*({exp})? |
X{digit}*"."{digit}+({exp})? |
X{digit}+{exp}		{yylval.d = atof(yytext); return tFLOAT;}
X{string}		{yylval.c = strsave(yytext); return tSTRING;}
X{filename}		{yylval.c = strsave(yytext); return tFILENAME;}
X.			return yytext[0];
X
X%%
Xyywrap() {return 1;}
X/*
X * Skip over comments.
X */
Xskipcomments()
X{
X	char c;
X
X	while (1) {
X		while (input() != '*')
X			;
X		if ((c = input()) == '/')
X			return;
X		unput(c);
X	}
X}
X/*
X * Deal with ccp-produced lines of the form:
X * # n "filename"
X * and
X * # n
X * Where filename is the name of the file being processed, and n is
X * the current line number in that file.
X */
Xhandlehash()
X{
X	char buf[BUFSIZ];
X	int i;
X	extern int yylineno;
X	extern char yyfilename[];
X
X	/*
X	 * Read the entire line into buf.
X	 */
X	for (i = 0; (buf[i] = input()) != '\n'; i++)
X			;
X	unput(buf[i]);		/* To make sure consecutive # lines work. */
X	buf[i] = (char)NULL;	/* Replace newline with NULL. */
X
X	/*
X	 * Complain if the line was not of the form #n "filename"
X	 */
X	if ((i = sscanf(buf, "%d \"%[^\"]s\"", &yylineno, yyfilename)) == 0) {
X		RLerror(RL_PANIC, "Unknown '#' control (%s).",buf);
X		exit(1);
X	}
X	if (i == 1) {
X		if (index(buf, '"') != (char *)NULL) {
X			/*
X			 * Filename was "", which means stdin.
X			 */
X			(void)strcpy(yyfilename, "stdin");
X		}
X	}
X	yylineno--;  /* The newline we unput will increment yylineno */
X}
END_OF_FILE
if test 5332 -ne `wc -c <'libshade/lex.l'`; then
    echo shar: \"'libshade/lex.l'\" unpacked with wrong size!
fi
# end of 'libshade/lex.l'
fi
if test -f 'libshade/setup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libshade/setup.c'\"
else
echo shar: Extracting \"'libshade/setup.c'\" \(5206 characters\)
sed "s/^X//" >'libshade/setup.c' <<'END_OF_FILE'
X/*
X * setup.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: setup.c,v 4.0 91/07/17 14:47:24 kolb Exp Locker: kolb $
X *
X * $Log:	setup.c,v $
X * Revision 4.0  91/07/17  14:47:24  kolb
X * Initial version.
X * 
X */
X#include "rayshade.h"
X#include "defaults.h"
X#include "libsurf/surface.h"
X#include "libsurf/atmosphere.h"
X#include "liblight/light.h"
X#include "liblight/infinite.h"
X#include "libobj/list.h"
X#include "options.h"
X#include "stats.h"
X#include "viewing.h"
X#include "picture.h"
X
X#ifdef MULTIMAX
X#include <parallel.h>
X#define SHARED_BYTES	23	/* 2^23 bytes of shared memory */
X#endif
X
Xextern GeomList *Defstack;
X
Xstatic void SetupWorld();
X
X/*
X * Set default parameters
X */
Xvoid
XRSSetup()
X{
X	extern SurfList *CurSurf;
X	extern Medium TopMedium;
X	extern void NoiseInit();
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		RLerror(RL_PANIC, "Cannot share_malloc %d bytes.\n",bytes);
X	} else
X		fprintf(fstats,"Malloced %d bytes of shared memory.\n",
X				bytes);
X#endif
X
X	Camera.hfov = HFOV;
X	Camera.vfov = UNSET;
X	Camera.pos.x = EYEX;
X	Camera.pos.y = EYEY;
X	Camera.pos.z = EYEZ;
X	Camera.lookp.x = LOOKX;
X	Camera.lookp.y = LOOKY;
X	Camera.lookp.z = LOOKZ;
X	Camera.up.x = UPX;
X	Camera.up.y = UPY;
X	Camera.up.z = UPZ;
X	Camera.focaldist = UNSET;
X	Camera.aperture = 0.;
X
X	Screen.xres = Screen.yres = UNSET;
X
X	Options.maxdepth = MAXDEPTH;
X	Options.report_freq = REPORTFREQ;
X	Options.jitter = TRUE;
X	Options.samples = UNSET;
X	Options.gaussian = GAUSSIAN;
X	Options.filterwidth = UNSET;
X	Options.contrast.r = UNSET;
X	Options.ambient.r = Options.ambient.g =
X		Options.ambient.b = 1.0;
X	Options.cutoff.r = UNSET;
X	Options.cache = TRUE;
X	Options.shadowtransp = TRUE;
X	Options.xmin = Options.ymin = 0.;
X	Options.xmax = Options.ymax = 1.;
X	Stats.fstats = stderr;
X	Options.pictfile = stdout;
X#ifdef URT
X	Options.alpha = TRUE;
X	Options.exp_output = FALSE;
X#endif
X	Options.gamma = GAMMA;
X	Options.eyesep = UNSET;
X#ifdef LINDA
X	Options.workers = WORKERS;
X#endif
X
X	Options.totalframes = 1;
X	Options.startframe = 0;
X	Options.starttime = 0.;
X	Options.framelength = 1.;
X	Options.shutterspeed = 0.;
X
X	TopMedium.index = DEFAULT_INDEX;
X	TopMedium.statten = 1.0;
X	NoiseInit();			/* Initialize values for Noise() */
X
X	/*
X	 * Top of object definition stack points to the World object.
X	 * The World object is always a list.
X	 */
X	Defstack = GeomStackPush(GeomListCreate(), (GeomList *)NULL);
X	Defstack->obj->name = strsave("World");
X	/* Initialize surface stack */
X	CurSurf = SurfPush((Surface *)NULL, (SurfList *)NULL);
X}
X
X/*
X * cleanup()
X *
X * Initialize options/variables not set on command line or in input file.
X * Perform sanity checks on widow dimension, maxdepth, etc.
X */
Xvoid
XRSCleanup()
X{
X	extern Light *Lights;
X	extern void OpenStatsFile();
X	extern FILE *yyin;
X
X	yyin = (FILE *)NULL;	/* mark that we're done reading input */
X
X	if (Options.samples == UNSET)
X		Options.samples = DEFSAMPLES;
X
X	if (Options.filterwidth == UNSET) {
X		if (Options.gaussian)
X			Options.filterwidth = FILTERWIDTH;
X		else
X			/* Default box filter width of 1.0 */
X			Options.filterwidth = 1.0;
X	}
X
X	Options.endframe = Options.startframe + Options.totalframes -1;
X
X	OpenStatsFile();
X
X	ViewingSetup();
X
X	if (Options.cutoff.r == UNSET)
X		Options.cutoff.r = Options.cutoff.g =
X			Options.cutoff.b = DEFCUTOFF;
X
X	/*
X	 * Set contrast.
X	 */
X	if (Options.contrast.r == UNSET) {
X		Options.contrast.r = DEFREDCONT;
X		Options.contrast.g = DEFGREENCONT;
X		Options.contrast.b = DEFBLUECONT;
X	}
X
X	/*
X	 * Image gamma is inverse of display gamma.
X	 */
X	if (fabs(Options.gamma) > EPSILON)
X		Options.gamma = 1. / Options.gamma;
X	else
X		Options.gamma = FAR_AWAY;
X
X	if (Options.maxdepth < 0)
X		Options.maxdepth = 0;
X
X
X	LightSetup();
X}
X
Xvoid
XRSStartFrame(frame)
Xint frame;
X{
X	/*
X	 * Set the frame start time
X	 */
X	Options.framenum = frame;
X	Options.framestart = Options.starttime +
X			Options.framenum*Options.framelength;
X	SamplingSetTime(Options.framestart, Options.shutterspeed,
X			Options.framenum);
X	/*
X	 * Set up viewing parameters.
X	 */
X	RSViewing();
X	/*
X	 * Initialize world
X	 */
X	WorldSetup();
X}
X
X/*
X * Initialize non-time-varying goodies.
X */
Xvoid
XRSInitialize(argc, argv)
Xint argc;
Xchar **argv;
X{
X	/*
X 	 * Initialize variables, etc.
X	 */
X	RSSetup();
X	/*
X	 * Parse options from command line.
X	 */
X	RSOptionsSet(argc, argv);
X	/*
X	 * Process input file.
X	 */
X	if (Options.verbose) {
X		VersionPrint();
X		fprintf(Stats.fstats,"Reading input file...\n");
X		(void)fflush(Stats.fstats);
X	}
X	RSReadInputFile();
X	/*
X	 * Set variables that weren't set on command line
X	 * or in input file.
X	 */
X	RSCleanup();
X	/*
X	 * Set sampling options.
X	 */
X	SamplingSetOptions(Options.samples, Options.gaussian,
X			   Options.filterwidth);
X}
END_OF_FILE
if test 5206 -ne `wc -c <'libshade/setup.c'`; then
    echo shar: \"'libshade/setup.c'\" unpacked with wrong size!
fi
# end of 'libshade/setup.c'
fi
echo shar: End of archive 9 \(of 19\).
cp /dev/null ark9isdone
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
