#! /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