home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-07-21 | 51.8 KB | 2,100 lines |
- Newsgroups: comp.sources.misc
- From: Rayshade Construction Co. <rayshade@weedeater.math.YALE.EDU>
- Subject: v21i011: rayshade - A raytracing package for UNIX, Part08/19
- Message-ID: <1991Jul21.033530.28980@sparky.IMD.Sterling.COM>
- X-Md4-Signature: 1ec025725cfa48faa06a8a934d79ef56
- Date: Sun, 21 Jul 1991 03:35:30 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Rayshade Construction Co. <rayshade@weedeater.math.YALE.EDU>
- Posting-number: Volume 21, Issue 11
- Archive-name: rayshade/part08
- Environment: UNIX, !16BIT
-
- #! /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 8 (of 19)."
- # Contents: Doc/Guide/animate.tex etc/rsconvert/lex.l
- # libray/libobj/cylinder.c libray/libobj/disc.c
- # libray/libobj/roots.c libray/libobj/sphere.c
- # libray/libsurf/surfshade.c libray/libtext/texture.c
- # libshade/misc.c libshade/stats.c
- # Wrapped by kolb@woody on Wed Jul 17 17:56:47 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Doc/Guide/animate.tex' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Doc/Guide/animate.tex'\"
- else
- echo shar: Extracting \"'Doc/Guide/animate.tex'\" \(4147 characters\)
- sed "s/^X//" >'Doc/Guide/animate.tex' <<'END_OF_FILE'
- X\chapter{Animation}
- X
- X\Rayshade provides basic animation animation support by
- Xallowing time-varying
- Xtransformations to be associated with primitives and aggregate objects.
- XCommands are provided for controlling the amount of time between each
- Xframe, the speed of the camera shutter, and the total number of frames
- Xto be rendered.
- X
- XBy default, rayshade renders a single frame, with the shutter open for
- Xan instant (0 units of time, in fact). The shutter speed in no way
- Xchanges the light-gathering properties of the camera, i.e. frames
- Xrendered using
- Xa longer exposure will not appear brighter than those with a shorter
- Xexposure. The only change will be in the potential amount of movement
- Xthat the
- Xframe ``sees'' during the time that the shutter is open.
- X
- XEach ray cast by \rayshade samples a particular moment in time.
- XThe time value assigned to a ray
- Xranges from the starting time of the current frame to the starting
- Xtime plus the amount of time the shutter is open. When
- Xa ray encounters an object or texture that possesses an animated
- Xtransformation, the transformed
- Xentity is moved into whatever position is appropriate
- Xfor the ray's current time value before intersection, shading, or texturing
- Xcomputations are performed.
- X
- XThe starting time of the current frame is computed using the
- Xlength of each frame
- Xthe current frame number, and the starting time of the first frame.
- X
- X\begin{defkey}{shutter}{{\em t}}
- X Specifies that the shutter is open for t units of
- X time for each exposure.
- X\end{defkey}
- XA larger value of {\em t} will lead to more motion blur in the final
- Ximage. Note that {\em t} may be greater than the actual length
- Xof a frame. By default, {\em t} is zero, which prevents all motion blur.
- X
- X\begin{defkey}{framelength}{{\em frameinc}}
- X Specifies the time increment between frames.
- X\end{defkey}
- XThe default time between frames is 1 unit.
- X
- X\begin{defkey}{starttime}{{\em time}}
- X Specifies the starting time of the first frame.
- X\end{defkey}
- XBy default, {\em time} is zero.
- X
- XVariables may be defined thorugh the use of the {\tt define} keyword:
- X
- X\begin{defkey}{define}{{\em name value}}
- X Associate {\em name} with the given {\em value}. Value may
- X be a constant or a parenthesized expression.
- X\end{defkey}
- XThe variable {\em name} may thereafter be used in expressions in the
- Xinput file.
- X
- XAn animated transformation is one for which animated expressions have
- Xbeen used to define one or more of its parameters (e.g. the angle through
- Xwhich a rotation occurs). An animated expression is one that makes
- Xuse of a time-varying (``animated'') variable or function.
- X
- XThere are two supported animated variables.
- XThe first, {\tt time}, is equal to the current time.
- XWhen a ray encounters an animated
- Xtransformation defined using an expression containing {\tt time}, the ray
- Xsubstitutes its time value into the expression before evaluation.
- XUsing the {\tt time} variable in an animated expression is the most
- Xbasic way to create blur-causing motion.
- X
- XThe second animated variable, {\tt frame}, is equal to the current
- Xframe number. Unlike the {\tt time} variable, {\tt frame} takes on
- Xa single value for the duration of each frame. Thus, transforms
- Xanimated through the use of the {\tt frame} variable will not exhibit
- Xmotion blurring.
- X
- XAlso supported is the {\tt linear} function. This function uses
- X{\tt time} implicitly to interplate between two values.
- X
- X\begin{defkey}{linear}{{\tt (} {\em Stime, Sval, Etime, Eval} {\tt )}}
- X Linearly interpolate between {\em Sval} at time
- X {\em Stime} and {\em Eval} at time {\em Etime}.
- X If the current time is less than {\em Stime}, the function
- X returns {\em Sval}. If the current time is greater than
- X {\em Etime}, {\em Eval} is returned.
- X\end{defkey}
- X
- XThe following example shows the use of the {\tt time} variable to
- Xanimate a sphere by translating it downwards over five frames.
- XNote thet the {\tt shutter} keyword is used to set the shutter duration
- Xin order to induce motion blurring.
- X
- X\begin{verbatim}
- X frames 5
- X shutter 1
- X sphere 1 0 0 2 translate 0 0 (-time)
- X\end{verbatim}
- X
- XFurther examples of animation may be found in the Examples directory
- Xof the \rayshade distribution.
- END_OF_FILE
- if test 4147 -ne `wc -c <'Doc/Guide/animate.tex'`; then
- echo shar: \"'Doc/Guide/animate.tex'\" unpacked with wrong size!
- fi
- # end of 'Doc/Guide/animate.tex'
- fi
- if test -f 'etc/rsconvert/lex.l' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'etc/rsconvert/lex.l'\"
- else
- echo shar: Extracting \"'etc/rsconvert/lex.l'\" \(4148 characters\)
- sed "s/^X//" >'etc/rsconvert/lex.l' <<'END_OF_FILE'
- X/* lex.l */
- X/* Copyright (C) 1989, 1991, Craig E. Kolb */
- X/* All rights reserved. */
- X/* */
- X/* This software may be freely copied, modified, and redistributed, */
- X/* provided that this copyright notice is preserved on all copies. */
- X/* */
- X/* You may not distribute this software, in whole or in part, as part of */
- X/* any commercial product without the express consent of the authors. */
- X/* */
- X/* There is no warranty or other guarantee of fitness of this software */
- X/* for any purpose. It is provided solely "as is". */
- X/* $Id: lex.l,v 4.0 91/07/17 14:29:16 kolb Exp Locker: kolb $ */
- X%{
- X#include "config.h"
- X#include <stdio.h>
- X#ifdef I_STRING
- X#include <string.h>
- X#else
- X#include <strings.h>
- X#endif
- X#include "libcommon/common.h"
- X#include "y.tab.h"
- X%}
- Xalpha [a-zA-Z]
- Xspecial [\.\_-]
- Xdigit [0-9]
- Xexp [Ee][-+]?{digit}+
- Xstring ({alpha}|"/")({alpha}|{digit}|{special}|"/")*
- X%p 3000
- X%%
- X[\t\n] {WriteVerbatim(yytext);};
- X" " {};
- X^# {handlehash();}
- X"/*" {skipcomments();}
- Xadaptive {return(tADAPTIVE);}
- Xaperture {return(tAPERTURE);}
- Xbackground {return(tBACKGROUND);}
- Xblotch {return(tBLOTCH);}
- Xbox {return(tBOX);}
- Xbump {return(tBUMP);}
- Xchecker {return(tCHECKER);}
- Xcone {return(tCONE);}
- Xcontrast {return(tCONTRAST);}
- Xcutoff {return(tCUTOFF);}
- Xcylinder {return(tCYL);}
- Xdefend {return(tENDDEF);}
- Xdefine {return(tSTARTDEF);}
- Xdirectional {return(tDIRECTIONAL);}
- Xendfile {return(tENDFILE);}
- Xextended {return(tEXTENDED);}
- Xeyep {return(tEYEP);}
- Xfbm {return(tFBM);}
- Xfbmbump {return(tFBMBUMP);}
- Xfocaldist {return(tFOCALDIST);}
- Xfog {return(tFOG);}
- Xfov {return(tFOV);}
- Xgloss {return(tGLOSS);}
- Xgrid {return(tGRID);}
- Xheightfield {return(tHEIGHTFIELD);}
- Xjittered {return(tJITTERED);}
- Xlight {return(tLIGHT);}
- Xlist {return(tLIST);}
- Xlookp {return(tLOOKP);}
- Xmarble {return(tMARBLE);}
- Xmaxdepth {return(tMAXDEPTH);}
- Xmist {return(tMIST);}
- Xobject {return(tOBJECT);}
- Xoutfile {return(tOUTFILE);}
- Xplane {return(tPLANE);}
- Xpoint {return(tPOINT);}
- Xpoly {return(tPOLY);}
- Xresolution {return(tRESOLUTION);}
- Xrotate {return(tROTATE);}
- Xsamples {return(tSAMPLES);}
- Xscale {return(tSCALE);}
- Xscreen {return(tSCREEN);}
- Xsphere {return(tSPHERE);}
- Xsuperq {return(tSUPERQ);}
- Xsurface {return(tSURFACE);}
- Xtexture {return(tTEXTURE);}
- Xtransform {return(tTRANSFORM);}
- Xtranslate {return(tTRANSLATE);}
- Xtriangle {return(tTRIANGLE);}
- Xup {return(tUP);}
- Xwood {return(tWOOD);}
- X{string} {yylval.c = strsave(yytext);
- X return(tSTRING);}
- X[+-]?{digit}+ {yylval.i = atoi(yytext);
- X return(tINT);}
- X
- X[+-]?{digit}+"."{digit}*({exp})? |
- X[+-]?{digit}*"."{digit}+({exp})? |
- X[+-]?{digit}+{exp} {yylval.d = atof(yytext); return(tFLOAT);}
- X
- X. {return yytext[0];}
- X
- X%%
- Xyywrap() {return(1);}
- X/*
- X * Skip over comments.
- X */
- Xskipcomments()
- X{
- X char c;
- X
- X WriteVerbatim("/*");
- X while (1) {
- X while ((c = input()) != '*')
- X WriteChar(c);
- X WriteChar(c);
- X if ((c = input()) == '/') {
- X WriteChar(c);
- X return;
- X }
- X unput(c);
- X }
- X}
- X/*
- X * Deal with ccp-produced lines of the form:
- X * # n "filename"
- X * and
- X * # n
- X * Where filename is the name of the file being processed, and n is
- X * the current line number in that file.
- X */
- Xhandlehash()
- X{
- X char buf[BUFSIZ];
- X int i;
- X extern int yylineno;
- X extern char yyfilename[];
- X
- X /*
- X * Read the entire line into buf.
- X */
- X for (i = 0; (buf[i] = input()) != '\n'; i++)
- X ;
- X unput(buf[i]); /* To make sure consecutive # lines work. */
- X buf[i] = (char)NULL; /* Replace newline with NULL. */
- X
- X /*
- X * Check to see if it's #include or
- X * #define.
- X * If so just spit out the line.
- X */
- X if (strncmp("include", buf, 7) == 0 || strncmp("define", buf, 6) == 0) {
- X WriteVerbatim("#");
- X WriteVerbatim(buf);
- X return;
- X }
- X /*
- X * Complain if the line was not of the form #n "filename"
- X */
- X if ((i = sscanf(buf, "%d \"%[^\"]s\"", &yylineno, yyfilename)) == 0) {
- X yyerror("Unknown '#' control.");
- X exit(1);
- X }
- X if (i == 1) {
- X#ifdef SYSV
- X if (strchr(buf, '"') != (char *)0) {
- X#else
- X if (index(buf, '"') != (char *)0) {
- X#endif
- X /*
- X * Filename was "", which means stdin.
- X */
- X strcpy(yyfilename, "stdin");
- X }
- X }
- X}
- END_OF_FILE
- if test 4148 -ne `wc -c <'etc/rsconvert/lex.l'`; then
- echo shar: \"'etc/rsconvert/lex.l'\" unpacked with wrong size!
- fi
- # end of 'etc/rsconvert/lex.l'
- fi
- if test -f 'libray/libobj/cylinder.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libobj/cylinder.c'\"
- else
- echo shar: Extracting \"'libray/libobj/cylinder.c'\" \(4773 characters\)
- sed "s/^X//" >'libray/libobj/cylinder.c' <<'END_OF_FILE'
- X/*
- X * cylinder.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: cylinder.c,v 4.0 91/07/17 14:37:12 kolb Exp Locker: kolb $
- X *
- X * $Log: cylinder.c,v $
- X * Revision 4.0 91/07/17 14:37:12 kolb
- X * Initial version.
- X *
- X */
- X#include "geom.h"
- X#include "cylinder.h"
- X
- Xstatic Methods *iCylinderMethods = NULL;
- Xstatic char cylName[] = "cylinder";
- X
- Xunsigned long CylTests, CylHits;
- X
- XCylinder *
- XCylinderCreate(r, bot, top)
- XFloat r;
- XVector *bot, *top;
- X{
- X Cylinder *cyl;
- X Float len;
- X Vector axis;
- X
- X if (r <= 0.) {
- X RLerror(RL_WARN, "Invalid cylinder radius.\n");
- X return (Cylinder*)NULL;
- X }
- X
- X VecSub(*top, *bot, &axis);
- X
- X len = VecNormalize(&axis);
- X
- X if (len < EPSILON) {
- X RLerror(RL_WARN, "Degenerate cylinder.\n");
- X return (Cylinder *)NULL;
- X }
- X
- X cyl = (Cylinder *)share_malloc(sizeof(Cylinder));
- X CoordSysTransform(bot, &axis, r, len, &cyl->trans);
- X return cyl;
- X}
- X
- XMethods *
- XCylinderMethods()
- X{
- X if (iCylinderMethods == (Methods *)NULL) {
- X iCylinderMethods = MethodsCreate();
- X iCylinderMethods->name = CylinderName;
- X iCylinderMethods->create = (GeomCreateFunc *)CylinderCreate;
- X iCylinderMethods->methods = CylinderMethods;
- X iCylinderMethods->intersect = CylinderIntersect;
- X iCylinderMethods->normal = CylinderNormal;
- X iCylinderMethods->uv = CylinderUV;
- X iCylinderMethods->bounds = CylinderBounds;
- X iCylinderMethods->stats = CylinderStats;
- X iCylinderMethods->checkbounds = TRUE;
- X iCylinderMethods->closed = FALSE;
- X }
- X return iCylinderMethods;
- X}
- X
- X/*
- X * Ray-cylinder intersection test.
- X */
- Xint
- XCylinderIntersect(cyl, ray, mindist, maxdist)
- XCylinder *cyl;
- XRay *ray;
- XFloat mindist, *maxdist;
- X{
- X Float t1, t2, a, b, c, zpos1, zpos2, disc;
- X Float distfact;
- X Ray newray;
- X Vector nray, npos;
- X Float nmin;
- X
- X CylTests++;
- X
- X /*
- X * Transform ray into canonical cylinder space.
- X */
- X newray = *ray;
- X distfact = RayTransform(&newray, &cyl->trans.itrans);
- X nray = newray.dir;
- X npos = newray.pos;
- X nmin = mindist * distfact;
- X
- X a = nray.x * nray.x + nray.y * nray.y;
- X if (a < EPSILON*EPSILON)
- X /* |nray.z| == 1. */
- X return FALSE;
- X
- X b = nray.x * npos.x + nray.y * npos.y;
- X c = npos.x*npos.x + npos.y*npos.y - 1;
- X disc = b*b - a*c;
- X if(disc < 0.)
- X return FALSE;
- X disc = sqrt(disc);
- X t1 = (-b + disc) / a;
- X t2 = (-b - disc) / a;
- X if (t1 < nmin && t2 < nmin)
- X return FALSE;
- X zpos1 = npos.z + t1 * nray.z;
- X zpos2 = npos.z + t2 * nray.z;
- X
- X if (t1 < nmin || zpos1 < 0. || zpos1 > 1.) {
- X if (t2 < nmin || zpos2 < 0. || zpos2 > 1.)
- X return FALSE;
- X else
- X t1 = t2 / distfact;
- X
- X } else {
- X if (t2 < nmin || zpos2 < 0. || zpos2 > 1.)
- X t1 /= distfact;
- X else {
- X t1 = min(t1, t2) / distfact;
- X }
- X }
- X
- X if (t1 < *maxdist) {
- X *maxdist = t1;
- X CylHits++;
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- Xint
- XCylinderNormal(cyl, pos, nrm, gnrm)
- XCylinder *cyl;
- XVector *pos, *nrm, *gnrm;
- X{
- X /*
- X * Transform position into cylinder space.
- X */
- X *nrm = *pos;
- X PointTransform(nrm, &cyl->trans.itrans);
- X /*
- X * The normal is equal to the point of intersection in cylinder
- X * space, but with Z = 0.;
- X */
- X nrm->z = 0.;
- X
- X /*
- X * Tranform normal back to world space.
- X */
- X NormalTransform(nrm, &cyl->trans.itrans);
- X *gnrm = *nrm;
- X return FALSE;
- X}
- X
- Xvoid
- XCylinderUV(cyl, pos, norm, uv, dpdu, dpdv)
- XCylinder *cyl;
- XVector *pos, *norm, *dpdu, *dpdv;
- XVec2d *uv;
- X{
- X Vector npos;
- X
- X npos = *pos;
- X PointTransform(&npos, &cyl->trans.itrans);
- X
- X uv->v = npos.z;
- X /*
- X * Due to roundoff error, |npos.x| may be > 1.
- X */
- X if (npos.x > 1.)
- X uv->u = 0.;
- X else if (npos.x < -1.)
- X uv->u = 0.5;
- X else
- X uv->u = acos(npos.x) / TWOPI;
- X if (npos.y < 0.)
- X uv->u = 1. - uv->u;
- X
- X if (dpdu) {
- X dpdv->x = dpdv->y = 0.;
- X dpdv->z = 1.;
- X dpdu->x = -npos.y;
- X dpdu->y = npos.x;
- X dpdu->z = 0.;
- X VecTransform(dpdu, &cyl->trans.trans);
- X VecTransform(dpdv, &cyl->trans.trans);
- X (void)VecNormalize(dpdu);
- X (void)VecNormalize(dpdv);
- X }
- X}
- X
- Xvoid
- XCylinderBounds(cyl, bounds)
- XCylinder *cyl;
- XFloat bounds[2][3];
- X{
- X bounds[LOW][X] = bounds[LOW][Y] = -1;
- X bounds[HIGH][X] = bounds[HIGH][Y] = 1;
- X bounds[LOW][Z] = 0.;
- X bounds[HIGH][Z] = 1;
- X /*
- X * Transform bounding box to world space.
- X */
- X BoundsTransform(&cyl->trans.trans, bounds);
- X}
- X
- Xchar *
- XCylinderName()
- X{
- X return cylName;
- X}
- X
- Xvoid
- XCylinderStats(tests, hits)
- Xunsigned long *tests, *hits;
- X{
- X *tests = CylTests;
- X *hits = CylHits;
- X}
- X
- Xvoid
- XCylinderMethodRegister(meth)
- XUserMethodType meth;
- X{
- X if (iCylinderMethods)
- X iCylinderMethods->user = meth;
- X}
- END_OF_FILE
- if test 4773 -ne `wc -c <'libray/libobj/cylinder.c'`; then
- echo shar: \"'libray/libobj/cylinder.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libobj/cylinder.c'
- fi
- if test -f 'libray/libobj/disc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libobj/disc.c'\"
- else
- echo shar: Extracting \"'libray/libobj/disc.c'\" \(4405 characters\)
- sed "s/^X//" >'libray/libobj/disc.c' <<'END_OF_FILE'
- X/*
- X * disc.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: disc.c,v 4.0 91/07/17 14:37:23 kolb Exp Locker: kolb $
- X *
- X * $Log: disc.c,v $
- X * Revision 4.0 91/07/17 14:37:23 kolb
- X * Initial version.
- X *
- X */
- X#include "geom.h"
- X#include "disc.h"
- X
- Xstatic Methods *iDiscMethods = NULL;
- Xstatic char discName[] = "disc";
- X
- Xunsigned long DiscTests, DiscHits;
- X
- XDisc *
- XDiscCreate(r, pos, norm)
- XFloat r;
- XVector *pos, *norm;
- X{
- X Disc *disc; /* Pointer to new disc. */
- X
- X if (r < EPSILON) {
- X RLerror(RL_WARN, "Degenerate disc.\n");
- X /*
- X * Don't create this primitive.
- X */
- X return (Disc *)NULL;
- X }
- X
- X if (VecNormalize(norm) == 0.) {
- X RLerror(RL_WARN, "Degenerate disc normal.\n");
- X return (Disc *)NULL;
- X }
- X /*
- X * Allocate new Disc.
- X */
- X disc = (Disc *)share_malloc(sizeof(Disc));
- X /*
- X * Initialize new disc.
- X * We store the square of the radius to save us a sqrt().
- X */
- X disc->radius = r*r;
- X disc->pos = *pos;
- X disc->norm = *norm;
- X /*
- X * Compute plane constant.
- X */
- X disc->d = dotp(pos, norm);
- X /*
- X * Allocate new primitive
- X */
- X return disc;
- X}
- X
- XMethods *
- XDiscMethods()
- X{
- X if (iDiscMethods == (Methods *)NULL) {
- X iDiscMethods = MethodsCreate();
- X iDiscMethods->name = DiscName;
- X iDiscMethods->create = (GeomCreateFunc *)DiscCreate;
- X iDiscMethods->methods = DiscMethods;
- X iDiscMethods->intersect = DiscIntersect;
- X iDiscMethods->normal = DiscNormal;
- X iDiscMethods->uv = DiscUV;
- X iDiscMethods->bounds = DiscBounds;
- X iDiscMethods->stats = DiscStats;
- X iDiscMethods->checkbounds = FALSE;
- X iDiscMethods->closed = FALSE;
- X }
- X return iDiscMethods;
- X}
- X
- Xint
- XDiscIntersect(disc, ray, mindist, maxdist)
- XDisc *disc;
- XRay *ray;
- XFloat mindist, *maxdist;
- X{
- X Vector hit;
- X Float denom, dist;
- X
- X DiscTests++;
- X
- X denom = dotp(&disc->norm, &ray->dir);
- X if (fabs(denom) < EPSILON)
- X /* Edge-on intersection */
- X return FALSE;
- X
- X dist = (disc->d - dotp(&disc->norm, &ray->pos)) / denom;
- X if (dist < mindist || dist > *maxdist)
- X /* Too close or too far */
- X return FALSE;
- X /*
- X * Find difference between point of intersection and center of disc.
- X */
- X VecAddScaled(ray->pos, dist, ray->dir, &hit);
- X VecSub(hit, disc->pos, &hit);
- X /*
- X * If hit point is <= disc->radius from center, we've hit the disc.
- X */
- X if (dotp(&hit, &hit) <= disc->radius) {
- X *maxdist = dist;
- X DiscHits++;
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- Xint
- XDiscNormal(disc, pos, nrm, gnrm)
- XDisc *disc;
- XVector *pos, *nrm, *gnrm;
- X{
- X *gnrm = *nrm = disc->norm;
- X return FALSE;
- X}
- X
- Xvoid
- XDiscUV(disc, pos, norm, uv, dpdu, dpdv)
- XDisc *disc;
- XVector *pos, *norm, *dpdu, *dpdv;
- XVec2d *uv;
- X{
- X Float dist, val;
- X
- X dist = (pos->x - disc->pos.x) * (pos->x - disc->pos.x) +
- X (pos->y - disc->pos.y) * (pos->y - disc->pos.y) +
- X (pos->z - disc->pos.z) * (pos->z - disc->pos.z);
- X
- X if (dist < EPSILON) {
- X uv->u = uv->v = 0.;
- X return;
- X }
- X
- X dist = sqrt(dist);
- X uv->v = dist / sqrt(disc->radius); /* should store r and r*r */
- X
- X val = pos->x / dist;
- X
- X if (fabs(val) > 1.)
- X uv->u = 0.5;
- X else {
- X uv->u = acos(val) / TWOPI;
- X if (pos->y < 0.)
- X uv->u = 1. - uv->u;
- X }
- X
- X if (dpdu) {
- X VecSub(*pos, disc->pos, dpdv);
- X /* dpdu = dpdv X norm */
- X VecCross(dpdv, norm, dpdu);
- X }
- X}
- X
- Xvoid
- XDiscBounds(disc, bounds)
- XDisc *disc;
- XFloat bounds[2][3];
- X{
- X Float extent, rad;
- X
- X rad = sqrt(disc->radius);
- X /*
- X * Project disc along each of X, Y and Z axes.
- X */
- X extent = rad * sqrt(1. - disc->norm.x * disc->norm.x);
- X bounds[LOW][X] = disc->pos.x - extent;
- X bounds[HIGH][X] = disc->pos.x + extent;
- X extent = rad * sqrt(1. - disc->norm.y * disc->norm.y);
- X bounds[LOW][Y] = disc->pos.y - extent;
- X bounds[HIGH][Y] = disc->pos.y + extent;
- X extent = rad * sqrt(1. - disc->norm.z * disc->norm.z);
- X bounds[LOW][Z] = disc->pos.z - extent;
- X bounds[HIGH][Z] = disc->pos.z + extent;
- X}
- X
- Xchar *
- XDiscName()
- X{
- X return discName;
- X}
- X
- Xvoid
- XDiscStats(tests, hits)
- Xunsigned long *tests, *hits;
- X{
- X *tests = DiscTests;
- X *hits = DiscHits;
- X}
- X
- Xvoid
- XDiscMethodRegister(meth)
- XUserMethodType meth;
- X{
- X if (iDiscMethods)
- X iDiscMethods->user = meth;
- X}
- END_OF_FILE
- if test 4405 -ne `wc -c <'libray/libobj/disc.c'`; then
- echo shar: \"'libray/libobj/disc.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libobj/disc.c'
- fi
- if test -f 'libray/libobj/roots.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libobj/roots.c'\"
- else
- echo shar: Extracting \"'libray/libobj/roots.c'\" \(4798 characters\)
- sed "s/^X//" >'libray/libobj/roots.c' <<'END_OF_FILE'
- X/*
- X * Roots3And4.c
- X *
- X * Utility functions to find cubic and quartic roots,
- X * coefficients are passed like this:
- X *
- X * c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
- X *
- X * The functions return the number of non-complex roots and
- X * put the values into the s array.
- X *
- X * Author: Jochen Schwarze (schwarze@isa.de)
- X *
- X * Jan 26, 1990 Version for Graphics Gems
- X * Oct 11, 1990 Fixed sign problem for negative q's in SolveQuartic
- X * (reported by Mark Podlipec),
- X * Old-style function definitions,
- X * IsZero() as a macro
- X * Nov 23, 1990 Some systems do not declare acos() and cbrt() in
- X * <math.h>, though the functions exist in the library.
- X * If large coefficients are used, EQN_EPS should be
- X * reduced considerably (e.g. to 1E-30), results will be
- X * correct but multiple roots might be reported more
- X * than once.
- X */
- X
- X#include "libcommon/common.h"
- X
- Xextern double sqrt(), cbrt(), cos(), acos();
- X
- X/* epsilon surrounding for near zero values */
- X
- X/*
- X * In case M_PI isn't defined in math.h
- X */
- X#ifndef M_PI
- X#define M_PI PI
- X#endif
- X
- X#define EQN_EPS 1e-9
- X#define IsZero(x) ((x) > -EQN_EPS && (x) < EQN_EPS)
- X
- X#ifndef CBRT
- X#define cbrt(x) ((x) > 0.0 ? pow((double)(x), 1.0/3.0) : \
- X ((x) < 0.0 ? -pow((double)-(x), 1.0/3.0) : 0.0))
- X#endif
- X
- X
- Xint SolveQuadric(c, s)
- X double c[ 3 ];
- X double s[ 2 ];
- X{
- X double p, q, D;
- X
- X /* normal form: x^2 + px + q = 0 */
- X
- X p = c[ 1 ] / (2 * c[ 2 ]);
- X q = c[ 0 ] / c[ 2 ];
- X
- X D = p * p - q;
- X
- X if (IsZero(D))
- X {
- X s[ 0 ] = - p;
- X return 1;
- X }
- X else if (D > 0)
- X {
- X double sqrt_D = sqrt(D);
- X
- X s[ 0 ] = sqrt_D - p;
- X s[ 1 ] = - sqrt_D - p;
- X return 2;
- X }
- X else /* if (D < 0) */
- X return 0;
- X}
- X
- X
- Xint SolveCubic(c, s)
- X double c[ 4 ];
- X double s[ 3 ];
- X{
- X int i, num;
- X double sub;
- X double A, B, C;
- X double sq_A, p, q;
- X double cb_p, D;
- X
- X /* normal form: x^3 + Ax^2 + Bx + C = 0 */
- X
- X A = c[ 2 ] / c[ 3 ];
- X B = c[ 1 ] / c[ 3 ];
- X C = c[ 0 ] / c[ 3 ];
- X
- X /* substitute x = y - A/3 to eliminate quadric term:
- X x^3 +px + q = 0 */
- X
- X sq_A = A * A;
- X p = 1.0/3 * (- 1.0/3 * sq_A + B);
- X q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
- X
- X /* use Cardano's formula */
- X
- X cb_p = p * p * p;
- X D = q * q + cb_p;
- X
- X if (IsZero(D))
- X {
- X if (IsZero(q)) /* one triple solution */
- X {
- X s[ 0 ] = 0;
- X num = 1;
- X }
- X else /* one single and one double solution */
- X {
- X double u = cbrt(-q);
- X s[ 0 ] = 2 * u;
- X s[ 1 ] = - u;
- X num = 2;
- X }
- X }
- X else if (D < 0) /* Casus irreducibilis: three real solutions */
- X {
- X double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
- X double t = 2 * sqrt(-p);
- X
- X s[ 0 ] = t * cos(phi);
- X s[ 1 ] = - t * cos(phi + M_PI / 3);
- X s[ 2 ] = - t * cos(phi - M_PI / 3);
- X num = 3;
- X }
- X else /* one real solution */
- X {
- X double sqrt_D = sqrt(D);
- X double u = cbrt(sqrt_D - q);
- X double v = - cbrt(sqrt_D + q);
- X
- X s[ 0 ] = u + v;
- X num = 1;
- X }
- X
- X /* resubstitute */
- X
- X sub = 1.0/3 * A;
- X
- X for (i = 0; i < num; ++i)
- X s[ i ] -= sub;
- X
- X return num;
- X}
- X
- X
- Xint SolveQuartic(c, s)
- X double c[ 5 ];
- X double s[ 4 ];
- X{
- X double coeffs[ 4 ];
- X double z, u, v, sub;
- X double A, B, C, D;
- X double sq_A, p, q, r;
- X int i, num;
- X
- X /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
- X
- X A = c[ 3 ] / c[ 4 ];
- X B = c[ 2 ] / c[ 4 ];
- X C = c[ 1 ] / c[ 4 ];
- X D = c[ 0 ] / c[ 4 ];
- X
- X /* substitute x = y - A/4 to eliminate cubic term:
- X x^4 + px^2 + qx + r = 0 */
- X
- X sq_A = A * A;
- X p = - 3.0/8 * sq_A + B;
- X q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
- X r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
- X
- X if (IsZero(r))
- X {
- X /* no absolute term: y(y^3 + py + q) = 0 */
- X
- X coeffs[ 0 ] = q;
- X coeffs[ 1 ] = p;
- X coeffs[ 2 ] = 0;
- X coeffs[ 3 ] = 1;
- X
- X num = SolveCubic(coeffs, s);
- X
- X s[ num++ ] = 0;
- X }
- X else
- X {
- X /* solve the resolvent cubic ... */
- X
- X coeffs[ 0 ] = 1.0/2 * r * p - 1.0/8 * q * q;
- X coeffs[ 1 ] = - r;
- X coeffs[ 2 ] = - 1.0/2 * p;
- X coeffs[ 3 ] = 1;
- X
- X (void) SolveCubic(coeffs, s);
- X
- X /* ... and take the one real solution ... */
- X
- X z = s[ 0 ];
- X
- X /* ... to build two quadric equations */
- X
- X u = z * z - r;
- X v = 2 * z - p;
- X
- X if (IsZero(u))
- X u = 0;
- X else if (u > 0)
- X u = sqrt(u);
- X else
- X return 0;
- X
- X if (IsZero(v))
- X v = 0;
- X else if (v > 0)
- X v = sqrt(v);
- X else
- X return 0;
- X
- X coeffs[ 0 ] = z - u;
- X coeffs[ 1 ] = q < 0 ? -v : v;
- X coeffs[ 2 ] = 1;
- X
- X num = SolveQuadric(coeffs, s);
- X
- X coeffs[ 0 ]= z + u;
- X coeffs[ 1 ] = q < 0 ? v : -v;
- X coeffs[ 2 ] = 1;
- X
- X num += SolveQuadric(coeffs, s + num);
- X }
- X
- X /* resubstitute */
- X
- X sub = 1.0/4 * A;
- X
- X for (i = 0; i < num; ++i)
- X s[ i ] -= sub;
- X
- X return num;
- X}
- X
- END_OF_FILE
- if test 4798 -ne `wc -c <'libray/libobj/roots.c'`; then
- echo shar: \"'libray/libobj/roots.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libobj/roots.c'
- fi
- if test -f 'libray/libobj/sphere.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libobj/sphere.c'\"
- else
- echo shar: Extracting \"'libray/libobj/sphere.c'\" \(4775 characters\)
- sed "s/^X//" >'libray/libobj/sphere.c' <<'END_OF_FILE'
- X/*
- X * sphere.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: sphere.c,v 4.0 91/07/17 14:39:17 kolb Exp Locker: kolb $
- X *
- X * $Log: sphere.c,v $
- X * Revision 4.0 91/07/17 14:39:17 kolb
- X * Initial version.
- X *
- X */
- X#include "geom.h"
- X#include "sphere.h"
- X
- Xstatic Methods *iSphereMethods = NULL;
- Xstatic char sphereName[] = "sphere";
- X
- Xunsigned long SphTests, SphHits;
- X
- X/*
- X * Create & return reference to a sphere.
- X */
- XSphere *
- XSphereCreate(r, pos)
- XFloat r;
- XVector *pos;
- X{
- X Sphere *sphere;
- X
- X if (r < EPSILON) {
- X RLerror(RL_WARN, "Degenerate sphere.\n");
- X return (Sphere *)NULL;
- X }
- X
- X sphere = (Sphere *)share_malloc(sizeof(Sphere));
- X /*
- X * sphere->rsq holds the square of the radius.
- X */
- X sphere->r = r;
- X sphere->rsq = r*r;
- X sphere->x = pos->x;
- X sphere->y = pos->y;
- X sphere->z = pos->z;
- X
- X return sphere;
- X}
- X
- XMethods *
- XSphereMethods()
- X{
- X if (iSphereMethods == (Methods *)NULL) {
- X iSphereMethods = MethodsCreate();
- X iSphereMethods->create = (GeomCreateFunc *)SphereCreate;
- X iSphereMethods->methods = SphereMethods;
- X iSphereMethods->name = SphereName;
- X iSphereMethods->intersect = SphereIntersect;
- X iSphereMethods->normal = SphereNormal;
- X iSphereMethods->uv = SphereUV;
- X iSphereMethods->enter = SphereEnter;
- X iSphereMethods->bounds = SphereBounds;
- X iSphereMethods->stats = SphereStats;
- X iSphereMethods->checkbounds = TRUE;
- X iSphereMethods->closed = TRUE;
- X }
- X return iSphereMethods;
- X}
- X
- X/*
- X * Ray/sphere intersection test.
- X */
- Xint
- XSphereIntersect(sph, ray, mindist, maxdist)
- XSphere *sph;
- XRay *ray;
- XFloat mindist, *maxdist;
- X{
- X Float xadj, yadj, zadj;
- X Float b, t, s;
- X
- X SphTests++;
- 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 - ray->pos.x;
- X yadj = sph->y - ray->pos.y;
- X zadj = sph->z - ray->pos.z;
- X
- X /*
- X * Solve quadratic equation.
- X */
- X b = xadj * ray->dir.x + yadj * ray->dir.y + zadj * ray->dir.z;
- X t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->rsq;
- X if (t < 0.)
- X return FALSE;
- X t = (Float)sqrt((double)t);
- X s = b - t;
- X if (s > mindist) {
- X if (s < *maxdist) {
- X *maxdist = s;
- X SphHits++;
- X return TRUE;
- X }
- X return FALSE;
- X }
- X s = b + t;
- X if (s > mindist && s < *maxdist) {
- X *maxdist = s;
- X SphHits++;
- X return TRUE;
- X }
- X return FALSE;
- X}
- X
- X/*
- X * Compute normal to sphere at pos
- X */
- Xint
- XSphereNormal(sphere, pos, nrm, gnrm)
- XSphere *sphere;
- XVector *pos, *nrm, *gnrm;
- X{
- X nrm->x = (pos->x - sphere->x) / sphere->r;
- X nrm->y = (pos->y - sphere->y) / sphere->r;
- X nrm->z = (pos->z - sphere->z) / sphere->r;
- X *gnrm = *nrm;
- X return FALSE;
- X}
- X
- X/*
- X * Determine if ray enters (TRUE) or leaves (FALSE) sphere at pos
- X */
- Xint
- XSphereEnter(sphere, ray, mind, hitd)
- XSphere *sphere;
- XRay *ray;
- XFloat mind, hitd;
- X{
- X Vector pos;
- X
- X VecAddScaled(ray->pos, mind, ray->dir, &pos);
- X pos.x -= sphere->x;
- X pos.y -= sphere->y;
- X pos.z -= sphere->z;
- X
- X return dotp(&pos, &pos) > sphere->rsq;
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- XSphereUV(sphere, pos, norm, uv, dpdu, dpdv)
- XSphere *sphere;
- XVector *pos, *norm, *dpdu, *dpdv;
- XVec2d *uv;
- X{
- X Float phi, theta;
- X Vector realnorm;
- X
- X realnorm.x = pos->x - sphere->x;
- X realnorm.y = pos->y - sphere->y;
- X realnorm.z = pos->z - sphere->z;
- X VecNormalize( &realnorm );
- X if (realnorm.z > 1.) /* roundoff */
- X phi = PI;
- X else if (realnorm.z < -1.)
- X phi = 0;
- X else
- X phi = acos(-realnorm.z);
- X
- X uv->v = phi / PI;
- X
- X if (fabs(uv->v) < EPSILON || equal(uv->v, 1.))
- X uv->u = 0.;
- X else {
- X theta = realnorm.x / sin(phi);
- X if (theta > 1.)
- X theta = 0.;
- X else if (theta < -1.)
- X theta = 0.5;
- X else
- X theta = acos(theta) / TWOPI;
- X
- X if (realnorm.y > 0)
- X uv->u = theta;
- X else
- X uv->u = 1 - theta;
- X }
- X if (dpdu != (Vector *)0) {
- X dpdu->x = -realnorm.y;
- X dpdu->y = realnorm.x;
- X dpdu->z = 0.;
- X (void)VecNormalize(dpdu);
- X (void)VecNormCross(&realnorm, dpdu, dpdv);
- X }
- X}
- X
- Xvoid
- XSphereBounds(s, bounds)
- XSphere *s;
- XFloat bounds[2][3];
- X{
- X bounds[LOW][X] = s->x - s->r;
- X bounds[HIGH][X] = s->x + s->r;
- X bounds[LOW][Y] = s->y - s->r;
- X bounds[HIGH][Y] = s->y + s->r;
- X bounds[LOW][Z] = s->z - s->r;
- X bounds[HIGH][Z] = s->z + s->r;
- X}
- X
- Xchar *
- XSphereName()
- X{
- X return sphereName;
- X}
- X
- Xvoid
- XSphereStats(tests, hits)
- Xunsigned long *tests, *hits;
- X{
- X *tests = SphTests;
- X *hits = SphHits;
- X}
- X
- Xvoid
- XSphereMethodRegister(meth)
- XUserMethodType meth;
- X{
- X if (iSphereMethods)
- X iSphereMethods->user = meth;
- X}
- END_OF_FILE
- if test 4775 -ne `wc -c <'libray/libobj/sphere.c'`; then
- echo shar: \"'libray/libobj/sphere.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libobj/sphere.c'
- fi
- if test -f 'libray/libsurf/surfshade.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libsurf/surfshade.c'\"
- else
- echo shar: Extracting \"'libray/libsurf/surfshade.c'\" \(4829 characters\)
- sed "s/^X//" >'libray/libsurf/surfshade.c' <<'END_OF_FILE'
- X/*
- X * surfshade.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: surfshade.c,v 4.0 91/07/17 14:41:15 kolb Exp Locker: kolb $
- X *
- X * $Log: surfshade.c,v $
- X * Revision 4.0 91/07/17 14:41:15 kolb
- X * Initial version.
- X *
- X */
- X#include "libobj/geom.h"
- X#include "surface.h"
- X
- X/*
- X * Compute surface properties from given hitlist
- X * Returns TRUE if ray is entering object, FALSE otherwise.
- X */
- Xint
- XComputeSurfProps(hitlist, ray, pos, norm, gnorm, surf, smooth)
- XHitList *hitlist; /* Hit information (path through DAG) */
- XRay *ray; /* Ray in world space */
- XVector *pos; /* Intersection point */
- XVector *norm, *gnorm; /* shading normal, geometric normal (return values) */
- XSurface *surf; /* Copy of surface to use, texture-modified */
- Xint *smooth;
- X{
- X HitNode *hp;
- X int i;
- X Ray rtmp;
- X Geom *prim, *obj;
- X Float k, kp;
- X int texturing, transforming, entering;
- X Trans prim2model, world2model;
- X
- X hp = hitlist->data;
- X prim = hp->obj;
- X
- X /*
- X * Compute point of intersection in "primitive space".
- X */
- X VecAddScaled(hp->ray.pos, hp->dist, hp->ray.dir, pos);
- X
- X /*
- X * Find normal to primitive at point of intersection.
- X */
- X *smooth = PrimNormal(prim, pos, norm, gnorm);
- X
- X texturing = transforming = FALSE;
- X
- X /*
- X * Walk down hit list, constructing world<-->primitive transformation
- X * and determining if we need to perform texture mapping.
- X * The last node is the World node, which cannot be textured or
- X * transformed, so we skip it.
- X */
- X for (i = 0, hp = hitlist->data; i < hitlist->nodes -1; hp++, i++) {
- X obj = hp->obj;
- X if (hp->dotrans) {
- X /*
- X * Here we're actually computing prim2world.
- X * When finished, we invert it.
- X */
- X if (transforming) {
- X TransCompose(&hp->trans, &world2model,
- X &world2model);
- X } else {
- X TransCopy(&hp->trans, &world2model);
- X }
- X transforming = TRUE;
- X }
- X if (obj->texture)
- X texturing = TRUE;
- X }
- X
- X /*
- X * Determine if we're entering or exiting the surface,
- X * flipping surface normals if necessary.
- X */
- X k = dotp(&hitlist->data[0].ray.dir, norm);
- X if (*smooth) {
- X /*
- X * If gnorm and shading norm differ and
- X * their dot products with the ray have
- X * different signs, use the geometric normal
- X * instead, ala Snyder & Barr's paper.
- X */
- X kp = dotp(&hitlist->data[0].ray.dir, gnorm);
- X if (k <= 0. && kp > 0. || k >= 0. && kp < 0.)
- X k = kp;
- X }
- X
- X if (k > 0.) {
- X /* flip normals */
- X VecScale(-1., *gnorm, gnorm);
- X VecScale(-1., *norm, norm);
- X /*
- X * Normal indicates that we're exiting.
- X * Only set entering to TRUE if csg has indicated
- X * that the ray is, indeed, entering.
- X */
- X entering = (hitlist->data[0].enter == ENTERING);
- X } else {
- X /*
- X * Normal indicates that we're entering.
- X * Set entering flag as such unless csg has
- X * told us that we're exiting.
- X */
- X entering = !(hitlist->data[0].enter == EXITING);
- X }
- X
- X /*
- X * If there are no transformations, then world2model is identity.
- X */
- X if (!transforming)
- X TransInit(&world2model);
- X /*
- X * If we're not performing texturing, we simply need to compute
- X * the normal and point of intersection to world space.
- X */
- X if (!texturing) {
- X /*
- X * At this point 'world2model' is really 'prim2world'.
- X */
- X if (transforming) {
- X NormalTransform(norm, &world2model.itrans);
- X NormalTransform(gnorm, &world2model.itrans);
- X VecAddScaled(ray->pos,
- X hitlist->data[hitlist->nodes -1].dist,
- X ray->dir, pos);
- X }
- X return entering;
- X }
- X /*
- X * world2model currently transforms from primitive to world space.
- X * Invert it to get transformation from world to primitive space.
- X */
- X TransInvert(&world2model, &world2model);
- X TransInit(&prim2model);
- X rtmp = hitlist->data[0].ray;
- X /*
- X * Walk down hitlist.
- X */
- X for (hp = hitlist->data, i = 0; i < hitlist->nodes -1; i++, hp++) {
- X obj = hp->obj;
- X if (hp->dotrans) {
- X NormalTransform(norm, &hp->trans.itrans);
- X if (texturing) {
- X /*
- X * Compose prim<-->model and world<-->model
- X * with current transformation.
- X */
- X TransCompose(&hp->trans, &prim2model,
- X &prim2model);
- X TransCompose(&hp->trans, &world2model,
- X &world2model);
- X /*
- X * Transform point and ray to model space.
- X */
- X PointTransform(pos, &hp->trans.trans);
- X (void)RayTransform(&rtmp, &hp->trans.trans);
- X }
- X }
- X /*
- X * Apply textures
- X */
- X if (obj->texture)
- X TextApply(obj->texture, prim, &rtmp, pos, norm,
- X gnorm, surf, &prim2model, &world2model);
- X }
- X return entering;
- X}
- END_OF_FILE
- if test 4829 -ne `wc -c <'libray/libsurf/surfshade.c'`; then
- echo shar: \"'libray/libsurf/surfshade.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libsurf/surfshade.c'
- fi
- if test -f 'libray/libtext/texture.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libray/libtext/texture.c'\"
- else
- echo shar: Extracting \"'libray/libtext/texture.c'\" \(4973 characters\)
- sed "s/^X//" >'libray/libtext/texture.c' <<'END_OF_FILE'
- X/*
- X * texture.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: texture.c,v 4.0 91/07/17 14:44:11 kolb Exp Locker: kolb $
- X *
- X * $Log: texture.c,v $
- X * Revision 4.0 91/07/17 14:44:11 kolb
- X * Initial version.
- X *
- X */
- X#include "texture.h"
- X
- X/*
- X * Transformation structures used to map from texture space to
- X * model/primitive/world space.
- X */
- XTrans prim2model, model2text, prim2text, world2text;
- X
- X#define ApplyMapping(m,o,p,n,c,u,v) (*m->method)(m, o, p, n, c, u, v)
- X
- XTexture *
- XTextCreate(data, meth)
- XTextRef data;
- Xvoid (*meth)();
- X{
- X Texture *res;
- X
- X res = (Texture *)share_calloc(1, sizeof(Texture));
- X res->data = data;
- X res->method = meth;
- X res->trans = (Trans *)NULL;
- X res->next = (Texture *)NULL;
- X res->animtrans = FALSE;
- X return res;
- X}
- X
- X/*
- X * Apply appropriate textures to a surface.
- X */
- Xvoid
- XTextApply(tlist, prim, ray, pos, norm, gnorm, surf, p2model, world2model)
- XTexture *tlist; /* Textures */
- XGeom *prim;
- XRay *ray;
- XVector *pos, *norm, *gnorm; /* pos, shading norm, geo. norm */
- XSurface *surf;
- XTrans *p2model, *world2model;
- X{
- X Vector ptmp;
- X Texture *ttmp;
- X
- X prim2model = *p2model;
- X /*
- X * Walk down texture list, applying each in turn.
- X */
- X for (ttmp = tlist; ttmp; ttmp = ttmp->next) {
- X /*
- X * Make copies of pos & ray to pass to the texturing function.
- X */
- X ptmp = *pos;
- X if (ttmp->trans) {
- X /*
- X * 'take' the inverse of ttmp->trans, since
- X * transforming a texture means applying the
- X * inverse of the transformation
- X * to the point of intersection, etc.
- X */
- X if (ttmp->animtrans) {
- X /*
- X * Resolve animated associations.
- X * We currently do not store a time
- X * for the texture, so we can't know if
- X * we're already resolved for the current
- X * ray->time.
- X */
- X TransResolveAssoc(ttmp->trans);
- X TransComposeList(ttmp->trans, &model2text);
- X TransInvert(&model2text, &model2text);
- X } else
- X TransInvert(ttmp->trans, &model2text);
- X /*
- X * We compose ttmp->trans, which maps from model to
- X * texture space, with prim2model and world2model
- X * to get prim2text and world2text.
- X */
- X TransCompose(&model2text, &prim2model, &prim2text);
- X TransCompose(&model2text, world2model, &world2text);
- X /*
- X * Transform intersection point to texture space.
- X * Ray and normal are passed in model space.
- X */
- X ModelPointToText(&ptmp);
- X } else {
- X /*
- X * By default, texture and model space are identical.
- X */
- X TransInit(&model2text);
- X TransCopy(&prim2model, &prim2text);
- X TransCopy(world2model, &world2text);
- X }
- X
- X /*
- X * Call texture function.
- X */
- X (*ttmp->method) (ttmp->data,prim,ray,&ptmp,norm,gnorm,surf);
- X }
- X}
- X
- X/*
- X * Compute UV at 'pos' on given primitive.
- X */
- XTextToUV(mapping, prim, pos, norm, u, v, dpdu, dpdv)
- XMapping *mapping;
- XGeom *prim;
- XVector *pos, *norm, *dpdu, *dpdv;
- XFloat *u, *v;
- X{
- X Vec2d uv;
- X Vector ptmp;
- X RSMatrix t;
- X
- X ptmp = *pos;
- X
- X if (mapping->flags & PRIMSPACE) {
- X /*
- X * Convert point and normal to primitive space.
- X */
- X TextPointToPrim(&ptmp);
- X } else {
- X /*
- X * Convert point and normal to object space.
- X */
- X TextPointToModel(&ptmp);
- X }
- X
- X ApplyMapping(mapping, prim, &ptmp, norm, &uv, dpdu, dpdv);
- X
- X /*
- X * Transform UV by model2text. We set X = u and Y = v,
- X * while Z = 0.
- X * Although the UV coordinates may be in prim space,
- X * we treat them as if they are model-space coords.
- X * This is due to the fact that we want the texture
- X * to be applied in model space.
- X */
- X ptmp.x = uv.u;
- X ptmp.y = uv.v;
- X ptmp.z = 0.;
- X PointTransform(&ptmp, &model2text.trans);
- X *u = ptmp.x;
- X *v = ptmp.y;
- X if (dpdu == (Vector *)NULL || dpdv == (Vector *)NULL)
- X return;
- X /*
- X * Here's the ugly part.
- X * Build initial UVN-->XYZ matrix...
- X */
- X ArbitraryMatrix(dpdu->x, dpdu->y, dpdu->z,
- X dpdv->x, dpdv->y, dpdv->z,
- X norm->x, norm->y, norm->z, 0., 0., 0., &t);
- X /*
- X * ...transform to model space...
- X */
- X MatrixMult(&t, &prim2model.trans, &t);
- X /*
- X * ... apply model2text in UVN space.
- X */
- X MatrixMult(&model2text.itrans, &t, &t);
- X dpdu->x = t.matrix[0][0];
- X dpdu->y = t.matrix[0][1];
- X dpdu->z = t.matrix[0][2];
- X dpdv->x = t.matrix[1][0];
- X dpdv->y = t.matrix[1][1];
- X dpdv->z = t.matrix[1][2];
- X (void)VecNormalize(dpdu);
- X (void)VecNormalize(dpdv);
- X}
- X
- X/*
- X * Append 'text' to the given linked list of textures.
- X * Note that 'text' may be a list, too.
- X */
- XTexture *
- XTextAppend(text, list)
- XTexture *text, *list;
- X{
- X Texture *tp;
- X
- X if (list) {
- X /*
- X * Walk to the end of the list
- X */
- X for (tp = list;tp->next ;tp = tp->next)
- X ;
- X tp->next = text;
- X return list;
- X }
- X /* else */
- X return text;
- X}
- END_OF_FILE
- if test 4973 -ne `wc -c <'libray/libtext/texture.c'`; then
- echo shar: \"'libray/libtext/texture.c'\" unpacked with wrong size!
- fi
- # end of 'libray/libtext/texture.c'
- fi
- if test -f 'libshade/misc.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libshade/misc.c'\"
- else
- echo shar: Extracting \"'libshade/misc.c'\" \(4080 characters\)
- sed "s/^X//" >'libshade/misc.c' <<'END_OF_FILE'
- X/*
- X * misc.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: misc.c,v 4.0 91/07/17 14:46:31 kolb Exp Locker: kolb $
- X *
- X * $Log: misc.c,v $
- X * Revision 4.0 91/07/17 14:46:31 kolb
- X * Initial version.
- X *
- X */
- X#include "rayshade.h"
- X#ifdef RUSAGE
- X#include <sys/time.h>
- X#include <sys/resource.h>
- X#else
- X#ifdef TIMES
- X#include <sys/types.h>
- X#include <sys/times.h>
- X#include <sys/param.h>
- X#endif
- X#endif
- X#include "options.h"
- X#include "stats.h"
- X
- XFloat RSabstmp; /* Temporary value used by fabs macro. Ugly. */
- Xstatic void RSmessage();
- X
- X/*
- X * Open input file and call yyparse().
- X */
- Xvoid
- XRSReadInputFile()
- X{
- X extern FILE *yyin; /* lex/yacc file pointer */
- X extern char yyfilename[];
- X
- X#if defined(CPPSTDIN) && defined(POPEN)
- X char cmd[BUFSIZ];
- X
- X if (Options.cppargs != (char *)NULL)
- X sprintf(cmd, "%s %s ", CPPSTDIN, Options.cppargs);
- X else
- X /* fromstdin */
- X sprintf(cmd, "%s %s ", CPPSTDIN, CPPMINUS);
- X
- X if (Options.inputname == (char *)NULL) {
- X (void)strcpy(yyfilename, "stdin");
- X } else {
- X (void)strcpy(yyfilename, Options.inputname);
- X (void)strcat(cmd, Options.inputname);
- X }
- X yyin = popen(cmd, "r");
- X if (yyin == (FILE *)NULL)
- X RLerror(RL_PANIC, "popen of \"%s\" failed!\n", cmd);
- X#else
- X if (Options.inputname == (char *)NULL) {
- X yyin = stdin;
- X (void)strcpy(yyfilename, "stdin");
- X } else {
- X (void)strcpy(yyfilename, Options.inputname);
- X yyin = fopen(Options.inputname, "r");
- X if (yyin == (FILE *)NULL)
- X RLerror(RL_PANIC,
- X "Cannot open %s.\n",Options.inputname);
- X }
- X#endif
- X /*
- X * Initialize symbol table.
- X */
- X SymtabInit();
- X (void)yyparse();
- X}
- X
- Xvoid
- XOpenStatsFile()
- X{
- X if (Options.statsname == (char *)NULL || Stats.fstats != stderr)
- X return; /* Not specified or already opened. */
- X
- X Stats.fstats = fopen(Options.statsname, "w");
- X if (Stats.fstats == (FILE *)NULL) {
- X RLerror(RL_PANIC,
- X "Cannot open stats file %s.\n", Options.statsname);
- X }
- X}
- X
- Xvoid
- XRLerror(level, pat, arg1, arg2, arg3)
- Xint level;
- Xchar *pat, *arg1, *arg2, *arg3;
- X{
- X switch (level) {
- X case RL_ADVISE:
- X if (!Options.quiet)
- X RSmessage("Warning", pat, arg1, arg2, arg3);
- X break;
- X case RL_WARN:
- X RSmessage("Warning", pat, arg1, arg2, arg3);
- X break;
- X case RL_ABORT:
- X RSmessage("Error", pat, arg1, arg2, arg3);
- X exit(1);
- X break;
- X case RL_PANIC:
- X RSmessage("Fatal error", pat, arg1, arg2, arg3);
- X exit(2);
- X break;
- X default:
- X RSmessage("Unknown error", pat, arg1, arg2, arg3);
- X exit(3);
- X }
- X}
- X
- Xstatic void
- XRSmessage(type, pat, arg1, arg2, arg3)
- Xchar *type, *pat, *arg1, *arg2, *arg3;
- X{
- X extern FILE *yyin;
- X extern int yylineno;
- X extern char yyfilename[];
- X
- X if (yyin) {
- X /*
- X * cleanup() hasn't nulled yyin, so line #
- X * info is valid.
- X */
- X fprintf(stderr,"%s: %s: %s, line %d: ",
- X Options.progname, type,
- X yyfilename == (char *)NULL ? "stdin" :
- X yyfilename, yylineno);
- X } else {
- X fprintf(stderr,"%s: %s: ", Options.progname, type);
- X }
- X fprintf(stderr, pat, arg1, arg2, arg3);
- X}
- X
- X#ifdef RUSAGE
- Xvoid
- XRSGetCpuTime(usertime, systime)
- XFloat *usertime, *systime;
- X{
- X struct rusage usage;
- X
- X getrusage(RUSAGE_SELF, &usage);
- X
- X *usertime = (Float)usage.ru_utime.tv_sec +
- X (Float)usage.ru_utime.tv_usec / 1000000.;
- X *systime = (Float)usage.ru_stime.tv_sec +
- X (Float)usage.ru_stime.tv_usec / 1000000.;
- X}
- X
- X#else
- X#ifdef TIMES
- X
- Xvoid
- XRSGetCpuTime(usertime, systime)
- XFloat *usertime, *systime;
- X{
- X extern CLOCKTYPE times();
- X struct tms time;
- X
- X (void)times(&time);
- X *usertime = (Float)time.tms_utime / (Float)HZ;
- X *systime = (Float)time.tms_stime / (Float)HZ;
- X}
- X
- X#else /* !RUSAGE && !TIMES */
- X
- Xvoid
- XRSGetCpuTime(usertime, systime)
- XFloat *usertime, *systime;
- X{
- X *usertime = *systime = 0.;
- X}
- X
- X#endif /* TIMES */
- X#endif /* RUSAGE */
- END_OF_FILE
- if test 4080 -ne `wc -c <'libshade/misc.c'`; then
- echo shar: \"'libshade/misc.c'\" unpacked with wrong size!
- fi
- # end of 'libshade/misc.c'
- fi
- if test -f 'libshade/stats.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'libshade/stats.c'\"
- else
- echo shar: Extracting \"'libshade/stats.c'\" \(4043 characters\)
- sed "s/^X//" >'libshade/stats.c' <<'END_OF_FILE'
- X/*
- X * stats.c
- X *
- X * Copyright (C) 1989, 1991, Craig E. Kolb
- X * All rights reserved.
- X *
- X * This software may be freely copied, modified, and redistributed
- X * provided that this copyright notice is preserved on all copies.
- X *
- X * You may not distribute this software, in whole or in part, as part of
- X * any commercial product without the express consent of the authors.
- X *
- X * There is no warranty or other guarantee of fitness of this software
- X * for any purpose. It is provided solely "as is".
- X *
- X * $Id: stats.c,v 4.0 91/07/17 14:47:41 kolb Exp Locker: kolb $
- X *
- X * $Log: stats.c,v $
- X * Revision 4.0 91/07/17 14:47:41 kolb
- X * Initial version.
- X *
- X */
- X#include <ctype.h>
- X#include "rayshade.h"
- X#include "options.h"
- X#include "stats.h"
- X
- XRSStats Stats; /* Statistical information */
- XGeom *GeomRep = NULL; /* Linked list of object representatives */
- X
- Xstatic void PrintGeomStats();
- X
- Xvoid
- XStatsPrint()
- X{
- X extern void PrintMemoryStats();
- X unsigned long TotalRays;
- X
- X#ifndef LINDA
- X RSGetCpuTime(&Stats.Utime, &Stats.Stime);
- X#endif
- X ShadowStats(&Stats.ShadowRays, &Stats.ShadowHits,
- X &Stats.CacheHits, &Stats.CacheMisses);
- X IntersectStats(&Stats.BVTests);
- X
- X TotalRays = Stats.EyeRays + Stats.ShadowRays + Stats.ReflectRays
- X + Stats.RefractRays;
- X Stats.ShadowHits += Stats.CacheHits;
- X Stats.HitRays += Stats.ShadowHits;
- X#ifdef LINDA
- X fprintf(Stats.fstats,"Workers:\t\t\t%d\n",Options.workers);
- X#endif
- X fprintf(Stats.fstats,"Eye rays:\t\t\t%lu\n", Stats.EyeRays);
- X fprintf(Stats.fstats,"Shadow rays:\t\t\t%lu\n",Stats.ShadowRays);
- X fprintf(Stats.fstats,"Reflected rays:\t\t\t%lu\n",Stats.ReflectRays);
- X fprintf(Stats.fstats,"Refracted rays:\t\t\t%lu\n",Stats.RefractRays);
- X fprintf(Stats.fstats,"Total rays:\t\t\t%lu\n", TotalRays);
- X if (TotalRays != 0)
- X fprintf(Stats.fstats,"Intersecting rays:\t\t%lu (%3.3f%%)\n",
- X Stats.HitRays,
- X 100. * (float)Stats.HitRays / (float)TotalRays);
- X if (Stats.ShadowRays != 0) {
- X if (Options.cache)
- X fprintf(Stats.fstats,
- X "Shadow cache hits:\t\t%lu (%lu misses)\n",
- X Stats.CacheHits, Stats.CacheMisses);
- X fprintf(Stats.fstats,"Total shadow hits:\t\t%lu (%3.3f%%)\n",
- X Stats.ShadowHits, 100.*(float)Stats.ShadowHits /
- X (float)Stats.ShadowRays);
- X }
- X fprintf(Stats.fstats,"Supersampled pixels:\t\t%lu\n",
- X Stats.SuperSampled);
- X fprintf(Stats.fstats,"B.V. intersection tests:\t%lu\n",Stats.BVTests);
- X PrintGeomStats();
- X#ifdef LINDA
- X fprintf(Stats.fstats,"Average CPU time/processor:\t");
- X#else
- X fprintf(Stats.fstats,"Total CPU time (sec):\t\t");
- X#endif
- X fprintf(Stats.fstats,"%2.2f (%2.2fu + %2.2fs)\n",
- X Stats.Utime+Stats.Stime, Stats.Utime, Stats.Stime);
- X if (TotalRays != 0.)
- X fprintf(Stats.fstats,"Seconds / ray:\t\t\t%4.4f\n",
- X (Stats.Utime + Stats.Stime) / (Float)TotalRays);
- X if (Stats.HitRays != 0.)
- X fprintf(Stats.fstats,"Seconds / intersecting ray:\t%4.4f\n",
- X (Stats.Utime + Stats.Stime)/(Float)Stats.HitRays);
- X PrintMemoryStats(Stats.fstats);
- X}
- X
- Xstatic void
- XPrintGeomStats()
- X{
- X Geom *otmp;
- X unsigned long tests, hits, totaltests, totalhits;
- X char *name;
- X extern void GeomStats();
- X
- X totaltests = totalhits = 0;
- X
- X for (otmp = GeomRep; otmp; otmp = otmp->next) {
- X GeomStats(otmp, &tests, &hits);
- X if (tests <= 0)
- X continue;
- X name = GeomName(otmp);
- X fprintf(Stats.fstats,
- X "%c%s intersection tests:\t%lu (%lu hit, %f%%)\n",
- X toupper((int)name[0]), &name[1], tests, hits,
- X 100.*(float)hits/(float)tests);
- X if (!IsAggregate(otmp)) {
- X totaltests += tests;
- X totalhits += hits;
- X }
- X }
- X fprintf(Stats.fstats,"Total prim. intersection tests:\t%lu",
- X totaltests);
- X if (totaltests == 0)
- X fprintf(Stats.fstats,"\n");
- X else
- X fprintf(Stats.fstats," (%lu hit, %f%%)\n", totalhits,
- X 100.*(float)totalhits/(float)totaltests);
- X}
- X
- Xvoid
- XStatsAddRep(obj)
- XGeom *obj;
- X{
- X Geom *otmp;
- X
- X for (otmp = GeomRep; otmp; otmp = otmp->next) {
- X if (otmp->methods->stats == obj->methods->stats)
- X return;
- X }
- X
- X /*
- X * Stats method didn't match anything found so far. Add
- X * a copy of obj to head of GeomRep list.
- X */
- X otmp = GeomCopy(obj);
- X otmp->next = GeomRep;
- X GeomRep = otmp;
- X}
- END_OF_FILE
- if test 4043 -ne `wc -c <'libshade/stats.c'`; then
- echo shar: \"'libshade/stats.c'\" unpacked with wrong size!
- fi
- # end of 'libshade/stats.c'
- fi
- echo shar: End of archive 8 \(of 19\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
- exit 0 # Just in case...
-