CCL Home Page
Up Directory CCL Part11
#! /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
Modified: Wed Dec 11 17:00:00 1996 GMT
Page accessed 1170 times since Sat Apr 17 21:59:33 1999 GMT