v05i046: ray tracing program for 3b1
Sid Grange
sid at chinet.UUCP
Wed Nov 9 13:39:27 AEST 1988
Posting-number: Volume 5, Issue 46
Submitted-by: "Sid Grange" <sid at chinet.UUCP>
Archive-name: tracer
[The author claims that it should be portable to other graphical Un*x systems.
Since I don't have one handy, I've no way to test that. ++bsa]
#! /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 shell archive."
# Contents: Makefile README.DOC README.HAK bdata.i conv.c extern.h
# find.c g_bal.c g_bod.c macros.h refract.c rtd.h shade.c support.c
# tracer.c
# Wrapped by sid at chinet on Mon Feb 8 20:03:07 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(536 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
Xtracer: tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o
X cc tracer.o shade.o find.o support.o refract.o g_bod.o g_bal.o -lm -o tracer
Xfind.o: find.c rtd.h extern.h macros.h
X cc -c find.c
Xshade.o: shade.c rtd.h extern.h macros.h
X cc -c shade.c
Xsupport.o: support.c rtd.h extern.h
X cc -c support.c
Xtracer.o: tracer.c rtd.h bdata.i macros.h
X cc -c tracer.c
Xrefract.o: refract.c rtd.h extern.h macros.h
X cc -c refract.c
Xg_bod.o: g_bod.c extern.h macros.h
X cc -c g_bod.c
Xg_bal.o: g_bal.c extern.h rtd.h
X cc -c g_bal.c
END_OF_Makefile
if test 536 -ne `wc -c <Makefile`; then
echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README.DOC -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README.DOC\"
else
echo shar: Extracting \"README.DOC\" \(2252 characters\)
sed "s/^X//" >README.DOC <<'END_OF_README.DOC'
X
X
X
XTRACER(99) FRITZZ GRAPHICS TRACER(99)
X
X
X
XNAME
X tracer- run a simple ray tracing procedure
X
XSYNOPSIS
X tracer -o [filename] -i [filename] -s <filename> -S<number>
X
XDESCRIPTION
X Tracer is a program developed originally to study how
X ray tracing works, and was later modified to the present state
X to make it more compatible for animated film production.
X
X It is capable of depicting a number of balls (up to 150)
X and a plane that is covered with a tiling of any bitmapped picture.
X
X
XOPTIONS
X -o Chooses the output data file. If no argument is givin, stdout
X is used. If the option is not used the default is data.dis.
X
X -i Chooses the input (ball) data file. If no argument is given, stdin
X is used. If the option is not used the default is bdata.i.
X
X -s Chooses the file containing the tiling bitmap. It requires an
X an argument. If the option is not used the default is pat.def.
X
X -S Chooses contrast of the pattern. 0.0 is no contrast, 1.0 is maximum
X contrast. 1.0 is the default. (useful for fading during animation)
X
XPROGRAM NOTES
X This program generates a file containing a header with x and y sizes,
X followed by the data in 8-bit greyscale, one pixel to a character, in
X scanlines.
X There are two neccessary input files: ball data, and a pattern bitmap.
X The tiling bitmap can be digitized data, it must be in the form of
X scan lines no longer than 512 bytes followed by newlines.
X the ball data is of the following form:
X
X x y z rad ior refract reflect diffuse ambient
X
X on each line where x y & z are the coordinates of the center of
X the ball, rad is the radius of the ball, ior is the index of refraction
X for translucent materials (index of refraction for glass is about 1.5)
X the last four numbers determine how much of each atrribute is used.
X Thus a pure silver ball would have 0.0 1.0 0.0 0.0 as the last numbers,
X and a pure glass ball would have 1.0 0.0 0.0 0.0 .
X
X
XFILES
X ./bdata.i default ball data
X ./pat.def default floor pattern
X ./data.dis default output file
X
XBUGS
X As with any good software, the complexity of this program hides
X all bugs.
X
END_OF_README.DOC
if test 2252 -ne `wc -c <README.DOC`; then
echo shar: \"README.DOC\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README.HAK -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README.HAK\"
else
echo shar: Extracting \"README.HAK\" \(1259 characters\)
sed "s/^X//" >README.HAK <<'END_OF_README.HAK'
X***** A Hackers Guide to Tracer *****
Xtracer consists of a bunch of files containing a program that does
Xray tracing (No shit sherlock).
XThes files are as follows:
Xtracer.c: main() sets up the initial rays and stores values
X in a file. booboo prints an error message and quits.
Xshade.c: shade() calculates the intensity returned by a ray. It is
X recursive, and also makes a call to refract().
Xrefract.c: The most difficult part of the program. This file contains
X refract(), inside(), refk() and getcapt().
X and these do all the refraction calculations.
Xfind.c: contains find(),findo() (for when a ray is inside a ball)
X and shadow() and finds() for shadows.
Xsupport.c: supportive subroutines. right now only contains mt_vec
X as all the others were either discarded or converted to
X macros.
Xg_bal.c g_bal() gets the ball data and points bl[] at them.
Xg_bod.c g_bod() loads the floor pattern into suzie.
X
Xmacros.h contains all the macro definitions. Definitely to be looked at.
Xrtd.h header file containing all the structure definitions.
Xextern.h keeps track of all global variables used through the program.
X
Xbdata.i sample ball data file.
X
Xpat.def \
Xcheck.pat\
Xsusie.pat >- sample pattern files. (susie is not for the purient).
Xship.pat /
X
END_OF_README.HAK
if test 1259 -ne `wc -c <README.HAK`; then
echo shar: \"README.HAK\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f bdata.i -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"bdata.i\"
else
echo shar: Extracting \"bdata.i\" \(213 characters\)
sed "s/^X//" >bdata.i <<'END_OF_bdata.i'
X
X-30.0 10.0 400.0 50.0 0.0 0.0 0.0 0.9 0.1
X210.0 175.0 400.0 50.0 0.0 0.0 0.3 0.6 0.1
X40.0 110.0 450.0 50.0 0.0 0.0 0.6 0.3 0.1
X140.0 65.0 450.0 50.0 0.0 0.0 0.9 0.0 0.1
X
X220.0 70.0 100.0 60.0 1.4 0.9 0.0 0.0 0.1
END_OF_bdata.i
if test 213 -ne `wc -c <bdata.i`; then
echo shar: \"bdata.i\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f conv.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"conv.c\"
else
echo shar: Extracting \"conv.c\" \(824 characters\)
sed "s/^X//" >conv.c <<'END_OF_conv.c'
X#include <stdio.h>
X#include <tam.h>
X#include <fcntl.h>
X
Xextern errno;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X
X{
X char *malloc();
X char *cd,*d;
X short *bm,*c;
X int fd, cont;
X register int a,b;
X
X cont = 60;
X/* if((argc == 2) && (atoi(argv[1]) >1) && (atoi(argv[1]) <100))
X cont = atoi(argv[1]);*/
X
X if ((fd=open(argv[1],O_RDONLY|O_NDELAY))==0) {
X fprintf("couldn't open %s for read\n", argv[1]);
X exit(-1);
X }
X if(lseek(fd,8,0)<0)
X exit(-1);
X cd=malloc(134400);
X if(read(fd,cd,134400)!=134400)
X exit(-1);
X bm=malloc(14974);
X c=bm+7487;
X for(a=287;a>=0;a--) {
X d=a*420+cd;
X for(b=415;b>=0;b--) {
X if(!(b&15))
X c-=1;
X *c=(*c<<1)|(*(d+b)>60);
X }
X }
X cd=bm;
X a = 0;
X while(a++ != 14974)
X fprintf(stdout, "%c", *cd++);
X}
END_OF_conv.c
if test 824 -ne `wc -c <conv.c`; then
echo shar: \"conv.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f extern.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"extern.h\"
else
echo shar: Extracting \"extern.h\" \(130 characters\)
sed "s/^X//" >extern.h <<'END_OF_extern.h'
Xextern double suzie[300][300],sam;
Xextern struct ball *bl[];
Xextern struct sphere ls;
Xextern int level,nob;
Xextern int xsue,ysue;
END_OF_extern.h
if test 130 -ne `wc -c <extern.h`; then
echo shar: \"extern.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f find.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"find.c\"
else
echo shar: Extracting \"find.c\" \(1942 characters\)
sed "s/^X//" >find.c <<'END_OF_find.c'
X#include <math.h>
X#include "rtd.h"
X#include "extern.h"
X#include "macros.h"
X
X
Xdouble findo (m, s) /* finds where a ray inside the ball exits. */
Xstruct mat *m;
Xstruct sphere *s;
X{
X/* foops id the rotated position vector. */
X struct vector foops;
X double t;
X MTV (foops, (*m), s -> cent);
X/* see if it hits the ball (it better)*/
X t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
X if (t > 0)
X t = foops.x + sqrt (t);
X else
X t = 0;
X/* return how far along the ray you were when you hit */
X return (t);
X}
X
Xdouble find (m, s)/* finds whether a ray hits a ball*/
Xstruct mat *m;
Xstruct sphere *s;
X{
X struct vector foops;
X double t;
X MTV (foops, (*m), s -> cent);
X t = s -> rad * s -> rad - foops.y * foops.y - foops.z * foops.z;
X if (t > 0)
X t = foops.x - sqrt (t);
X else
X t = 0;
X return (t);
X}
X
Xdouble finds (m, s)/* finds if a ball is between a point and a
X lightsource. Returns how obscuring the ball is */
Xstruct mat *m;
Xstruct sphere *s;
X{
X struct vector foops;
X double t;
X MTV (foops, (*m), s -> cent);
X t = s -> rad - sqrt (foops.y * foops.y + foops.z * foops.z);
X if (t > 0)
X t = t / foops.x;
X else
X t = 0;
X return (t);
X}
X
X
X
X
Xdouble shadow (p)/* finds if a point is in a shadow, or if it is on edge */
Xstruct vector *p;
X{
X struct mat trans;
X struct sphere ss;
X struct vector d;
X int c,
X i;
X double l,
X k,
X x,
X y,
X z,
X finds ();
X l = 0.0;
X c = -1;
X SV (d, ls.cent, (*p));
X d.l = LEN (d);
X d.xzl = XZL (d);
X mt (&(d), &trans);
X
X for (i = 0; i < nob; i++) {
X ss.rad = bl[i] -> s.rad;
X SV (ss.cent, bl[i] -> s.cent, (*p));
X if ((k = finds (&trans, &ss)) > l) {
X c = i;
X l = k;
X }
X }
X if (c == -1)
X k = 200.0;
X else {
X k = 1.0 - l / ((ls.rad) / (d.l));
X if (k < 0.0)
X k = 0.0;
X k *= 200.0;
X }
X return (k);
X}
END_OF_find.c
if test 1942 -ne `wc -c <find.c`; then
echo shar: \"find.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f g_bal.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"g_bal.c\"
else
echo shar: Extracting \"g_bal.c\" \(652 characters\)
sed "s/^X//" >g_bal.c <<'END_OF_g_bal.c'
X#include <stdio.h>
X#include "rtd.h"
X#include "extern.h"
Xg_bal (df)
XFILE * df;
X{
X int i;
X double x,
X y,
X z,
X r,
X ior,
X rfr,
X rfl,
X dif,
X amb;
X for (i = 0;
X fscanf (df, "%F %F %F %F %F %F %F %F %F",
X &x, &y, &z, &r, &ior, &rfr, &rfl, &dif, &amb) != EOF;
X i++) {
X bl[i] = (struct ball *) malloc (sizeof (struct ball));
X bl[i] -> s.cent.x = x;
X bl[i] -> s.cent.y = y;
X bl[i] -> s.cent.z = z;
X bl[i] -> s.rad = r;
X bl[i] -> ior = ior;
X bl[i] -> rfr = rfr;
X bl[i] -> rfl = rfl;
X bl[i] -> dif = dif;
X bl[i] -> amb = amb;
X }
X return (i);
X}
X
END_OF_g_bal.c
if test 652 -ne `wc -c <g_bal.c`; then
echo shar: \"g_bal.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f g_bod.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"g_bod.c\"
else
echo shar: Extracting \"g_bod.c\" \(595 characters\)
sed "s/^X//" >g_bod.c <<'END_OF_g_bod.c'
X#include <stdio.h>
X#include <math.h>
X#include "extern.h"
X#include "macros.h"
X
X
Xg_bod (f)
XFILE * f;
X{
X int k,
X x;
X double big = 0.0,
X little = HUGE;
X char buf[512];
X
X
X for (ysue = 0;; ysue++) {
X if (fgets (buf, 512, f) == NULL)
X break;
X xsue = strlen (buf) - 1;
X for (x = 0; x < xsue; x++) {
X k = buf[x];
X suzie[x][ysue] = (double) k;
X if (big < k)
X big = k;
X if (little > k)
X little = k;
X }
X }
X big = big - little;
X for (k = 0; k < ysue; k++)
X for (x = 0; x < xsue; x++)
X suzie[x][k] = (suzie[x][k] - little) / big;
X}
END_OF_g_bod.c
if test 595 -ne `wc -c <g_bod.c`; then
echo shar: \"g_bod.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f macros.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"macros.h\"
else
echo shar: Extracting \"macros.h\" \(1116 characters\)
sed "s/^X//" >macros.h <<'END_OF_macros.h'
X/* some of the most important stuff in the program */
X#define DOT(v1,v2) (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z)
X/* returns dot product of two vectors */
X#define LN2(v) (DOT(v,v))
X/* returns the square of the length of a vector */
X#define LEN(v) sqrt(LN2(v))
X/* guess */
X#define XZL(v) sqrt(v.x*v.x+v.z*v.z)
X/* returns the component in the xz plane of a vector */
X#define SCMLT(sc,vct) vct.x*= sc;vct.y*= sc;vct.z*= sc;vct.l*= sc;
X/* multiplies a vetor by a scalar */
X#define MV(a,b,c,v) v.x= a;v.y= b;v.z= c;
X/* makes a vector. wouldn't need this with c++ */
X#define SV(t,u,v) t.x=u.x-v.x;t.y=u.y-v.y;t.z=u.z-v.z;
X/*subtract vector t=u-v */
X#define AV(t,u,v) t.x=u.x+v.x;t.y=u.y+v.y;t.z=u.z+v.z;
X/* add vector t=u+v */
X#define MTV(v1,m,v2) MV(DOT(m.x,v2),DOT(m.y,v2),DOT(m.z,v2),v1)
X/* multiply transpose matrix by vector. v1=m*v2 */
X
X#define LEVEL 5/* levels of recursion */
X#define RLEV 3/*don't want as many inside the ball, takes forever as it is*/
X
X#define XMIN 10.0
X#define XMAX 220.0
X#define YMIN 10.0
X#define YMAX 170.0
X/* window size, virtual units */
X#define SCALE 2.0
X/* maginification factor */
END_OF_macros.h
if test 1116 -ne `wc -c <macros.h`; then
echo shar: \"macros.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f refract.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"refract.c\"
else
echo shar: Extracting \"refract.c\" \(2965 characters\)
sed "s/^X//" >refract.c <<'END_OF_refract.c'
X#include <math.h>
X#include "rtd.h"
X#include "macros.h"
X#include "extern.h"
X
Xint rlev;
Xint refract (r, bll)
Xstruct ray *r;
Xstruct ball *bll;
X{
X struct vector new,
X norm;
X struct mat trans;
X struct ray ir;
X double l,
X refk (), getcapt (), capt, inside ();
X double stupid;
X struct sphere ss;
X
X SV (norm, r -> org, bll -> s.cent);
X norm.l = bll-> s.rad;
X
X capt = getcapt (&norm, &(r -> dir), bll -> ior);
X
X
X/* get the addition factor for the normal for refraction*/
X stupid = refk (&(norm), &(r -> dir), bll -> ior);
X SCMLT (stupid, norm);
X
X AV (ir.dir, r -> dir, norm);
X MV (r -> org.x, r -> org.y, r -> org.z, ir.org);
X
X/* now get it for reflection */
X SV (norm, r -> org, bll -> s.cent);
X norm.l = bll -> s.rad;
X SCMLT (1.0 / norm.l, norm);
X stupid = 2.0 * DOT (norm, r -> dir);
X SCMLT (stupid, norm);
X SV (r -> dir, r -> dir, norm);
X
X return ((int) ((1.0 - capt) * (double) shade (r) + ((capt) * inside (&ir, bll))));
X}
X
Xdouble inside (r, bll)
Xstruct ray *r;
Xstruct ball *bll;
X{
X struct vector new,
X norm;
X struct mat trans;
X struct ray er;
X double findo (), lght, l, refk (), getcapt (), capt;
X double stupid;
X struct sphere ss;
X
X
X if (++rlev < RLEV) {
X r -> dir.l = LEN (r -> dir);
X r -> dir.xzl = XZL (r -> dir);
X mt (&(r -> dir), &trans);
X ss.rad = bll -> s.rad;
X SV (ss.cent, bll -> s.cent, r -> org);
X
X l = findo (&trans, &ss);
X MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
X AV (er.org, r -> org, new);
X AV (r -> org, r -> org, new);
X SV (norm, er.org, bll -> s.cent);
X
X norm.l = bll -> s.rad;
X capt = getcapt (&norm, &(r -> dir), 1.0 / bll -> ior);
X
X stupid = refk (&norm, &(r -> dir), 1.0 / bll -> ior);
X SCMLT (stupid, norm);
X AV (er.dir, norm, r -> dir);
X
X SCMLT (1.0 / norm.l, norm);
X stupid = 2.0 * DOT (norm, r -> dir);
X SCMLT (stupid, norm);
X SV (r -> dir, r -> dir, norm);
X lght = (1.0 - capt) * inside (r, bll) + (capt * (double) shade (&er));
X }
X else
X lght = 0.0;
X rlev--;
X if (lght<0.0) lght=0.0;
X if (lght>255.0) lght=255.0;
X return (lght);
X}
X
X
X
Xdouble refk (nrm, in, ior)
Xstruct vector *nrm,
X *in;
Xdouble ior;
X{
X double dt,
X ln,
X li,
X ret;
X
X ior = ior * ior;
X dt = DOT ((*nrm), (*in));
X ln = LN2 ((*nrm));
X li = LN2 ((*in));
X if (dt < 0)
X ret = (-dt - sqrt (dt * dt - ln * li * (1 - ior))) / ln;
X else
X ret = (-dt + sqrt (dt * dt - ln * li * (1 - ior))) / ln;
X return (ret);
X}
X
Xdouble getcapt (nrm, dr, ior)
Xstruct vector *nrm,
X *dr;
Xdouble ior;
X{
X double dt,
X cs1,
X cs2,
X p,
X s;
X dt = DOT ((*nrm), (*dr));
X dt = dt * dt / LN2 ((*nrm)) / LN2 ((*dr));
X cs1 = sqrt (dt);
X cs2 = sqrt (1.0 - (1.0 - dt) / ior);
X p = cs1 / (cs1 + ior * cs2);
X s = cs1 / (ior * cs1 + cs2);
X return (2.0 * (p * p + s * s));
X}
END_OF_refract.c
if test 2965 -ne `wc -c <refract.c`; then
echo shar: \"refract.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rtd.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"rtd.h\"
else
echo shar: Extracting \"rtd.h\" \(434 characters\)
sed "s/^X//" >rtd.h <<'END_OF_rtd.h'
Xstruct color {
Xint r;int g;int b;};
X
Xstruct vector {
Xdouble x;
Xdouble y;
Xdouble z;
Xdouble l;
Xdouble xzl;} ;
X
Xstruct ray {
Xstruct vector org;
Xstruct vector dir;} ;
X
Xstruct sphere {
Xstruct vector cent;
Xdouble rad;} ;
X
Xstruct ball {
Xstruct sphere s;
Xdouble ior;
Xdouble rfr;
Xdouble rfl;
Xdouble dif;
Xdouble amb;
X};
X
Xstruct mat {
Xstruct vector x; /* first !row! */
Xstruct vector y; /*second !row! */
Xstruct vector z;}; /* third !row! */
X
END_OF_rtd.h
if test 434 -ne `wc -c <rtd.h`; then
echo shar: \"rtd.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f shade.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"shade.c\"
else
echo shar: Extracting \"shade.c\" \(3454 characters\)
sed "s/^X//" >shade.c <<'END_OF_shade.c'
X/*
X * this subroutine does all the gritty work- it calculates
X * what shade each pixel should be. I like recursion.
X */
X#include <math.h>
X#include "rtd.h"
X#include "macros.h"
X#include "extern.h"
X
Xint shade (r)
Xstruct ray *r;
X{
X int i,
X c,
X refract ();
X struct ray refr;
X double lght,
X x,
X y,
X z,
X l,
X k,
X dot (), find (), shadow ();
X int sx,
X sy;
X double stupid;
X struct vector new,
X norm;
X struct mat trans;
X struct sphere ss;
X if (++level <= LEVEL) {
X c = -1;
X l = HUGE;
X/* get vector length and xz component for mt() */
X r -> dir.l = LEN (r -> dir);
X r -> dir.xzl = XZL (r -> dir);
X/* make a transform matrix that rotates something in space so
X that the ray will be aligned with the x axis */
X mt (&(r -> dir), &trans);
X
X/* for starters we find out whether we hit anything. */
X for (i = 0; i < nob; i++) {
X ss.rad = bl[i] -> s.rad;
X SV (ss.cent, bl[i] -> s.cent, r -> org);
X if ((k = find (&trans, &ss)) > 0.0 && k < l) {
X c = i;
X l = k;
X }
X }
X if (c >= 0 && (l * trans.x.y + r -> org.y) > 0.0) {
X /* WE HIT SOMETHING */
X MV (l * trans.x.x, l * trans.x.y, l * trans.x.z, new);
X new.l=l;
X/* move the new orgin of the ray to the intersection */
X AV (refr.org, new, r -> org);
X AV (r -> org, new, r -> org);
X MV (r -> dir.x, r -> dir.y, r -> dir.z, refr.dir);
X/* get a normal vector for the intersection point */
X SV (norm, r -> org, bl[c] -> s.cent);
X norm.l=bl[c] ->s.rad;
X
X/* ambient lighting */
X lght = 200.0 * bl[c] -> amb;
X
X/* shaded lighting (diffuse). subroutine shadow is in find.c */
X if (bl[c] -> dif != 0.0) {
X SV (new, ls.cent, r -> org);
X new.l = LEN(new);
X if ((k = DOT (new, norm)) > 0.0)
X lght += bl[c] -> dif * shadow (&(r -> org)) * k / (new.l) / (norm.l);
X }
X
X/*reflection... easy */
X if (bl[c] -> rfl != 0.0) {
X/* make the normal unit length */
X SCMLT ((1.0 / norm.l), norm);
X/* get the length of the ray's component in the normal direction */
X stupid = 2.0 * DOT (norm, r -> dir);
X SCMLT (stupid, norm);
X/* subtract double the normal component- !reflection! */
X SV (r -> dir, r -> dir, norm);
X lght += bl[c] -> rfl * (double) shade (r);
X }
X
X/* refraction. this is ugly, which is why I choose to deal with
X it in it's own subroutine which comes after this one */
X if (bl[c] -> rfr != 0.0) {
X lght += bl[c] -> rfr * (double) refract (&refr, bl[c]);
X }
X
X
X
X }
X else { /* hit no objects... */
X if ((r -> dir.y) < 0.0) {/* crosses floor */
X z = -(r -> org.y) / (r -> dir.y);
X (r -> org.x) += z * (r -> dir.x);
X (r -> org.z) += z * (r -> dir.z);
X (r -> org.y) = 0.0;
X
X SV (new, ls.cent, r -> org);
X new.l = LEN(new);
X sx = (int) (r -> org.x / 1.5) % xsue;
X if (sx < 0)
X sx += xsue;
X sy = -(int) (r -> org.z / 1.5) % ysue;
X if (sy < 0)
X sy += ysue;
X lght = (sam * suzie[sx][sy] + 1.0 - sam) * (0.8 *
X shadow (&(r -> org)) * (new.y) / (new.l) + 40.0);
X
X
X }
X else { /* check to see if it hit lightsource */
X SV (ss.cent, ls.cent, r -> org);
X ss.rad = ls.rad;
X if (find (&trans, &(ss.cent)) > 0.0)
X lght = 255;
X else
X lght = 0;
X }
X }
X }
X/* to many levels return 0 cause it shouldn't matter */
X else
X lght = 0;
X level--;
X if (lght < 0.0)
X lght = 0.0;
X if (lght > 255.0)
X lght = 255.0;
X return ((int) lght);
X}
END_OF_shade.c
if test 3454 -ne `wc -c <shade.c`; then
echo shar: \"shade.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f support.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"support.c\"
else
echo shar: Extracting \"support.c\" \(834 characters\)
sed "s/^X//" >support.c <<'END_OF_support.c'
X/*
X * supportive subroutines...
X */
X
X#include <math.h>
X#include <stdio.h>
X#include "rtd.h"
X#include "extern.h"
X
X
Xmt (vec, trans)
Xstruct vector *vec;
Xstruct mat *trans;
X{
X if (vec -> xzl == 0.0) {
X trans -> x.x = 0.0;
X trans -> x.y = 1.0;
X trans -> x.z = 0.0;
X trans -> y.x = -1.0;
X trans -> y.y = 0.0;
X trans -> y.z = 0.0;
X trans -> z.x = 0.0;
X trans -> z.y = 0.0;
X trans -> z.z = 1.0;
X }
X else {
X trans -> x.x = (vec -> x) / (vec -> l);
X trans -> x.y = (vec -> y) / (vec -> l);
X trans -> x.z = (vec -> z) / (vec -> l);
X trans -> y.x = -(vec -> x) * (vec -> y) / ((vec -> l) * (vec -> xzl));
X trans -> y.y = (vec -> xzl) / (vec -> l);
X trans -> y.z = -(vec -> z) * (vec -> y) / ((vec -> l) * (vec -> xzl));
X trans -> z.x = -(vec -> z) / (vec -> xzl);
X trans -> z.y = 0;
X trans -> z.z = (vec -> x) / (vec -> xzl);
X }
X}
END_OF_support.c
if test 834 -ne `wc -c <support.c`; then
echo shar: \"support.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tracer.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"tracer.c\"
else
echo shar: Extracting \"tracer.c\" \(2624 characters\)
sed "s/^X//" >tracer.c <<'END_OF_tracer.c'
X
X
X/* tracer version 2.1 */
X#include <stdio.h>
X#include <math.h>
X#include "rtd.h"
X#include "macros.h"
X
X
XFILE * fp;
Xdouble suzie[300][300],
X sam = 1.0;
Xint xsue,
X ysue;
Xstruct ball *bl[150];
Xint level,
X nob;
Xstruct sphere ls;
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X FILE * df, *texfile;
X static double xco,
X yco;
X struct ray rr;
X struct vector vp;
X double x,
X y,
X z;
X int i,
X in = 0,
X out = 0,
X tex = 0;
X int c;
X
X/* command interp */
X
X for (i = 1; i < argc; i++) {
X if (argv[i][0] != '-')
X booboo ("Options strt with a '-' bozo");
X c = argv[i][1];
X
X switch (c) {
X case ('i'):
X if (in)
X booboo ("Sorry, but you may only have one input file");
X in = 1;
X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
X df = stdin;
X else
X if ((df = fopen (argv[++i], "r")) == NULL)
X booboo ("input file not found");
X break;
X case ('o'):
X if (out)
X booboo ("Sorry, but you may have only one output file");
X out = 1;
X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
X fp = stdout;
X else
X fp = fopen (argv[++i], "w");
X break;
X case ('s'):
X if (tex)
X booboo ("Sorry, but you may have only one image file");
X if ((i + 1) >= argc || argv[i + 1][0] == '-')/* no arg */
X booboo ("-s requires an argument");
X tex = 1;
X if ((texfile = fopen (argv[++i], "r")) == NULL)
X booboo ("image file not found");
X break;
X booboo ("this line shouldn't do anything");
X case ('S'):
X if (argv[i][2] < '0' || argv[i][2] > '9'){
Xprintf("%c\n",argv[i][2]);
X booboo ("-S needs a numerical argument");}
X sam = atof (&(argv[i][2]));
X break;
X default:
X booboo ("Unrecognized option. Better try again");
X }
X }
X
X
X if (!in)
X if ((df = fopen ("bdata.i", "r")) == NULL)
X booboo ("bdata.i not found");
X if (!out)
X fp = fopen ("data.dis", "w");
X if (!tex)
X if ((texfile = fopen ("pat.def", "r")) == NULL)
X booboo ("pat.def not found");
X
X
X
X nob = g_bal (df);
X g_bod (texfile);
X
X
X
X MV (95.0, 140.0, -200.0, vp);
X MV (0.0, 900.0, 0.0, ls.cent);
X ls.rad = 40;
X fprintf (fp, "%d %d\n", (int) ((XMAX - XMIN) * SCALE +0.9999999), (int) ((YMAX - YMIN) * SCALE +0.9999999));
X
X for (yco = YMAX * SCALE; yco > YMIN * SCALE; yco--)
X for (xco = XMIN * SCALE; xco < XMAX * SCALE; xco++) {
X MV (xco / SCALE, yco / SCALE, 0.0, rr.org);
X SV (rr.dir, rr.org, vp);
X fprintf (fp, "%c", shade (&rr));
X }
X}
X
Xbooboo (str)
Xchar *str; {
X printf ("%s\n", str);
X exit (-1);
X}
END_OF_tracer.c
if test 2624 -ne `wc -c <tracer.c`; then
echo shar: \"tracer.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
More information about the Comp.sources.misc
mailing list