kits@6
|
Part01,
Part02,
Part03,
Part04,
Part05,
Part06,
Part07,
Part08,
Part09,
Part10,
Part11,
Part12,
Part13,
Part14,
Part15,
Part16,
Part17,
Part18,
Part19,
|
|
|
#! /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
|