v21i009: A ray tracing program, Part02/08
Rich Salz
rsalz at uunet.uu.net
Thu Feb 8 07:49:11 AEST 1990
Submitted-by: Craig Kolb <craig at weedeater.math.yale.edu>
Posting-number: Volume 21, Issue 9
Archive-name: rayshade/part02
#! /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 <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 8)."
# Contents: Examples/pool.ray nff2shade.awk src/datatypes.h
# src/funcdefs.h src/input.c src/list.c src/main.c src/outputp.c
# src/primobj.h src/setup.c src/sphere.c src/superq.c src/surface.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Examples/pool.ray' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Examples/pool.ray'\"
else
echo shar: Extracting \"'Examples/pool.ray'\" \(3579 characters\)
sed "s/^X//" >'Examples/pool.ray' <<'END_OF_FILE'
X/*
X * Example rayshade input file
X *
X * pool table from "Reds' Nightmare"
X *
X * Warning: this will take a while to render, as it uses 9 rays/pixel
X * and makes heavy use of texturing routines.
X *
X * To speed rendering, use -P or -S options.
X *
X * C. Kolb 2/88
X */
Xup 0.0 0.0 1.
Xfov 45
Xscreen 512 512
Xmaxdepth 2
Xbackground 0 0 0
Xlight 1.4 point 20.0 0.0 66.0
Xsurface blacktile 0.01 0.01 0.01 0.01 0.01 0.01 0. 0. 0. 0. 0. 0 0
Xsurface s0 0.862745 0.862745 0.862745 0.039216 0.039216 0.039216 0. 0. 0.
X 7. 0. 0. 1.
Xsurface s1 0.470588 0.156863 0.392157 0.470588 0.156863 0.392157 0. 0. 0.
X 25. 1. 0. 1.
Xsurface s2 0.117647 0.117647 0.392157 0.117647 0.117647 0.392157 0. 0. 0.
X 25. 0. 0. 1.
Xsurface s3 0.784314 0.078431 0.078431 0.470588 0.039216 0.039216 0. 0. 0.
X 25. 0. 0. 1.
Xsurface s4 0 .2235 .145 0 .2235 .145 0 0 0 0.0 0. 0. 1.
Xsurface mirror 0.04 0.04 0.04 0.05 0.05 0.05 1. 1. 1. 60. 0.95 0. 1.
Xsurface s5 0.196078 0.392157 0.117647 0.196078 0.392157 0.117647
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
Xsurface s6 0.588235 0.392157 0.117647 0.196078 0.392157 0.117647
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
Xsurface s7 0.196078 0.392157 0.509804 0.196078 0.392157 0.117647
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
Xsurface s8 0.980392 0.196078 0.117647 0.196078 0.392157 0.117647
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
Xsurface s9 0.196078 0.392157 0.901961 0.196078 0. 0.117647
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
Xsurface s10 0.411765 0.411765 0.176471 0.411765 0.411765 0.176471 0. 0. 0.
X 0. 0. 0. 1.
Xsurface floor .1 .1 .1 .5 .5 .45 0.8 0.8 0.8 18 0.0 0 0
X/*surface floor 0.5 0.5 0.5 0.8 0.78 0.78
X 0.8 0.76 0.76 10. 0.0 0. 1. */
Xsurface s12 0.313725 0.313725 0.313725 0.745098 0.745098 0.745098
X 0. 0. 0. 0. 0. 0. 1.
Xsurface s13 0.078431 0.862745 0.078431 0.039216 0.039216 0.039216
X 0.156863 0.156863 0.156863 7. 0. 0. 1.
Xsurface s14 0.784314 0.078431 0.078431 0.470588 0.039216 0.039216
X 0. 0. 0. 25. 0. 0. 1.
Xsurface s15 0.392157 0.098039 0.047059 0.392157 0.098039 0.047059
X 0.039216 0.039216 0.039216 3. 0. 0. 1.
Xsurface s16 0.509804 0.509804 0.509804 0.509804 0.509804 0.509804
X 0.156863 0.156863 0.156863 7. 0.1 0. 1.
X
X sphere s5 1.5 0.0 -21. 1.5
X sphere s6 1.5 1.5 -23.598026 1.5
X sphere s7 1.5 -1.5 -23.598026 1.5
X sphere s8 1.5 3.0 -26.196152 1.5
X sphere s9 1.5 0.0 -26.196152 1.5
X sphere s5 1.5 -3.0 -26.196152 1.5
X sphere s6 1.5 4.5 -28.794229 1.5
X sphere s7 1.5 1.5 -28.794229 1.5
X sphere s8 1.5 -1.5 -28.794229 1.5
X sphere s9 1.5 -4.5 -28.794229 1.5
X sphere s5 1.5 6.0 -31.392305 1.5
X sphere s6 1.5 3.0 -31.392305 1.5
X sphere s7 1.5 0.0 -31.392305 1.5
X sphere s8 1.5 -3.0 -31.392305 1.5
X sphere s9 1.5 -6.0 -31.392305 1.5
X
X box s4 0. 0. -1. 30. 57. 1.
X box s15 30. 0. 0. 3. 54. 1.5 texture wood scale 5. 5. 5.
X box s15 -30. 0. 0. 3. 54. 1.5 texture wood scale 5. 5. 5.
X box s15 0. 57. 0. 33. 3. 1.5 texture wood scale 5. 5. 5.
X box s15 0. -57. 0. 33. 3. 1.5 texture wood scale 5. 5. 5.
X sphere s16 1.5 0. 0. 0. translate 0. 21. 1.5
X box mirror 10. -144. 30. 21.3333 .1 20. /* was 40. -144 30. */
X /*
X * Walls
X */
X plane s10 0. 1. 0. 0. -144. 0.
X plane s10 1. 0. 0. -180. 0. 0.
X plane s10 -1. 0. 0. 180. 0. 0.
X plane s10 0. -1. 0. 0. 144. 0.
X /*
X * Floor
X */
X plane floor 0. 0. 1. 0. 0. -30.
X texture marble scale 4. 4. 4. translate 0. 0. -4.376
X texture checker blacktile scale 12.3 12.3 12.3
X /*
X * Ceiling
X */
X plane s12 0. 0. -1. 0. 0. 72.
X
Xeyep 38. 100. 43.
Xlookp 0. 0. 0.
Xgrid 20 20 10
Xjittered
Xsamples 3
END_OF_FILE
if test 3579 -ne `wc -c <'Examples/pool.ray'`; then
echo shar: \"'Examples/pool.ray'\" unpacked with wrong size!
fi
# end of 'Examples/pool.ray'
fi
if test -f 'nff2shade.awk' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'nff2shade.awk'\"
else
echo shar: Extracting \"'nff2shade.awk'\" \(3223 characters\)
sed "s/^X//" >'nff2shade.awk' <<'END_OF_FILE'
X#
X# This awk script will convert an NFF-format input file (as output by
X# Eric Haines' SPD) to something rayshade can understand.
X# The World object will be enclosed in a single grid of 22*22*22 voxels.
X#
X# Example usage:
X# mountains | awk -f nff2shade.awk | rayshade > mountains.rle
X#
X# For best results, one should modify the output for all but the tetra
X# and mountain databases to provide a tighter bounding box around the
X# object of interest (tree, gears, etc.). This is done by placing
X# all primitives but the ground pologon into an object stored as a Grid,
X# and then instantiating that object once. This will decrease ray-tracing
X# time dramatically.
X#
X# $Id: nff2shade.awk,v 3.0 89/10/27 01:30:24 craig Exp $
X#
X# $Log: nff2shade.awk,v $
X# Revision 3.0 89/10/27 01:30:24 craig
X# Baseline for first official release.
X#
X# C. Kolb 9/21/89
X# Fixed comment bug; check first character rather than first field for "#".
X# Keep track of defined surfaces in associative array so if one is used
X# again we don't create another copy.
X# Halved ambient intensity of surfaces.
X# C. Kolb 10/12/89
X# Added "adaptive 0" and "cutoff 0" to BEGIN and removed "endfile" from END.
X# C. Kolb 2/89
X# First version.
X#
XBEGIN{
X lights = 0;
X surfs = 0;
X print "maxdepth 4"
X print "adaptive 0"
X print "cutoff 0."
X}
Xsubstr($1, 1, 1) == "#" { print "/* " $0 " */"; next;}
X$1 == "v" { next;}
X$1 == "from" { print "eyep " $2 " "$3 " " $4; next;}
X$1 == "at" {print "lookp " $2 " "$3 " "$4; next;}
X$1 == "up" {print; next;}
X$1 == "angle" { print "fov " $2; next;}
X$1 == "hither" {next;}
X$1 == "resolution" {print "screen " $2 " "$3; next;}
X
X$1 == "l" { lightd[lights] = $2 " "$3 " "$4; lights++; next; }
X$1 == "b" {print "background " $2 " "$3 " "$4; next; }
X$1 == "f" {
X if (surfaces[$2 $3 $4 $5 $6 $7 $8] != 0) {
X cursurf = surfaces[$2 $3 $4 $5 $6 $7 $8];
X next;
X }
X surfs++;
X surfaces[$2 $3 $4 $5 $6 $7 $8] = surfs;
X cursurf = surfs;
X aintens = sqrt(lights) / (4*lights);
X dr = $2*$5;
X dg = $3*$5;
X db = $4*$5;
X# this is a good guess....
X ar = aintens*dr;
X ag = aintens*dg;
X ab = aintens*db;
X#
X# We set "reflectance" to the minimum of Ks and 1. - T, as
X# Eric Haines' SPD includes several objects which have Ks + T > 1.
X#
X if ($6 < 1. - $8)
X reflect = $6;
X else
X reflect = 1. - $8;
X printf("surface s%d %f %f %f %f %f %f %f %f %f %f %f %f %f\n", \
X cursurf, ar, ag, ab, dr, dg, db, $6, $6, $6, $7, reflect, $8, $9);
X next;
X}
X
X$1 == "c" {
X getline;
X x1 = $1;
X y1 = $2;
X z1 = $3;
X br = $4;
X getline;
X printf("cone s%d %f %f %f %f %f %f %f %f\n", \
X cursurf, x1, y1, z1, $1, $2, $3, br, $4);
X next;
X}
X$1 == "s" {
X print "sphere s"cursurf " "$5 " "$2 " "$3 " "$4;
X next;
X}
X$1 == "pp" {
X if ($2 == 3)
X print "triangle s"cursurf;
X else
X print "poly s"cursurf;
X next;
X}
X$1 == "p" {
X#
X# Polygon -- the vertices will print out in the default statement.
X# If there are three vertices, make it a triangle.
X#
X if ($2 == 3)
X print "triangle s"cursurf;
X else
X print "poly s"cursurf;
X next;
X}
X{
X# Matched nothing (or is a vertex data) -- print it.
X print;
X next;
X}
XEND{
X#
X# Output light definitions.
X#
X intens = sqrt(lights) / (lights);
X for (i = 0; i < lights; i++) {
X print "light " intens " point " lightd[i]
X }
X print "grid 22 22 22"
X}
END_OF_FILE
if test 3223 -ne `wc -c <'nff2shade.awk'`; then
echo shar: \"'nff2shade.awk'\" unpacked with wrong size!
fi
# end of 'nff2shade.awk'
fi
if test -f 'src/datatypes.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/datatypes.h'\"
else
echo shar: Extracting \"'src/datatypes.h'\" \(3914 characters\)
sed "s/^X//" >'src/datatypes.h' <<'END_OF_FILE'
X/*
X * datatypes.h
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: datatypes.h,v 3.0 89/10/27 02:05:49 craig Exp $
X *
X * $Log: datatypes.h,v $
X * Revision 3.0 89/10/27 02:05:49 craig
X * Baseline for first official release.
X *
X */
X
X#ifdef NOVOID
Xtypedef int void;
X#endif
X
Xtypedef struct {
X double u, v; /* 2D point */
X} Vec2d;
X
Xtypedef struct Vector {
X double x, y, z; /* 3D point */
X} Vector;
X
Xtypedef struct Ray {
X Vector pos; /* Origin */
X Vector dir; /* Direction */
X char shadow;
X struct SurfaceList *media; /* Medium ray is passing through */
X} Ray;
X
Xtypedef struct Color {
X double r, g, b; /* Red, green, blue. */
X} Color;
X
Xtypedef struct {
X double matrix[3][3]; /* Rotation matrix */
X Vector translate; /* Translation */
X} TransInfo;
X
Xtypedef struct Trans {
X TransInfo world2obj, /* worldspace --> object space */
X obj2world; /* object space --> world space */
X} Trans;
X
Xtypedef struct {
X struct ObjList *list; /* List of prims/objs. in object */
X struct ObjList *unbounded; /* List of unbounded prims. */
X double bounds[2][3]; /* Bounding box of object */
X} List;
X
Xtypedef struct {
X short xsize, ysize, zsize; /* # of voxels along each axis */
X double bounds[2][3]; /* bounding box */
X double voxsize[3]; /* size of a voxel */
X struct ObjList ****cells; /* Voxels */
X struct ObjList *unbounded; /* Unbounded objects */
X} Grid;
X
X/*
X * Surface definition.
X */
Xtypedef struct Surface {
X char *name; /* Name */
X struct Color amb; /* Ambient color */
X struct Color diff; /* Diffuse color */
X struct Color spec; /* Specular color */
X double coef; /* Phong shading coef. */
X double refl; /* Reflectivity (0-1) */
X double transp; /* Transparency (0-1) */
X double kref; /* Index of refraction */
X double translucency; /* translucency (0-1) */
X double stcoef; /* Phong coef. for transmitted light */
X} Surface;
X
Xtypedef struct SurfaceList {
X Surface *surf;
X struct SurfaceList *next;
X} SurfaceList;
X
Xtypedef struct ObjList {
X struct Object *data; /* Pointer to object data */
X struct ObjList *next; /* Next in list */
X} ObjList;
X
Xtypedef struct PointList {
X Vector vec; /* Vector data */
X struct PointList *next; /* Next in list */
X} PointList;
X
X/*
X * Data about point of intersection.
X * (May be modified by texture mapping.)
X */
Xtypedef struct HitInfo {
X Vector pos, /* Location of intersection */
X norm; /* Normal to surface at int. point */
X struct Primitive *prim; /* Pointer to primitive hit. */
X struct Surface surf; /* Surface to be used. */
X TransInfo *totaltrans;
X} HitInfo;
X
X/*
X * General-purpose texture structure. The (bad) idea is to
X * have one structure which every texturing function will use.
X */
Xtypedef struct Texture {
X char type; /* Texture type */
X Surface *surf1; /* Alternate surface */
X double size; /* Scale/size factor */
X double *args; /* Random arguments. */
X Color *colormap; /* Colormap */
X Trans *trans; /* Transformation matrices. */
X struct Texture *next; /* Pointer to next texture. */
X} Texture;
X
Xtypedef struct {
X Color color;
X double trans;
X} Fog;
X
Xtypedef struct {
X Color color; /* Mist color */
X Color trans; /* R, G, B trans. */
X double scale, zero; /* Height scale, start Z */
X} Mist;
END_OF_FILE
if test 3914 -ne `wc -c <'src/datatypes.h'`; then
echo shar: \"'src/datatypes.h'\" unpacked with wrong size!
fi
# end of 'src/datatypes.h'
fi
if test -f 'src/funcdefs.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/funcdefs.h'\"
else
echo shar: Extracting \"'src/funcdefs.h'\" \(4762 characters\)
sed "s/^X//" >'src/funcdefs.h' <<'END_OF_FILE'
X/*
X * funcdefs.h
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: funcdefs.h,v 3.0 89/10/27 02:05:50 craig Exp $
X *
X * $Log: funcdefs.h,v $
X * Revision 3.0 89/10/27 02:05:50 craig
X * Baseline for first official release.
X *
X */
X
X/*
X * This file should eventually disappear; function declarations should
X * appear as externs where needed. Macros should be moved to a separate file.
X */
X/*
X * Normal routines
X */
Xint nrmsph(), nrmbox(), nrmtri(), nrmsup(),nrmplane(), nrmcyl(),
X nrmpoly(), nrmcone(), nrmhf();
X/*
X * Intersection routines
X */
Xdouble intsph(), intbox(), inttri(), intsup(),intplane(), crossp(), intcyl(),
X intpoly(), intcone(), inthf();
X/*
X * Extent-box finding routines
X */
Xint sphextent(),boxextent(),triextent(),supextent(),planeextent(),
X cylextent(), polyextent(), coneextent(), hfextent();
X
X/*
X * Object creation routines
X */
XObject *maksph(), *makbox(), *maktri(), *maksup(), *makplane(), *makcyl(),
X *makpoly(), *makcone(), *makhf(), *new_object();
X/*
X * Intersection routines.
X */
Xdouble int_grid(), int_list(), int_primitive(), IntBounds();
X
X/*
X * Misc.
X */
Xchar *Malloc(), *Calloc(), *strsave();
Xdouble normalize(), Noise();
X
X/*
X * Transformations
X */
XTrans *new_trans();
XTransInfo *new_transinfo();
X
X/*
X * Surfaces
X */
XSurface *find_surface(), *make_surface(), *get_surface();
XSurfaceList *add_surface();
X/*
X * Objects
X */
XObject *add_child_named(), *add_child(), *get_object_named();
X
Xextern double ftmp; /* Yick -- keeps us from evaluating twice during fabs. */
X
X/*
X * Macros
X */
X
X/*
X * Absolute value -- uses "ftmp" to store value of argument, which
X * keeps us from evaluating expressions more than once.
X */
X#define fabs(x) ((ftmp=(x)) < 0. ? -(ftmp) : (ftmp))
X#define abs(x) ((x) < 0 ? -(x) : (x))
X
X#ifdef SYSV
Xdouble drand48();
X/*
X * nrand() returns a uniformly distributed random variable between 0 and 1.
X */
X#define nrand() (drand48())
X#else
Xlong random();
X#define nrand() ((double)random() / (double)((1 << 31) - 1))
X#endif
X
X#ifdef MULTIMAX
X/*
X * On the multimax, allocate large pieces of memory as shared memory.
X */
Xextern char *share_malloc(), *share_calloc();
X#define mallocprim() (Primitive *)share_malloc(sizeof(Primitive))
X#else
X/*
X * Otherwise, malloc is malloc, etc.
X */
X#define share_malloc(x) Malloc(x)
X#define share_calloc(x,y) Calloc(x,y)
X#define mallocprim() (Primitive *)Malloc(sizeof(Primitive))
X#endif
X
X/*
X * Return a uniformly distributed random variable between -s/2 and s/2.
X */
X#define jitter(s) ((nrand() * (s)) - (s)/2.)
X/*
X * Dot product
X */
X#define dotp(a, b) (((a)->x*(b)->x)+((a)->y*(b)->y)+((a)->z*(b)->z))
X/*
X * Close enough for us.
X */
X#define equal(a, b) (fabs((a) - (b)) < EPSILON)
X/*
X * Maximum/Minimum functions
X */
X#define max(a, b) ((a) > (b) ? (a) : (b))
X#define min(a, b) ((a) < (b) ? (a) : (b))
X/*
X * Convert from voxel number along X/Y/Z to corresponding coordinate.
X */
X#define voxel2x(g,x) ((x) * g->voxsize[0]+ g->bounds[0][0])
X#define voxel2y(g,y) ((y) * g->voxsize[1] + g->bounds[0][1])
X#define voxel2z(g,z) ((z) * g->voxsize[2] + g->bounds[0][2])
X/*
X * And vice-versa.
X */
X#define x2voxel(g,x) (((x) - g->bounds[0][0]) / g->voxsize[0])
X#define y2voxel(g,y) (((y) - g->bounds[0][1]) / g->voxsize[1])
X#define z2voxel(g,z) (((z) - g->bounds[0][2]) / g->voxsize[2])
X/*
X * Is the point "p" outisde of the bounding box "b"?
X */
X#define OutOfBounds(p,b) ((p)->x < b[0][0] || (p)->x > b[1][0] ||\
X (p)->y < b[0][1] || (p)->y > b[1][1] ||\
X (p)->z < b[0][2] || (p)->z > b[1][2])
X
X#ifndef DUMB_CPP
X
X#define vecsub(a,b,r) (r)->x= (a).x-(b).x;(r)->y= (a).y-(b).y;(r)->z= (a).z-(b).z
X#define vecadd(a,b,r) (r)->x= (a).x+(b).x;(r)->y= (a).y+(b).y;(r)->z= (a).z+(b).z
X#define scalar_prod(s,a,r) (r)->x= s*(a).x;(r)->y= s*(a).y;(r)->z= s*(a).z
X#define veccomb(s1,v1,s2,v2,r) (r)->x = s1*(v1).x + s2*(v2).x; \
X (r)->y = s1*(v1).y + s2*(v2).y; \
X (r)->z = s1*(v1).z + s2*(v2).z;
X#define addscaledvec(v1,s,v2,r) (r)->x = (v1).x + s*(v2).x; \
X (r)->y = (v1).y + s*(v2).y; \
X (r)->z = (v1).z + s*(v2).z;
X#endif
END_OF_FILE
if test 4762 -ne `wc -c <'src/funcdefs.h'`; then
echo shar: \"'src/funcdefs.h'\" unpacked with wrong size!
fi
# end of 'src/funcdefs.h'
fi
if test -f 'src/input.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/input.c'\"
else
echo shar: Extracting \"'src/input.c'\" \(3342 characters\)
sed "s/^X//" >'src/input.c' <<'END_OF_FILE'
X/*
X * input.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: input.c,v 3.0 89/10/27 02:05:51 craig Exp $
X *
X * $Log: input.c,v $
X * Revision 3.0 89/10/27 02:05:51 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#ifdef SYSV
X#include <string.h>
X#else
X#ifndef AZTEC_C
X#include <strings.h>
X#else /* AZTEC_C */
X
Xgetpid()
X{
X return 123;
X}
X#endif
X#endif
X#include "constants.h"
X#include "typedefs.h"
X
X#define INCLUDE_STR "#include "
X
Xchar *infilename; /* Name of input file. NULL signifies stdin. */
Xchar tmpname[BUFSIZ]; /* name of temporary file */
Xextern FILE *yyin; /* lex/yacc file pointer */
X
Xread_input_file()
X{
X extern char *infilename;
X
X /*
X * Open temporary file.
X */
X sprintf(tmpname,"%s/raytmp.%d",TMPDIR, getpid());
X yyin = fopen(tmpname, "w");
X
X if (yyin == (FILE *)NULL) {
X fprintf(stderr,"Cannot write to temp file %s\n",tmpname);
X exit(1);
X }
X
X if (!process_file(infilename)) {
X /*
X * Some kind of error occurred -- unlink
X * temporary file and exit.
X */
X fclose(yyin);
X unlink(tmpname);
X exit(1);
X }
X /*
X * File processed okay. Close the file, open it again for
X * reading, and call lex/yacc.
X */
X fclose(yyin);
X yyin = fopen(tmpname, "r");
X yyparse();
X /*
X * All done -- unlink temporary file.
X */
X unlink(tmpname);
X}
X
X/*
X * Open the named file and copy its contents into the temporary file.
X * If we run across a #include directive, recurse on the desired
X * file. Note that *no checking is performed* -- a file could,
X * for example, include itself. Rayshade will happily go on
X * copying data into the temporary file until it runs out
X * of file pointers (an fopen will fail), or you run out of disk space...
X */
Xprocess_file(filename)
Xchar *filename;
X{
X FILE *fp;
X char buf[BUFSIZ], *name, *np;
X extern int yylineno;
X
X if (filename == (char *)NULL)
X fp = stdin;
X else {
X fp = fopen(filename, "r");
X if (fp == (FILE *)NULL) {
X fprintf(stderr,"Cannot open %s for reading.\n",filename);
X return FALSE;
X }
X }
X
X while(fgets(buf, BUFSIZ, fp) != NULL) {
X if (strncmp(buf, INCLUDE_STR, strlen(INCLUDE_STR)) == 0) {
X /*
X * Got an "#include "...
X */
X#ifdef SYSV
X name = strchr(buf, '"');
X np = strrchr(buf, '"');
X#else
X name = index(buf, '"');
X np = rindex(buf, '"');
X#endif
X /*
X * Get name between quotes. If no or
X * one quote, complain.
X */
X if (name == (char *)0 || name == np) {
X fprintf(stderr,"Invalid include directive (line %d)\n", yylineno);
X return FALSE;
X }
X name++;
X *np = (char)NULL;
X if (process_file(name) == FALSE)
X return FALSE;
X } else
X fputs(buf, yyin);
X }
X return TRUE;
X}
END_OF_FILE
if test 3342 -ne `wc -c <'src/input.c'`; then
echo shar: \"'src/input.c'\" unpacked with wrong size!
fi
# end of 'src/input.c'
fi
if test -f 'src/list.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/list.c'\"
else
echo shar: Extracting \"'src/list.c'\" \(3185 characters\)
sed "s/^X//" >'src/list.c' <<'END_OF_FILE'
X/*
X * list.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: list.c,v 3.0 89/10/27 02:05:54 craig Exp $
X *
X * $Log: list.c,v $
X * Revision 3.0 89/10/27 02:05:54 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#include "constants.h"
X#include "typedefs.h"
X#include "funcdefs.h"
X/*
X * Take a list whose DATA field points to a linked list of objects and
X * turn it into a List.
X */
Xmake_list(obj)
XObject *obj;
X{
X int i;
X List *list;
X extern ObjList *find_bounds();
X
X list = (List *)Malloc(sizeof(List));
X /*
X * Find the unbounded objects on the list as well as the
X * bounding box of the list.
X */
X list->unbounded = find_bounds((ObjList **)&obj->data, obj->bounds);
X /*
X * Transform bounding box if necessary.
X */
X if (obj->trans)
X transform_bounds(&obj->trans->obj2world, obj->bounds);
X for (i = 0; i < 3; i++) {
X list->bounds[LOW][i] = obj->bounds[LOW][i];
X list->bounds[HIGH][i] = obj->bounds[HIGH][i];
X }
X /*
X * obj->data now holds list of bounded objects.
X */
X list->list = (ObjList *)obj->data;
X obj->data = (char *)list;
X}
X
X/*
X * Intersect ray & list of objects.
X */
Xdouble
Xint_list(list, source, ray, hitinfo)
XList *list;
XPrimitive *source;
XRay *ray;
XHitInfo *hitinfo;
X{
X register ObjList *objlist;
X double offset;
X HitInfo hittmp;
X double dist, mindist;
X extern double intersect();
X
X mindist = FAR_AWAY;
X hittmp.totaltrans = hitinfo->totaltrans;
X /*
X * Intersect with unbounded objects.
X */
X for (objlist = list->unbounded; objlist ; objlist = objlist->next) {
X dist = intersect((Object *)objlist->data, source, ray,
X &hittmp);
X if (dist > EPSILON && dist < mindist) {
X mindist = dist;
X *hitinfo = hittmp;
X }
X }
X /*
X * Check for intersection with bounding box.
X */
X if (OutOfBounds(&ray->pos, list->bounds)) {
X offset = IntBounds(ray, list->bounds);
X if (offset < EPSILON)
X /*
X * Ray never hit list.
X */
X return (mindist == FAR_AWAY ? 0. : mindist);
X else if (mindist < offset)
X /*
X * Ray hit unbounded object closer than bounding box.
X */
X return mindist;
X /*
X * Else the ray enters list-space before it hits an
X * unbounded object.
X */
X }
X /*
X * Intersect with objects on list.
X */
X for (objlist = list->list; objlist ; objlist = objlist->next) {
X dist = intersect((Object *)objlist->data, source, ray,
X &hittmp);
X if (dist > EPSILON && dist < mindist) {
X mindist = dist;
X *hitinfo = hittmp;
X }
X }
X
X return (mindist == FAR_AWAY ? 0. : mindist);
X}
END_OF_FILE
if test 3185 -ne `wc -c <'src/list.c'`; then
echo shar: \"'src/list.c'\" unpacked with wrong size!
fi
# end of 'src/list.c'
fi
if test -f 'src/main.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/main.c'\"
else
echo shar: Extracting \"'src/main.c'\" \(4705 characters\)
sed "s/^X//" >'src/main.c' <<'END_OF_FILE'
Xchar rcsid[] =
X "$Id: main.c,v 3.0 89/10/27 17:05:45 craig Exp $";
X/*
X * main.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Log: main.c,v $
X * Revision 3.0 89/10/27 17:05:45 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#include <signal.h>
X#ifdef SYSV
X#include <sys/types.h>
X#include <sys/times.h>
X#include <sys/param.h>
X#else
X#ifndef AZTEC_C
X#include <sys/time.h>
X#include <sys/resource.h>
X#endif
X#endif
X#include "constants.h"
X#include "typedefs.h"
X#include "defaults.h"
X
Xunsigned long EyeRays, /* # of eye rays spawned */
X ShadowRays, /* # of shadow rays spawned */
X ReflectRays, /* # of reflected rays */
X RefractRays, /* # of refracted rays */
X HitRays, /* # of rays which hit something. */
X BVTests, /* # of bounding volume tests. */
X SuperSampled; /* # of supersampled pixels. */
Xdouble ftmp; /* Used by fabs() macro. */
XFILE *fstats; /* Statistics file */
X
X/*
X * LINDA silliness.
X */
X#ifdef LINDA
Xrayshade_main(argc, argv)
X#else
Xmain(argc, argv)
X#endif
Xint argc;
Xchar **argv;
X{
X double utime, stime;
X unsigned long TotalRays;
X extern int Verbose, Cache;
X extern unsigned long CacheWorked, CacheFailed, ShadowHits;
X
X /*
X * Initialize variables, etc.
X */
X setup();
X /*
X * Parse options from command line.
X */
X parse_options(argc, argv);
X /*
X * Process input file.
X */
X if (Verbose) {
X print_version();
X fprintf(fstats,"Reading input file...\n");
X fflush(fstats);
X }
X read_input_file();
X /*
X * Set variables which weren't set on command line
X * or in input file.
X */
X cleanup();
X /*
X * Start new picture.
X */
X startpic();
X /*
X * Set up viewing parameters.
X */
X viewing();
X /*
X * Set up world.
X */
X if (Verbose)
X fprintf(fstats,"Setting up voxels...\n");
X SetupWorld();
X get_cpu_time(&utime, &stime);
X fprintf(fstats,"Preprocessing time:\t");
X fprintf(fstats,"%2.2lfu %2.2lfs\n",utime, stime);
X fprintf(fstats,"Starting trace.\n");
X fflush(fstats);
X /*
X * Trace the image.
X */
X raytrace();
X /*
X * Close the image file.
X */
X endpic();
X
X get_cpu_time(&utime, &stime);
X
X#ifndef LINDA
X TotalRays = EyeRays + ShadowRays + ReflectRays + RefractRays;
X ShadowHits += CacheWorked;
X HitRays += ShadowHits;
X fprintf(fstats,"Eye rays:\t\t\t%ld\n", EyeRays);
X fprintf(fstats,"Shadow rays:\t\t\t%ld\n",ShadowRays);
X fprintf(fstats,"Reflected rays:\t\t\t%ld\n",ReflectRays);
X fprintf(fstats,"Refracted rays:\t\t\t%ld\n",RefractRays);
X fprintf(fstats,"Total rays:\t\t\t%ld\n", TotalRays);
X if (TotalRays != 0.)
X fprintf(fstats,"Intersecting rays:\t\t%ld (%3.3f%%)\n",
X HitRays, 100. * (float)HitRays / (float)TotalRays);
X if (ShadowRays != 0) {
X if (Cache)
X fprintf(fstats,"Shadow cache hits:\t\t%ld (%ld misses)\n",
X CacheWorked, CacheFailed);
X fprintf(fstats,"Total shadow hits:\t\t%ld (%3.3f%%)\n",
X ShadowHits, 100.*(float)ShadowHits / (float)ShadowRays);
X }
X fprintf(fstats,"Supersampled pixels:\t\t%ld\n",SuperSampled);
X fprintf(fstats,"B.V. intersection tests:\t%ld\n", BVTests);
X print_prim_stats();
X#endif
X fprintf(fstats,"Total CPU time (sec):\t\t");
X fprintf(fstats,"%2.2lf (%2.2lfu + %2.2lfs)\n",utime+stime, utime, stime);
X#ifndef LINDA
X if (TotalRays != 0.)
X fprintf(fstats,"Seconds / ray:\t\t\t%4.4lf\n",
X (utime + stime) / (double)TotalRays);
X if (HitRays != 0.)
X fprintf(fstats, "Seconds / intersecting ray:\t%4.4lf\n",
X (utime + stime) / (double)HitRays);
X#endif
X PrintMemoryStats();
X exit(0);
X}
X
X#ifdef SYSV
Xget_cpu_time(utime, stime)
Xdouble *utime, *stime;
X{
X struct tms time;
X long times();
X
X (void)times(&time);
X *utime = (double)time.tms_utime / (double)HZ;
X *stime = (double)time.tms_stime / (double)HZ;
X}
X#else
X#ifdef AZTEC_C
Xget_cpu_time()
X{
X}
X#else /* !SYSV && !AZTEC_C */
Xget_cpu_time(utime, stime)
Xdouble *utime, *stime;
X{
X struct rusage usage;
X
X getrusage(RUSAGE_SELF, &usage);
X
X *utime = (double)usage.ru_utime.tv_sec +
X (double)usage.ru_utime.tv_usec / 1000000.;
X *stime = (double)usage.ru_stime.tv_sec +
X (double)usage.ru_stime.tv_usec / 1000000.;
X}
X#endif
X#endif
END_OF_FILE
if test 4705 -ne `wc -c <'src/main.c'`; then
echo shar: \"'src/main.c'\" unpacked with wrong size!
fi
# end of 'src/main.c'
fi
if test -f 'src/outputp.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/outputp.c'\"
else
echo shar: Extracting \"'src/outputp.c'\" \(4181 characters\)
sed "s/^X//" >'src/outputp.c' <<'END_OF_FILE'
X/*
X * outputp.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: outputp.c,v 3.0 89/10/27 02:05:58 craig Exp $
X *
X * $Log: outputp.c,v $
X * Revision 3.0 89/10/27 02:05:58 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#include "typedefs.h"
X#include "constants.h"
X#include "funcdefs.h"
X#ifndef NORLE
X#include "svfb_global.h"
Xunsigned char *buffer[3]; /* Output buffer */
X#endif
X
XFILE *imgfile; /* Raster output file */
Xchar outfilename[BUFSIZ]; /* Name of output file */
Xint Appending; /* Appending to output file? */
X
X/*
X * Convert floating-point to unsigned char (0-255).
X * This could easily be a macro, but the old SGI compilers dump core
X * on it for some reason.
X */
Xunsigned char
Xcorrect(x)
Xdouble x;
X{
X if (x < 0)
X return 0;
X if (x > 255)
X return 255;
X return x;
X}
X
X#ifndef NORLE
X/*
X * Open image file and write RLE header.
X */
Xstartpic()
X{
X extern int Xres, Yres;
X
X if (*outfilename) {
X if (Appending) {
X /*
X * If we're appending, we *still* have to write
X * the Utah Raster header to the file. This is
X * due to strangeness in the Utah Raster toolkit,
X * which does some vital initialization in sv_setup().
X */
X imgfile = fopen(outfilename, "r+");
X } else
X imgfile = fopen(outfilename, "w");
X if (imgfile == (FILE *)NULL) {
X fprintf(stderr,"Cannot open %s for writing.\n",
X outfilename);
X exit(2);
X }
X } else
X imgfile = stdout;
X sv_globals.svfb_fd = imgfile;
X sv_globals.sv_xmax = Xres -1;
X sv_globals.sv_ymax = Yres -1;
X sv_globals.sv_xmin = sv_globals.sv_ymin = 0;
X sv_globals.sv_ncolors = 3;
X sv_globals.sv_alpha = 0;
X sv_setup(RUN_DISPATCH, &sv_globals);
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 fflush(sv_globals.svfb_fd);
X buffer[0]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres);
X buffer[1]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres);
X buffer[2]=(unsigned char *)Malloc(sizeof(unsigned char)*(unsigned)Xres);
X if (Appending)
X fseek(imgfile, 0L, 2); /* Go to end of file */
X}
X
X
X/*
X * Write a scanline of output.
X * "buf" is an array of Color structures of size Xres. Each color
X * component is normalized to [0, 1.].
X */
Xoutline(buf)
XColor *buf;
X{
X register int i;
X extern int Xres;
X
X for(i = 0;i < Xres;i++) {
X /*
X * Scale colors to fit unsigned char and check for
X * over/underflow.
X */
X buffer[0][i] = correct(255 * buf[i].r);
X buffer[1][i] = correct(255 * buf[i].g);
X buffer[2][i] = correct(255 * buf[i].b);
X }
X sv_putrow(buffer, Xres, &sv_globals);
X}
X
X/*
X * Close image file.
X */
Xendpic()
X{
X sv_puteof(&sv_globals);
X fclose(imgfile);
X}
X
X#else /* NORLE */
X
Xstartpic()
X{
X extern int Xres, Yres;
X
X if (*outfilename) {
X if (Appending)
X imgfile = fopen(outfilename, "a");
X else
X imgfile = fopen(outfilename, "w");
X if (imgfile == (FILE *)NULL) {
X fprintf(stderr,"Cannot open %s for writing.\n",
X outfilename);
X exit(2);
X }
X } else
X imgfile = stdout;
X
X fprintf(imgfile,"%d %d\n",Xres, Yres);
X fflush(imgfile);
X}
X
Xoutline(buf)
XColor *buf;
X{
X register int i;
X extern int Xres;
X
X for (i = 0; i < Xres; i++) {
X fputc(correct(255.*buf[i].r), imgfile);
X fputc(correct(255.*buf[i].g), imgfile);
X fputc(correct(255.*buf[i].b), imgfile);
X }
X fflush(imgfile);
X}
X
Xendpic()
X{
X fclose(imgfile);
X}
X#endif /* NORLE */
X
END_OF_FILE
if test 4181 -ne `wc -c <'src/outputp.c'`; then
echo shar: \"'src/outputp.c'\" unpacked with wrong size!
fi
# end of 'src/outputp.c'
fi
if test -f 'src/primobj.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/primobj.h'\"
else
echo shar: Extracting \"'src/primobj.h'\" \(3420 characters\)
sed "s/^X//" >'src/primobj.h' <<'END_OF_FILE'
X/*
X * primobj.h
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: primobj.h,v 3.0 89/10/27 02:06:00 craig Exp $
X *
X * $Log: primobj.h,v $
X * Revision 3.0 89/10/27 02:06:00 craig
X * Baseline for first official release.
X *
X */
X
X/*
X * Cylinder
X */
Xtypedef struct cylinder {
X double rad, len; /* Radius and length. */
X} Cylinder;
X
Xtypedef struct cone {
X double start_pos, end_pos, apex_rad; /* End cap Z positions */
X double tantheta; /* "slope" */
X} Cone;
X
X/*
X * Sphere
X */
Xtypedef struct {
X double r; /* radius */
X double x, y, z; /* position */
X} Sphere;
X
X/*
X * Box
X */
Xtypedef struct {
X double bounds[2][3]; /* Box corners */
X} Box;
X
X/*
X * Triangle
X */
Xtypedef struct {
X Vector nrm; /* triangle normal */
X Vector p1, p2, p3; /* vertices */
X double d; /* plane constant */
X char index; /* Flag used for shading/intersection test. */
X Vector *vnorm; /* Array of vertex normals */
X double *b; /* Array of barycentric coordinates */
X Vector e1, e2, e3; /* edge vectors */
X} Triangle;
X
X/*
X * Polygon
X */
Xtypedef struct {
X Vector norm; /* Normal to polygon */
X double d; /* Plane constant */
X char index; /* Which normal coord is "dominant"? */
X Vector *points; /* Array of vertices */
X int npoints; /* Number of vertices */
X} Polygon;
X
X/*
X * Superquadric
X */
Xtypedef struct {
X double bounds[2][3]; /* bounding box */
X double x, y, z; /* Center */
X double pow; /* Superquadric power */
X double a, b, c, r;
X double err; /* Error constant */
X} Superq;
X
X/*
X * Plane
X */
Xtypedef struct {
X Vector norm; /* Plane normal. */
X double d; /* Plane constant. */
X} Plane;
X
X/*
X * Height field gunk.
X */
Xtypedef struct hfTri {
X Vector v1, v2, v3, norm;
X double d;
X char type;
X struct hfTri *next, *prev;
X} hfTri;
X
Xtypedef struct {
X int len;
X hfTri *head, *tail;
X} TriQueue;
X
Xtypedef struct {
X float **data; /* Altitude points */
X float minz, maxz;
X int size, *lsize; /* # of points/side */
X int BestSize; /* "best" division size */
X float iBestSize; /* inverse of above (for faster computation) */
X int levels; /* log base BestSize of size */
X float ***boundsmax; /* high data values at various resolutions. */
X float ***boundsmin;
X float *spacing;
X hfTri hittri, **q; /* hit triangle and triangle cache */
X int qtail, qsize; /* end and length of cache */
X double boundbox[2][3]; /* bounding box of HF */
X} Hf;
X
X/*
X * Primitive object.
X */
Xtypedef struct Primitive {
X char type; /* object type */
X struct Surface *surf; /* default surface */
X union {
X Sphere *p_sphere;
X Box *p_box;
X Triangle *p_triangle;
X Superq *p_superq;
X Plane *p_plane;
X Cylinder *p_cylinder;
X Polygon *p_poly;
X Cone *p_cone;
X Hf *p_hf;
X } objpnt; /* Pointer to primitive */
X} Primitive;
END_OF_FILE
if test 3420 -ne `wc -c <'src/primobj.h'`; then
echo shar: \"'src/primobj.h'\" unpacked with wrong size!
fi
# end of 'src/primobj.h'
fi
if test -f 'src/setup.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/setup.c'\"
else
echo shar: Extracting \"'src/setup.c'\" \(4525 characters\)
sed "s/^X//" >'src/setup.c' <<'END_OF_FILE'
X/*
X * setup.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: setup.c,v 3.0 89/10/27 02:06:03 craig Exp $
X *
X * $Log: setup.c,v $
X * Revision 3.0 89/10/27 02:06:03 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#include "constants.h"
X#include "defaults.h"
X#include "typedefs.h"
X#include "funcdefs.h"
X
X#ifdef MULTIMAX
X#include <parallel.h>
X#define SHARED_BYTES 23 /* 2^23 bytes of shared memory */
X#endif
X/*
X * Set default parameters
X */
Xsetup()
X{
X extern int maxlevel;
X extern double hfov, vfov;
X extern Vector eyep, lookp, up;
X extern Object *World;
X extern ObjList *CurObj;
X#ifdef MULTIMAX
X unsigned int bytes;
X
X /*
X * Initialize shared memory stuff.
X */
X bytes = 1 << SHARED_BYTES;
X if (share_malloc_init(bytes) == -1) {
X fprintf(stderr,"Cannot share_malloc %d bytes.\n",bytes);
X exit(10);
X } else
X fprintf(stderr,"Malloced %d bytes of shared memory.\n",
X bytes);
X#endif
X /*
X * Like every other object, the objects that make up
X * "World" are stored in a simple linked list until it
X * has been completely defined. Once the definition is
X * complete we convert the linked list into a Grid or List
X * as per the user's wishes.
X */
X World = new_object("world", LIST, (char *)NULL, (Trans *)NULL);
X
X maxlevel = MAXLEVEL;
X hfov = HFOV;
X vfov = UNSET;
X eyep.x = EYEX;
X eyep.y = EYEY;
X eyep.z = EYEZ;
X lookp.x = LOOKX;
X lookp.y = LOOKY;
X lookp.z = LOOKZ;
X up.x = UPX;
X up.y = UPY;
X up.z = UPZ;
X
X /*
X * Kinda yicky, but compatible.
X */
X CurObj = (ObjList *)Malloc(sizeof(ObjList));
X CurObj->next = (ObjList *)0;
X CurObj->data = (Object *)0;
X InitRTable(); /* Initialize values for Noise() */
X}
X
X/*
X * cleanup()
X *
X * Initialize variables not set on command line or in input file.
X */
Xcleanup()
X{
X int i;
X extern int nlight, maxlevel;
X extern int Xres, Yres, StartLine, Jittered, JitSamples, pixel_div;
X extern double RedContrast, GreenContrast, BlueContrast, TreeCutoff;
X extern double vfov, hfov;
X extern Light light[];
X extern FILE *fstats;
X
X /*
X * Because we want the user to be able to override the input file
X * through the command line, we have to initialize some variables to
X * bogus values so that when the file is being parsed, it is
X * possible to tell if a given variable has been set on the
X * command line.
X *
X * If such variables are not set to legal values on the command
X * line or in the input file, we must do it here.
X */
X if (Xres == UNSET)
X Xres = XRESOLUTION;
X if (Yres == UNSET)
X Yres = YRESOLUTION;
X
X if (StartLine == UNSET)
X StartLine = Yres -1;
X else
X fprintf(fstats,"Starting on line %d\n",StartLine);
X
X /*
X * If not defined in the input file, calculate VFOV
X * by hand. This assumes that pixels are square, which is
X * probably a bad idea. ("aspect" option?)
X */
X if (vfov == UNSET)
X vfov = hfov * Yres / Xres;
X
X if (!Jittered && pixel_div == UNSET)
X pixel_div = PIXEL_DIV;
X
X if (JitSamples == UNSET)
X JitSamples = DEFLIGHTSAMPLES;
X
X if (Jittered && JitSamples > 5) {
X fprintf(stderr,"Sorry, %d rays/pixel not supported.\n",
X JitSamples*JitSamples);
X exit(2);
X }
X if (!Jittered && JitSamples < 3) {
X fprintf(stderr,"Samples (-S) value must be at least 3.\n");
X exit(2);
X }
X
X if (TreeCutoff == UNSET)
X TreeCutoff = DEFCUTOFF;
X
X if (RedContrast == UNSET)
X RedContrast = DEFREDCONT;
X if (GreenContrast == UNSET)
X GreenContrast = DEFGREENCONT;
X if (BlueContrast == UNSET)
X BlueContrast = DEFBLUECONT;
X
X /*
X * Now that we've parsed the input file, we know what
X * maxlevel is, so we can allocate the right amount of
X * space for each light source's cache and related
X * transformation.
X */
X for (i = 0; i < nlight; i++) {
X light[i].cache = (Primitive **)Calloc(maxlevel+1,
X sizeof(Primitive *));
X light[i].trans = (TransInfo *)Malloc((maxlevel+1)*
X sizeof(TransInfo));
X }
X}
END_OF_FILE
if test 4525 -ne `wc -c <'src/setup.c'`; then
echo shar: \"'src/setup.c'\" unpacked with wrong size!
fi
# end of 'src/setup.c'
fi
if test -f 'src/sphere.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/sphere.c'\"
else
echo shar: Extracting \"'src/sphere.c'\" \(3346 characters\)
sed "s/^X//" >'src/sphere.c' <<'END_OF_FILE'
X/*
X * sphere.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: sphere.c,v 3.0 89/10/27 02:06:04 craig Exp $
X *
X * $Log: sphere.c,v $
X * Revision 3.0 89/10/27 02:06:04 craig
X * Baseline for first official release.
X *
X */
X#include <math.h>
X#include <stdio.h>
X#include "constants.h"
X#include "typedefs.h"
X#include "funcdefs.h"
X
X/*
X * Create & return reference to a sphere.
X */
XObject *
Xmaksph(surf, r, pos)
Xchar *surf;
Xdouble r;
XVector *pos;
X{
X Sphere *sphere;
X Object *newobj;
X Primitive *prim;
X extern int Quiet, yylineno;
X
X if (r < EPSILON) {
X if (!Quiet)
X fprintf(stderr,"Degenerate sphere (line %d)\n",
X yylineno);
X return (Object *)0;
X }
X
X prim = mallocprim();
X newobj = new_object(NULL, SPHERE, (char *)prim, (Trans *)NULL);
X prim->type = SPHERE;
X prim->surf = find_surface(surf);
X sphere = (Sphere *)Malloc(sizeof(Sphere));
X prim->objpnt.p_sphere = sphere;
X /*
X * sphere->r really holds the square of the radius.
X */
X sphere->r = r*r;
X sphere->x = pos->x;
X sphere->y = pos->y;
X sphere->z = pos->z;
X
X return newobj;
X}
X
X/*
X * Ray/sphere intersection test.
X */
Xdouble
Xintsph(pos, ray, obj)
Xregister Vector *pos, *ray;
XPrimitive *obj;
X{
X Sphere *sph;
X double xadj, yadj, zadj;
X double b, t, s;
X extern unsigned long primtests[];
X
X primtests[SPHERE]++;
X sph = obj->objpnt.p_sphere;
X /*
X * Translate ray origin to object space and negate everything.
X * (Thus, we translate the sphere into ray space, which saves
X * us a couple of negations below.)
X */
X xadj = sph->x - pos->x;
X yadj = sph->y - pos->y;
X zadj = sph->z - pos->z;
X
X /*
X * Solve quadratic equiation. Recall that sph->r is the square of r.
X */
X b = xadj * ray->x + yadj * ray->y + zadj * ray->z;
X t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->r;
X if (t < 0)
X return 0.;
X t = sqrt(t);
X s = b - t;
X if (s > EPSILON)
X return s;
X s = b + t;
X if (s > EPSILON)
X return s;
X return 0.;
X}
X
Xnrmsph(pos, obj, nrm)
XVector *pos, *nrm;
XPrimitive *obj;
X{
X /*
X * Don't bother dividing by by sphere->r -- the normal will be
X * normalized later.
X */
X nrm->x = (pos->x - obj->objpnt.p_sphere->x);
X nrm->y = (pos->y - obj->objpnt.p_sphere->y);
X nrm->z = (pos->z - obj->objpnt.p_sphere->z);
X}
X
Xsphextent(o, bounds)
XPrimitive *o;
Xdouble bounds[2][3];
X{
X Sphere *s = o->objpnt.p_sphere;
X double r;
X
X /*
X * Could store both r*r and r, but sphextent is only
X * called in preprocessing, so...
X */
X r = sqrt(s->r);
X bounds[LOW][X] = s->x - r;
X bounds[HIGH][X] = s->x + r;
X bounds[LOW][Y] = s->y - r;
X bounds[HIGH][Y] = s->y + r;
X bounds[LOW][Z] = s->z - r;
X bounds[HIGH][Z] = s->z + r;
X}
END_OF_FILE
if test 3346 -ne `wc -c <'src/sphere.c'`; then
echo shar: \"'src/sphere.c'\" unpacked with wrong size!
fi
# end of 'src/sphere.c'
fi
if test -f 'src/superq.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/superq.c'\"
else
echo shar: Extracting \"'src/superq.c'\" \(3390 characters\)
sed "s/^X//" >'src/superq.c' <<'END_OF_FILE'
X/*
X * superq.c
X *
X * Slightly modified version of Kuchkuda's superquadric code.
X *
X * $Id: superq.c,v 3.0 89/10/27 02:06:05 craig Exp $
X *
X * $Log: superq.c,v $
X * Revision 3.0 89/10/27 02:06:05 craig
X * Baseline for first official release.
X *
X */
X#include <math.h>
X#include "constants.h"
X#include "typedefs.h"
X#include "funcdefs.h"
X
X#define ERRCONST 1.006
X
X/*
X * Create and return reference to a superquadric.
X */
XObject *
Xmaksup(surf, x, y, z, xs, ys, zs, power)
Xchar *surf;
Xdouble x, y, z, xs, ys, zs, power;
X{
X double maxval;
X Superq *super;
X Primitive *prim;
X Object *newobj;
X
X prim = mallocprim();
X prim->surf = find_surface(surf);
X newobj = new_object(NULL, SUPERQ, (char *)prim, (Trans *)NULL);
X prim->type = SUPERQ;
X super = (Superq *) Malloc((unsigned)sizeof(Superq));
X prim->objpnt.p_superq = super;
X super->x = x;
X super->y = y;
X super->z = z;
X super->bounds[LOW][X] = x - xs;
X super->bounds[HIGH][X] = x + xs;
X super->bounds[LOW][Y] = y - ys;
X super->bounds[HIGH][Y] = y + ys;
X super->bounds[LOW][Z] = z - zs;
X super->bounds[HIGH][Z] = z + zs;
X
X super->pow = power;
X maxval = xs;
X if (ys > maxval)
X maxval = ys;
X if (zs > maxval)
X maxval = zs;
X super->a = xs / maxval;
X super->b = ys / maxval;
X super->c = zs / maxval;
X super->r = pow(maxval, power);
X super->err = pow((ERRCONST * maxval), power) - super->r;
X
X return newobj;
X}
X
Xdouble
Xintsup(pos, ray, obj)
XVector *pos, *ray;
XPrimitive *obj;
X{
X double s, si, t;
X double xadj, yadj, zadj;
X double old, result, p;
X Ray tmpray;
X Superq *super;
X extern unsigned long primtests[];
X
X primtests[SUPERQ]++;
X super = obj->objpnt.p_superq;
X /* find box intersection */
X if (OutOfBounds(pos, super->bounds)) {
X tmpray.pos = *pos;
X tmpray.dir = *ray;
X s = IntBounds(&tmpray, super->bounds);
X if (s <= 0.)
X return 0;
X }
X else
X s = 0.;
X
X xadj = pos->x - super->x;
X yadj = pos->y - super->y;
X zadj = pos->z - super->z;
X
X /* initial solution */
X p = super->pow;
X result = pow(fabs((xadj + ray->x * s) / super->a), p)
X + pow(fabs((yadj + ray->y * s) / super->b), p)
X + pow(fabs((zadj + ray->z * s) / super->c), p)
X - super->r;
X
X si = s;
X s = s + 0.001;
X /* iterative refinement */
X while (result > super->err) {
X old = result;
X result = pow(fabs((xadj + ray->x * s) / super->a), p)
X + pow(fabs((yadj + ray->y * s) / super->b), p)
X + pow(fabs((zadj + ray->z * s) / super->c), p)
X - super->r;
X
X if (result >= old)
X return (0.0);
X t = (result * (s - si)) / (result - old);
X si = s;
X s -= t;
X }
X
X return (s);
X}
X
Xnrmsup(pos, obj, nrm)
XVector *pos, *nrm;
XPrimitive *obj;
X{
X double k;
X Superq *super;
X
X super = obj->objpnt.p_superq;
X nrm->x = (pos->x - super->x) / super->a;
X nrm->y = (pos->y - super->y) / super->b;
X nrm->z = (pos->z - super->z) / super->c;
X k = super->pow - 1;
X if (nrm->x > 0)
X nrm->x = pow(nrm->x, k);
X else
X nrm->x = -pow(-nrm->x, k);
X if (nrm->y > 0)
X nrm->y = pow(nrm->y, k);
X else
X nrm->y = -pow(-nrm->y, k);
X if (nrm->z > 0)
X nrm->z = pow(nrm->z, k);
X else
X nrm->z = -pow(-nrm->z, k);
X}
X
X
Xsupextent(o, bounds)
XPrimitive *o;
Xdouble bounds[2][3];
X{
X Superq *s = o->objpnt.p_superq;
X
X bounds[LOW][X] = s->bounds[LOW][X];
X bounds[HIGH][X] = s->bounds[HIGH][X];
X bounds[LOW][Y] = s->bounds[LOW][Y];
X bounds[HIGH][Y] = s->bounds[HIGH][Y];
X bounds[LOW][Z] = s->bounds[LOW][Z];
X bounds[HIGH][Z] = s->bounds[HIGH][Z];
X}
END_OF_FILE
if test 3390 -ne `wc -c <'src/superq.c'`; then
echo shar: \"'src/superq.c'\" unpacked with wrong size!
fi
# end of 'src/superq.c'
fi
if test -f 'src/surface.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/surface.c'\"
else
echo shar: Extracting \"'src/surface.c'\" \(3946 characters\)
sed "s/^X//" >'src/surface.c' <<'END_OF_FILE'
X/*
X * surface.c
X *
X * Copyright (C) 1989, Craig E. Kolb
X *
X * This software may be freely copied, modified, and redistributed,
X * provided that this copyright notice is preserved on all copies.
X *
X * There is no warranty or other guarantee of fitness for this software,
X * it is provided solely . Bug reports or fixes may be sent
X * to the author, who may or may not act on them as he desires.
X *
X * You may not include this software in a program or other software product
X * without supplying the source, or without informing the end-user that the
X * source is available for no extra charge.
X *
X * If you modify this software, you should include a notice giving the
X * name of the person performing the modification, the date of modification,
X * and the reason for such modification.
X *
X * $Id: surface.c,v 3.0 89/10/27 02:06:05 craig Exp $
X *
X * $Log: surface.c,v $
X * Revision 3.0 89/10/27 02:06:05 craig
X * Baseline for first official release.
X *
X */
X#include <stdio.h>
X#include "constants.h"
X#include "typedefs.h"
X#include "funcdefs.h"
X
X#define blend(a, b, p, q) (a * p + b * q)
X#define NORMCONST (1. / 255.)
X
XSurfaceList *Surfaces; /* Linked list of defined surfaces */
X
X/*
X * Create and return pointer to surface with given properties.
X */
XSurface *
Xmake_surface(name, amb, diff, spec, coef, refl, refr, k, translu, stcoef)
Xchar *name;
XColor *amb, *diff, *spec;
Xdouble coef, refl, refr, k, translu, stcoef;
X{
X Surface *stmp;
X
X /*
X * Complain if named surface already exists.
X */
X if ((stmp = get_surface(name)) != (Surface *)0)
X yyerror("Surface redefined.");
X
X stmp = (Surface *)Malloc(sizeof(Surface));
X stmp->name = strsave(name);
X
X stmp->amb = *amb;
X stmp->diff = *diff;
X stmp->spec = *spec;
X
X stmp->coef = coef; stmp->refl = refl; stmp->transp = refr;
X stmp->kref = k; stmp->translucency = translu;
X stmp->stcoef = stcoef;
X
X return stmp;
X}
X
XSurfaceList *
Xadd_surface(surf, list)
XSurface *surf;
XSurfaceList *list;
X{
X SurfaceList *res;
X
X res = (SurfaceList *)Malloc(sizeof(SurfaceList));
X res->surf = surf;
X res->next = list;
X
X return res;
X}
X
X/*
X * Search for surface with given name. If not found, complain and exit.
X */
XSurface *
Xfind_surface(name)
Xchar *name;
X{
X Surface *stmp;
X
X stmp = get_surface(name);
X if (stmp == (Surface *)0)
X yyerror("Undefined surface.");
X
X return stmp;
X}
X
X/*
X * Return pointer to surface with given name, NULL if no such surface.
X */
XSurface *
Xget_surface(name)
Xchar *name;
X{
X SurfaceList *stmp;
X
X for (stmp = Surfaces; stmp ; stmp = stmp->next)
X if(strcmp(name, stmp->surf->name) == 0)
X return stmp->surf;
X /*
X * No surface named "name".
X */
X return (Surface *)0;
X}
X
X/*
X * Compute combination of two surfaces. Resulting surface is copied into surf1.
X */
Xblend_surface(surf1, surf2, p, q)
XSurface *surf1, *surf2;
Xdouble p, q;
X{
X /*
X * P is weight of surf1. q is weight of surf2.
X * Result is placed in surf1.
X */
X
X blend_color(&surf1->amb, &surf2->amb, p, q);
X blend_color(&surf1->diff, &surf2->diff, p, q);
X blend_color(&surf1->spec, &surf2->spec, p, q);
X
X surf1->coef = blend(surf1->coef, surf2->coef, p, q);
X surf1->refl = blend(surf1->refl, surf2->refl, p, q);
X surf1->transp = blend(surf1->transp, surf2->transp, p, q);
X surf1->kref = blend(surf1->kref, surf2->kref, p, q);
X}
X
X/*
X * Blend two colors. Result is placed in color1.
X */
Xblend_color(color1, color2, p, q)
XColor *color1, *color2;
Xdouble p, q;
X{
X color1->r = blend(color1->r, color2->r, p, q);
X color1->g = blend(color1->g, color2->g, p, q);
X color1->b = blend(color1->b, color2->b, p, q);
X}
X
X/*
X * Scale color by given red, green and blue factors.
X */
XScaleColor(scalar, color, res)
Xdouble scalar;
XColor color, *res;
X{
X res->r = color.r * scalar;
X res->g = color.g * scalar;
X res->b = color.b * scalar;
X}
X
XAddScaledColor(color1, scalar, color2, res)
XColor color1, color2, *res;
Xdouble scalar;
X{
X res->r = color1.r + scalar * color2.r;
X res->g = color1.g + scalar * color2.g;
X res->b = color1.b + scalar * color2.b;
X}
END_OF_FILE
if test 3946 -ne `wc -c <'src/surface.c'`; then
echo shar: \"'src/surface.c'\" unpacked with wrong size!
fi
# end of 'src/surface.c'
fi
echo shar: End of archive 2 \(of 8\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 8 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list