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 'blurb.urt' <<'END_OF_FILE'
X
X THE UTAH RASTER TOOLKIT
X
XThe Utah Raster toolkit is a collection of programs and C routines for
Xdealing with raster images commonly encountered in computer graphics. It
Xprovides the following major functions:
X
X * A device and system independent image format for storing images
X and information about them. Called the RLE format, it uses
X run length encoding to reduce storage space for most images.
X
X * A library of C routines for reading, writing and manipulating
X images stored in the RLE format.
X
X * A collections of programs for manipulating and displaying RLE
X images.
X
X
XThe Format:
X
X The device independent RLE file has two parts, the header, which stores
X information about the image (size, position, channel information,
X color maps, comments, etc), and the actual image data in a run length
X encoded format. The RLE format often requires about a third of the
X available space for most "image synthesis" style images. If the image
X does not compress well, the RLE format stores it as straight pixel data
X with little extra overhead. The format was first developed around
X 1983 at the University of Utah.
X
XThe Library:
X
X C routines are provided for setting up and reading the image header,
X and for reading and writing the image a scanline at a time. Images can
X be read or written using two different methods. Using the "row" method,
X the library performs the RLE encoding and decoding. With the "raw" method,
X scanlines are constructed directly with RLE opcodes. Additional routines
X are available for generating dither matrices (e.g., for display programs
X running on devices with less than 24 bits of color).
X
XThe Tools:
X applymap - Apply color map values to pixel values.
X avg4 - Downfilter an image by 1/4, generating a matte channel if one
X didn't previously exist
X crop - Crop an image.
X dvirle - Convert TeX output into anti-aliased images.
X fant - Rotate and/or scale in image by an arbitrary (float) value.
X mcut - Quantize an image from 24 to eight bits using the median cut
X algorithm.
X mergechan - Merge several channels from different files into a single
X RLE file.
X pyrmask - Blend images using Gaussian pyramids.
X repos - Change the position in the RLE header.
X rleClock - Generate an image of a clock.
X rleaddcom - Add a comment to the RLE file's header.
X rlebg - Generate a solid or variable background.
X rlebox - Find the actual non-background area of an image.
X rlecomp - Digital image compositor. Provides the operations over, atop,
X in, out, xor, plus, minus and diff on two images.
X rledither - Floyd-Steinberg to a given color map.
X rleflip - Rotate an image by 90/180 degree increments.
X rlehdr - Dump the contents of the RLE header in human readable form.
X rlehisto - Generate the histogram of an RLE file.
X rleldmap - Load a color map into an RLE file from a variety of sources.
X rlemandl - Generate Mandlebrot sets as RLE files.
X rlenoise - Adds random noise to an image.
X rlepatch - Overlay several smaller images over a larger one.
X rleprint - Print all pixel values.
X rlequant - Variance-based color quantization.
X rlescale - Generates gray scale and color scale RLE files.
X rleselect - Select specific images from a file.
X rlesetbg - Set the background color stored in the RLE header.
X rleskel - A skeleton application, for rolling your own.
X rlespiff - Simple contrast enhancement to "spiff up" images.
X rlesplice - Splice images together horizontally or vertically.
X rlesplit - Split a file containing several images into several files.
X rleswap - Swap, copy or delete channels in an RLE file.
X rlezoom - Enlarge or shrink an image with pixel replication.
X smush - Perform a simple Gaussian filter on an image.
X to8 - Convert a 24 bit RGB image to an eight bit dithered one.
X tobw - Convert 24 bits to 8 bits black and white.
X unexp - Convert an "exponential" image to a displayable one.
X unslice - Quickly assemble an image from several horizontal strips
X
X Format conversion programs are provided for:
X - Ascii (line printer pictures) (to)
X - Cubicomp image format (from)
X - GIF (to and from)
X - MacPaint (to and from)
X - PBMPLUS pgm (from) and ppm (to and from)
X - PostScript (to)
X - Sun rasterfiles (to and from)
X - Targa image format (from)
X - TIFF (to and from)
X - Wasatch paint systems (from)
X - Wavefront 'RLA' format (to and from)
X - Simple pixel streams (color & B&W) (to and from)
X
X Display programs are provided for:
X get4d - SGI Iris 4D workstation
X get_orion - Orion displays
X getap - Apollo workstations
X getbob - HP Series 300 ("bobcat") running Windows 9000
X getcx3d - Chromatics CX1500 display
X getfb - BRL "libfb" displays
X getgmr - Grinnell GMR-27 (remember those?)
X getiris - Iris in raw 24 bit mode.
X getmac - Macintosh.
X getmex - Iris running Mex
X getqcr - Photograph images with the Matrix QCR-Z camera.
X getren - HP 98721 "Renaissance" display
X getsun - Suns running Suntools
X getx10 - Workstations running the X10 window system
X getx11 - Workstations running X11
X - [Note display programs for a particular device are
X simple to add]
X
X All the tools are designed to pipe together, so they can be used as
X filters on images much like the standard Unix tools filter text.
X
XPlus:
X
X The raster toolkit also includes Unix man pages for the library and
X commands, some sample images, and additional documentation.
X
XSystem Requirements:
X
X We have successfully ported the Raster Toolkit to a number of Unix
X systems, including 4.2/4.3bsd (Vax, Sun, etc), Apollo Domain/IX, HP
X Series 300, SGI Iris, IBM RT and RS6000, Stardent GS-1000, Cray
X running UNICOS. Display programs are included for several devices.
X Creating display programs for additional devices is a
X straightforward task.
X
XDistribution:
X
X For Internet sites, the toolkit may be obtained via anonymous FTP to
X the sites listed below, in the file pub/urt-3.0.tar.Z. Some sample
X images are in the file pub/urt-img.tar.Z, and the file
X pub/urt-doc.tar.Z contains some (somewhat out-of-date) "papers"
X describing the toolkit. We are still working out distribution
X mechanisms for sites not connected to the Internet. We will
X probably be adding other archive sites; please send mail to one of
X the addresses below if you don't see a site near you (particularly
X if you are on the other side of the Atlantic or Pacific). If you
X would like to offer to be an archive site, please let us know, too.
X
X cs.utah.edu (128.110.4.21)
X weedeater.math.yale.edu (130.132.23.17)
X freebie.engin.umich.edu (35.2.68.23)
X
X Although the Raster Toolkit software is copyrighted, it may be freely
X re-distributed on a "GNU-like" basis.
X
XIf you have further questions, please direct them to
X toolkit-request@cs.utah.edu
Xor urt-request@caen.engin.umich.edu
X(but not both).
END_OF_FILE
if test 7019 -ne `wc -c <'blurb.urt'`; then
echo shar: \"'blurb.urt'\" unpacked with wrong size!
fi
# end of 'blurb.urt'
fi
if test -f 'libray/liblight/shadow.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'libray/liblight/shadow.c'\"
else
echo shar: Extracting \"'libray/liblight/shadow.c'\" \(7574 characters\)
sed "s/^X//" >'libray/liblight/shadow.c' <<'END_OF_FILE'
X/*
X * shadow.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: shadow.c,v 4.0.1.1 91/09/29 15:40:57 cek Exp Locker: cek $
X *
X * $Log: shadow.c,v $
X * Revision 4.0.1.1 91/09/29 15:40:57 cek
X * patch1: ShadowOptions was incorrectly externed.
X *
X * Revision 4.0 91/07/17 14:35:34 kolb
X * Initial version.
X *
X */
X#include "libobj/geom.h"
X#include "libsurf/surface.h"
X#include "light.h"
X
X/*
X * Shadow stats.
X * External functions have read access via ShadowStats().
X */
Xstatic unsigned long ShadowRays, ShadowHits, CacheMisses, CacheHits;
X/*
X * Options controlling how shadowing information is determined.
X * Set by external modules via ShadowSetOptions().
X */
Xstatic long ShadowOptions;
X
Xvoid LightCacheHit();
X
X/*
X * Trace ray from point of intersection to a light. If an intersection
X * occurs at a distance less than "dist" (the distance to the
X * light source), then the point is in shadow, and TRUE is returned.
X * Otherwise, the brightness/color of the light is computed ('result'),
X * and FALSE is returned.
X */
Xint
XShadowed(result, color, cache, ray, dist, noshadow)
XColor *result, *color; /* resultant intensity, light color */
XShadowCache *cache; /* shadow cache for light */
XRay *ray; /* ray, origin on surface, dir towards light */
XFloat dist; /* distance from pos to light source */
Xint noshadow; /* If TRUE, no shadow ray is cast. */
X{
X int i, smooth, enter;
X HitList hitlist;
X Ray tmpray;
X ShadowCache *cp;
X Vector hitpos, norm, gnorm;
X Surface surf, *sptr, *prevsurf;
X Float s, totaldist, statten;
X Color res;
X
X if (noshadow || NOSHADOWS(ShadowOptions)) {
X *result = *color;
X return FALSE;
X }
X
X ShadowRays++;
X s = dist;
X cp = &cache[ray->depth];
X /*
X * Check shadow cache. SHADOWCACHE() is implied.
X */
X if (cp->obj) {
X /*
X * Transform ray to the space of the cached primitive.
X */
X tmpray = *ray;
X if (cp->dotrans)
X s *= RayTransform(&tmpray, &cp->trans);
X /*
X * s = distance to light source in 'primitive space'.
X * Intersect ray with cached object.
X */
X if (cp->obj->animtrans) {
X /*
X * Geom has animated transformation --
X * call intersect so that the transformation
X * is resolved properly.
X */
X if (intersect(cp->obj, &tmpray, &hitlist,
X SHADOW_EPSILON, &s)) {
X CacheHits++;
X return TRUE;
X }
X } else if (IsAggregate(cp->obj)) {
X if ((*cp->obj->methods->intersect)(cp->obj->obj,
X &tmpray, &hitlist, SHADOW_EPSILON, &s)) {
X CacheHits++;
X return TRUE;
X }
X } else if ((*cp->obj->methods->intersect)(cp->obj->obj,
X &tmpray, SHADOW_EPSILON, &s)) {
X /* Hit cached object. */
X CacheHits++;
X return TRUE;
X }
X /*
X * Did not hit anything -- zero out the cache.
X */
X CacheMisses++;
X /*
X * Transformed -- reset s for use below.
X */
X s = dist;
X cp->obj = (Geom *)NULL;
X cp->dotrans = FALSE;
X }
X
X hitlist.nodes = 0;
X if (!TraceRay(ray, &hitlist, SHADOW_EPSILON, &s)) {
X /* Shadow ray didn't hit anything. */
X *result = *color;
X return FALSE;
X }
X
X /*
X * Otherwise, we've hit something.
X */
X ShadowHits++;
X
X /*
X * If we're not worrying about transparent objects...
X * This is ugly due to the fact that we have to find
X * the surface associated with the object that was hit.
X * GetShadingSurf() will always return a non-null value.
X *
X * ***NOTE**
X * The transparency of the surface is checked below without
X * applying textures, if any, to it. This means that if
X * an object may be made trasparent by a texture, its
X * surface should have non-zero transparency *before* texturing
X * as well.
X */
X if (!SHADOWTRANSP(ShadowOptions)) {
X if (SHADOWCACHE(ShadowOptions))
X LightCacheHit(&hitlist, cp);
X return TRUE;
X }
X
X /*
X * We've hit a transparent object. Attenuate the color of the light
X * source and continue the ray until we hit background or a
X * non-transparent object. Note that this is incorrect if DefIndex or
X * any of the indices of refraction of the surfaces differ.
X */
X
X totaldist = 0.;
X prevsurf = (Surface *)NULL;
X res = *color;
X
X do {
X /*
X * Get a pointer to the surface to be used
X * for shading...
X */
X sptr = GetShadingSurf(&hitlist);
X if (sptr->transp < EPSILON) {
X if (SHADOWCACHE(ShadowOptions))
X LightCacheHit(&hitlist, cp);
X return TRUE;
X }
X /*
X * Take specular transmission attenuation from
X * previous intersection into account.
X */
X if (prevsurf) {
X if (prevsurf->statten != 1.) {
X statten = pow(prevsurf->statten, s - totaldist);
X ColorScale(statten, res, &res);
X }
X }
X /*
X * Perform texturing and the like in case surface
X * transparency is modulated.
X */
X /* copy the surface to be used... */
X surf = *sptr;
X enter = ComputeSurfProps(&hitlist, ray, &hitpos,
X &norm, &gnorm, &surf, &smooth);
X if (enter)
X prevsurf = &surf;
X else
X prevsurf = (Surface *)NULL;
X /*
X * Attenuate light source by body color of surface.
X */
X ColorScale(surf.transp, res, &res);
X ColorMultiply(res, surf.body, &res);
X /*
X * Return if attenuation becomes large.
X * In this case, the light was attenuated to nothing,
X * so we can't cache anything...
X */
X if (res.r < EPSILON && res.g < EPSILON && res.b < EPSILON)
X return TRUE;
X /*
X * Min distance is previous max.
X */
X totaldist = s + EPSILON;
X /*
X * Max distance is dist to light source
X */
X s = dist;
X /*
X * Trace ray starting at new origin and in the
X * same direction.
X */
X hitlist.nodes = 0;
X } while (TraceRay(ray, &hitlist, totaldist, &s));
X
X *result = res;
X return FALSE;
X}
X
Xvoid
XShadowStats(shadowrays, shadowhit, cachehit, cachemiss)
Xunsigned long *shadowrays, *shadowhit, *cachehit, *cachemiss;
X{
X *shadowrays = ShadowRays;
X *shadowhit = ShadowHits;
X *cachehit = CacheHits;
X *cachemiss = CacheMisses;
X}
X
Xvoid
XShadowSetOptions(options)
Xlong options;
X{
X ShadowOptions = options;
X}
X
Xvoid
XLightCacheHit(hitlist, cache)
XHitList *hitlist;
XShadowCache *cache;
X{
X HitNode *np;
X int i, n;
X extern long ShadowOptions;
X
X i = 0;
X
X if (SHADOWCSG(ShadowOptions)) {
X /*
X * There's possibly a CSG object in the
X * hitlist, so we can't simply cache the
X * primitive that was hit. Find the
X * object lowest in hit that's not part
X * of a CSG object, and cache it.
X */
X i = FirstCSGGeom(hitlist);
X }
X
X if (SHADOWBLUR(ShadowOptions)) {
X /*
X * Something might be animated --
X * gotta cache the puppy.
X */
X n = FirstAnimatedGeom(hitlist);
X if (n > i)
X i = n;
X }
X
X /*
X * Compute total world-->cached object
X * transformation and store in cache->trans.
X */
X /*
X * Find the first transformation...
X */
X np = &hitlist->data[i];
X cache->obj = np->obj;
X /*
X * If the cached object is animated, then we don't
X * want to include the object's transformation(s)
X * in cache->trans (it's taken care of in shadowed()
X * by calling intersect).
X */
X if (cache->obj->animtrans) {
X i++;
X np++;
X }
X cache->dotrans = FALSE;
X while (i < hitlist->nodes -1) {
X if (np->obj->trans) {
X if (cache->dotrans) {
X MatrixMult(
X &np->obj->trans->itrans,
X &cache->trans,
X &cache->trans);
X } else {
X MatrixCopy(
X &np->obj->trans->itrans,
X &cache->trans);
X cache->dotrans = TRUE;
X }
X }
X i++;
X np++;
X }
X}
END_OF_FILE
if test 7574 -ne `wc -c <'libray/liblight/shadow.c'`; then
echo shar: \"'libray/liblight/shadow.c'\" unpacked with wrong size!
fi
# end of 'libray/liblight/shadow.c'
fi
if test -f 'libray/libtext/noise.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'libray/libtext/noise.c'\"
else
echo shar: Extracting \"'libray/libtext/noise.c'\" \(7883 characters\)
sed "s/^X//" >'libray/libtext/noise.c' <<'END_OF_FILE'
X/*
X * noise.c
X *
X * Copyright (C) 1989, 1991, Robert Skinner, 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: noise.c,v 4.0 91/07/17 14:43:38 kolb Exp Locker: kolb $
X *
X * $Log: noise.c,v $
X * Revision 4.0 91/07/17 14:43:38 kolb
X * Initial version.
X *
X */
X#include "libcommon/common.h"
X
X#define MINX -1000000
X#define MINY MINX
X#define MINZ MINX
X
X#define SCURVE(a) ((a)*(a)*(3.0-2.0*(a)))
X#define REALSCALE ( 2.0 / 65536.0 )
X#define NREALSCALE ( 2.0 / 4096.0 )
X#define Hash3d(a,b,c) hashTable[hashTable[hashTable[(a) & 0xfff] ^ ((b) & 0xfff)] ^ ((c) & 0xfff)]
X#define Hash(a,b,c) (xtab[(xtab[(xtab[(a) & 0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff)
X
X#define INCRSUM(m,s,x,y,z) ((s)*(RTable[m]*0.5 \
X + RTable[m+1]*(x) \
X + RTable[m+2]*(y) \
X + RTable[m+3]*(z))) \
X
X
X#define MAXSIZE 267
X
XFloat RTable[MAXSIZE];
Xstatic short *hashTable;
Xstatic int R(), Crc16();
X
Xstatic unsigned short xtab[256] =
X{
X 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
X 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
X 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
X 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
X 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
X 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
X 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
X 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
X 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
X 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
X 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
X 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
X 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
X 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
X 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
X 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
X 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
X 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
X 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
X 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
X 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
X 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
X 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
X 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
X 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
X 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
X 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
X 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
X 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
X 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
X 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
X 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
X};
X
XFloat Chaos(), Marble();
X
Xvoid
XInitTextureTable()
X{
X int i, j, temp;
X
X seednrand(1);
X hashTable = (short *) Malloc(4096*sizeof(short int));
X for (i = 0; i < 4096; i++)
X hashTable[i] = i;
X for (i = 4095; i > 0; i--) {
X j = (int)(nrand() * 4096);
X temp = hashTable[i];
X hashTable[i] = hashTable[j];
X hashTable[j] = temp;
X }
X}
X
Xvoid
XNoiseInit()
X{
X int i;
X Vector rp;
X
X InitTextureTable();
X
X for (i = 0; i < MAXSIZE; i++) {
X rp.x = rp.y = rp.z = (Float)i;
X RTable[i] = R(&rp)*REALSCALE - 1.0;
X }
X}
X
Xstatic int
XR(v)
XVector *v;
X{
X v->x *= .12345;
X v->y *= .12345;
X v->z *= .12345;
X
X return Crc16(v, sizeof(Vector));
X}
X
X/*
X * Note that passing a Float to Crc16 and interpreting it as
X * an array of chars means that machines with different floating-point
X * representation schemes will evaluate Noise(point) differently.
X */
Xstatic int
XCrc16(buf, count)
Xregister char *buf;
Xregister int count;
X{
X register unsigned int crc = 0;
X
X while (count--)
X crc = (crc >> 8) ^ xtab[ (unsigned char) (crc ^ *buf++) ];
X
X return crc;
X}
X
X
X/*
X * Robert Skinner's Perlin-style "Noise" function
X */
XFloat
XNoise3(point)
XVector *point;
X{
X register int ix, iy, iz, jx, jy, jz;
X Float x, y, z;
X Float sx, sy, sz, tx, ty, tz;
X Float sum;
X short m;
X
X
X /* ensures the values are positive. */
X x = point->x - MINX; y = point->y - MINY; z = point->z - MINZ;
X
X /* its equivalent integer lattice point. */
X ix = (int)x; iy = (int)y; iz = (int)z;
X jx = ix+1; jy = iy + 1; jz = iz + 1;
X
X sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
X
X /* the complement values of sx,sy,sz */
X tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
X
X /*
X * interpolate!
X */
X m = Hash3d( ix, iy, iz ) & 0xFF;
X sum = INCRSUM(m,(tx*ty*tz),(x-ix),(y-iy),(z-iz));
X
X m = Hash3d( jx, iy, iz ) & 0xFF;
X sum += INCRSUM(m,(sx*ty*tz),(x-jx),(y-iy),(z-iz));
X
X m = Hash3d( ix, jy, iz ) & 0xFF;
X sum += INCRSUM(m,(tx*sy*tz),(x-ix),(y-jy),(z-iz));
X
X m = Hash3d( jx, jy, iz ) & 0xFF;
X sum += INCRSUM(m,(sx*sy*tz),(x-jx),(y-jy),(z-iz));
X
X m = Hash3d( ix, iy, jz ) & 0xFF;
X sum += INCRSUM(m,(tx*ty*sz),(x-ix),(y-iy),(z-jz));
X
X m = Hash3d( jx, iy, jz ) & 0xFF;
X sum += INCRSUM(m,(sx*ty*sz),(x-jx),(y-iy),(z-jz));
X
X m = Hash3d( ix, jy, jz ) & 0xFF;
X sum += INCRSUM(m,(tx*sy*sz),(x-ix),(y-jy),(z-jz));
X
X m = Hash3d( jx, jy, jz ) & 0xFF;
X sum += INCRSUM(m,(sx*sy*sz),(x-jx),(y-jy),(z-jz));
X
X return sum;
X
X}
X
X/*
X * Vector-valued "Noise"
X */
Xvoid
XDNoise3(point, result)
XVector *point, *result;
X{
X register int ix, iy, iz, jx, jy, jz;
X Float x, y, z;
X Float px, py, pz, s;
X Float sx, sy, sz, tx, ty, tz;
X short m;
X
X /* ensures the values are positive. */
X x = point->x - MINX; y = point->y - MINY; z = point->z - MINZ;
X
X /* its equivalent integer lattice point. */
X ix = (int)x; iy = (int)y; iz = (int)z;
X jx = ix+1; jy = iy + 1; jz = iz + 1;
X
X sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
X
X /* the complement values of sx,sy,sz */
X tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
X
X /*
X * interpolate!
X */
X m = Hash3d( ix, iy, iz ) & 0xFF;
X px = x-ix; py = y-iy; pz = z-iz;
X s = tx*ty*tz;
X result->x = INCRSUM(m,s,px,py,pz);
X result->y = INCRSUM(m+4,s,px,py,pz);
X result->z = INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( jx, iy, iz ) & 0xFF;
X px = x-jx;
X s = sx*ty*tz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( jx, jy, iz ) & 0xFF;
X py = y-jy;
X s = sx*sy*tz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( ix, jy, iz ) & 0xFF;
X px = x-ix;
X s = tx*sy*tz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( ix, jy, jz ) & 0xFF;
X pz = z-jz;
X s = tx*sy*sz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( jx, jy, jz ) & 0xFF;
X px = x-jx;
X s = sx*sy*sz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( jx, iy, jz ) & 0xFF;
X py = y-iy;
X s = sx*ty*sz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X
X m = Hash3d( ix, iy, jz ) & 0xFF;
X px = x-ix;
X s = tx*ty*sz;
X result->x += INCRSUM(m,s,px,py,pz);
X result->y += INCRSUM(m+4,s,px,py,pz);
X result->z += INCRSUM(m+8,s,px,py,pz);
X}
END_OF_FILE
if test 7883 -ne `wc -c <'libray/libtext/noise.c'`; then
echo shar: \"'libray/libtext/noise.c'\" unpacked with wrong size!
fi
# end of 'libray/libtext/noise.c'
fi
if test -f 'libshade/picture.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'libshade/picture.c'\"
else
echo shar: Extracting \"'libshade/picture.c'\" \(7990 characters\)
sed "s/^X//" >'libshade/picture.c' <<'END_OF_FILE'
X/*
X * picture.c
X *
X * Copyright (C) 1989, 1991, Craig E. Kolb, Rod G. Bogart
X * All rights reserved.
X *
X * This software may be freely copied, modified, and redistributed
X * provided that this copyright notice is preserved on all copies.
X *
X * You may not distribute this software, in whole or in part, as part of
X * any commercial product without the express consent of the authors.
X *
X * There is no warranty or other guarantee of fitness of this software
X * for any purpose. It is provided solely "as is".
X *
X * $Id: picture.c,v 4.0.1.2 92/02/07 09:22:20 cek Exp Locker: cek $
X *
X * $Log: picture.c,v $
X * Revision 4.0.1.2 92/02/07 09:22:20 cek
X * patch6: Fixed typo in MTV error message.
X *
X * Revision 4.0.1.1 92/01/10 16:28:28 cek
X * patch3: Added check for nonexistent patial image file.
X * patch3: Fixed declaration of nrow in count_rle_rows().
X * patch3: Changed level of several error messages.
X *
X * Revision 4.0 91/07/17 14:47:00 kolb
X * Initial version.
X *
X */
X#include "rayshade.h"
X#include "picture.h"
X#include "viewing.h"
X#include "options.h"
X#include "stats.h"
X
X#ifdef URT
Xunsigned char **outptr; /* Output buffer */
Xstatic int count_rle_rows();
X#endif
X
X/*
X * Convert floating-point (0.-1.) to unsigned char (0-255), with no gamma
X * correction.
X */
Xunsigned char
Xcorrect(x)
XFloat x;
X{
X /*
X * Truncate values < 0 or > 1.
X */
X if (x < 0)
X return 0;
X if (x > 1.)
X return 255;
X return (unsigned char)(x * 255.);
X}
X
X#ifdef URT
X/*
X * Open image file and write RLE header.
X */
Xvoid
XPictureStart(argv)
Xchar **argv;
X{
X char gammacom[40];
X
X if (Options.framenum != Options.startframe) {
X /*
X * We've been here before;
X * write a new header and return.
X */
X rle_put_setup(&rle_dflt_hdr);
X return;
X }
X /*
X * If Appending, then we know that outfile is valid, 'cause
X * we've already read its header.
X */
X if (Options.appending) {
X Options.pictfile = fopen(Options.imgname, "a");
X if (Options.pictfile == (FILE *)0)
X RLerror(RL_PANIC, "Cannot append to %s?!\n",
X Options.imgname);
X rle_dflt_hdr.rle_file = Options.pictfile;
X rle_put_init(&rle_dflt_hdr);
X } else {
X /*
X * Starting image from scatch.
X */
X if (Options.imgname) {
X Options.pictfile = fopen(Options.imgname, "w");
X if (Options.pictfile == (FILE *)NULL)
X RLerror(RL_ABORT,"Cannot open %s for writing.",
X Options.imgname);
X } else
X Options.pictfile = stdout;
X
X rle_dflt_hdr.xmax = Screen.maxx;
X rle_dflt_hdr.ymax = Screen.maxy;
X rle_dflt_hdr.xmin = Screen.minx;
X rle_dflt_hdr.ymin = Screen.miny;
X rle_dflt_hdr.alpha = Options.alpha;
X if (Options.alpha)
X RLE_SET_BIT(rle_dflt_hdr, RLE_ALPHA);
X if (Options.exp_output) {
X RLE_SET_BIT(rle_dflt_hdr, RLE_BLUE + 1);
X rle_dflt_hdr.ncolors = 4;
X rle_putcom("exponential_data", &rle_dflt_hdr);
X }
X else
X rle_dflt_hdr.ncolors = 3;
X /*
X * Document image gamma in RLE comment area.
X * Options.gamma has been inverted.
X */
X (void)sprintf(gammacom, "display_gamma=%g", 1./Options.gamma);
X rle_putcom(gammacom, &rle_dflt_hdr);
X /*
X * Document command line in RLE history.
X */
X rle_addhist(argv, (rle_hdr *)0, &rle_dflt_hdr);
X rle_dflt_hdr.rle_file = Options.pictfile;
X rle_put_setup(&rle_dflt_hdr);
X /*
X * Flush the header. If we don't, and LINDA forks off
X * a bunch of workers, strange things will happen (they'll
X * all flush the buffer when they die, and you end up with
X * lots of headers at the end of the file).
X */
X (void)fflush(rle_dflt_hdr.rle_file);
X }
X
X if (rle_row_alloc(&rle_dflt_hdr, &outptr) < 0)
X RLerror(RL_PANIC, "Unable to allocate image memory.\n");
X}
X
X/*
X * Read RLE header to which we are appending in order determine
X * old resolution, window location, and the like.
X */
Xvoid
XPictureSetWindow()
X{
X if (Options.imgname == (char *)NULL)
X RLerror(RL_ABORT,
X "No partially-completed image file specified.\n");
X
X /*
X * Open image and read RLE header.
X */
X Options.pictfile = fopen(Options.imgname, "r");
X if (Options.pictfile == (FILE *)NULL) {
X RLerror(RL_ABORT, "Cannot open image file %s.\n",
X Options.imgname);
X }
X rle_dflt_hdr.rle_file = Options.pictfile;
X rle_get_setup_ok(&rle_dflt_hdr, "rayshade", Options.imgname);
X
X /*
X * If user specified a window that does not match what's in
X * the header, complain.
X if (Screen.minx != UNSET && Screen.minx != rle_dflt_hdr.xmin ||
X Screen.miny != UNSET && Screen.miny != rle_dflt_hdr.ymin ||
X Screen.maxx != UNSET && Screen.maxx != rle_dflt_hdr.xmax ||
X Screen.maxy != UNSET && Screen.maxy != rle_dflt_hdr.ymax)
X RLerror(RL_ADVISE, "Image window: %d - %d, %d - %d.\n",
X rle_dflt_hdr.xmin, rle_dflt_hdr.xmax,
X rle_dflt_hdr.ymin, rle_dflt_hdr.ymax);
X */
X /*
X * Set window.
X */
X Screen.minx = rle_dflt_hdr.xmin;
X Screen.miny = rle_dflt_hdr.ymin;
X Screen.maxx = rle_dflt_hdr.xmax;
X Screen.maxy = rle_dflt_hdr.ymax;
X
X /*
X * Set alpha. Warn the user if the alpha option doesn't reflect
X * what's already been rendered.
X */
X if (Options.alpha != rle_dflt_hdr.alpha)
X RLerror(RL_WARN, "Image %s %s an alpha channel.\n",
X Options.imgname,
X rle_dflt_hdr.alpha ? "has" : "does not have");
X
X Options.alpha = rle_dflt_hdr.alpha;
X
X /*
X * Determine number of scanlines written to file.
X */
X Screen.miny += count_rle_rows(&rle_dflt_hdr);
X if (Screen.miny >= Screen.maxy) {
X fprintf(stderr, "\"%s\" is a complete image.\n",
X Options.imgname);
X exit(0);
X }
X fprintf(Stats.fstats,"Continuing \"%s\" at scanline #%d.\n",
X Options.imgname, Screen.miny);
X (void)fclose(Options.pictfile);
X}
X
Xstatic int
Xcount_rle_rows( hdr )
Xrle_hdr *hdr;
X{
X rle_op **raw;
X int *nraw, y, ynext;
X
X if (rle_raw_alloc( hdr, &raw, &nraw ) < 0) {
X RLerror(RL_PANIC,
X "Unable to allocate memory in count_rle_rows.\n");
X }
X
X y = hdr->ymin;
X while ((ynext = rle_getraw( hdr, raw, nraw )) != 32768) {
X y = ynext+1;
X rle_freeraw( hdr, raw, nraw );
X }
X
X /* Free memory. */
X rle_raw_free( hdr, raw, nraw );
X
X return y - hdr->ymin;
X}
X
X/*
X * Write a scanline of output.
X * "buf" is an array of Color structures of size Screen.xsize. Each color
X * component is normalized to [0, 1.].
X */
Xvoid
XPictureWriteLine(buf)
XPixel *buf;
X{
X register int i, chan;
X float floats[3];
X rle_pixel pixels[4];
X
X for(i = 0; i < Screen.xsize; i++) {
X if (!Options.exp_output) {
X /*
X * Scale colors to fit unsigned char and check for
X * over/underflow.
X */
X outptr[0][i] = CORRECT(buf[i].r);
X outptr[1][i] = CORRECT(buf[i].g);
X outptr[2][i] = CORRECT(buf[i].b);
X } else {
X /*
X * Convert 3 floats to 4 unsigned chars for
X * 'exponential_data' RLE file.
X */
X floats[0] = GAMMACORRECT(buf[i].r);
X floats[1] = GAMMACORRECT(buf[i].g);
X floats[2] = GAMMACORRECT(buf[i].b);
X float_to_exp( 3, floats, pixels );
X for (chan = 0; chan <= 3; chan++)
X outptr[chan][i] = pixels[chan];
X }
X if (Options.alpha)
X /*
X * Don't gamma correct alpha channel.
X */
X outptr[-1][i] = correct(buf[i].alpha);
X }
X rle_putrow(outptr, Screen.xsize, &rle_dflt_hdr);
X}
X
X/*
X * End the frame.
X */
Xvoid
XPictureFrameEnd()
X{
X rle_puteof(&rle_dflt_hdr);
X}
X
X/*
X * Close image file.
X */
Xvoid
XPictureEnd()
X{
X (void)fclose(Options.pictfile);
X}
X
X#else /* !URT */
Xvoid
XPictureStart(argv)
Xchar **argv;
X{
X if (Options.imgname) {
X Options.pictfile = fopen(Options.imgname, "w");
X if (Options.pictfile == (FILE *)NULL)
X RLerror(RL_ABORT, "Cannot open %s for writing.",
X Options.imgname);
X } else
X Options.pictfile = stdout;
X
X fprintf(Options.pictfile,"%d %d\n",Screen.xsize, Screen.ysize);
X
X (void)fflush(Options.pictfile);
X}
X
Xvoid
XPictureWriteLine(buf)
XPixel *buf;
X{
X register int i;
X
X for (i = 0; i < Screen.xsize; i++) {
X (void)fputc((int)CORRECT(buf[i].r), Options.pictfile);
X (void)fputc((int)CORRECT(buf[i].g), Options.pictfile);
X (void)fputc((int)CORRECT(buf[i].b), Options.pictfile);
X }
X (void)fflush(Options.pictfile);
X}
X
Xvoid
XPictureFrameEnd()
X{
X /*
X * Don't do anything -- generic format has no end-of-image marker.
X */
X}
X
Xvoid
XPictureEnd()
X{
X (void)fclose(Options.pictfile);
X}
X
X#endif /* URT */
END_OF_FILE
if test 7990 -ne `wc -c <'libshade/picture.c'`; then
echo shar: \"'libshade/picture.c'\" unpacked with wrong size!
fi
# end of 'libshade/picture.c'
fi
if test -f 'raypaint/xgraphics.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'raypaint/xgraphics.c'\"
else
echo shar: Extracting \"'raypaint/xgraphics.c'\" \(7806 characters\)
sed "s/^X//" >'raypaint/xgraphics.c' <<'END_OF_FILE'
X/*
X * xgraphics.c
X *
X * Copyright (C) 1989, 1991 Craig E. Kolb, Rod G. Bogart
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: xgraphics.c,v 4.0 91/07/17 17:37:32 kolb Exp Locker: kolb $
X *
X * $Log: xgraphics.c,v $
X * Revision 4.0 91/07/17 17:37:32 kolb
X * Initial version.
X *
X */
X
X#include
X#include
X#include
X#include
X
Xchar *display_name = NULL;
XDisplay *dpy = NULL;
XScreen *scrn;
XVisual *vis;
XColormap cmap;
XGC gc;
XWindow win;
Xint screen_height;
X
Xunsigned long graymap[256];
Xint max_colors;
Xdouble one_over_gamma = 0.4;
X
X/*****************************************************************
X * Sets the gray color map for the device. A 2.5 gamma map is used
X * by default.
X */
Xsetup_gray_gamma_map()
X{
X int cc, col;
X int gamma_color;
X
X XColor xcolor;
X
X /* Use the default colormap if possible. */
X if ( vis == DefaultVisualOfScreen( scrn ) )
X cmap = DefaultColormapOfScreen( scrn );
X else
X cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
X vis, AllocNone );
X
X /* try to share with current colormap */
X for (max_colors = 256; max_colors >= 16; max_colors = max_colors >> 1) {
X xcolor.flags= DoRed | DoGreen | DoBlue;
X for(col=0; col < max_colors; col++) {
X gamma_color = (pow((float) col / (float) max_colors,
X one_over_gamma) * 65536);
X xcolor.red= gamma_color;
X xcolor.green= gamma_color;
X xcolor.blue= gamma_color;
X if (!XAllocColor(dpy, cmap, &xcolor)) {
X for (cc=0; cc < col; cc++)
X XFreeColors(dpy, cmap, &graymap[cc], 1, 0);
X col = 0;
X break;
X }
X graymap[col] = xcolor.pixel;
X }
X if (col)
X return;
X }
X
X /* use new map */
X cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
X vis, AllocNone );
X if (cmap == NULL) {
X fprintf(stderr, "Could not create color map for visual\n");
X exit(-2);
X }
X for(cc=0; cc < 256; cc++)
X if (!XAllocColorCells(dpy, cmap, False, NULL, 0, &graymap[cc], 1))
X break;
X max_colors = cc;
X
X xcolor.flags= DoRed | DoGreen | DoBlue;
X for(col=0; col < max_colors; col++) {
X xcolor.pixel= graymap[col];
X gamma_color = (pow((float) col / (float) max_colors,
X one_over_gamma) * 65536);
X xcolor.red= gamma_color;
X xcolor.green= gamma_color;
X xcolor.blue= gamma_color;
X XStoreColor(dpy, cmap, &xcolor);
X }
X}
X
XGraphicsInit(xsize, ysize, name)
Xint xsize, ysize;
Xchar *name;
X{
X int win_size;
X XSetWindowAttributes attrs;
X XSizeHints sh;
X
X /* Open the display. */
X if ( ! dpy )
X {
X XVisualInfo vis_temp, *vis_list, *max_vis;
X int n_ret, i;
X
X dpy = XOpenDisplay( display_name );
X if ( ! dpy )
X {
X fprintf( stderr, "rayview: Can't open display %s\n",
X XDisplayName( display_name ) );
X exit(1);
X }
X
X /* Get a PseudoColor visual that has the maximum number of planes. */
X vis_temp.class = PseudoColor;
X vis_list = XGetVisualInfo( dpy, VisualClassMask, &vis_temp, &n_ret );
X if ( n_ret == 0 )
X {
X fprintf(stderr,
X "Can't find any PseudoColor visual from display %s.\n",
X XDisplayName( display_name ));
X exit(1);
X }
X max_vis = &vis_list[0];
X for ( i = 1; i < n_ret; i++ )
X {
X if ( max_vis->depth < vis_list[i].depth )
X max_vis = &vis_list[i];
X }
X vis = max_vis->visual;
X scrn = ScreenOfDisplay( dpy, max_vis->screen );
X gc = DefaultGCOfScreen( scrn );
X
X setup_gray_gamma_map();
X
X XFree( (char *)vis_list );
X }
X
X screen_height = ysize;
X
X attrs.backing_store = Always;
X attrs.colormap = cmap;
X attrs.event_mask = ExposureMask;
X attrs.background_pixel = BlackPixelOfScreen(scrn);
X attrs.border_pixel = WhitePixelOfScreen(scrn);
X
X win = XCreateWindow( dpy, RootWindowOfScreen( scrn ),
X 0, 0, xsize, ysize, 2,
X 0, 0, vis,
X CWBackingStore | CWColormap | CWEventMask |
X CWBackPixel | CWBorderPixel,
X &attrs );
X
X sh.flags = PSize | PMinSize | PMaxSize;
X sh.width = sh.min_width = sh.max_width = xsize;
X sh.height = sh.min_height = sh.max_height = ysize;
X XSetStandardProperties( dpy, win, name, name, None, NULL, 0, &sh );
X
X XMapWindow( dpy, win );
X
X XFlush( dpy );
X}
X
X/*
X * Draw the pixel at (xp, yp) in the color given by the rgb-triple,
X * 0 indicating 0 intensity, 255 max intensity.
X */
XGraphicsDrawPixel(xp, yp, color)
Xint xp, yp;
Xunsigned char color[3];
X{
X float bwvalue;
X int val;
X
X bwvalue = ( 0.35*color[0] + 0.55*color[1] + 0.10*color[2] ) / 256.0;
X val = (int) ( bwvalue * max_colors );
X XSetForeground( dpy, gc, graymap[val] );
X XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + 1)),
X 1, 1 );
X}
X
X/*
X * Draw the rect with lower left corner (xp, yp) and upper right
X * corner (xp+ys, yp+ys). The colors of the l-l, l-r, u-r, and u-l
X * corners are given as arrays of unsigned chars as above.
X */
XGraphicsDrawRectangle(xp, yp, xs, ys, ll, lr, ur, ul)
Xint xp, yp, xs, ys;
Xunsigned char ll[3], lr[3], ur[3], ul[3];
X{
X float bwvalue;
X int val;
X
X bwvalue = ( 0.35*ll[0] + 0.55*ll[1] + 0.10*ll[2] ) / 256.0;
X val = (int) ( bwvalue * max_colors );
X XSetForeground( dpy, gc, graymap[val] );
X XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + ys + 1)),
X xs+1, ys+1 );
X XFlush( dpy );
X}
X
XGraphicsLeftMouseEvent()
X{
X Window root_ret, child_ret;
X int rx, ry, wx, wy;
X unsigned int mask;
X
X if (XQueryPointer(dpy, win, &root_ret, &child_ret,
X &rx, &ry, &wx, &wy, &mask)) {
X return mask & Button1Mask;
X }
X else
X return 0;
X}
X
XGraphicsMiddleMouseEvent()
X{
X Window root_ret, child_ret;
X int rx, ry, wx, wy;
X unsigned int mask;
X
X if (XQueryPointer(dpy, win, &root_ret, &child_ret,
X &rx, &ry, &wx, &wy, &mask)) {
X return mask & Button2Mask;
X }
X else
X return 0;
X}
X
XGraphicsRightMouseEvent()
X{
X Window root_ret, child_ret;
X int rx, ry, wx, wy;
X unsigned int mask;
X
X if (XQueryPointer(dpy, win, &root_ret, &child_ret,
X &rx, &ry, &wx, &wy, &mask)) {
X return mask & Button3Mask;
X }
X else
X return 0;
X}
X
XGraphicsGetMousePos(x, y)
Xint *x, *y;
X{
X Window root_ret, child_ret;
X int rx, ry, wx, wy;
X unsigned int mask;
X
X if (XQueryPointer(dpy, win, &root_ret, &child_ret,
X &rx, &ry, &wx, &wy, &mask)) {
X *x = wx;
X *y = screen_height - wy - 1;
X }
X else {
X *x = 0;
X *y = 0;
X }
X}
X
XGraphicsRedraw()
X{
X XEvent event;
X if (XCheckTypedEvent(dpy, Expose, &event)) {
X XSetForeground( dpy, gc, graymap[0] );
X XFillRectangle( dpy, win, gc, event.xexpose.x, event.xexpose.y,
X event.xexpose.width, event.xexpose.height );
X XFlush( dpy );
X return 1;
X }
X else
X return 0;
X}
X
END_OF_FILE
if test 7806 -ne `wc -c <'raypaint/xgraphics.c'`; then
echo shar: \"'raypaint/xgraphics.c'\" unpacked with wrong size!
fi
# end of 'raypaint/xgraphics.c'
fi
if test -f 'rayview/spheregen.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'rayview/spheregen.c'\"
else
echo shar: Extracting \"'rayview/spheregen.c'\" \(7060 characters\)
sed "s/^X//" >'rayview/spheregen.c' <<'END_OF_FILE'
X/*
X * Routines to define a unit sphere Object.
X * If you have a sphere library (-lsphere on most SGI machines), you can
X * use that by defining SPHERELIB on the cc command line. Otherwise,
X * we use Jon Leech's code to generate a sphere.
X * C. Kolb 6/91
X */
X#ifdef SPHERELIB
X#include
X
X/*
X * Define unit sphere Object. Here, we make use of sgi's spherelib.
X * If not available, undefine SPHERELIB, and the code below will be used.
X */
XObject
XGLSphereObjectDefine()
X{
X int sphere;
X
X sphere = genobj();
X sphobj(sphere);
X return sphere;
X}
X#else
X
X/*
X * The following code has been slightly modified. The original sphere
X * code is available via anonymous
X * ftp from weedeater.math.yale.edu (130.132.23.17) in pub/sphere.c
X *
X * Modifications include changing print_triangle to draw a GL object,
X * the inclusion of gl.h,
X * the renaming of main() to GLSphereObjectDefine(), the nuking of anything
X * phigs-related, and setting the ccw flag to be true.
X *
X * C. Kolb 6/91
X */
X
X/*% cc -g sphere.c -o sphere -lm
X *
X * sphere - generate a triangle mesh approximating a sphere by
X * recursive subdivision. First approximation is an octahedron;
X * each level of refinement increases the number of triangles by
X * a factor of 4.
X * Level 3 (128 triangles) is a good tradeoff if gouraud
X * shading is used to render the database.
X *
X * Usage: sphere [level] [-p] [-c]
X * level is an integer >= 1 setting the recursion level (default 1).
X * -p causes generation of a PPHIGS format ASCII archive
X * instead of the default generic output format.
X * -c causes triangles to be generated with vertices in counterclockwise
X * order as viewed from the outside in a RHS coordinate system.
X * The default is clockwise order.
X *
X * The subroutines print_object() and print_triangle() should
X * be changed to generate whatever the desired database format is.
X *
X * Jon Leech (leech@cs.unc.edu) 3/24/89
X */
X#include
X#include
X
X#include
X
Xtypedef struct {
X double x, y, z;
X} point;
X
Xtypedef struct {
X point pt[3]; /* Vertices of triangle */
X double area; /* Unused; might be used for adaptive subdivision */
X} triangle;
X
Xtypedef struct {
X int npoly; /* # of triangles in object */
X triangle *poly; /* Triangles */
X} object;
X
X/* Six equidistant points lying on the unit sphere */
X#define XPLUS { 1, 0, 0 } /* X */
X#define XMIN { -1, 0, 0 } /* -X */
X#define YPLUS { 0, 1, 0 } /* Y */
X#define YMIN { 0, -1, 0 } /* -Y */
X#define ZPLUS { 0, 0, 1 } /* Z */
X#define ZMIN { 0, 0, -1 } /* -Z */
X
X/* Vertices of a unit octahedron */
Xtriangle octahedron[] = {
X { { XPLUS, ZPLUS, YPLUS }, 0.0 },
X { { YPLUS, ZPLUS, XMIN }, 0.0 },
X { { XMIN , ZPLUS, YMIN }, 0.0 },
X { { YMIN , ZPLUS, XPLUS }, 0.0 },
X { { XPLUS, YPLUS, ZMIN }, 0.0 },
X { { YPLUS, XMIN , ZMIN }, 0.0 },
X { { XMIN , YMIN , ZMIN }, 0.0 },
X { { YMIN , XPLUS, ZMIN }, 0.0 }
X};
X
X/* A unit octahedron */
Xobject oct = {
X sizeof(octahedron) / sizeof(octahedron[0]),
X &octahedron[0]
X};
X
X/* Forward declarations */
Xpoint *normalize(/* point *p */);
Xpoint *midpoint(/* point *a, point *b */);
Xvoid print_object(/* object *obj, int level */);
Xvoid print_triangle(/* triangle *t */);
X
X/*extern char *malloc(/* unsigned );*/
X
XObject
XGLSphereObjectDefine(maxlevel)
Xint maxlevel;
X{
X object *old,
X *new;
X int ccwflag = 1, /* Reverse vertex order if true */
X i, level;
X Object sph;
X
X makeobj(sph = genobj());
X
X if (ccwflag) {
X /* Reverse order of points in each triangle */
X for (i = 0; i < oct.npoly; i++) {
X point tmp;
X tmp = oct.poly[i].pt[0];
X oct.poly[i].pt[0] = oct.poly[i].pt[2];
X oct.poly[i].pt[2] = tmp;
X }
X }
X
X old = &oct;
X
X /* Subdivide each starting triangle (maxlevel - 1) times */
X for (level = 1; level < maxlevel; level++) {
X /* Allocate a new object */
X new = (object *)malloc(sizeof(object));
X if (new == NULL) {
X fprintf(stderr, "GLSphereObjectDefine: out of memory, level %d\n",
X level);
X exit(1);
X }
X new->npoly = old->npoly * 4;
X
X /* Allocate 4* the number of points in the current approximation */
X new->poly = (triangle *)malloc(new->npoly * sizeof(triangle));
X if (new->poly == NULL) {
X fprintf(stderr, "GLSphereObjectDefine: out of memory, level %d\n",
X level);
X exit(1);
X }
X
X /* Subdivide each triangle in the old approximation and normalize
X * the new points thus generated to lie on the surface of the unit
X * sphere.
X * Each input triangle with vertices labelled [0,1,2] as shown
X * below will be turned into four new triangles:
X *
X * Make new points
X * a = (0+2)/2
X * b = (0+1)/2
X * c = (1+2)/2
X * 1
X * /\ Normalize a, b, c
X * / \
X * b/____\ c Construct new triangles
X * /\ /\ [0,b,a]
X * / \ / \ [b,1,c]
X * /____\/____\ [a,b,c]
X * 0 a 2 [a,c,2]
X */
X for (i = 0; i < old->npoly; i++) {
X triangle
X *oldt = &old->poly[i],
X *newt = &new->poly[i*4];
X point a, b, c;
X
X a = *normalize(midpoint(&oldt->pt[0], &oldt->pt[2]));
X b = *normalize(midpoint(&oldt->pt[0], &oldt->pt[1]));
X c = *normalize(midpoint(&oldt->pt[1], &oldt->pt[2]));
X
X newt->pt[0] = oldt->pt[0];
X newt->pt[1] = b;
X newt->pt[2] = a;
X newt++;
X
X newt->pt[0] = b;
X newt->pt[1] = oldt->pt[1];
X newt->pt[2] = c;
X newt++;
X
X newt->pt[0] = a;
X newt->pt[1] = b;
X newt->pt[2] = c;
X newt++;
X
X newt->pt[0] = a;
X newt->pt[1] = c;
X newt->pt[2] = oldt->pt[2];
X }
X
X if (level > 1) {
X free(old->poly);
X free(old);
X }
X
X /* Continue subdividing new triangles */
X old = new;
X }
X
X /* Print out resulting approximation */
X
X print_object(old, maxlevel);
X closeobj();
X return sph;
X}
X
X/* Normalize a point p */
Xpoint *normalize(p)
Xpoint *p;
X{
X static point r;
X double mag;
X
X r = *p;
X mag = r.x * r.x + r.y * r.y + r.z * r.z;
X if (mag != 0.0) {
X mag = 1.0 / sqrt(mag);
X r.x *= mag;
X r.y *= mag;
X r.z *= mag;
X }
X
X return &r;
X}
X
X/* Return the midpoint on the line between two points */
Xpoint *midpoint(a, b)
Xpoint *a, *b;
X{
X static point r;
X
X r.x = (a->x + b->x) * 0.5;
X r.y = (a->y + b->y) * 0.5;
X r.z = (a->z + b->z) * 0.5;
X
X return &r;
X}
X
X/* Write out all triangles in an object */
Xvoid print_object(obj, level)
Xobject *obj;
Xint level;
X{
X int i;
X
X /* Spit out coordinates for each triangle */
X for (i = 0; i < obj->npoly; i++)
X print_triangle(&obj->poly[i]);
X}
X
X/* Output a triangle */
Xvoid print_triangle(t)
Xtriangle *t;
X{
X int i;
X float p[3];
X
X#ifdef sgi
X bgnpolygon();
X#endif
X
X p[0] = t->pt[0].x; p[1] = t->pt[0].y; p[2] = t->pt[0].z;
X n3f(p);
X#ifdef sgi
X v3f(p);
X#else
X pmv(p[0], p[1], p[2]);
X#endif
X p[0] = t->pt[1].x; p[1] = t->pt[1].y; p[2] = t->pt[1].z;
X n3f(p);
X#ifdef sgi
X v3f(p);
X#else
X pdr(p[0], p[1], p[2]);
X#endif
X p[0] = t->pt[2].x; p[1] = t->pt[2].y; p[2] = t->pt[2].z;
X n3f(p);
X#ifdef sgi
X v3f(p);
X endpolygon();
X#else
X pdr(p[0], p[1], p[2]);
X pclos();
X#endif
X}
X
X#endif
END_OF_FILE
if test 7060 -ne `wc -c <'rayview/spheregen.c'`; then
echo shar: \"'rayview/spheregen.c'\" unpacked with wrong size!
fi
# end of 'rayview/spheregen.c'
fi
echo shar: End of archive 11 \(of 19\).
cp /dev/null ark11isdone
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
|