#! /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 'Doc/Guide/camera.tex' <<'END_OF_FILE' X\chapter{Specifying a View} X XWhen designing a \rayshade input file, there are two main Xissues that must be considered. The first and more complex Xis the selection of the objects to be rendered and the appearances Xthey should be assigned. The second and usually easier issue is Xthe choice of viewing parameters. This chapter deals with the Xlatter problem; the majority of the following chapters Xdiscuss aspects of objects and their appearances. X X{\em Rayshade} uses a camera model to describe Xthe geometric relationship between the objects to be rendered Xand the image that is produced. This relationship describes Xa perspective projection from world space onto the image plane. X XThe geometry of the perspective projection Xmay be thought of as an Xinfinite pyramid, known as the viewing {\em frustum}. XThe apex of the frustum is defined by the camera's position, Xand the main axis of the frustum by a ``look'' vector. XThe four sides of Xthe pyramid are differentiated by their relationship to a Xreference ``up'' vector from the camera's position. X XThe image Xultimately produced by rayshade may then be thought of as Xthe projection of the objects closest to the eye onto Xa rectangular screen formed by the intersection of the pyramid with Xa plane orthogonal to the pyramid's axis. The overall shape Xof the frustum (the lengths of the top and bottom sides compared Xto left and right) Xis described by the horizontal and vertical fields Xof view. X X\section{Camera Position} X XThe three basic camera properties are its position, the direction Xin which it is pointing, and its orientation. The keywords for Xspecifying these values are described below. XThe default values Xare designed to provide a reasonable view of a sphere or radius 2 Xlocated at origin. If these default values are used, Xthe origin is projected onto the center of the image plane, with Xthe world $x$ axis running left-to-right, the $z$ axis bottom-to-top, Xand the $y$ axis going ``into'' the screen. X X\begin{defkey}{eyep}{\evec{pos}} X Place the virtual camera at the given position. X\end{defkey} XThe default camera position is (0, -8, 0). X X\begin{defkey}{lookp}{\evec{pos}} X Point the virtual camera toward the given position. X\end{defkey} XThe default look point is the origin (0, 0, 0). The look point Xand camera position must not be coincident. X X\begin{defkey}{up}{\evec{direction}} X The ``up'' vector from the camera point is set to the X given direction. X\end{defkey} XThis up vector need not be orthogonal to Xthe view vector, nor need it be normalized. The default up Xdirection is (0, 0, 1). X XAnother popular standard viewing geometry, with the $x$ axis running Xleft-to-right, Xthe $y$ axis bottom-to-top, and the $z$ axis pointing out of the screen, Xmay be obtained by setting the up vector to (0, 1, 0) and by placing Xthe camera on the positive $z$ axis. X X\section{Field of View} X XAnother important choice to be made is that of the Xfield of view of the camera. The size of this field describes Xthe angles between the left and right sides and top and bottom sides Xof the frustum. X X\begin{defkey}{fov}{{\em hfov} [{\em vfov}]} X Specify X the horizontal and vertical field of view, in degrees. X\end{defkey} XThe default horizontal field of view is 45 degrees. XIf {\em vfov} is omitted, as is the general practice, Xthe vertical field of view is computed using the horizontal Xfield of view, the output image resolution, and the assumption Xthat a pixel samples a square area. Thus, Xthe values passed via the X{\tt screen} keyword define the shape of the final image. XIf you are Xdisplaying on a non-square pixeled device, Xyou must set the vertical field of view Xto compensate for the ``squashing'' that will result. X X\section{Depth of Field} X XUnder many circumstances, Xit is desirable to render Xobjects in the image such that they are in sharp Xfocus on the image plane. This is achieved by using the default X``pinhole' camera. In this mode, the camera's aperture is a single Xpoint, and all light rays are focused on the image plane. X XAlternatively, one may widen the aperture in order to Xsimulate depth of field. In this case, rays are cast from various places on Xthe aperture disk towards a point whose distance from the Xcamera is equal to the X{\em focus distance}. Objects that lay in the focal plane will be Xin sharp focus. The farther an object is from the image plane, Xthe more out-of-focus it will appear to be. XA wider aperture will lead to a greater blurring of Xobjects that do not lay in the focal plane. XWhen using a non-zero aperture radius, it is best to use jittered Xsampling in order to reduce aliasing. X X\begin{defkey}{aperture}{{\em radius}} X Use an aperture with the given {\em radius}. X\end{defkey} XThe default radius is zero, resulting in a pinhole camera model. X X\begin{defkey}{focaldist}{{\em distance}} X Set the focal plane to be {\em distance} units from the camera. X\end{defkey} XBy default, the focal distance is equal to the distance from the Xcamera to the look point. X X\section{Stereo Rendering} X XProducing a stereo pair is a relatively simple process; rather than Xsimply rendering a single image, one creates two related images which Xmay then be viewed on a stereo monitor, in a stereo slide viewer, or Xby using colored glasses and an appropriate display filter. X XRayshade facilitates the rendering of stereo pairs by allowing you Xto specify the distance between the camera positions used in Xcreating the two images. The camera position given in the X\rayshade input file Xdefines Xthe midpoint between the two camera positions used to generate the Ximages. XGenerally, the remainder of the viewing parameters are kept constant. X X\begin{defkey}{eyesep}{{\em separation}} X Specifies the camera separation to be used in rendering stereo X pairs. X\end{defkey} XThere is no default value. XThe separation may also be specified on the command line through Xthe {\em -E} option. XThe view to be rendered (left or right) Xmust be specified on the command line by using Xthe {\tt -l} or {\tt -r} options. X XThere are several things to keep in mind when generating stereo Xpairs. Firstly, those objects that lie in from of the focal plane will Xappear to protrude from the screen when viewed in stereo, while objects Xfarther Xthan the focal plane will recede into the screen. As it is usually Xeasier to look at stereo images that recede into the screen, you will Xusually Xwant to place the look point closer to the camera than the object Xof primary interest. X XThe degree of stereo effect is a Xfunction of the camera separation and the distance from the camera Xto the look point. Too large a separation will result in a hyperstereo Xeffect that will be hard to resolve, while too little a value will result Xin no stereo effect Xat all. A separation equal to one tenth the distance from the Xcamera to the look point is often a good choice. END_OF_FILE if test 6810 -ne `wc -c <'Doc/Guide/camera.tex'`; then echo shar: \"'Doc/Guide/camera.tex'\" unpacked with wrong size! fi # end of 'Doc/Guide/camera.tex' fi if test -f 'Doc/Guide/options.tex' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Doc/Guide/options.tex'\" else echo shar: Extracting \"'Doc/Guide/options.tex'\" \(6390 characters\) sed "s/^X//" >'Doc/Guide/options.tex' <<'END_OF_FILE' X\chapter{Options} X XThis appendix describes the command-line arguments accepted by {\em rayshade}. XThese options override defaults Xas well as any values or flags given in the input file, Xand are thus useful for generating test and other unusual, ``non-standard'' Xrenderings. X XThe general form of a \rayshade command line is: X\begin{quote} X{\tt rayshade} [{\em Options}] [{\em filename}] X\end{quote} X XIf given, the input file is read from {\em filename}. By default, Xthe input file is read from the standard input. XRecall that, by default, the image file is written to the standard Xoutput; you will need to redirect the standard output if you have not Xchosen to write the image to a file directly. The name of the input Xfile may be given anywhere on the command line. X XCommand-line options fall into two broad categories: those that set Xnumerical or other values and thus must be followed by further arguments, Xand those that simply turn features on and off. {\em Rayshade}'s Xconvention is to denote the value-setting arguments using capital letters, Xand feature-toggling arguments using lower-case letters. X X\begin{defkey}{-A}{{\em frame}} X Begin rendering (action) on the given frame. X\end{defkey} XThe default starting frame is number zero. X X\begin{defkey}{-a}{} X Toggle writing of alpha channel. X\end{defkey} XThis option is only available when the Utah Raster Toolkit is Xbeing used. X X\begin{defkey}{-C}{{\em R G B}} X Set the adaptive ray tree pruning color. If all X channel contributions falls below the given cutoff X values, no further rays are spawned. X\end{defkey} XOverrides the value specified via the {\tt cutoff} keyword. X X\begin{defkey}{-c}{} X Continue an interrupted rendering. X\end{defkey} XWhen given, this option indicates that the image file being written Xto contains a partially-completed image. \Rayshade will read the Ximage to determine the scanline from which to continue the rendering. XThis option is only available with the Utah Raster Toolkit. XThe {\tt -O} option must also be used. X X\begin{defkey}{-D}{{\em depth}} X Set maximum ray tree depth. X\end{defkey} XOverrides the value specified in the input file via the {\tt maxdepth} Xkeyword. X X\begin{defkey}{-E}{{\em separation}} X Set eye separation for rendering of stereo pairs. X\end{defkey} XOverrides the value specified via the {\tt eyesep} keyword. X X\begin{defkey}{-e}{} X Write exponential RLE file. X\end{defkey} XThis option is only available for use with the Utah Raster Toolkit. XSee the Utah Raster Toolkit's {\em unexp} manual page for details on Xexponential RLE files. X X\begin{defkey}{-F}{{\em freq}} X Set frequency of status report. X\end{defkey} XOverrides the value given using the {\tt report} keyword. X X\begin{defkey}{-G}{{\em gamma}} X Use given gamma correction exponent writing writing X color information to the image file. X\end{defkey} XThe default value for {\em gamma} is 1.0. X X\begin{defkey}{-g}{} X Use a Gaussian pixel filter. X\end{defkey} XOverrides the filter selected through the use of the {\tt filter} Xkeyword. X X\begin{defkey}{-h}{} X Print a short use message. X\end{defkey} X X\begin{defkey}{-j}{} X Use jittered sampling to perform antialiasing. X\end{defkey} XThis option overrides the {\tt adaptive} keyword, if present, Xin the input file. X X\begin{defkey}{-l}{} X Render the left stereo pair image. X\end{defkey} X X\begin{defkey}{-m}{} X Write a sampling map to the alpha channel. X\end{defkey} XRather than containing coverage information, the alpha channel values Xwill be restricted to zero, indicating no supersampling, and full intensity, Xindicating supersampling. This option is only available if the Utah XRaster Toolkit is being used. X X\begin{defkey}{-N}{{\em frames}} X Set the total number of frames to be rendered. X\end{defkey} XThis option overrides any value specified through the use of the X{\tt frames} keyword. By default, a single frame is rendered. X X\begin{defkey}{-n}{} X Do not render shadows. X\end{defkey} X X\begin{defkey}{-O}{{\em outfile}} X Write the image to the named file. X\end{defkey} XThis option overrides the name given with the {\tt outfile} keyword, Xif any, Xin the input file. X X\begin{defkey}{-o}{} X Toggle the effect of object opacity on shadows. X\end{defkey} XThis option is equivalent to specifying {\tt shadowtransp} Xin the input file. By default, \rayshade traces shadow Xrays through non-opaque objects. X X\begin{defkey}{-P}{{\em depth}} X Use adaptive supersampling with the given X maximum depth. X\end{defkey} XThis option overrides the {\tt jittered} keyword and the Xvalue associated the X{\tt adaptive} keyword given in the input file, if any. X X\begin{defkey}{-P}{} X Specify the options that should be passed to the C X preprocessor. X\end{defkey} XThe C preprocessor, if available, is applied to all of the input X Xpassed to {\em rayshade}. X\begin{defkey}{-p}{} X Perform preview-quality rendering. X\end{defkey} XThis option is equivalent to {\tt -n -S 1 -D 0}. X X\begin{defkey}{-q}{} X Do not print warning messages. X\end{defkey} X X\begin{defkey}{-R}{{\em xsize ysize}} X Produce an image {\em xsize} pixels wide by X {\em ysize} pixels high. X\end{defkey} XThis option overrides any screen size set by use of Xthe {\tt screen} keyword. X X\begin{defkey}{-r}{} X Render the right stereo pair image. X\end{defkey} X X\begin{defkey}{-S}{{\em samples}} X Use $samples^2$ jittered samples. X\end{defkey} XThis option overrides any value set through the use of Xthe {\tt samples} keyword in the input file. X X\begin{defkey}{-s}{} X Disable caching of shadowing information. X\end{defkey} XIt should not be necessary to ever use this option. X X\begin{defkey}{-T}{{\em r g b}} X Set the contrast threshold in the three X color channels for use in adaptive supersampling. X\end{defkey} XThis option overrides any value given through the use of Xthe {\em contrast} keyword. X X\begin{defkey}{-V}{{\em filename}} X Write verbose output to the named file. X\end{defkey} XThis option overrides any file named through the use of Xthe {\tt report} keyword. X X\begin{defkey}{-v}{} X Write verbose output. X\end{defkey} XWhen given, this option causes information about the options Xselected and the objects defined to be included in the Xreport file. X X\begin{defkey}{-W}{{\em minx miny maxx maxy}} X Render the specified subwindow. The parameters X should fall between zero and one. X\end{defkey} XThis option is provided to facilitate changing and/or examining a Xsmall portion of an image without having to re-render the entire Ximage. END_OF_FILE if test 6390 -ne `wc -c <'Doc/Guide/options.tex'`; then echo shar: \"'Doc/Guide/options.tex'\" unpacked with wrong size! fi # end of 'Doc/Guide/options.tex' fi if test -f 'blurb.urt' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'blurb.urt'\" else echo shar: Extracting \"'blurb.urt'\" \(7019 characters\) sed "s/^X//" >'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 'config.h.SH' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'config.h.SH'\" else echo shar: Extracting \"'config.h.SH'\" \(6456 characters\) sed "s/^X//" >'config.h.SH' <<'END_OF_FILE' Xcase $CONFIG in X'') X if test ! -f config.sh; then X ln ../config.sh . || \ X ln ../../config.sh . || \ X ln ../../../config.sh . || \ X (echo "Can't find config.sh."; exit 1) X echo "Using config.sh from above..." X fi X . ./config.sh X ;; Xesac Xecho "Extracting config.h (with variable substitutions)" Xsed <config.h -e 's!^#undef!/\*#undef!' X/* config.h X * This file was produced by running the config.h.SH script, which X * gets its values from config.sh, which is generally produced by X * running Configure. X * X * Feel free to modify any of this as the need arises. Note, however, X * that running config.h.SH again will wipe out any changes you've made. X * For a more permanent change edit config.sh and rerun config.h.SH. X */ X X X/* EUNICE: X * This symbol, if defined, indicates that the program is being compiled X * under the EUNICE package under VMS. The program will need to handle X * things like files that don't go away the first time you unlink them, X * due to version numbering. It will also need to compensate for lack X * of a respectable link() command. X */ X/* VMS: X * This symbol, if defined, indicates that the program is running under X * VMS. It is currently only set in conjunction with the EUNICE symbol. X */ X/* XENIX: X * This symbol, if defined, indicates thet the program is running under X * Xenix (at least 3.0 ?). X */ X/* BSD: X * This symbol, if defined, indicates that the program is running under X * a BSD system. X */ X#$d_eunice EUNICE /**/ X#$d_eunice VMS /**/ X#$d_xenix XENIX /**/ X#$d_bsd BSD /**/ X X/* CPPSTDIN: X * This symbol contains the first part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. Typical value of "cc -E" or "/lib/cpp". X */ X/* CPPMINUS: X * This symbol contains the second part of the string which will invoke X * the C preprocessor on the standard input and produce to standard X * output. This symbol will have the value "-" if CPPSTDIN needs a minus X * to specify standard input, otherwise the value is "". X */ X#define CPPSTDIN "$cppstdin" X#define CPPMINUS "$cppminus" X X/* bzero: X * This symbol is maped to memset if the bzero() routine is not X * available to set memory to 0. X */ X#$d_bzero bzero(s,l) memset((s),0,(l)) ; /* mapped to memset */ X X/* CBRT: X * This symbol, if defined, indicates that the cbrt() (cube root) X * function is available. X */ X#$d_cbrt CBRT /**/ X X/* index: X * This preprocessor symbol is defined, along with rindex, if the system X * uses the strchr and strrchr routines instead. X */ X/* rindex: X * This preprocessor symbol is defined, along with index, if the system X * uses the strchr and strrchr routines instead. X */ X#$d_index index strchr /* cultural */ X#$d_index rindex strrchr /* differences? */ X X/* MEMSET: X * This symbol, if defined, indicates that the memset routine is available X * to set blocks of memory. You should always use bzero() instead of X * memset() because bzero is remaped to memset if necessary. This means X * that a memset() routine must be provided in case MEMSET is not defined X * and no bzero() is found. X */ X#$d_memset MEMSET /**/ X X/* POPEN: X * This symbol, if defined, indicates that the popen routine is X * available to open a pipe from a process. X */ X#$d_popen POPEN /**/ X X/* RUSAGE: X * This symbol, if defined, indicates that the getrusage() routine exists. X * Inclusion of and may be necessary. X */ X#$d_rusage RUSAGE /**/ X X/* TIMES: X * This symbol, if defined, indicates that the times() routine exists. X * Note that this became obsolete on some systems (SUNOS), which now X * use getrusage(). X */ X/* CLOCKTYPE: X * This symbol holds the type returned by times(). It can be long, X * or clock_t on BSD sites (in which case should be X * included). Moreover, the Clock_t symbol is defined in common.h X * and should be used for easy clean reference. X */ X#$d_times TIMES /**/ X#define CLOCKTYPE $clocktype /**/ X X/* I_STRING: X * This symbol, if defined, indicates to the C program that it should X * include (USG systems) instead of (BSD systems). X */ X#$i_string I_STRING /**/ X X/* I_SYSRESOURCE: X * This symbol, if defined, indicates to the C program that it should X * include . X */ X#$i_sysresrc I_SYSRESOURCE /**/ X X/* I_SYSTYPES: X * This symbol, if defined, indicates to the C program that it should X * include . X */ X#$i_systypes I_SYSTYPES /**/ X X/* I_TIME: X * This symbol, if defined, indicates to the C program that it should X * include . X */ X/* I_SYSTIME: X * This symbol, if defined, indicates to the C program that it should X * include . X */ X/* I_SYSTIMEKERNEL: X * This symbol, if defined, indicates to the C program that it should X * include with KERNEL defined. X */ X#$i_time I_TIME /**/ X#$i_systime I_SYSTIME /**/ X#$i_systimek I_SYSTIMEKERNEL /**/ X X/* nrand: X * This macro is to be used to generate uniformly distributed X * random numbers over the range [0., 1.]. X */ X/* seednrand: X * This symbol defines the macro to be used in seeding the X * random number generator (see nrand). X */ X#define nrand() $mrand /**/ X#define seednrand(x) $seedfunc(x) /**/ X X/* VOIDFLAGS: X * This symbol indicates how much support of the void type is given by this X * compiler. What various bits mean: X * X * 1 = supports declaration of void X * 2 = supports arrays of pointers to functions returning void X * 4 = supports comparisons between pointers to void functions and X * addresses of void functions X * 8 = suports declaration of generic void pointers X * X * The package designer should define VOIDUSED to indicate the requirements X * of the package. This can be done either by #defining VOIDUSED before X * including config.h, or by defining defvoidused in Myinit.U. If the X * latter approach is taken, only those flags will be tested. If the X * level of void support necessary is not present, defines void to int. X */ X#ifndef VOIDUSED X#define VOIDUSED $defvoidused X#endif X#define VOIDFLAGS $voidflags X#if (VOIDFLAGS & VOIDUSED) != VOIDUSED X#$define void int /* is void to be avoided? */ X#$define M_VOID /* Xenix strikes again */ X#endif X X/* URT: X * This symbol, if defined, indicates that the Utah Raster X * Toolkit is being used. X */ X#$d_urt URT /**/ X X/* I_VARARGS: X * This symbol, if defined, indicates to the C program that it should X * include . X */ X#$i_stdlib I_STDLIB /**/ X X!GROK!THIS! END_OF_FILE if test 6456 -ne `wc -c <'config.h.SH'`; then echo shar: \"'config.h.SH'\" unpacked with wrong size! fi # end of 'config.h.SH' fi if test -f 'libray/libobj/cone.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'libray/libobj/cone.c'\" else echo shar: Extracting \"'libray/libobj/cone.c'\" \(6723 characters\) sed "s/^X//" >'libray/libobj/cone.c' <<'END_OF_FILE' X/* X * cone.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: cone.c,v 4.0 91/07/17 14:36:46 kolb Exp Locker: kolb $ X * X * $Log: cone.c,v $ X * Revision 4.0 91/07/17 14:36:46 kolb X * Initial version. X * X */ X#include "geom.h" X#include "cone.h" X Xstatic Methods *iConeMethods = NULL; Xstatic char coneName[] = "cone"; X Xunsigned long ConeTests, ConeHits; X XCone * XConeCreate(br, bot, ar, apex) XVector *bot, *apex; XFloat br, ar; X{ X Cone *cone; X Float tantheta, lprime, tlen, len, dtmp; X Vector axis, base, tmp; X X /* X * The passed basepoint must be closer to the origin of the X * cone than the apex point, implying that the base radius X * must be smaller than the apex radius. If the values passed X * reflect the opposite, we switch everything. X */ X if(ar < br) { X tmp = *bot; X *bot = *apex; X *apex = tmp; X dtmp = br; X br = ar; X ar = dtmp; X } else if (equal(ar, br)) { X RLerror(RL_WARN, "Cone is a cylinder -- discarding.\n"); X return (Cone *)NULL; X } X /* X * Find the axis and axis length. X */ X VecSub(*apex, *bot, &axis); X len = VecNormalize(&axis); X if (len < EPSILON) { X RLerror(RL_WARN, "Degenerate cone.\n"); X return (Cone *)NULL; X } X X cone = (Cone *)share_malloc(sizeof(Cone)); X X /* X * To render a cone, we transform the desired cone into X * a canonical, Z-axis aligned, unit length, unit radius X * at the apex cone. X * X * Here, we construct the transformation matrix to map X * from cone<-->world space. X */ X X /* X * "tantheta" is the change in radius per unit length along X * the cone axis. X */ X tantheta = (ar - br) / len; X /* X * lprime defines the distance along the axis where the cone starts X */ X lprime = br / tantheta; X /* X * Find the true base (origin) of the cone. X */ X VecScale(-lprime, axis, &base); X VecAdd(base, *bot, &base); X /* X * tlen is the total length of the cone. X */ X tlen = lprime + len; X /* X * start_dist is the distance from the origin of the canonical X * cone at which the cone begins X */ X cone->start_dist = lprime / tlen; X CoordSysTransform(&base, &axis, ar, tlen, &cone->trans); X return cone; X} X XMethods * XConeMethods() X{ X if (iConeMethods == (Methods *)NULL) { X iConeMethods = MethodsCreate(); X iConeMethods->name = ConeName; X iConeMethods->create = (GeomCreateFunc *)ConeCreate; X iConeMethods->methods = ConeMethods; X iConeMethods->intersect = ConeIntersect; X iConeMethods->normal = ConeNormal; X iConeMethods->uv = ConeUV; X iConeMethods->bounds = ConeBounds; X iConeMethods->stats = ConeStats; X iConeMethods->checkbounds = TRUE; X iConeMethods->closed = FALSE; X } X return iConeMethods; X} X X/* X * Ray-cone intersection test. This routine is far from optimal, but X * it's straight-forward and it works... X */ Xint XConeIntersect(cone, ray, mindist, maxdist) XCone *cone; XRay *ray; XFloat mindist, *maxdist; X{ X Float t1, t2, a, b, c, disc, zpos, distfact; X Ray newray; X Vector nray, npos; X Float nmin; X X ConeTests++; X X /* X * Transform ray from world to cone space. X */ X newray = *ray; X distfact = RayTransform(&newray, &cone->trans.itrans); X nray = newray.dir; X npos = newray.pos; X nmin = mindist * distfact; X X a = nray.x * nray.x + nray.y * nray.y - nray.z*nray.z; X b = nray.x * npos.x + nray.y * npos.y - nray.z*npos.z; X c = npos.x*npos.x + npos.y*npos.y - npos.z*npos.z; X X if (fabs(a) < EPSILON) { X /* X * Only one intersection point... X */ X t1 = -0.5*c / b; X zpos = npos.z + t1 * nray.z; X if (t1 < nmin || zpos < cone->start_dist || zpos > 1.) X return FALSE; X t1 /= distfact; X if (t1 < *maxdist) { X *maxdist = t1; X ConeHits++; X return TRUE; X } X return FALSE; X } else { X disc = b*b - a*c; X if (disc < 0.) X return FALSE; /* No possible intersection */ X disc = sqrt(disc); X t1 = (-b + disc) / a; X t2 = (-b - disc) / a; X /* X * Clip intersection points. X */ X zpos = npos.z + t1 * nray.z; X if (t1 < nmin || zpos < cone->start_dist || zpos > 1.) { X zpos = npos.z + t2 * nray.z; X if (t2 < nmin || zpos < cone->start_dist || X zpos > 1.) X return FALSE; X else X t1 = t2 / distfact; X } else { X zpos = npos.z + t2 * nray.z; X if (t2 < nmin || zpos < cone->start_dist || X zpos > 1.) X t1 /= distfact; X else X t1 = min(t1, t2) / distfact; X } X if (t1 < *maxdist) { X *maxdist = t1; X ConeHits++; X return TRUE; X } X return FALSE; X } X} X X/* X * Compute the normal to a cone at a given location on its surface. X */ Xint XConeNormal(cone, pos, nrm, gnrm) XCone *cone; XVector *pos, *nrm, *gnrm; X{ X Vector npos; X X /* X * Transform intersection point to cone space. X */ X npos = *pos; X PointTransform(&npos, &cone->trans.itrans); X X /* X * The following is equal to X * (pos X (0, 0, 1)) X pos X */ X nrm->x = npos.x * npos.z; X nrm->y = npos.y * npos.z; X nrm->z = -npos.x * npos.x - npos.y * npos.y; X X /* X * Transform normal back to world space. X */ X NormalTransform(nrm, &cone->trans.itrans); X *gnrm = *nrm; X return FALSE; X} X Xvoid XConeUV(cone, pos, norm, uv, dpdu, dpdv) XCone *cone; XVector *pos, *norm, *dpdu, *dpdv; XVec2d *uv; X{ X Vector npos; X Float val; X X npos = *pos; X PointTransform(&npos, &cone->trans.itrans); X X uv->v = (npos.z - cone->start_dist) / (1. - cone->start_dist); X if (npos.z < EPSILON) X uv->u = 0.; X else { X val = npos.x / npos.z; X /* X * Be careful not to feed |val| > 1 to acos X */ X if (val > 1.) X uv->u = 0.; X else if (val < -1.) X uv->u = 0.5; X else { X uv->u = acos(val) / TWOPI; X if (npos.y < 0.) X uv->u = 1. - uv->u; X } X } X /* X * dpdv = pos X * dpdu = dpdv X norm = (-norm->y, norm->x, 0.) X */ X if (dpdu) { X *dpdv = npos; X dpdu->x = -npos.y; X dpdu->y = npos.x; X dpdu->z = 0.; X VecTransform(dpdu, &cone->trans.trans); X VecTransform(dpdu, &cone->trans.trans); X (void)VecNormalize(dpdu); X (void)VecNormalize(dpdv); X } X} X X/* X * Return the extent of a cone. X */ Xvoid XConeBounds(cone, bounds) XCone *cone; XFloat bounds[2][3]; X{ X bounds[LOW][X] = bounds[LOW][Y] = -1; X bounds[HIGH][X] = bounds[HIGH][Y] = 1; X bounds[LOW][Z] = cone->start_dist; X bounds[HIGH][Z] = 1; X /* X * Transform bounding box to world space. X */ X BoundsTransform(&cone->trans.trans, bounds); X} X Xchar * XConeName() X{ X return coneName; X} X Xvoid XConeStats(tests, hits) Xunsigned long *tests, *hits; X{ X *tests = ConeTests; X *hits = ConeHits; X} X Xvoid XConeMethodRegister(meth) XUserMethodType meth; X{ X if (iConeMethods) X iConeMethods->user = meth; X} END_OF_FILE if test 6723 -ne `wc -c <'libray/libobj/cone.c'`; then echo shar: \"'libray/libobj/cone.c'\" unpacked with wrong size! fi # end of 'libray/libobj/cone.c' fi if test -f 'libray/libtext/imagetext.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'libray/libtext/imagetext.c'\" else echo shar: Extracting \"'libray/libtext/imagetext.c'\" \(6113 characters\) sed "s/^X//" >'libray/libtext/imagetext.c' <<'END_OF_FILE' X/* X * imagetext.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: imagetext.c,v 4.0 91/07/17 14:42:42 kolb Exp Locker: kolb $ X * X * $Log: imagetext.c,v $ X * Revision 4.0 91/07/17 14:42:42 kolb X * Initial version. X * X */ X#include "texture.h" X#include "libimage/image.h" X#include "imagetext.h" X X#define INTERP(v) (text->lo + (v)*(text->hi - text->lo)) X X/* X * Create Image texture. X * Image texture has so many options that there's usually no X * nice way to parse without resorting to additional keywords. X * Thus the ImageTextCreate routine only reads the image to be used; X * all but ->component must be set by hand. The routine X * ImageTextSetComponent is provided to set the component and X * ensure that the image being used is appropriate. X */ XImageText * XImageTextCreate(imagefile) Xchar *imagefile; X{ X ImageText *text; X X text = (ImageText *)Calloc(1, sizeof(ImageText)); X text->component = COLOR; /* texture all colors by default*/ X /* X * Only apply one copy of the texture by default X */ X text->tileu = text->tilev = 0; X text->lo = 0.; text->hi = 1.; X text->smooth = FALSE; X text->mapping = UVMappingCreate(); X text->image = ImageRead(imagefile); X return text; X} X X/* X * Set image texture to apply to given component, X * ensuring that the image that is being used is compatible. X */ Xvoid XImageTextSetComponent(text, component) XImageText *text; Xint component; X{ X switch (component) { X case COLOR: /* usual case, texture on amb, diff, spec, body */ X case AMBIENT: X case DIFFUSE: X case SPECULAR: X case BODY: X /* all of the above can use 1 or 3 channel images */ X if (text->image->chan != 1 && text->image->chan != 3) { X RLerror(RL_ABORT, X "Image %s must have 1 or 3 channels\n", X text->image->filename); X } X break; X case REFLECT: X case TRANSP: X case SPECPOW: X case BUMP: X case INDEX: X /* the above need 1 channel images */ X if (text->image->chan != 1) { X RLerror(RL_ABORT, "Image %s must have 1 channel\n", X text->image->filename); X } X break; X } X text->component = component; X} X Xvoid XImageTextApply(text, prim, ray, pos, norm, gnorm, surf) XImageText *text; XGeom *prim; XRay *ray; XVector *pos, *norm, *gnorm; XSurface *surf; X{ X Float fx, fy; X Float outval[4], outval_u[4], outval_v[4]; X Float u, v; X Surface tmpsurf; X int ix, iy; X int rchan, gchan, bchan; X Vector dpdu, dpdv, ntmp; X X /* X * First, find the floating point location in image coords. X * Then set ix, iy to the integer location in image coords and X * use fx, fy to represent the subpixel position. X */ X if (text->component == BUMP) X TextToUV(text->mapping, prim, pos, gnorm, &u, &v, X &dpdu, &dpdv); X else X TextToUV(text->mapping, prim, pos, gnorm, &u, &v, X (Vector *)NULL, (Vector *)NULL); X /* X * Handle tiling at this point. X */ X if (TileValue(text->tileu, text->tilev, u, v)) X return; X u -= floor(u); X v -= floor(v); X fx = u * (Float) text->image->width; X fy = v * (Float) text->image->height; X ix = fx; X iy = fy; X fx = fx - (Float) ix; X fy = fy - (Float) iy; X X if (text->image->has_alpha) { X /* Alpha channel is 0 */ X rchan = 1; X gchan = 2; X bchan = 3; X } else { X rchan = 0; X gchan = 1; X bchan = 2; X } X X if (text->image->chan == 1) { X gchan = rchan; X bchan = rchan; X } X X ImageIndex(text->image, ix, iy, fx, fy, text->smooth, outval); X X /* X * escape when alpha is zero, 'cause there is no change X */ X if (text->image->has_alpha && (outval[0] < 0.001)) X return; X X if (text->component != COLOR || text->surf == (Surface *)NULL) { X tmpsurf = *surf; X } else { X tmpsurf = *text->surf; X } X X switch (text->component) { X case COLOR: /* amb, diff, spec */ X tmpsurf.spec.r *= outval[rchan]; X tmpsurf.spec.g *= outval[gchan]; X tmpsurf.spec.b *= outval[bchan]; X tmpsurf.diff.r *= outval[rchan]; X tmpsurf.diff.g *= outval[gchan]; X tmpsurf.diff.b *= outval[bchan]; X tmpsurf.amb.r *= outval[rchan]; X tmpsurf.amb.g *= outval[gchan]; X tmpsurf.amb.b *= outval[bchan]; X break; X case AMBIENT: /* ambient */ X tmpsurf.amb.r *= INTERP(outval[rchan]); X tmpsurf.amb.g *= INTERP(outval[gchan]); X tmpsurf.amb.b *= INTERP(outval[bchan]); X break; X case DIFFUSE: /* diffuse */ X tmpsurf.diff.r *= INTERP(outval[rchan]); X tmpsurf.diff.g *= INTERP(outval[gchan]); X tmpsurf.diff.b *= INTERP(outval[bchan]); X break; X case SPECULAR: /* specular */ X tmpsurf.spec.r *= INTERP(outval[rchan]); X tmpsurf.spec.g *= INTERP(outval[gchan]); X tmpsurf.spec.b *= INTERP(outval[bchan]); X break; X case BODY: /* transmitted */ X tmpsurf.body.r *= INTERP(outval[rchan]); X tmpsurf.body.g *= INTERP(outval[gchan]); X tmpsurf.body.b *= INTERP(outval[bchan]); X break; X case REFLECT: /* specular reflectivity */ X tmpsurf.reflect *= INTERP(outval[rchan]); X break; X case TRANSP: /* specular transmittance */ X tmpsurf.transp *= INTERP(outval[rchan]); X break; X case SPECPOW: /* specpow */ X tmpsurf.srexp *= INTERP(outval[rchan]); X break; X case INDEX: /* index of refraction */ X tmpsurf.index *= INTERP(outval[rchan]); X break; X case BUMP: /* bump map */ X ImageIndex(text->image, X (ix == text->image->width - 1) ? 0 : ix+1, X iy, fx, fy, X text->smooth, outval_u); X ImageIndex(text->image, ix, X (iy == text->image->height - 1) ? 0 : iy+1, X fx, fy, X text->smooth, outval_v); X MakeBump(norm, &dpdu, &dpdv, X INTERP(outval_u[rchan] - outval[rchan]), X INTERP(outval_v[rchan] - outval[rchan])); X return; X } X X if (text->image->has_alpha && (outval[0] < 0.999)) { X /* X * image partial coverage means blend surf and text->surf X */ X SurfaceBlend(surf, &tmpsurf, 1. - outval[0], outval[0]); X } else { X /* X * image full coverage means use text->surf X */ X *surf = tmpsurf; X } X} END_OF_FILE if test 6113 -ne `wc -c <'libray/libtext/imagetext.c'`; then echo shar: \"'libray/libtext/imagetext.c'\" unpacked with wrong size! fi # end of 'libray/libtext/imagetext.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 10 \(of 19\). cp /dev/null ark10isdone 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