Path: utzoo!utgpu!cs.utexas.edu!sdd.hp.com!elroy.jpl.nasa.gov!usc!srhqla!avatar!kory From: kory@avatar.avatar.com (Kory Hamzeh) Newsgroups: alt.sources Subject: prt: a parallel raytracer. Part 2 of 3. Message-ID: <110@avatar.avatar.com> Date: 6 Dec 90 03:39:17 GMT Organization: Kory Hamzeh, Canoga Park, Ca, USA Lines: 2500 Archive-name: prt/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 'FORMAT' <<'END_OF_FILE' X X PRT INPUT FILE FORMAT X Version 1.0 X Copyright (C) Kory Hamzeh, 1990. X XInitially prt used the NFF file format. Then I started adding features to it, Xand decided not to call it NFF since it wasn't NFF anymore (makes sense, Xdoesn't it?). X XHere is a list of keywords: X X from X at X up X angle X resolution X light X background X surface X cone X sphere X hsphere X polygon X ring X quadric X instance X end_instance X instance_of X XHere is an explanation of each keyword: X X---------- X XEach input file must begin with the following keywords: X X from %g %g %g X at %g %g %g X up %g %g %g X angle %g X resolution %d %d X XThe parameters are: X X From: the eye location in XYZ. X At: a position to be at the center of the image, in XYZ world X coordinates. A.k.a. "lookat". X Up: a vector defining which direction is up, as an XYZ vector. X Angle: in degrees, defined as from the center of top pixel row to X bottom pixel row and left column to right column. X Resolution: in pixels, in x and in y. X X---------- X XLight sources: X X light X Y Z X XFormat: X X light %g %g %g X XThis keyword defines the position of the light sources. All light sources Xmust be defined before any objects are defined. X X---------- X XBackground color: X X background R G B y X XFormat: X X background %g %g %g y X XThe background color in RGB. The last field is used for color cueing which Xis not implemented yet and must always be 'y'. X X---------- X XSurface properties: X X surface Rr Rg Rb Ks Fr Fg Fb T Ar Ag Ab Dr Dg Db Sr Sg Sb P Ior X XFormat: X X surface %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g X XThe parameters are: X X Rr Rg Rb The reflective color triplet. This value should always X be 1 1 1 unless you want this surface to reflect X different percentage per color component. X Ks The specular component. This value is the percentage X of light that is reflected from this object. A value X of 0 means no reflection, and a value of 1 means a X perfect reflector (mirror). X Fr Fg Fb The refractive color triplet. This value should always X be 1 1 1 unless you want this surface to refract X different percentage per color component. X T Transparency value. The amount of light that can go X through this object. A value of 0 means a totally opaque X object. A value of 1 means a totally transparent object. X Ar Ag Ab The ambient color for this object. This means the color X of an object if it were fully shadowed. All objects are X assigned this color before any shading algorithm is X started. X Dr Dg Db The diffuse color component. X Sr Sg Sb This value is the color of the specular highlights. X Usually it should be 1 1 1. X P The Phong cosine power for highlights. The higher the X number (for example 100), the smaller the highlight. X Ior Index of refraction. X X--------- X XCylinder or cone: X X cone X base.x base.y base.z base_radius X apex.x apex.y apex.z apex_radius X XFormat: X X cone X %g %g %g %g X %g %g %g %g X X X-------- X XSphere: X X sphere center.x center.y center.z radius X XFormat: X X sphere %g %g %g %g X X X-------- X XHollow sphere: X X sphere center.x center.y center.z radius thickness X XFormat: X X sphere %g %g %g %g %g X X-------- X XPolygon: A polygon is defined by a set of vertices. With these databases, X a polygon is defined to have all points coplanar. A polygon has only X one side, with the order of the vertices being counterclockwise as you X face the polygon (right-handed coordinate system). The first two edges X must form a non-zero convex angle, so that the normal and side X visibility can be determined. Description: X X polygon total_vertices X vert1.x vert1.y vert1.z X [etc. for total_vertices vertices] X XFormat: X X polygon %d X [ %g %g %g ] <-- for total_vertices vertices X X-------- X XRing: X A ring is a flat coplaner round shaped object. For a ring object, X you must specify the center, 2 points on the surface of the ring, X the inner radius, and the outer radius. If the inner radius is non-zero, X then the ring will have a hole in the middle with the given radius. X X ring center.x center.y center.z p1.x p1.y p1.z p2.x p2.y p2.z or ir X XFormat: X X ring %g %g %g %g %g %g %g %g %g %g %g X X---------- X XQuadratic: X X You can raytrace any quadratic object by specifying the center, X min, max, and coefficients. This is a very powerful object type. X It can do ellipsoids, hyperbolas, and any other quadratic surface. X X quadric center.x center.y center.Z X min.x min.y min.z max.x max.y max.z X a b c d e X f g h i j X X The fields "a" through "j" are the coefficients. X XFormat: X X quadric %g %g %g X %g %g %g %g %g %g X %g %g %g %g %g X %g %g %g %g %g X X---------- X XObject instances. X XDefining an object instance: X X You may define a group of objects (and surface properties) to an X instance and assign a name to that instance. When the instance X is then used, all the objects in that instance will be placed X relative to the given origin. Note that instances by themselves X do not create any objects; the objects are created when the X instance is referenced. Instances can not be nested. X X Instances are used as follows: X X instance nameofthisinstance X X [ objects and surface properties ] X X end_instance X X where "nameofthisinstance" is a user assigned name such X as, for example, "tile_pattern". X X An instance is referenced as follows: X X instance_of nameofinstance loc.x loc.y loc.z X X where X X nameofinstance is the name assigned to a previously X defined object instance. X loc.x, loc.y, loc.z, the location of this object group. X X X---------- X X ** END OF DOCUMENT ** X END_OF_FILE if test 5595 -ne `wc -c <'FORMAT'`; then echo shar: \"'FORMAT'\" unpacked with wrong size! fi # end of 'FORMAT' fi if test -f 'cone.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cone.c'\" else echo shar: Extracting \"'cone.c'\" \(5612 characters\) sed "s/^X//" >'cone.c' <<'END_OF_FILE' X X/* X * cone.c X * X * This module conatins all of the code which relates to cones and cylinders. X * X * I must admit, MTV's code helped to "inspire" this module. X * X * Copyright (C) 1990, Kory Hamzeh. X */ X X X#include X#include X#include "rt.h" X#include "externs.h" X X Xint Cone_intersect(), Cone_normal(); X X X XBuild_cone(cd) XCONE *cd; X{ X OBJECT *obj; X double dmin, dmax, d, ftmp; X VECTOR tmp; X int i; X X if (nobjects == MAX_PRIMS) X { X fprintf(stderr, "%s: too many objects specified\n", my_name); X exit(1); X } X X if ((obj = (OBJECT *) malloc(sizeof(OBJECT))) == NULL) X { X fprintf(stderr, "%s: malloc failed\n", my_name); X exit(1); X } X X objects[nobjects++] = obj; X X obj->type = T_CONE; X obj->inter = Cone_intersect; X obj->normal = Cone_normal; X obj->surf = cur_surface; X X VecSub(cd->apex, cd->base, cd->w); X cd->height = VecNormalize(&cd->w); X cd->slope = (cd->apex_radius - cd->base_radius) / (cd->height); X cd->base_d = -VecDot(cd->base, cd->w); X X tmp.x = 0; X tmp.y = 0; X tmp.z = 1; X X if (1.0 - fabs(VecDot(tmp, cd->w)) < MIN_T) X { X tmp.y = 1; X tmp.x = 0; X } X X /* X * find two axes which are at right angles to cone_w X */ X X VecCross(cd->w, tmp, cd->u); X VecCross(cd->u, cd->w, cd->v); X X VecNormalize(&cd->u); X VecNormalize(&cd->v); X X cd->min_d = VecDot(cd->w, cd->base); X cd->max_d = VecDot(cd->w, cd->apex); X X if (cd->max_d < cd->min_d) X { X ftmp = cd->max_d; X cd->max_d = cd->min_d; X cd->min_d = ftmp; X } X X obj->obj = cd; X X /* X * Create the bounding box for this puppy. X */ X X dmin = HUGE; X dmax = -HUGE; X X /* first the X plane */ X d = cd->base.x - cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->base.x + cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.x - cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.x + cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X obj->b_min.x = dmin; X obj->b_max.x = dmax; X X /* now the Y plane */ X dmin = HUGE; X dmax = -HUGE; X X d = cd->base.y - cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->base.y + cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.y - cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.y + cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X obj->b_min.y = dmin; X obj->b_max.y = dmax; X X /* and finally the Z plane */ X dmin = HUGE; X dmax = -HUGE; X X d = cd->base.z - cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->base.z + cd->base_radius; X X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.z - cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X d = cd->apex.z + cd->apex_radius; X if (d < dmin) X dmin = d; X if (d > dmax) X dmax = d; X X obj->b_min.z = dmin; X obj->b_max.z = dmax; X} X X XCone_intersect(obj, ray, inter) XOBJECT *obj; XRAY *ray; XINTERSECT *inter; X{ X RAY tray; X CONE *cd; X VECTOR v, p; X double a, b, c, d, disc; X double t1, t2; X int nroots; X X cd = (CONE *) (obj->obj); X X /* X * First, we get the coordinates of the ray origin in the objects X * space.... X */ X X VecSub(ray->pos, cd->base, v); X X tray.pos.x = VecDot(v, cd->u); X tray.pos.y = VecDot(v, cd->v); X tray.pos.z = VecDot(v, cd->w); X X tray.dir.x = VecDot(ray->dir, cd->u); X tray.dir.y = VecDot(ray->dir, cd->v); X tray.dir.z = VecDot(ray->dir, cd->w); X X X a = tray.dir.x * tray.dir.x X + tray.dir.y * tray.dir.y X - cd->slope * cd->slope * tray.dir.z * tray.dir.z; X X b = 2.0 * (tray.pos.x * tray.dir.x + tray.pos.y * tray.dir.y - X cd->slope * cd->slope * tray.pos.z * tray.dir.z X - cd->base_radius * cd->slope * tray.dir.z); X X c = cd->slope * tray.pos.z + cd->base_radius; X c = tray.pos.x * tray.pos.x + tray.pos.y * tray.pos.y - (c * c); X X disc = b * b - 4.0 * a * c; X X if (disc < 0.0) X return (0); X X disc = sqrt(disc); X t1 = (-b - disc) / (2.0 * a); X t2 = (-b + disc) / (2.0 * a); X X if (t2 < MIN_T) X return (0); X X if (t1 < MIN_T) X { X nroots = 1; X t1 = t2; X } X else X { X nroots = 2; X } X X /* X * ensure that the points are between the two bounding planes... X */ X X switch (nroots) X { X case 1: X VecAddS(t1, ray->dir, ray->pos, p); X d = VecDot(cd->w, p); X X if (d >= cd->min_d && d <= cd->max_d) X { X inter->t = t1; X inter->obj = obj; X inter->inside = 1; X return (1); X } X else X { X return (0); X } X break; X X case 2: X VecAddS(t1, ray->dir, ray->pos, p); X d = VecDot(cd->w, p); X X if (d >= cd->min_d && d <= cd->max_d) X { X inter->t = t1; X inter->obj = obj; X inter->inside = 0; X return (1); X } X else X { X VecAddS(t2, ray->dir, ray->pos, p); X d = VecDot(cd->w, p); X if (d >= cd->min_d && d <= cd->max_d) X { X inter->t = t2; X inter->obj = obj; X inter->inside = 1; X return (1); X } X } X return (0); X } X return (0); X} X X XCone_normal(cone, ray, ip, normal) XCONE *cone; XRAY *ray; XVECTOR *ip; XVECTOR *normal; X{ X VECTOR v; X double t; X X /* X * fill in the real normal... Project the point onto the base plane. X * The normal is a vector from the basepoint through this point, plus X * the slope times the cone_w vector... X */ X X t = -(VecDot(*ip, cone->w) + cone->base_d); X VecAddS(t, cone->w, *ip, v); X VecSub(v, cone->base, *normal); X VecNormalize(normal); X VecAddS(-cone->slope, cone->w, *normal, *normal); X VecNormalize(normal); X if (VecDot(ray->dir, *normal) >= 0) X VecNegate(*normal); X} END_OF_FILE if test 5612 -ne `wc -c <'cone.c'`; then echo shar: \"'cone.c'\" unpacked with wrong size! fi # end of 'cone.c' fi if test -f 'example2.dat' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'example2.dat'\" else echo shar: Extracting \"'example2.dat'\" \(5604 characters\) sed "s/^X//" >'example2.dat' <<'END_OF_FILE' X# Xfrom 2 2 5 Xat 2 2 0 Xup 0 1 0 Xangle 40 Xresolution 512 512 Xbackground .3 .3 .9 n Xlight 6 6 8 Xlight -4 7 8 X# X# Xinstance tile Xpolygon 4 X0 0 0 X0.25 0 0 X0.25 0 0.25 X0 0 0.25 Xpolygon 4 X0.25 0 0.25 X0.50 0 0.25 X0.50 0 0.50 X0.25 0 0.50 Xend_instance X# X# floor X# Xsurface 1 1 1 .9 0 0 0 0 .4 .4 .4 .5 .5 .5 1 1 1 30 0 Xsphere 1.8 2.4 1 0.7 Xsurface 1 1 1 .7 0 0 0 0 .1 .1 .1 .1 .1 .1 1 1 1 30 0 Xcone X3.5 1.5 1 0.3 X2.5 1.5 -0.5 0.3 Xsurface 1 1 1 0.2 1 1 1 0.9 0 0 0 0 0 0 1 1 1 40 1.5 Xsphere 0.8 1.5 1 0.4 X# Xsurface 0 0 0 0 0 0 0 0 0 .4 .4 0 .5 .5 0 0 0 0 0 Xpolygon 4 X-1 0.999 -4 X5 0.999 -4 X5 0.999 4 X-1 0.999 4 Xsurface 0 0 0 0 0 0 0 0 .4 0 0 .55 0 0 0 0 0 0 0 Xinstance_of tile -1 1 -4 Xinstance_of tile -0.5 1 -4 Xinstance_of tile 0 1 -4 Xinstance_of tile 0.5 1 -4 Xinstance_of tile 1 1 -4 Xinstance_of tile 1.5 1 -4 Xinstance_of tile 2 1 -4 Xinstance_of tile 2.5 1 -4 Xinstance_of tile 3 1 -4 Xinstance_of tile 3.5 1 -4 Xinstance_of tile 4 1 -4 Xinstance_of tile 4.5 1 -4 Xinstance_of tile -1 1 -3.5 Xinstance_of tile -0.5 1 -3.5 Xinstance_of tile 0 1 -3.5 Xinstance_of tile 0.5 1 -3.5 Xinstance_of tile 1 1 -3.5 Xinstance_of tile 1.5 1 -3.5 Xinstance_of tile 2 1 -3.5 Xinstance_of tile 2.5 1 -3.5 Xinstance_of tile 3 1 -3.5 Xinstance_of tile 3.5 1 -3.5 Xinstance_of tile 4 1 -3.5 Xinstance_of tile 4.5 1 -3.5 Xinstance_of tile -1 1 -3 Xinstance_of tile -0.5 1 -3 Xinstance_of tile 0 1 -3 Xinstance_of tile 0.5 1 -3 Xinstance_of tile 1 1 -3 Xinstance_of tile 1.5 1 -3 Xinstance_of tile 2 1 -3 Xinstance_of tile 2.5 1 -3 Xinstance_of tile 3 1 -3 Xinstance_of tile 3.5 1 -3 Xinstance_of tile 4 1 -3 Xinstance_of tile 4.5 1 -3 Xinstance_of tile -1 1 -2.5 Xinstance_of tile -0.5 1 -2.5 Xinstance_of tile 0 1 -2.5 Xinstance_of tile 0.5 1 -2.5 Xinstance_of tile 1 1 -2.5 Xinstance_of tile 1.5 1 -2.5 Xinstance_of tile 2 1 -2.5 Xinstance_of tile 2.5 1 -2.5 Xinstance_of tile 3 1 -2.5 Xinstance_of tile 3.5 1 -2.5 Xinstance_of tile 4 1 -2.5 Xinstance_of tile 4.5 1 -2.5 Xinstance_of tile -1 1 -2 Xinstance_of tile -0.5 1 -2 Xinstance_of tile 0 1 -2 Xinstance_of tile 0.5 1 -2 Xinstance_of tile 1 1 -2 Xinstance_of tile 1.5 1 -2 Xinstance_of tile 2 1 -2 Xinstance_of tile 2.5 1 -2 Xinstance_of tile 3 1 -2 Xinstance_of tile 3.5 1 -2 Xinstance_of tile 4 1 -2 Xinstance_of tile 4.5 1 -2 Xinstance_of tile -1 1 -1.5 Xinstance_of tile -0.5 1 -1.5 Xinstance_of tile 0 1 -1.5 Xinstance_of tile 0.5 1 -1.5 Xinstance_of tile 1 1 -1.5 Xinstance_of tile 1.5 1 -1.5 Xinstance_of tile 2 1 -1.5 Xinstance_of tile 2.5 1 -1.5 Xinstance_of tile 3 1 -1.5 Xinstance_of tile 3.5 1 -1.5 Xinstance_of tile 4 1 -1.5 Xinstance_of tile 4.5 1 -1.5 Xinstance_of tile -1 1 -1 Xinstance_of tile -0.5 1 -1 Xinstance_of tile 0 1 -1 Xinstance_of tile 0.5 1 -1 Xinstance_of tile 1 1 -1 Xinstance_of tile 1.5 1 -1 Xinstance_of tile 2 1 -1 Xinstance_of tile 2.5 1 -1 Xinstance_of tile 3 1 -1 Xinstance_of tile 3.5 1 -1 Xinstance_of tile 4 1 -1 Xinstance_of tile 4.5 1 -1 Xinstance_of tile -1 1 -0.5 Xinstance_of tile -0.5 1 -0.5 Xinstance_of tile 0 1 -0.5 Xinstance_of tile 0.5 1 -0.5 Xinstance_of tile 1 1 -0.5 Xinstance_of tile 1.5 1 -0.5 Xinstance_of tile 2 1 -0.5 Xinstance_of tile 2.5 1 -0.5 Xinstance_of tile 3 1 -0.5 Xinstance_of tile 3.5 1 -0.5 Xinstance_of tile 4 1 -0.5 Xinstance_of tile 4.5 1 -0.5 Xinstance_of tile -1 1 0 Xinstance_of tile -0.5 1 0 Xinstance_of tile 0 1 0 Xinstance_of tile 0.5 1 0 Xinstance_of tile 1 1 0 Xinstance_of tile 1.5 1 0 Xinstance_of tile 2 1 0 Xinstance_of tile 2.5 1 0 Xinstance_of tile 3 1 0 Xinstance_of tile 3.5 1 0 Xinstance_of tile 4 1 0 Xinstance_of tile 4.5 1 0 Xinstance_of tile -1 1 0.5 Xinstance_of tile -0.5 1 0.5 Xinstance_of tile 0 1 0.5 Xinstance_of tile 0.5 1 0.5 Xinstance_of tile 1 1 0.5 Xinstance_of tile 1.5 1 0.5 Xinstance_of tile 2 1 0.5 Xinstance_of tile 2.5 1 0.5 Xinstance_of tile 3 1 0.5 Xinstance_of tile 3.5 1 0.5 Xinstance_of tile 4 1 0.5 Xinstance_of tile 4.5 1 0.5 Xinstance_of tile -1 1 1 Xinstance_of tile -0.5 1 1 Xinstance_of tile 0 1 1 Xinstance_of tile 0.5 1 1 Xinstance_of tile 1 1 1 Xinstance_of tile 1.5 1 1 Xinstance_of tile 2 1 1 Xinstance_of tile 2.5 1 1 Xinstance_of tile 3 1 1 Xinstance_of tile 3.5 1 1 Xinstance_of tile 4 1 1 Xinstance_of tile 4.5 1 1 Xinstance_of tile -1 1 1.5 Xinstance_of tile -0.5 1 1.5 Xinstance_of tile 0 1 1.5 Xinstance_of tile 0.5 1 1.5 Xinstance_of tile 1 1 1.5 Xinstance_of tile 1.5 1 1.5 Xinstance_of tile 2 1 1.5 Xinstance_of tile 2.5 1 1.5 Xinstance_of tile 3 1 1.5 Xinstance_of tile 3.5 1 1.5 Xinstance_of tile 4 1 1.5 Xinstance_of tile 4.5 1 1.5 Xinstance_of tile -1 1 2 Xinstance_of tile -0.5 1 2 Xinstance_of tile 0 1 2 Xinstance_of tile 0.5 1 2 Xinstance_of tile 1 1 2 Xinstance_of tile 1.5 1 2 Xinstance_of tile 2 1 2 Xinstance_of tile 2.5 1 2 Xinstance_of tile 3 1 2 Xinstance_of tile 3.5 1 2 Xinstance_of tile 4 1 2 Xinstance_of tile 4.5 1 2 Xinstance_of tile -1 1 2.5 Xinstance_of tile -0.5 1 2.5 Xinstance_of tile 0 1 2.5 Xinstance_of tile 0.5 1 2.5 Xinstance_of tile 1 1 2.5 Xinstance_of tile 1.5 1 2.5 Xinstance_of tile 2 1 2.5 Xinstance_of tile 2.5 1 2.5 Xinstance_of tile 3 1 2.5 Xinstance_of tile 3.5 1 2.5 Xinstance_of tile 4 1 2.5 Xinstance_of tile 4.5 1 2.5 Xinstance_of tile -1 1 3 Xinstance_of tile -0.5 1 3 Xinstance_of tile 0 1 3 Xinstance_of tile 0.5 1 3 Xinstance_of tile 1 1 3 Xinstance_of tile 1.5 1 3 Xinstance_of tile 2 1 3 Xinstance_of tile 2.5 1 3 Xinstance_of tile 3 1 3 Xinstance_of tile 3.5 1 3 Xinstance_of tile 4 1 3 Xinstance_of tile 4.5 1 3 Xinstance_of tile -1 1 3.5 Xinstance_of tile -0.5 1 3.5 Xinstance_of tile 0 1 3.5 Xinstance_of tile 0.5 1 3.5 Xinstance_of tile 1 1 3.5 Xinstance_of tile 1.5 1 3.5 Xinstance_of tile 2 1 3.5 Xinstance_of tile 2.5 1 3.5 Xinstance_of tile 3 1 3.5 Xinstance_of tile 3.5 1 3.5 Xinstance_of tile 4 1 3.5 Xinstance_of tile 4.5 1 3.5 END_OF_FILE if test 5604 -ne `wc -c <'example2.dat'`; then echo shar: \"'example2.dat'\" unpacked with wrong size! fi # end of 'example2.dat' fi if test -f 'nff.y' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nff.y'\" else echo shar: Extracting \"'nff.y'\" \(9364 characters\) sed "s/^X//" >'nff.y' <<'END_OF_FILE' X%{ X#include X#include X Xtypedef double Flt ; Xtypedef Flt Vec[3] ; Xtypedef Vec Point ; Xtypedef Vec Color ; X Xchar *Progname; Xint yylinecount = 1; Xextern char yytext[] ; Xextern FILE * yyin ; XVec * pl, * plist ; X%} X X%token VIEWPOINT FROM AT UP ANGLE HITHER RESOLUTION LIGHT X%token BACKGROUND SURFACE CONE SPHERE POLYGON PATCH NUM TOKEN X X%union { X Vec vec ; X Vec * vecl ; X double flt ; X} ; X X%type point primcolor TOKEN X%type cone sphere polygon ppatch X%type num X X%% X Xscene: X camera elementlist ; X Xelementlist: X elementlist element X | ; X Xelement: X light X | background X | surface X | object ; X Xobject: cone X | sphere X | polygon X | ppatch ; X Xcamera: X VIEWPOINT /* $1 */ X FROM point /* $2-$3 */ X AT point /* $4-$5 */ X UP point /* $6-$7 */ X ANGLE num /* $8-$9 */ X HITHER num /* $10-$11 */ X RESOLUTION num num /* $12-$14 */ X { X printf("from %g %g %g\n", $3[0], $3[1], $3[2]); X printf("at %g %g %g\n", $5[0], $5[1], $5[2]); X printf("up %g %g %g\n", $7[0], $7[1], $7[2]); X printf("angle %g\n", $11); X printf("resolution %d %d\n", (int) $13, (int) $14); X } ; X Xlight: X LIGHT point X { X printf("light %g %g %g\n", $2[0], $2[1], $2[2]); X } ; X Xbackground: X BACKGROUND primcolor X { X printf("background %g %g %g n\n", $2[0], $2[1], $2[2]); X } ; X Xsurface: X SURFACE primcolor num num num num num X { X printf("surface 1 1 1 %g 1 1 1 %g ", $4, $6); X printf("%g %g %g %g %g %g 1 1 1 %g %g\n", X $2[0] * 0.3, $2[1] * 0.3, $2[2] * 0.3, X $2[0] * 0.7, $2[1] * 0.7, $2[2] * 0.7, X $5, $7); X } ; X Xcone: X CONE point num point num X { X printf("cone %g %g %g %g %g %g %g %g\n", X $2[0], $2[1], $2[2], $3, $4[0], $4[1], $4[2], $5); X } ; X Xsphere: X SPHERE point num X { X printf("sphere %g %g %g %g\n", X $2[0], $2[1], $2[2], $3); X } ; X Xpolygon: X POLYGON num X { X printf("polygon %d\n", (int) $2); X } X pointlist X { X X } ; X Xppatch: X PATCH num X { X fprintf(stderr, "%s: sorry, rt doesn't support polygon patches.\n", X Progname); X } ; X Xprimcolor: X num num num X { X $$[0] = $1 ; X $$[1] = $2 ; X $$[2] = $3 ; X } X | TOKEN X { X char buf[80] ; X X if (LookupColorByName(yytext, $$) == 0) { X sprintf(buf, "cannot find color \"%s\"\n", X yytext) ; X yyerror(buf) ; X } X } ; X X Xpoint: X num num num X { X $$[0] = $1 ; X $$[1] = $2 ; X $$[2] = $3 ; X } ; X Xpointlist: X pointlist point X { X printf("%g %g %g\n", $2[0], $2[1], $2[2]); X } X | ; X X Xnum: X NUM X { X $$ = atof(yytext) ; X } ; X X%% X Xyyerror(str) X char * str ; X{ X fprintf(stderr, "%s: error at line %d\n", X Progname, yylinecount) ; X fprintf(stderr, "%s: %s\n", Progname, str) ; X exit(-1) ; X} X X Xmain(argc, argv) X int argc; X char *argv[] ; X{ X Progname = argv[0]; X X yyin = stdin ; X if (yyparse() == 1) { X fprintf(stderr, "%s: invalid input specification\n", Progname); X exit(-1) ; X } X} X X X#define NCOLORS (142) X Xtypedef struct t_color_entry { X char * ce_name ; X Vec ce_color ; X} ColorEntry ; X X#define LESS_THAN -1 X#define GREATER_THAN 1 X#define EQUAL_TO 0 X X/* X * Note: These colors must be in sorted order, because we binary search X * for them. X * X * They were swiped from the X-11 distribution. Sorry.... X */ X XColorEntry Colors[] = { X "Aquamarine", {.439216, .858824, .576471}, X "Black", {0, 0, 0}, X "Blue", {0, 0, 1}, X "BlueViolet", {.623529, .372549, .623529}, X "Brown", {.647059, .164706, .164706}, X "CadetBlue", {.372549, .623529, .623529}, X "Coral", {1, .498039, 0}, X "CornflowerBlue", {.258824, .258824, .435294}, X "Cyan", {0, 1, 1}, X "DarkGreen", {.184314, .309804, .184314}, X "DarkOliveGreen", {.309804, .309804, .184314}, X "DarkOrchid", {.6, .196078, .8}, X "DarkSlateBlue", {.419608, .137255, .556863}, X "DarkSlateGray", {.184314, .309804, .309804}, X "DarkSlateGrey", {.184314, .309804, .309804}, X "DarkTurquoise", {.439216, .576471, .858824}, X "DimGray", {.329412, .329412, .329412}, X "DimGrey", {.329412, .329412, .329412}, X "Firebrick", {.556863, .137255, .137255}, X "ForestGreen", {.137255, .556863, .137255}, X "Gold", {.8, .498039, .196078}, X "Goldenrod", {.858824, .858824, .439216}, X "Gray", {.752941, .752941, .752941}, X "Green", {0, 1, 0}, X "GreenYellow", {.576471, .858824, .439216}, X "Grey", {.752941, .752941, .752941}, X "IndianRed", {.309804, .184314, .184314}, X "Khaki", {.623529, .623529, .372549}, X "LightBlue", {.74902, .847059, .847059}, X "LightGray", {.658824, .658824, .658824}, X "LightGrey", {.658824, .658824, .658824}, X "LightSteelBlue", {.560784, .560784, .737255}, X "LimeGreen", {.196078, .8, .196078}, X "Magenta", {1, 0, 1}, X "Maroon", {.556863, .137255, .419608}, X "MediumAquamarine", {.196078, .8, .6}, X "MediumBlue", {.196078, .196078, .8}, X "MediumForestGreen", {.419608, .556863, .137255}, X "MediumGoldenrod", {.917647, .917647, .678431}, X "MediumOrchid", {.576471, .439216, .858824}, X "MediumSeaGreen", {.258824, .435294, .258824}, X "MediumSlateBlue", {.498039, 0, 1}, X "MediumSpringGreen", {.498039, 1, 0}, X "MediumTurquoise", {.439216, .858824, .858824}, X "MediumVioletRed", {.858824, .439216, .576471}, X "MidnightBlue", {.184314, .184314, .309804}, X "Navy", {.137255, .137255, .556863}, X "NavyBlue", {.137255, .137255, .556863}, X "Orange", {.8, .196078, .196078}, X "OrangeRed", {1, 0, .498039}, X "Orchid", {.858824, .439216, .858824}, X "PaleGreen", {.560784, .737255, .560784}, X "Pink", {.737255, .560784, .560784}, X "Plum", {.917647, .678431, .917647}, X "Red", {1, 0, 0}, X "Salmon", {.435294, .258824, .258824}, X "SeaGreen", {.137255, .556863, .419608}, X "Sienna", {.556863, .419608, .137255}, X "SkyBlue", {.196078, .6, .8}, X "SlateBlue", {0, .498039, 1}, X "SpringGreen", {0, 1, .498039}, X "SteelBlue", {.137255, .419608, .556863}, X "Tan", {.858824, .576471, .439216}, X "Thistle", {.847059, .74902, .847059}, X "Turquoise", {.678431, .917647, .917647}, X "Violet", {.309804, .184314, .309804}, X "VioletRed", {.8, .196078, .6}, X "Wheat", {.847059, .847059, .74902}, X "White", {.988235, .988235, .988235}, X "Yellow", {1, 1, 0}, X "YellowGreen", {.6, .8, .196078}, X "aquamarine", {.439216, .858824, .576471}, X "black", {0, 0, 0}, X "blue", {0, 0, 1}, X "blue_violet", {.623529, .372549, .623529}, X "brown", {.647059, .164706, .164706}, X "cadet_blue", {.372549, .623529, .623529}, X "coral", {1, .498039, 0}, X "cornflower_blue", {.258824, .258824, .435294}, X "cyan", {0, 1, 1}, X "dark_green", {.184314, .309804, .184314}, X "dark_olive_green", {.309804, .309804, .184314}, X "dark_orchid", {.6, .196078, .8}, X "dark_slate_blue", {.419608, .137255, .556863}, X "dark_slate_gray", {.184314, .309804, .309804}, X "dark_slate_grey", {.184314, .309804, .309804}, X "dark_turquoise", {.439216, .576471, .858824}, X "dim_gray", {.329412, .329412, .329412}, X "dim_grey", {.329412, .329412, .329412}, X "firebrick", {.556863, .137255, .137255}, X "forest_green", {.137255, .556863, .137255}, X "gold", {.8, .498039, .196078}, X "goldenrod", {.858824, .858824, .439216}, X "gray", {.752941, .752941, .752941}, X "green", {0, 1, 0}, X "green_yellow", {.576471, .858824, .439216}, X "grey", {.752941, .752941, .752941}, X "indian_red", {.309804, .184314, .184314}, X "khaki", {.623529, .623529, .372549}, X "light_blue", {.74902, .847059, .847059}, X "light_gray", {.658824, .658824, .658824}, X "light_grey", {.658824, .658824, .658824}, X "light_steel_blue", {.560784, .560784, .737255}, X "lime_green", {.196078, .8, .196078}, X "magenta", {1, 0, 1}, X "maroon", {.556863, .137255, .419608}, X "medium_aquamarine", {.196078, .8, .6}, X "medium_blue", {.196078, .196078, .8}, X "medium_forest_green", {.419608, .556863, .137255}, X "medium_goldenrod", {.917647, .917647, .678431}, X "medium_orchid", {.576471, .439216, .858824}, X "medium_sea_green", {.258824, .435294, .258824}, X "medium_slate_blue", {.498039, 0, 1}, X "medium_spring_green", {.498039, 1, 0}, X "medium_turquoise", {.439216, .858824, .858824}, X "medium_violet_red", {.858824, .439216, .576471}, X "midnight_blue", {.184314, .184314, .309804}, X "navy", {.137255, .137255, .556863}, X "navy_blue", {.137255, .137255, .556863}, X "orange", {.8, .196078, .196078}, X "orange_red", {1, 0, .498039}, X "orchid", {.858824, .439216, .858824}, X "pale_green", {.560784, .737255, .560784}, X "pink", {.737255, .560784, .560784}, X "plum", {.917647, .678431, .917647}, X "red", {1, 0, 0}, X "salmon", {.435294, .258824, .258824}, X "sea_green", {.137255, .556863, .419608}, X "sienna", {.556863, .419608, .137255}, X "sky_blue", {.196078, .6, .8}, X "slate_blue", {0, .498039, 1}, X "spring_green", {0, 1, .498039}, X "steel_blue", {.137255, .419608, .556863}, X "tan", {.858824, .576471, .439216}, X "thistle", {.847059, .74902, .847059}, X "turquoise", {.678431, .917647, .917647}, X "violet", {.309804, .184314, .309804}, X "violet_red", {.8, .196078, .6}, X "wheat", {.847059, .847059, .74902}, X "white", {.988235, .988235, .988235}, X "yellow", {1, 1, 0}, X "yellow_green", {.6, .8, .196078} X} ; X Xint XLookupColorByName(name, color) X char * name ; X Vec color ; X{ X int rc ; X rc = BinarySearch(name, 0, NCOLORS - 1 , Colors) ; X if (rc < 0) { X return(0) ; X } X X color[0] = Colors[rc].ce_color[0]; X color[1] = Colors[rc].ce_color[1]; X color[2] = Colors[rc].ce_color[2]; X return 1 ; X} X X Xint XBinarySearch(name, l, h, array) X char * name ; X int l, h ; X ColorEntry array[] ; X{ X int m, rc ; X if (l > h) X return(-1) ; X X m = (l + h) / 2 ; X X rc = strcmp(name, array[m].ce_name) ; X if (rc == 0) X return m ; X else if (rc < 0) X return BinarySearch(name, l, m-1, array) ; X else X return BinarySearch(name, m + 1, h, array) ; X} END_OF_FILE if test 9364 -ne `wc -c <'nff.y'`; then echo shar: \"'nff.y'\" unpacked with wrong size! fi # end of 'nff.y' fi if test -f 'prt.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'prt.c'\" else echo shar: Extracting \"'prt.c'\" \(10451 characters\) sed "s/^X//" >'prt.c' <<'END_OF_FILE' X/* X * prt - Paralel Ray Tracer X * X * Copyright (C) 1990, Kory Hamzeh. X * X * This program acts as a front-end to 'rt'. It takes the user given list X * of hostnames, and using rsh, it spawns off copys of rt running on different X * machines. It will gather up the image fragments that each sub-process sends X * it, and builds one final image. The usage syntax is as follows: X * X * prt input-file output-file host [host ... ] X */ X X#include X#include X#include X#include X#include X X#define MAX_HOSTS 64 X Xtypedef struct rt_info { X char hostname[32]; X int pid; X int cur_bytes; X int tot_bytes; X int offset; X int bld_offset; X long time_st; X long time_en; X int out_pipe[2]; X int err_pipe[2]; X } RT_INFO; X XRT_INFO rt_tab[MAX_HOSTS]; X Xint num_hosts = 0; Xint tot_bytes = 0; Xint cur_bytes = 0; Xint percent_done = 0; Xint verbose = 0; Xint in_file[64]; Xint out_file[64]; XFILE *in_fp; XFILE *out_fp; Xint image_x; Xint image_y; Xchar *image; Xchar *my_name; Xfd_set work_fds; Xfd_set orig_fds; Xlong time_st; Xlong time_en; Xchar *rt_args[32]; X Xint Dead_baby(); X X/* X** Main startup code. X*/ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i, pix1, pix2; X X time(&time_st); X X my_name = argv[0]; X ++argv; X --argc; X X if(argc < 3) X Usage(); X X /* X ** Check for the verbose option. X */ X X if(!strcmp(argv[0], "-v")) X { X verbose = 1; X ++argv; X --argc; X } X X if(argc < 2) X Usage(); X X rt_args[0] = "rsh"; X rt_args[2] = "rt"; X rt_args[3] = "-z"; X rt_args[4] = "-y"; X X i = 7; X rt_args[i] = NULL; X while(argc > 2 && *argv[0] == '-') X { X rt_args[i] = *argv; X rt_args[i + 1] = NULL; X i++; X ++argv; X --argc; X } X X strcpy(in_file, argv[0]); X ++argv; X --argc; X X strcpy(out_file, argv[0]); X ++argv; X --argc; X X signal(SIGCLD, Dead_baby); X X /* X ** Get the list of hosts from the command line. X */ X X while(argc > 0 && num_hosts < MAX_HOSTS) X { X strcpy(rt_tab[num_hosts].hostname, argv[0]); X X rt_tab[num_hosts].cur_bytes = 0; X rt_tab[num_hosts].tot_bytes = 0; X X ++argv; X --argc; X ++num_hosts; X } X X if(num_hosts == 0) X { X fprintf(stderr, "%s: no host were specified.\n", my_name); X exit(0); X } X X /* X ** Check to see if too many hosts were specified. X */ X X if(num_hosts == MAX_HOSTS) X { X fprintf(stderr, "%s: Too many hosts. Max is %d.\n", X my_name, MAX_HOSTS); X exit(1); X } X X /* X ** Check the image size. X */ X X Get_image_size(); X X if(verbose) X { X fprintf(stderr, "%s: image size is %d x %d\n", X my_name, image_x, image_y); X } X X /* X ** Allocate an image buffer. X */ X X if((image = (char *) malloc(image_x * image_y * 3)) == NULL) X { X fprintf(stderr, "%s: malloc of %d failed.\n", my_name, X image_x, image_y); X exit(1); X } X X /* X ** Open the output file. X */ X X if((out_fp = fopen(out_file, "w")) == NULL) X { X fprintf(stderr, "%s: unable to create file '%s'.\n", my_name, out_file); X exit(1); X } X X /* X ** Calculate the total number of pixels that each sub-process X ** must render. X */ X X pix1 = image_y / num_hosts; X pix2 = image_y % num_hosts; X X for(i = 0; i < num_hosts; i++) X rt_tab[i].tot_bytes = pix1 * (image_x * 3); X X for(i = 0; i < pix2; i++) X rt_tab[i].tot_bytes += image_x * 3; X X /* X ** Calculate the offset into the image buffer which each host X ** will use. X */ X X for(i = 0, pix1 = 0; i < num_hosts; i++, pix1 += rt_tab[i].tot_bytes) X rt_tab[i].offset = rt_tab[i].bld_offset = pix1; X X /* X ** Start the sub-processes. X */ X X Start_tracers(); X X /* X ** Gather bits of image and build one final big image. X */ X X Gather_image(); X X /* X ** Exit and go home. X */ X X time(&time_en); X X if(verbose) X fprintf(stderr, "%s: Total execution time: %02d:%02d.\n", X my_name, (time_en - time_st) / 60, (time_en - time_st) % 60); X X fclose(out_fp); X exit(0); X} X X X/* X** Get_image_size() X** X** Scan the object database looking for the resolution key word to figure X** out how big this image will be. X*/ X XGet_image_size() X{ X int found = 0; X int line = 1; X char buf[512]; X X if((in_fp = fopen(in_file, "r")) == NULL) X { X fprintf(stderr, "%s: unable to open input file '%s'\n", X my_name, in_file); X exit(1); X } X X /* X ** Scan the file looking for 'resolution xxx yyy'. X */ X X while(fgets(buf, sizeof(buf), in_fp)) X { X if(!strncmp(buf, "resolution", 10)) X { X if(sscanf(buf + 10, "%d %d", &image_x, &image_y) != 2) X { X fprintf(stderr, "%s: invalid resolution specified in input file on line %d.\n", my_name, line); X fclose(in_fp); X exit(1); X } X X found = 1; X break; X } X X ++line; X } X X fclose(in_fp); X if(!found) X { X fprintf(stderr, "%s: image resolution not found in file '%s'.\n", X my_name, in_file); X exit(1); X } X} X X/* X** Start_tracers() X** X** This routine is a bit hairy. It creates the input, output, and error X** pipe, and then rsh's rt. X*/ X XStart_tracers() X{ X int rc, h, in_fd, i; X char starty[32], incy[32]; X X X for(h = 0; h < num_hosts; h++) X { X /* First, create the pipe. */ X rc = pipe(rt_tab[h].out_pipe); X rc += pipe(rt_tab[h].err_pipe); X X if(rc != 0) X { X fprintf(stderr, "%s: pipe() failed.\n", my_name); X Kill_tracers(h); X } X X if(verbose) X fprintf(stderr, "%s: starting rt on host %s.\n", my_name, X rt_tab[h].hostname); X /* fork */ X if((rt_tab[h].pid = fork()) < 0) X { X fprintf(stderr, "%s: fork() failed.\n", my_name); X Kill_tracers(h); X } X X if(rt_tab[h].pid > 0) /* parent */ X { X /* Close the write end of the pipes. */ X close(rt_tab[h].out_pipe[1]); X close(rt_tab[h].err_pipe[1]); X /* Set for no delay on read */ X fcntl(rt_tab[h].out_pipe[0], F_SETFL, O_NDELAY); X fcntl(rt_tab[h].err_pipe[0], F_SETFL, O_NDELAY); X /* set the start time */ X time(&rt_tab[h].time_st); X } X else X { X sprintf(starty, "%d", h); X sprintf(incy, "%d", num_hosts); X X /* Close the read end of the pipe */ X close(rt_tab[h].out_pipe[0]); X close(rt_tab[h].err_pipe[0]); X X in_fd = open(in_file, O_RDONLY); X close(0); /* the data file */ X dup(in_fd); X close(1); X dup(rt_tab[h].out_pipe[1]); X X close(2); X dup(rt_tab[h].err_pipe[1]); X X for(i = 3; i < 100; i++) X close(i); X X rt_args[1] = rt_tab[h].hostname; X rt_args[5] = starty; X rt_args[6] = incy; X X /* exec the sucker */ X execvp("rsh", rt_args); X X fprintf(stderr, "%s: rsh on host %s failed.\n", my_name, X rt_tab[h].hostname); X exit(1); X } X } X} X X/* X** Gather_image() X** X** This routine gathers the bits of images flying back from the various X** sub-processes, and build one big final image. X*/ X XGather_image() X{ X int h, width, rc; X extern int errno; X X /* X ** Build fd list for select. X */ X X Build_fd_set(); X X /* X ** Write the image header. X */ X X fprintf(out_fp, "%d %d\n", image_x, image_y); X tot_bytes = image_x * image_y * 3; X cur_bytes = 0; X percent_done = 0; X width = MAX_HOSTS * 2; X X /* X ** Main loop. X */ X X if(verbose) X fprintf(stderr, "%s: %d%% done ", my_name, percent_done); X X while(cur_bytes < tot_bytes) X { X Build_fd_set(); X work_fds = orig_fds; X rc = select(width, &work_fds, NULL, NULL, NULL); X if(rc < 0) X continue; X X for(h = 0; h < num_hosts; h++) X { X if(rt_tab[h].pid == 0) X continue; X X if(FD_ISSET(rt_tab[h].out_pipe[0], &work_fds)) X { X Get_image_frag(h); X FD_CLR(rt_tab[h].out_pipe[0], &work_fds); X } X X if(FD_ISSET(rt_tab[h].err_pipe[0], &work_fds)) X { X Tracer_error_report(h); X FD_CLR(rt_tab[h].err_pipe[0], &work_fds); X } X X } X X if(verbose) X { X if(((cur_bytes * 100) / tot_bytes) != percent_done) X { X percent_done = (cur_bytes * 100) / tot_bytes; X fprintf(stderr, "\r%s: %d%% done ", my_name, X percent_done); X } X } X } X X /* Write out the image */ X Write_image(); X X} X X/* X** Get_image_frag(host) X** X** Get the image fragment which just came form one of the tracers. Just store X** it in the buffer for now, and we'll sort it out later. X*/ X XGet_image_frag(h) Xint h; X{ X int fd, count; X char *p; X extern int errno; X X if(rt_tab[h].pid == 0) X return; X X fd = rt_tab[h].out_pipe[0]; X p = image + rt_tab[h].offset + rt_tab[h].cur_bytes; X X while((count = read(fd, p, image_x * 3)) > 0) X { X p += count; X rt_tab[h].cur_bytes += count; X cur_bytes += count; X if(rt_tab[h].cur_bytes == rt_tab[h].tot_bytes) X { X if(verbose) X Rt_done(h); X rt_tab[h].pid = 0; X return ; X } X } X X if(count == 0 && errno != EWOULDBLOCK && errno != EINTR) X { X rt_tab[h].pid = 0; /* this guy is done */ X if(verbose) X fprintf(stderr, "\n%s: rt on host %s is done.\n", my_name, X rt_tab[h].hostname); X } X X} X X X/* X** Tracer_error_report() X** X** A rt sub-process sent us a message through its stderr pipe. Display the X** message and kill them all. X*/ X XTracer_error_report(h) Xint h; X{ X char ebuf[512]; X int count; X X if(rt_tab[h].pid == 0) X return ; X X count = read(rt_tab[h].err_pipe[0], ebuf, sizeof(ebuf)); X if(count > 0) X { X fprintf(stderr, "\n%s: Error from rt on host %s\007\n", my_name, X rt_tab[h].hostname); X ebuf[count] = 0; X fprintf(stderr, "%s", ebuf); X Kill_tracers(num_hosts); X exit(0); X } X} X X X/* X** Write_image() X** X** Take the image fragments that came back from all of the tracers and X** write one big image. X*/ X XWrite_image() X{ X int h, rs; X char *p; X X if(verbose) X fprintf(stderr, "\n%s: writing image ... ", my_name); X X cur_bytes = 0; X rs = image_x * 3; X h = 0; X X while(cur_bytes < tot_bytes) X { X p = image + rt_tab[h].bld_offset; X fwrite(p, rs, 1, out_fp); X rt_tab[h].bld_offset += rs; X cur_bytes += rs; X X h++; X if(h == num_hosts) X h = 0; X } X X if(verbose) X fprintf(stderr, "\n"); X} X X X/* X** Usage() X** X** Print usage message. X*/ X X XUsage() X{ X fprintf(stderr, "Usage: %s [-v] input-file output-file host [host ..]\n", X my_name); X exit(1); X} X X X/* X** Kill_tracers() X** X*/ X XKill_tracers(count) Xint count; X{ X int h; X X for(h = 0; h < count; h++) X kill(rt_tab[h].pid, 9); /* a sure kill */ X} X X/* X** Dead_baby() X** X** Death of a child signal is vectored here. X*/ X XDead_baby() X{ X int status; X X wait(&status); X signal(SIGCLD, Dead_baby); X} X X/* X** Build_fd_set() - Build an fd_set for select() X*/ X XBuild_fd_set() X{ X int h; X X FD_ZERO(&orig_fds); X X for(h = 0; h < num_hosts; h++) X { X if(rt_tab[h].pid == 0) X continue; X X FD_SET(rt_tab[h].out_pipe[0], &orig_fds); X FD_SET(rt_tab[h].err_pipe[0], &orig_fds); X } X} X X X/* X** Rt_done() X** X** A rt sub-process fisnished, let the user know. X*/ X XRt_done(h) Xint h; X{ X int min, sec; X X time(&rt_tab[h].time_en); X min = (rt_tab[h].time_en - rt_tab[h].time_st) / 60; X sec = (rt_tab[h].time_en - rt_tab[h].time_st) % 60; X X fprintf(stderr, "\n%s: rt on host %s is done. Execution time: %02d:%02d.\n", X my_name, rt_tab[h].hostname, min, sec); X} X END_OF_FILE if test 10451 -ne `wc -c <'prt.c'`; then echo shar: \"'prt.c'\" unpacked with wrong size! fi # end of 'prt.c' fi if test -f 'rt.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rt.h'\" else echo shar: Extracting \"'rt.h'\" \(7836 characters\) sed "s/^X//" >'rt.h' <<'END_OF_FILE' X/* X * rt.h - General information file for rt X * X * Copyright (C) 1990, Kory Hamzeh X */ X X/* X * Define some stuff X */ X X#define MAX_LIGHTS 8 /* maximum number of light sources */ X#define MAX_PRIMS 80000 /* maximum number of primitives */ X#define MAX_INSTANCE 64 /* maximum number of instances */ X#define MAX_TOKENS 17 X#define MIN_T 1e-12 X#define MAX_LEVEL 5 /* maxmimum recursion level */ X#define GROUP_SIZE 4 X#define STACK_SIZE 512 X X/* X * Object types X */ X X#define T_COMPOSITE 0 X#define T_POLYGON 1 X#define T_SPHERE 2 X#define T_HSPHERE 3 X#define T_CONE 4 X#define T_RING 5 X#define T_QUADRIC 6 X X/* X * Instance type flags X */ X X#define I_OBJECT 0 /* object type */ X#define I_SURFACE 1 /* surface properties */ X#define I_LIGHT 2 /* light sources */ X X/* X * Structures X */ X X/* vector */ X Xtypedef struct vector X{ X double x; X double y; X double z; X} VECTOR; X X X/* color pixel info */ X Xtypedef struct color X{ X double r; X double g; X double b; X} COLOR; X X/* surface properties */ X Xtypedef struct surface X{ X double p_reflect; /* percentage of reflection */ X double p_refract; /* percentage of refraction */ X COLOR c_reflect; /* reflect color */ X COLOR c_refract; /* refract color */ X COLOR c_ambient; /* ambient color */ X COLOR c_diffuse; /* diffues color */ X COLOR c_specular; /* specular color */ X double spec_width; /* specular width factor */ X double i_refraction; /* index of refraction */ X double refl_diffuse; /* circle of diffusion in refl. */ X double refr_diffuse; /* circle of diffusion in refr. */ X} SURFACE; X X/* composite (slab) data */ X Xtypedef struct composite X{ X int num; /* number of object in this group */ X struct object *child[GROUP_SIZE]; /* pointer to members */ X} COMPOSITE; X X/* n-point polygon */ X Xtypedef struct polygon X{ X int npoints;/* number of points */ X VECTOR normal; /* surface normal (normalized) */ X double d; /* the D coefficient */ X int p1, p2; /* the dominant normals */ X VECTOR points[1]; /* actual points */ X} POLYGON; X X X/* sphere */ X Xtypedef struct sphere X{ X VECTOR center; /* center of sphere */ X double radius; /* and its radius */ X double radius2;/* radius * radius */ X} SPHERE; X X/* hallow sphere */ X Xtypedef struct hsphere X{ X VECTOR center; /* center of sphere */ X double radius; /* and its radius */ X double radius2;/* radius * radius */ X double i_radius; /* inner_radius = outer - tickness */ X double i_radius2; /* i_radius * i_radius */ X} HSPHERE; X X X/* cone */ X Xtypedef struct cone X{ X VECTOR base; /* center of base */ X double base_radius; /* base radius */ X double base_d; /* base D coefficient */ X VECTOR apex; /* center of apex */ X double apex_radius; /* apex radius */ X VECTOR u; X VECTOR v; X VECTOR w; X double height; /* apex - base */ X double slope; /* slope of the damn thing */ X double min_d; X double max_d; X} CONE; X X/* ring */ X Xtypedef struct ring X{ X VECTOR center; /* center of ring */ X VECTOR point1; /* one point on surface */ X VECTOR point2; /* another point on surface */ X VECTOR normal; /* surface normal */ X double d; /* the D coefficient */ X double o_radius; /* outer radius */ X double i_radius; /* inner radius */ X double o_radius2; /* o_radius * o_radius */ X double i_radius2; /* i_radius * i_radius */ X} RING; X X/* X * General form quadratic data type. X */ X Xtypedef struct quadric X{ X VECTOR loc; /* location of the quadratic */ X VECTOR min; /* minumum extent */ X VECTOR max; /* maximum extent */ X double a, b, c, d, e; /* coefficients a to J follow */ X double f, g, h, i, j; X double a2, b2, c2, d2; /* a2 = A * 2, etc... */ X double f2, g2, i2; X} QUADRIC; X X/* X * The OBJECT data type is built from all of the previous types. X */ X Xtypedef struct object X{ X int type; /* T_* goes here */ X void *obj; /* actually point to type CONE, etc. */ X VECTOR b_min; /* bounding box in values */ X VECTOR b_max; /* bounding box max values */ X int active; /* TRUE if on active hit list */ X SURFACE *surf; /* object surface properties */ X int (*inter) (); /* pointer to intersect routine */ X int (*normal) (); /* pointer to normal routine */ X} OBJECT; X X/* X * This data type contains info about object intersection X */ X Xtypedef struct intersect X{ X OBJECT *obj; /* object that caused the intersect */ X double t; /* distance */ X int inside; /* 1 = ray is inside object */ X} INTERSECT; X X/* X * This date type conatins info about the image and observer. X */ X Xtypedef struct view_info X{ X VECTOR from; /* observer's location */ X VECTOR look_at;/* looking at here */ X VECTOR up; /* which way is up? */ X double angle; /* field of view */ X int x_res; /* x resolution */ X int y_res; /* y res */ X} VIEW_INFO; X X/* X * This data type contains info about background colors and cueing. X */ X Xtypedef struct background X{ X COLOR col; X char cue; X} BACKGROUND; X X/* X * This data type contains info about lights. X */ X Xtypedef struct light X{ X VECTOR pos; /* light position */ X COLOR col; /* color of light */ X double intensity; /* light intensity */ X OBJECT *cache[MAX_LEVEL]; /* shadow cache */ X} LIGHT; X X/* X * This data type contains info about rays. X */ X Xtypedef struct ray X{ X VECTOR pos; /* ray origin */ X VECTOR dir; /* ray direction */ X} RAY; X X/* X * Instance info holder X */ X Xtypedef struct instance X{ X char *name; /* name of instance */ X void *next; /* next object pointer */ X void *data; /* points to object data */ X int type; /* I_* type */ X int subtype;/* T_* type */ X} INSTANCE; X X/* vector math stuff */ X X#define MakeVector(x, y, z, v) (v).x=(x),(v).y=(y),(v).z=(z) X X#define VecNegate(a) {(a).x=0-(a).x;\ X (a).y=0-(a).y;\ X (a).z=0-(a).z;} X X#define VecDot(a,b) ((a).x*(b).x+(a).y*(b).y+(a).z*(b).z) X X#define VecLen(a) (sqrt(VecDot(a,a))) X X#define VecCopy(a,b) {(b).x=(a).x;(b).y=(a).y;(b).z=(a).z;} X X#define VecAdd(a,b,c) {(c).x=(a).x+(b).x;\ X (c).y=(a).y+(b).y;\ X (c).z=(a).z+(b).z;} X X#define VecSub(a,b,c) {(c).x=(a).x-(b).x;\ X (c).y=(a).y-(b).y;\ X (c).z=(a).z-(b).z;} X X#define VecComb(A,a,B,b,c) {(c).x=(A)*(a).x+(B)*(b).x;\ X (c).y=(A)*(a).y+(B)*(b).y;\ X (c).z=(A)*(a).z+(B)*(b).z;} X X#define VecAddS(A,a,b,c) {(c).x=(A)*(a).x+(b).x;\ X (c).y=(A)*(a).y+(b).y;\ X (c).z=(A)*(a).z+(b).z;} X X#define VecSProd(A,a,b) {(b).x=(A)*(a).x;\ X (b).y=(A)*(a).y;\ X (b).z=(A)*(a).z;} X X#define VecCross(a,b,c) {(c).x=(a).y*(b).z-(a).z*(b).y;\ X (c).y=(a).z*(b).x-(a).x*(b).z;\ X (c).z=(a).x*(b).y-(a).y*(b).x;}; X X#define MIN(a, b) ((a) < (b) ? (a) : (b)) X#define MAX(a, b) ((a) > (b) ? (a) : (b)) X Xdouble VecNormalize(); XOBJECT *Pop_object(); X X/* X * This macro returns a random number between 0 and 1.0. It probably is not X * portable!! X */ X X#define RAND() ((double) rand() / 32767.0) END_OF_FILE if test 7836 -ne `wc -c <'rt.h'`; then echo shar: \"'rt.h'\" unpacked with wrong size! fi # end of 'rt.h' fi if test -f 'shade.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'shade.c'\" else echo shar: Extracting \"'shade.c'\" \(5265 characters\) sed "s/^X//" >'shade.c' <<'END_OF_FILE' X/* X * shade.c - This module contains the illumination model. X * X * Copyright (C) 1990, Kory Hamzeh X */ X X#include X#include X X#include "rt.h" X#include "externs.h" X X X XCOLOR Illuminate(), Trace_a_ray(); X X/* X * Illuminate() X * X * Apply the proper illumination model to determine the color of the object at X * the given point. X */ X X XCOLOR XIlluminate(inter, ray, ip, n) XINTERSECT *inter; XRAY *ray; XVECTOR *ip; Xint n; /* Level of recursion */ X{ X COLOR col, c; X OBJECT *obj, *scache; X SURFACE *surf, *surf2; X VECTOR normal, l_dir, h, refl; X INTERSECT test_inter; X RAY ray2; X double t, l_dist, incident, spec; X double n1, n2, intensity; X int in_shadow, l; X X /* X * If the maximum level of recusion has been reached, then return X * peacefully. X */ X X if (n >= MAX_LEVEL) X { X col.r = col.g = col.b = 0; X return (col); X } X X obj = inter->obj; X surf = obj->surf; X t = inter->t; X X /* get the surface normal */ X (*obj->normal) (obj->obj, ray, ip, &normal); X X /* first set the color to ambient color */ X col = surf->c_ambient; X X /* foreach light source */ X for (l = 0; l < nlights; l++) X { X /* X * get the vector from the light source to the intersection X * point X */ X VecSub(lights[l]->pos, *ip, l_dir); X X intensity = lights[l]->intensity; X X /* X * Calculate the angle of incident. X */ X X if (VecDot(normal, l_dir) >= 0) X { X /* X * Test to see if any object is casting a shadow on X * this point by firing a test ray from the light X * source to this spot. If there is a hit and the X * object is not the current object, then a shadow is X * casted. In such a case, we don't need to calculate X * the diffuse color. X */ X X l_dist = VecNormalize(&l_dir); X in_shadow = 0; X if (shadow) X { X ray2.pos = *ip; X ray2.dir = l_dir; X ++n_shadows; X X /* X * If we do have a shadow cache entry for X * this light at this level, try that first. X * If it hits, then a shadow is casted. If it X * doesn't hit, then try all of the other X * primitives. X */ X X if ((scache = lights[l]->cache[n]) != NULL) X { X if ((*scache->inter) (scache, &ray2, &test_inter) && X inter->obj != test_inter.obj && X test_inter.t < l_dist - MIN_T) X { X ++n_shadinter; X continue; X } X } X X if (Intersect(&ray2, &test_inter) && X inter->obj != test_inter.obj && X test_inter.t < l_dist - MIN_T) X { X lights[l]->cache[n] = test_inter.obj; X ++n_shadinter; X continue; X } X else X { X lights[l]->cache[n] = NULL; X } X } X X incident = VecDot(normal, l_dir); X /* calculate the diffuse color */ X col.r += incident * surf->c_diffuse.r * intensity; X col.g += incident * surf->c_diffuse.g * intensity; X col.b += incident * surf->c_diffuse.b * intensity; X X /* X * Add some specular highlights. This is accomplished X * by calculating the angle of reflection and getting X * the dot product of it with the ray direction. X */ X X if (surf->spec_width != 0.0) X { X Reflect(&ray->dir, &normal, &ray2.dir); X spec = pow(VecDot(l_dir, ray2.dir), surf->spec_width); X X col.r += spec * surf->c_specular.r * intensity; X col.g += spec * surf->c_specular.g * intensity; X col.b += spec * surf->c_specular.b * intensity; X } X } X } X X /* X * If reflections are enabled, calculat the reflection color. X */ X X if (reflect && surf->p_reflect != 0.0) X { X ++n_reflect; X ray2.pos = *ip; X Reflect(&ray->dir, &normal, &ray2.dir); X X /* X * Send out reflection ray. X */ X X c = Trace_a_ray(&ray2, n + 1); X col.r += c.r * surf->p_reflect * surf->c_reflect.r; X col.g += c.g * surf->p_reflect * surf->c_reflect.g; X col.b += c.b * surf->p_reflect * surf->c_reflect.b; X } X X /* X * If refraction are enable, calculate the refracted color. X */ X X if (refract && surf->p_refract != 0.0) X { X /* X * determine the this ray is inside or outside the object so X * that we can determine the proper index of refraction to X * use. X */ X X if (inter->inside) X { X n1 = surf->i_refraction; X n2 = 1.0; X } X else X { X n1 = 1.0; X n2 = surf->i_refraction; X } X X ray2.pos = *ip; X if (Refract(n1, n2, &ray->dir, &normal, &ray2.dir)) X { X ++n_refract; X c = Trace_a_ray(&ray2, n + 1); X X col.r += c.r * surf->p_refract * surf->c_refract.r; X col.g += c.g * surf->p_refract * surf->c_refract.g; X col.b += c.b * surf->p_refract * surf->c_refract.b; X } X } X X /* return that color */ X return (col); X X} X X X/* X * Reflect() X * X * Calculate the reflected vector. X */ X XReflect(v, norm, refl) XVECTOR *v; XVECTOR *norm; XVECTOR *refl; X{ X double nl; X X nl = 1 / fabs(VecDot(*v, *norm)); X X VecComb(nl, *v, 2.0, *norm, *refl); X VecNormalize(refl); X} X X/* X * Refract() X * X * Calculate the refraction vector. X */ X XRefract(n1, n2, i, n, r) Xdouble n1; Xdouble n2; XVECTOR *i; XVECTOR *n; XVECTOR *r; X{ X double eta, c1, c2, c3; X X eta = n1 / n2; X c1 = -VecDot(*i, *n); X c2 = 1.0 - eta * eta * (1.0 - (c1 * c1)); X if (c2 < 0.0) X return (0); /* total internal reflection */ X X c3 = (eta * c1) - sqrt(c2); X X VecComb(eta, *i, c3, *n, *r); X return (1); X} END_OF_FILE if test 5265 -ne `wc -c <'shade.c'`; then echo shar: \"'shade.c'\" unpacked with wrong size! fi # end of 'shade.c' fi echo shar: End of archive 2 \(of 3\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 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 -- ------------------------------------------------------------------------------- Kory Hamzeh UUCP: avatar!kory or ..!uunet!avatar!kory INTERNET: kory@avatar.com Brought to you by Super Global Mega Corp .com