CCL Home Page
Up Directory CCL Part09
#! /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 '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 
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'\" \(5573 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.1.2 91/10/05 18:17:29 cek Exp Locker: cek $
X *
X * $Log:	bounds.c,v $
X * Revision 4.0.1.2  91/10/05  18:17:29  cek
X * patch1: Faster box transform, a la Jim Arvo.
X * 
X * Revision 4.0.1.1  1991/09/29  15:42:05  cek
X * patch1: Justified floating point compare...
X *
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	/*
X	 * If tmin == mindist, then there was no "near"
X	 * intersection farther than EPSILON away.
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	Float bounds[2][3], a, b;
X	int i, j;
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	bounds[LOW][X] = bounds[HIGH][X] = trans->translate.x;
X	bounds[LOW][Y] = bounds[HIGH][Y] = trans->translate.y;
X	bounds[LOW][Z] = bounds[HIGH][Z] = trans->translate.z;
X
X	for (i = 0; i < 3; i++) {
X		for (j = 0; j < 3; j++) {
X			a = trans->matrix[j][i] * objbounds[LOW][j];
X			b = trans->matrix[j][i] * objbounds[HIGH][j];
X			if (a < b) {
X				bounds[LOW][i] += a;
X				bounds[HIGH][i] += b;
X			} else {
X				bounds[LOW][i] += b;
X				bounds[HIGH][i] += a;
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 5573 -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/libsurf/surfshade.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libsurf/surfshade.c'\"
else
echo shar: Extracting \"'libray/libsurf/surfshade.c'\" \(5452 characters\)
sed "s/^X//" >'libray/libsurf/surfshade.c' <<'END_OF_FILE'
X/*
X * surfshade.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: surfshade.c,v 4.0.1.2 92/01/10 14:08:28 cek Exp Locker: cek $
X *
X * $Log:	surfshade.c,v $
X * Revision 4.0.1.2  92/01/10  14:08:28  cek
X * patch3: Fixed additional composition problems.
X * 
X * Revision 4.0.1.1  91/12/13  11:54:51  cek
X * patch3: Fixed ordering of world/model xform composition.
X * patch3: Geometric normal now transformed correctly.
X * 
X * Revision 4.0  91/07/17  14:41:15  kolb
X * Initial version.
X * 
X */
X#include "libobj/geom.h"
X#include "surface.h"
X
X/*
X * Compute surface properties from given hitlist
X * Returns TRUE if ray is entering object, FALSE otherwise.
X */
Xint
XComputeSurfProps(hitlist, ray, pos, norm, gnorm, surf, smooth)
XHitList *hitlist;	/* Hit information (path through DAG) */
XRay *ray;		/* Ray in world space */
XVector *pos;		/* Intersection point */
XVector *norm, *gnorm;	/* shading normal, geometric normal (return values) */
XSurface *surf;		/* Copy of surface to use, texture-modified */
Xint *smooth;
X{
X	HitNode *hp;
X	int i;
X	Ray rtmp;
X	Geom *prim, *obj;
X	Float k, kp;
X	int texturing, transforming, entering;
X	Trans prim2model, world2model;
X
X	hp = hitlist->data;
X	prim = hp->obj;
X
X	/*
X	 * Compute point of intersection in "primitive space".
X	 */
X	VecAddScaled(hp->ray.pos, hp->dist, hp->ray.dir, pos);
X
X	/*
X	 * Find normal to primitive at point of intersection.
X	 */
X	*smooth = PrimNormal(prim, pos, norm, gnorm);
X
X	texturing = transforming = FALSE;
X
X	/*
X	 * Walk down hit list, constructing world<-->primitive transformation
X	 * and determining if we need to perform texture mapping.
X	 * The last node is the World node, which cannot be textured or
X	 * transformed, so we skip it.
X	 */
X	for (i = 0, hp = hitlist->data; i < hitlist->nodes -1; hp++, i++) {
X		obj = hp->obj;
X		texturing = texturing || obj->texture;
X		if (hp->dotrans) {
X			/*
X			 * Here we're actually computing prim2world.
X			 * When finished, we invert it.
X			 */
X			if (transforming) {
X				TransCompose(&world2model, &hp->trans,
X					&world2model);
X			} else {
X				TransCopy(&hp->trans, &world2model);
X				transforming = TRUE;
X			}
X		}
X	}
X
X	/*
X	 * Determine if we're entering or exiting the surface,
X	 * flipping surface normals if necessary.
X	 */
X	k = dotp(&hitlist->data[0].ray.dir, norm);
X	if (*smooth) {
X		/*
X		 * If gnorm and shading norm differ and
X		 * their dot products with the ray have
X		 * different signs, use the geometric normal
X		 * instead, ala Snyder & Barr's paper.
X		 */
X		kp = dotp(&hitlist->data[0].ray.dir, gnorm);
X		if (k <= 0. && kp > 0. || k >= 0. && kp < 0.)
X			k = kp;
X	}
X
X	if (k > 0.) {
X		/* flip normals */
X		VecScale(-1., *gnorm, gnorm);
X		VecScale(-1., *norm, norm);
X		/*
X		 * Normal indicates that we're exiting.
X		 * Only set entering to TRUE if csg has indicated
X		 * that the ray is, indeed, entering.
X		 */
X		entering = (hitlist->data[0].enter == ENTERING);
X	} else {
X		/*
X		 * Normal indicates that we're entering.
X		 * Set entering flag as such unless csg has
X		 * told us that we're exiting.
X		 */
X		entering = !(hitlist->data[0].enter == EXITING);
X	}
X		
X	/*
X	 * If there are no transformations, then world2model is identity.
X	 */
X	if (!transforming)
X		TransInit(&world2model);
X	/*
X	 * If we're not performing texturing, we simply need to compute
X	 * the normal and point of intersection to world space.
X	 */
X	if (!texturing) {
X		/*
X	 	 * At this point 'world2model' is really 'prim2world'.
X		 */
X		if (transforming) {
X			NormalTransform(norm, &world2model.itrans);
X			NormalTransform(gnorm, &world2model.itrans);
X			VecAddScaled(ray->pos,
X				     hitlist->data[hitlist->nodes -1].dist,
X				     ray->dir, pos);
X		}
X		return entering;
X	}
X	/*
X	 * world2model currently transforms from primitive to world space.
X	 * Invert it to get transformation from world to primitive space.
X	 */
X	TransInvert(&world2model, &world2model);
X	TransInit(&prim2model);
X	rtmp = hitlist->data[0].ray;
X	/*
X	 * Walk down hitlist (from primitive up to World object),
X	 * transforming hit point and shading normal and applying textures.
X	 * Note that the texturing routines want gnorm in object space,
X	 * so we don't transform the geometric normal until texturing
X	 * is complete.
X	 */
X	for (hp = hitlist->data, i = 0; i < hitlist->nodes -1; i++, hp++) {
X		obj = hp->obj;
X		if (hp->dotrans) {
X			NormalTransform(norm, &hp->trans.itrans);
X			if (texturing) {
X				/*
X				 * Compose prim<-->model and world<-->model
X				 * with current transformation.
X				 */
X				TransCompose(&prim2model, &hp->trans,
X					&prim2model);
X				TransCompose(&world2model, &hp->trans,
X					&world2model);
X				/*
X				 * Transform point and ray to model space.
X				 */
X				PointTransform(pos, &hp->trans.trans);
X				(void)RayTransform(&rtmp, &hp->trans.trans);
X			}
X		}
X		/*
X		 * Apply textures
X		 */
X		if (obj->texture)
X			TextApply(obj->texture, prim, &rtmp, pos, norm,
X				gnorm, surf, &prim2model, &world2model);
X	}
X	/* Transform geometric normal from object to world space. */
X	NormalTransform(gnorm, &world2model.trans);
X	return entering;
X}
END_OF_FILE
if test 5452 -ne `wc -c <'libray/libsurf/surfshade.c'`; then
    echo shar: \"'libray/libsurf/surfshade.c'\" unpacked with wrong size!
fi
# end of 'libray/libsurf/surfshade.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 'libray/libtext/texture.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libray/libtext/texture.c'\"
else
echo shar: Extracting \"'libray/libtext/texture.c'\" \(4973 characters\)
sed "s/^X//" >'libray/libtext/texture.c' <<'END_OF_FILE'
X/*
X * texture.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: texture.c,v 4.0 91/07/17 14:44:11 kolb Exp Locker: kolb $
X *
X * $Log:	texture.c,v $
X * Revision 4.0  91/07/17  14:44:11  kolb
X * Initial version.
X * 
X */
X#include "texture.h"
X
X/*
X * Transformation structures used to map from texture space to
X * model/primitive/world space.
X */
XTrans prim2model, model2text, prim2text, world2text;
X
X#define ApplyMapping(m,o,p,n,c,u,v)	(*m->method)(m, o, p, n, c, u, v)
X
XTexture *
XTextCreate(data, meth)
XTextRef data;
Xvoid (*meth)();
X{
X	Texture *res;
X
X	res = (Texture *)share_calloc(1, sizeof(Texture));
X	res->data = data;
X	res->method = meth;
X	res->trans = (Trans *)NULL; 
X	res->next = (Texture *)NULL;
X	res->animtrans = FALSE;
X	return res;
X}
X
X/*
X * Apply appropriate textures to a surface.
X */
Xvoid
XTextApply(tlist, prim, ray, pos, norm, gnorm, surf, p2model, world2model)
XTexture *tlist;				/* Textures */
XGeom *prim;
XRay *ray;
XVector *pos, *norm, *gnorm;		/* pos, shading norm, geo. norm */
XSurface *surf;
XTrans *p2model, *world2model;
X{
X	Vector ptmp;
X	Texture *ttmp;
X
X	prim2model = *p2model;
X	/*
X	 * Walk down texture list, applying each in turn.
X	 */
X	for (ttmp = tlist; ttmp; ttmp = ttmp->next) {
X		/*
X		 * Make copies of pos & ray to pass to the texturing function.
X		 */
X		ptmp = *pos;
X		if (ttmp->trans) {
X			/*
X			 * 'take' the inverse of ttmp->trans, since
X			 * transforming a texture means applying the
X			 * inverse of the transformation
X			 * to the point of intersection, etc.
X			 */
X			if (ttmp->animtrans) {
X				/*
X				 * Resolve animated associations.
X				 * We currently do not store a time
X				 * for the texture, so we can't know if
X				 * we're already resolved for the current
X				 * ray->time.
X				 */
X				TransResolveAssoc(ttmp->trans);
X				TransComposeList(ttmp->trans, &model2text);
X				TransInvert(&model2text, &model2text);
X			} else
X				TransInvert(ttmp->trans, &model2text);
X			/*
X			 * We compose ttmp->trans, which maps from model to
X			 * texture space, with prim2model and world2model
X			 * to get prim2text and world2text.
X			 */
X			TransCompose(&model2text, &prim2model, &prim2text);
X			TransCompose(&model2text, world2model, &world2text);
X			/*
X			 * Transform intersection point to texture space.
X			 * Ray and normal are passed in model space.
X			 */
X			ModelPointToText(&ptmp);
X		} else {
X			/*
X		 	 * By default, texture and model space are identical.
X		 	 */
X			TransInit(&model2text);
X			TransCopy(&prim2model, &prim2text);
X			TransCopy(world2model, &world2text);
X		}
X
X		/*
X		 * Call texture function.
X		 */
X		(*ttmp->method) (ttmp->data,prim,ray,&ptmp,norm,gnorm,surf);
X	}
X}
X
X/*
X * Compute UV at 'pos' on given primitive.
X */
XTextToUV(mapping, prim, pos, norm, u, v, dpdu, dpdv)
XMapping *mapping;
XGeom *prim;
XVector *pos, *norm, *dpdu, *dpdv;
XFloat *u, *v;
X{
X	Vec2d uv;
X	Vector ptmp;
X	RSMatrix t;
X
X	ptmp = *pos;
X
X	if (mapping->flags & PRIMSPACE) {
X		/*
X	 	 * Convert point and normal to primitive space.
X	 	 */
X		TextPointToPrim(&ptmp);
X	} else {
X		/*
X		 * Convert point and normal to object space.
X		 */
X		TextPointToModel(&ptmp);
X	}
X
X	ApplyMapping(mapping, prim, &ptmp, norm, &uv, dpdu, dpdv);
X
X	/*
X	 * Transform UV by model2text.  We set X = u and Y = v,
X	 * while Z = 0.
X	 * Although the UV coordinates may be in prim space,
X	 * we treat them as if they are model-space coords.
X	 * This is due to the fact that we want the texture
X	 * to be applied in model space.
X	 */
X	ptmp.x = uv.u;
X	ptmp.y = uv.v;
X	ptmp.z = 0.;
X	PointTransform(&ptmp, &model2text.trans);
X	*u = ptmp.x;
X	*v = ptmp.y;
X	if (dpdu == (Vector *)NULL || dpdv == (Vector *)NULL)
X		return;
X	/*
X	 * Here's the ugly part.
X	 * Build initial UVN-->XYZ matrix...
X	 */
X	ArbitraryMatrix(dpdu->x, dpdu->y, dpdu->z,
X			 dpdv->x, dpdv->y, dpdv->z,
X			 norm->x, norm->y, norm->z, 0., 0., 0., &t);
X	/*
X	 * ...transform to model space...
X	 */
X	MatrixMult(&t, &prim2model.trans, &t);
X	/*
X	 * ... apply model2text in UVN space.
X	 */
X	MatrixMult(&model2text.itrans, &t, &t);
X	dpdu->x = t.matrix[0][0];
X	dpdu->y = t.matrix[0][1];
X	dpdu->z = t.matrix[0][2];
X	dpdv->x = t.matrix[1][0];
X	dpdv->y = t.matrix[1][1];
X	dpdv->z = t.matrix[1][2];
X	(void)VecNormalize(dpdu);
X	(void)VecNormalize(dpdv);
X}
X
X/*
X * Append 'text' to the given linked list of textures.
X * Note that 'text' may be a list, too.
X */
XTexture *
XTextAppend(text, list)
XTexture *text, *list;
X{
X	Texture *tp;
X
X	if (list) {
X		/*
X		 * Walk to the end of the list
X		 */
X		for (tp = list;tp->next ;tp = tp->next)
X				;
X		tp->next = text;
X		return list;
X	}
X	/* else */
X	return text;
X}
END_OF_FILE
if test 4973 -ne `wc -c <'libray/libtext/texture.c'`; then
    echo shar: \"'libray/libtext/texture.c'\" unpacked with wrong size!
fi
# end of 'libray/libtext/texture.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'\" \(5430 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.1.3 92/01/14 18:28:38 cek Exp Locker: cek $ */
X%{
X#include "config.h"
X#include "rayshade.h"
X#ifdef I_STRING
X#include 
X#else
X#include 
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 1500
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;
Xcrop			return tCROP;
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;
Xwindow			return tWINDOW;
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	    (i = sscanf(buf," line %d \"%[^\"]s\"",&yylineno,yyfilename))==0) {
X		RLerror(RL_PANIC, "Unknown '#' control (%s).\n",buf);
X		exit(1);
X	}
X	if (i == 1 && (index(buf,'"') != (char *)NULL)) {
X		/*
X		 * Filename was given as ""
X		 */
X		(void)strcpy(yyfilename, "stdin");
X	}
X	yylineno--;  /* The newline we unput will increment yylineno */
X}
END_OF_FILE
if test 5430 -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'\" \(5673 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.1.2 92/01/14 18:29:35 cek Exp Locker: cek $
X *
X * $Log:	setup.c,v $
X * Revision 4.0.1.2  92/01/14  18:29:35  cek
X * patch3: Added initialization of cpp option.
X * 
X * Revision 4.0.1.1  91/09/29  15:52:20  cek
X * patch1: Added crop window initialization.
X * patch1: Moved RSViewing call to appropriate location.
X * 
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 
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.cpp = TRUE;
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.crop[LOW][X] = Options.crop[LOW][Y] = 0.;
X	Options.crop[HIGH][X] = Options.crop[HIGH][Y] = 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	 * Can't animate camera yet; when possible, this will
X	 * need to be much smarter.
X	 * RSViewing();
X	 */
X
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	/*
X	 * Camera is currently static; initialize it here.
X	 */
X	RSViewing();
X}
END_OF_FILE
if test 5673 -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
Modified: Wed Dec 11 17:00:00 1996 GMT
Page accessed 1356 times since Sat Apr 17 21:59:32 1999 GMT