home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume21 / rayshade / part08 < prev    next >
Encoding:
Text File  |  1991-07-21  |  51.8 KB  |  2,100 lines

  1. Newsgroups: comp.sources.misc
  2. From: Rayshade Construction Co. <rayshade@weedeater.math.YALE.EDU>
  3. Subject:  v21i011:  rayshade - A raytracing package for UNIX, Part08/19
  4. Message-ID: <1991Jul21.033530.28980@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 1ec025725cfa48faa06a8a934d79ef56
  6. Date: Sun, 21 Jul 1991 03:35:30 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Rayshade Construction Co. <rayshade@weedeater.math.YALE.EDU>
  10. Posting-number: Volume 21, Issue 11
  11. Archive-name: rayshade/part08
  12. Environment: UNIX, !16BIT
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 8 (of 19)."
  21. # Contents:  Doc/Guide/animate.tex etc/rsconvert/lex.l
  22. #   libray/libobj/cylinder.c libray/libobj/disc.c
  23. #   libray/libobj/roots.c libray/libobj/sphere.c
  24. #   libray/libsurf/surfshade.c libray/libtext/texture.c
  25. #   libshade/misc.c libshade/stats.c
  26. # Wrapped by kolb@woody on Wed Jul 17 17:56:47 1991
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'Doc/Guide/animate.tex' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'Doc/Guide/animate.tex'\"
  30. else
  31. echo shar: Extracting \"'Doc/Guide/animate.tex'\" \(4147 characters\)
  32. sed "s/^X//" >'Doc/Guide/animate.tex' <<'END_OF_FILE'
  33. X\chapter{Animation}
  34. X
  35. X\Rayshade provides basic animation animation support by
  36. Xallowing time-varying
  37. Xtransformations to be associated with primitives and aggregate objects.
  38. XCommands are provided for controlling the amount of time between each
  39. Xframe, the speed of the camera shutter, and the total number of frames
  40. Xto be rendered.
  41. X
  42. XBy default, rayshade renders a single frame, with the shutter open for
  43. Xan instant (0 units of time, in fact).  The shutter speed in no way
  44. Xchanges the light-gathering properties of the camera, i.e. frames
  45. Xrendered using
  46. Xa longer exposure will not appear brighter than those with a shorter
  47. Xexposure.  The only change will be in the potential amount of movement
  48. Xthat the
  49. Xframe ``sees'' during the time that the shutter is open.
  50. X
  51. XEach ray cast by \rayshade samples a particular moment in time.
  52. XThe time value assigned to a ray
  53. Xranges from the starting time of the current frame to the starting
  54. Xtime plus the amount of time the shutter is open.  When
  55. Xa ray encounters an object or texture that possesses an animated
  56. Xtransformation, the transformed
  57. Xentity is moved into whatever position is appropriate
  58. Xfor the ray's current time value before intersection, shading, or texturing
  59. Xcomputations are performed.
  60. X
  61. XThe starting time of the current frame is computed using the
  62. Xlength of each frame
  63. Xthe current frame number, and the starting time of the first frame.
  64. X
  65. X\begin{defkey}{shutter}{{\em t}}
  66. X    Specifies that the shutter is open for t units of
  67. X    time for each exposure.
  68. X\end{defkey}
  69. XA larger value of {\em t} will lead to more motion blur in the final
  70. Ximage.   Note that {\em t} may be greater than the actual length
  71. Xof a frame.  By default, {\em t} is zero, which prevents all motion blur.
  72. X
  73. X\begin{defkey}{framelength}{{\em frameinc}}
  74. X    Specifies the time increment between frames.
  75. X\end{defkey}
  76. XThe default time between frames is 1 unit.
  77. X
  78. X\begin{defkey}{starttime}{{\em time}}
  79. X    Specifies the starting time of the first frame.
  80. X\end{defkey}
  81. XBy default, {\em time} is zero.
  82. X
  83. XVariables may be defined thorugh the use of the {\tt define} keyword:
  84. X
  85. X\begin{defkey}{define}{{\em name value}}
  86. X    Associate {\em name} with the given {\em value}.  Value may
  87. X    be a constant or a parenthesized expression.
  88. X\end{defkey}
  89. XThe variable {\em name} may thereafter be used in expressions in the
  90. Xinput file.
  91. X
  92. XAn animated transformation is one for which animated expressions have
  93. Xbeen used to define one or more of its parameters (e.g. the angle through
  94. Xwhich a rotation occurs).  An animated expression is one that makes
  95. Xuse of a time-varying (``animated'') variable or function.
  96. X
  97. XThere are two supported animated variables.
  98. XThe first, {\tt time}, is equal to the current time.
  99. XWhen a ray encounters an animated
  100. Xtransformation defined using an expression containing {\tt time}, the ray
  101. Xsubstitutes its time value into the expression before evaluation.
  102. XUsing the {\tt time} variable in an animated expression is the most
  103. Xbasic way to create blur-causing motion.
  104. X
  105. XThe second animated variable, {\tt frame}, is equal to the current
  106. Xframe number.  Unlike the {\tt time} variable, {\tt frame} takes on
  107. Xa single value for the duration of each frame.  Thus, transforms
  108. Xanimated through the use of the {\tt frame} variable will not exhibit
  109. Xmotion blurring.
  110. X
  111. XAlso supported is the {\tt linear} function.  This function uses
  112. X{\tt time} implicitly to interplate between two values.
  113. X
  114. X\begin{defkey}{linear}{{\tt (} {\em Stime, Sval, Etime, Eval} {\tt )}}
  115. X    Linearly interpolate between {\em Sval} at time
  116. X    {\em Stime} and {\em Eval} at time {\em Etime}.
  117. X    If the current time is less than {\em Stime}, the function
  118. X    returns {\em Sval}.  If the current time is greater than
  119. X    {\em Etime}, {\em Eval} is returned.
  120. X\end{defkey}
  121. X
  122. XThe following example shows the use of the {\tt time} variable to
  123. Xanimate a sphere by translating it downwards over five frames.
  124. XNote thet the {\tt shutter} keyword is used to set the shutter duration
  125. Xin order to induce motion blurring.
  126. X
  127. X\begin{verbatim}
  128. X    frames 5
  129. X    shutter 1
  130. X    sphere 1 0 0 2 translate 0 0 (-time)
  131. X\end{verbatim}
  132. X
  133. XFurther examples of animation may be found in the Examples directory
  134. Xof the \rayshade distribution.
  135. END_OF_FILE
  136. if test 4147 -ne `wc -c <'Doc/Guide/animate.tex'`; then
  137.     echo shar: \"'Doc/Guide/animate.tex'\" unpacked with wrong size!
  138. fi
  139. # end of 'Doc/Guide/animate.tex'
  140. fi
  141. if test -f 'etc/rsconvert/lex.l' -a "${1}" != "-c" ; then 
  142.   echo shar: Will not clobber existing file \"'etc/rsconvert/lex.l'\"
  143. else
  144. echo shar: Extracting \"'etc/rsconvert/lex.l'\" \(4148 characters\)
  145. sed "s/^X//" >'etc/rsconvert/lex.l' <<'END_OF_FILE'
  146. X/* lex.l                                   */
  147. X/* Copyright (C) 1989, 1991, Craig E. Kolb                   */
  148. X/* All rights reserved.                               */
  149. X/*                                       */
  150. X/* This software may be freely copied, modified, and redistributed,       */
  151. X/* provided that this copyright notice is preserved on all copies.       */
  152. X/*                                       */
  153. X/* You may not distribute this software, in whole or in part, as part of   */
  154. X/* any commercial product without the express consent of the authors.       */
  155. X/*                                        */
  156. X/* There is no warranty or other guarantee of fitness of this software       */
  157. X/* for any purpose.  It is provided solely "as is".               */
  158. X/* $Id: lex.l,v 4.0 91/07/17 14:29:16 kolb Exp Locker: kolb $ */
  159. X%{
  160. X#include "config.h"
  161. X#include <stdio.h>
  162. X#ifdef I_STRING
  163. X#include <string.h>
  164. X#else
  165. X#include <strings.h>
  166. X#endif
  167. X#include "libcommon/common.h"
  168. X#include "y.tab.h"
  169. X%}
  170. Xalpha    [a-zA-Z]
  171. Xspecial    [\.\_-]
  172. Xdigit    [0-9]
  173. Xexp    [Ee][-+]?{digit}+
  174. Xstring    ({alpha}|"/")({alpha}|{digit}|{special}|"/")*
  175. X%p 3000
  176. X%%
  177. X[\t\n]            {WriteVerbatim(yytext);};
  178. X" "            {};
  179. X^#            {handlehash();}
  180. X"/*"            {skipcomments();}
  181. Xadaptive        {return(tADAPTIVE);}
  182. Xaperture        {return(tAPERTURE);}
  183. Xbackground        {return(tBACKGROUND);}
  184. Xblotch            {return(tBLOTCH);}
  185. Xbox            {return(tBOX);}
  186. Xbump            {return(tBUMP);}
  187. Xchecker            {return(tCHECKER);}
  188. Xcone            {return(tCONE);}
  189. Xcontrast        {return(tCONTRAST);}
  190. Xcutoff            {return(tCUTOFF);}
  191. Xcylinder        {return(tCYL);}
  192. Xdefend            {return(tENDDEF);}
  193. Xdefine            {return(tSTARTDEF);}
  194. Xdirectional        {return(tDIRECTIONAL);}
  195. Xendfile            {return(tENDFILE);}
  196. Xextended        {return(tEXTENDED);}
  197. Xeyep            {return(tEYEP);}
  198. Xfbm            {return(tFBM);}
  199. Xfbmbump            {return(tFBMBUMP);}
  200. Xfocaldist        {return(tFOCALDIST);}
  201. Xfog            {return(tFOG);}
  202. Xfov            {return(tFOV);}
  203. Xgloss            {return(tGLOSS);}
  204. Xgrid            {return(tGRID);}
  205. Xheightfield        {return(tHEIGHTFIELD);}
  206. Xjittered        {return(tJITTERED);}
  207. Xlight            {return(tLIGHT);}
  208. Xlist            {return(tLIST);}
  209. Xlookp            {return(tLOOKP);}
  210. Xmarble            {return(tMARBLE);}
  211. Xmaxdepth        {return(tMAXDEPTH);}
  212. Xmist            {return(tMIST);}
  213. Xobject            {return(tOBJECT);}
  214. Xoutfile            {return(tOUTFILE);}
  215. Xplane            {return(tPLANE);}
  216. Xpoint            {return(tPOINT);}
  217. Xpoly            {return(tPOLY);}
  218. Xresolution        {return(tRESOLUTION);}
  219. Xrotate            {return(tROTATE);}
  220. Xsamples            {return(tSAMPLES);}
  221. Xscale            {return(tSCALE);}
  222. Xscreen            {return(tSCREEN);}
  223. Xsphere            {return(tSPHERE);}
  224. Xsuperq            {return(tSUPERQ);}
  225. Xsurface            {return(tSURFACE);}
  226. Xtexture            {return(tTEXTURE);}
  227. Xtransform        {return(tTRANSFORM);}
  228. Xtranslate        {return(tTRANSLATE);}
  229. Xtriangle        {return(tTRIANGLE);}
  230. Xup            {return(tUP);}
  231. Xwood            {return(tWOOD);}
  232. X{string}        {yylval.c = strsave(yytext);
  233. X                return(tSTRING);}
  234. X[+-]?{digit}+        {yylval.i = atoi(yytext);
  235. X                return(tINT);}
  236. X
  237. X[+-]?{digit}+"."{digit}*({exp})? |
  238. X[+-]?{digit}*"."{digit}+({exp})? |
  239. X[+-]?{digit}+{exp}        {yylval.d = atof(yytext); return(tFLOAT);}
  240. X
  241. X.            {return yytext[0];}
  242. X
  243. X%%
  244. Xyywrap() {return(1);}
  245. X/*
  246. X * Skip over comments.
  247. X */
  248. Xskipcomments()
  249. X{
  250. X    char c;
  251. X
  252. X    WriteVerbatim("/*");
  253. X    while (1) {
  254. X        while ((c = input()) != '*')
  255. X            WriteChar(c);
  256. X        WriteChar(c);
  257. X        if ((c = input()) == '/') {
  258. X            WriteChar(c);
  259. X            return;
  260. X        }
  261. X        unput(c);
  262. X    }
  263. X}
  264. X/*
  265. X * Deal with ccp-produced lines of the form:
  266. X * # n "filename"
  267. X * and
  268. X * # n
  269. X * Where filename is the name of the file being processed, and n is
  270. X * the current line number in that file.
  271. X */
  272. Xhandlehash()
  273. X{
  274. X    char buf[BUFSIZ];
  275. X    int i;
  276. X    extern int yylineno;
  277. X    extern char yyfilename[];
  278. X
  279. X    /*
  280. X     * Read the entire line into buf.
  281. X     */
  282. X    for (i = 0; (buf[i] = input()) != '\n'; i++)
  283. X            ;
  284. X    unput(buf[i]);        /* To make sure consecutive # lines work. */
  285. X    buf[i] = (char)NULL;    /* Replace newline with NULL. */
  286. X
  287. X    /*
  288. X     * Check to see if it's #include or
  289. X     * #define.
  290. X     * If so just spit out the line.
  291. X     */
  292. X    if (strncmp("include", buf, 7) == 0 || strncmp("define", buf, 6) == 0) {
  293. X        WriteVerbatim("#");
  294. X        WriteVerbatim(buf);
  295. X        return;
  296. X    }
  297. X    /*
  298. X     * Complain if the line was not of the form #n "filename"
  299. X     */
  300. X    if ((i = sscanf(buf, "%d \"%[^\"]s\"", &yylineno, yyfilename)) == 0) {
  301. X        yyerror("Unknown '#' control.");
  302. X        exit(1);
  303. X    }
  304. X    if (i == 1) {
  305. X#ifdef SYSV
  306. X        if (strchr(buf, '"') != (char *)0) {
  307. X#else
  308. X        if (index(buf, '"') != (char *)0) {
  309. X#endif
  310. X            /*
  311. X             * Filename was "", which means stdin.
  312. X             */
  313. X            strcpy(yyfilename, "stdin");
  314. X        }
  315. X    }
  316. X}
  317. END_OF_FILE
  318. if test 4148 -ne `wc -c <'etc/rsconvert/lex.l'`; then
  319.     echo shar: \"'etc/rsconvert/lex.l'\" unpacked with wrong size!
  320. fi
  321. # end of 'etc/rsconvert/lex.l'
  322. fi
  323. if test -f 'libray/libobj/cylinder.c' -a "${1}" != "-c" ; then 
  324.   echo shar: Will not clobber existing file \"'libray/libobj/cylinder.c'\"
  325. else
  326. echo shar: Extracting \"'libray/libobj/cylinder.c'\" \(4773 characters\)
  327. sed "s/^X//" >'libray/libobj/cylinder.c' <<'END_OF_FILE'
  328. X/*
  329. X * cylinder.c
  330. X *
  331. X * Copyright (C) 1989, 1991, Craig E. Kolb
  332. X * All rights reserved.
  333. X *
  334. X * This software may be freely copied, modified, and redistributed
  335. X * provided that this copyright notice is preserved on all copies.
  336. X *
  337. X * You may not distribute this software, in whole or in part, as part of
  338. X * any commercial product without the express consent of the authors.
  339. X *
  340. X * There is no warranty or other guarantee of fitness of this software
  341. X * for any purpose.  It is provided solely "as is".
  342. X *
  343. X * $Id: cylinder.c,v 4.0 91/07/17 14:37:12 kolb Exp Locker: kolb $
  344. X *
  345. X * $Log:    cylinder.c,v $
  346. X * Revision 4.0  91/07/17  14:37:12  kolb
  347. X * Initial version.
  348. X * 
  349. X */
  350. X#include "geom.h"
  351. X#include "cylinder.h"
  352. X
  353. Xstatic Methods *iCylinderMethods = NULL;
  354. Xstatic char cylName[] = "cylinder";
  355. X
  356. Xunsigned long CylTests, CylHits;
  357. X
  358. XCylinder *
  359. XCylinderCreate(r, bot, top)
  360. XFloat r;
  361. XVector *bot, *top;
  362. X{
  363. X    Cylinder *cyl;
  364. X    Float len;
  365. X    Vector axis;
  366. X
  367. X    if (r <= 0.) {
  368. X        RLerror(RL_WARN, "Invalid cylinder radius.\n");
  369. X        return (Cylinder*)NULL;
  370. X    }
  371. X
  372. X    VecSub(*top, *bot, &axis);
  373. X
  374. X    len = VecNormalize(&axis);
  375. X
  376. X    if (len < EPSILON) {
  377. X        RLerror(RL_WARN, "Degenerate cylinder.\n");
  378. X        return (Cylinder *)NULL;
  379. X    }
  380. X
  381. X    cyl = (Cylinder *)share_malloc(sizeof(Cylinder));
  382. X    CoordSysTransform(bot, &axis, r, len, &cyl->trans);
  383. X    return cyl;
  384. X}
  385. X
  386. XMethods *
  387. XCylinderMethods()
  388. X{
  389. X    if (iCylinderMethods == (Methods *)NULL) {
  390. X        iCylinderMethods = MethodsCreate();
  391. X        iCylinderMethods->name = CylinderName;
  392. X        iCylinderMethods->create = (GeomCreateFunc *)CylinderCreate;
  393. X        iCylinderMethods->methods = CylinderMethods;
  394. X        iCylinderMethods->intersect = CylinderIntersect;
  395. X        iCylinderMethods->normal = CylinderNormal;
  396. X        iCylinderMethods->uv = CylinderUV;
  397. X        iCylinderMethods->bounds = CylinderBounds;
  398. X        iCylinderMethods->stats = CylinderStats;
  399. X        iCylinderMethods->checkbounds = TRUE;
  400. X        iCylinderMethods->closed = FALSE;
  401. X    }
  402. X    return iCylinderMethods;
  403. X}
  404. X
  405. X/*
  406. X * Ray-cylinder intersection test.
  407. X */
  408. Xint
  409. XCylinderIntersect(cyl, ray, mindist, maxdist)
  410. XCylinder *cyl;
  411. XRay *ray;
  412. XFloat mindist, *maxdist;
  413. X{
  414. X    Float t1, t2, a, b, c, zpos1, zpos2, disc;
  415. X    Float distfact;
  416. X    Ray newray;
  417. X    Vector nray, npos;
  418. X    Float nmin;
  419. X
  420. X    CylTests++;
  421. X
  422. X    /*
  423. X     * Transform ray into canonical cylinder space.
  424. X     */
  425. X    newray = *ray;
  426. X    distfact = RayTransform(&newray, &cyl->trans.itrans);
  427. X    nray = newray.dir;
  428. X    npos = newray.pos;
  429. X    nmin = mindist * distfact;
  430. X
  431. X    a = nray.x * nray.x + nray.y * nray.y;
  432. X    if (a < EPSILON*EPSILON)
  433. X        /* |nray.z| == 1. */
  434. X        return FALSE;
  435. X
  436. X    b = nray.x * npos.x + nray.y * npos.y;
  437. X    c = npos.x*npos.x + npos.y*npos.y - 1;
  438. X    disc = b*b - a*c;
  439. X    if(disc < 0.)
  440. X        return FALSE;
  441. X    disc = sqrt(disc);
  442. X    t1 = (-b + disc) / a;
  443. X    t2 = (-b - disc) / a;
  444. X    if (t1 < nmin && t2 < nmin)
  445. X        return FALSE;
  446. X    zpos1 = npos.z + t1 * nray.z;
  447. X    zpos2 = npos.z + t2 * nray.z;
  448. X
  449. X    if (t1 < nmin || zpos1 < 0. || zpos1 > 1.) {
  450. X        if (t2 < nmin || zpos2 < 0. || zpos2 > 1.)
  451. X            return FALSE;
  452. X        else
  453. X            t1 = t2 / distfact;
  454. X
  455. X    } else {
  456. X        if (t2 < nmin || zpos2 < 0. || zpos2 > 1.)
  457. X            t1 /= distfact;
  458. X        else {
  459. X            t1 = min(t1, t2) / distfact;
  460. X        }
  461. X    }
  462. X    
  463. X    if (t1 < *maxdist) {
  464. X        *maxdist = t1;
  465. X        CylHits++;
  466. X        return TRUE;
  467. X    }
  468. X    return FALSE;
  469. X}
  470. X
  471. Xint
  472. XCylinderNormal(cyl, pos, nrm, gnrm)
  473. XCylinder *cyl;
  474. XVector *pos, *nrm, *gnrm;
  475. X{
  476. X    /*
  477. X     * Transform position into cylinder space.
  478. X     */
  479. X    *nrm = *pos;
  480. X    PointTransform(nrm, &cyl->trans.itrans);
  481. X    /*
  482. X     * The normal is equal to the point of intersection in cylinder
  483. X     * space, but with Z = 0.;
  484. X     */
  485. X    nrm->z = 0.;
  486. X
  487. X    /*
  488. X     * Tranform normal back to world space.
  489. X     */
  490. X    NormalTransform(nrm, &cyl->trans.itrans);
  491. X    *gnrm = *nrm;
  492. X    return FALSE;
  493. X}
  494. X
  495. Xvoid
  496. XCylinderUV(cyl, pos, norm, uv, dpdu, dpdv)
  497. XCylinder *cyl;
  498. XVector *pos, *norm, *dpdu, *dpdv;
  499. XVec2d *uv;
  500. X{
  501. X    Vector npos;
  502. X
  503. X    npos = *pos;
  504. X    PointTransform(&npos, &cyl->trans.itrans);
  505. X
  506. X    uv->v = npos.z;
  507. X    /*
  508. X     * Due to roundoff error, |npos.x| may be > 1.
  509. X     */
  510. X    if (npos.x > 1.)
  511. X        uv->u = 0.;
  512. X    else if (npos.x < -1.)
  513. X        uv->u = 0.5;
  514. X    else
  515. X        uv->u = acos(npos.x) / TWOPI;
  516. X    if (npos.y < 0.)
  517. X        uv->u = 1. - uv->u;
  518. X
  519. X    if (dpdu) {
  520. X        dpdv->x = dpdv->y = 0.;
  521. X        dpdv->z = 1.;
  522. X        dpdu->x = -npos.y;
  523. X        dpdu->y = npos.x;
  524. X        dpdu->z = 0.;
  525. X        VecTransform(dpdu, &cyl->trans.trans);
  526. X        VecTransform(dpdv, &cyl->trans.trans);
  527. X        (void)VecNormalize(dpdu);
  528. X        (void)VecNormalize(dpdv);
  529. X    }
  530. X}
  531. X
  532. Xvoid
  533. XCylinderBounds(cyl, bounds)
  534. XCylinder *cyl;
  535. XFloat bounds[2][3];
  536. X{
  537. X    bounds[LOW][X] = bounds[LOW][Y] = -1;
  538. X    bounds[HIGH][X] = bounds[HIGH][Y] = 1;
  539. X    bounds[LOW][Z] = 0.;
  540. X    bounds[HIGH][Z] = 1;
  541. X    /*
  542. X     * Transform bounding box to world space.
  543. X     */
  544. X    BoundsTransform(&cyl->trans.trans, bounds);
  545. X}
  546. X
  547. Xchar *
  548. XCylinderName()
  549. X{
  550. X    return cylName;
  551. X}
  552. X
  553. Xvoid
  554. XCylinderStats(tests, hits)
  555. Xunsigned long *tests, *hits;
  556. X{
  557. X    *tests = CylTests;
  558. X    *hits = CylHits;
  559. X}
  560. X
  561. Xvoid
  562. XCylinderMethodRegister(meth)
  563. XUserMethodType meth;
  564. X{
  565. X    if (iCylinderMethods)
  566. X        iCylinderMethods->user = meth;
  567. X}
  568. END_OF_FILE
  569. if test 4773 -ne `wc -c <'libray/libobj/cylinder.c'`; then
  570.     echo shar: \"'libray/libobj/cylinder.c'\" unpacked with wrong size!
  571. fi
  572. # end of 'libray/libobj/cylinder.c'
  573. fi
  574. if test -f 'libray/libobj/disc.c' -a "${1}" != "-c" ; then 
  575.   echo shar: Will not clobber existing file \"'libray/libobj/disc.c'\"
  576. else
  577. echo shar: Extracting \"'libray/libobj/disc.c'\" \(4405 characters\)
  578. sed "s/^X//" >'libray/libobj/disc.c' <<'END_OF_FILE'
  579. X/*
  580. X * disc.c
  581. X *
  582. X * Copyright (C) 1989, 1991, Craig E. Kolb
  583. X * All rights reserved.
  584. X *
  585. X * This software may be freely copied, modified, and redistributed
  586. X * provided that this copyright notice is preserved on all copies.
  587. X *
  588. X * You may not distribute this software, in whole or in part, as part of
  589. X * any commercial product without the express consent of the authors.
  590. X *
  591. X * There is no warranty or other guarantee of fitness of this software
  592. X * for any purpose.  It is provided solely "as is".
  593. X *
  594. X * $Id: disc.c,v 4.0 91/07/17 14:37:23 kolb Exp Locker: kolb $
  595. X *
  596. X * $Log:    disc.c,v $
  597. X * Revision 4.0  91/07/17  14:37:23  kolb
  598. X * Initial version.
  599. X * 
  600. X */
  601. X#include "geom.h"
  602. X#include "disc.h"
  603. X
  604. Xstatic Methods *iDiscMethods = NULL;
  605. Xstatic char discName[] = "disc";
  606. X
  607. Xunsigned long DiscTests, DiscHits;
  608. X
  609. XDisc *
  610. XDiscCreate(r, pos, norm)
  611. XFloat r;
  612. XVector *pos, *norm;
  613. X{
  614. X    Disc *disc;        /* Pointer to new disc. */
  615. X
  616. X    if (r < EPSILON) {
  617. X        RLerror(RL_WARN, "Degenerate disc.\n");
  618. X            /*
  619. X             * Don't create this primitive.
  620. X             */
  621. X            return (Disc *)NULL;
  622. X    }
  623. X
  624. X    if (VecNormalize(norm) == 0.) {
  625. X        RLerror(RL_WARN, "Degenerate disc normal.\n");
  626. X        return (Disc *)NULL;
  627. X    }
  628. X    /*
  629. X     * Allocate new Disc.
  630. X     */
  631. X    disc = (Disc *)share_malloc(sizeof(Disc));
  632. X    /*
  633. X     * Initialize new disc.
  634. X     * We store the square of the radius to save us a sqrt().
  635. X     */
  636. X    disc->radius = r*r;
  637. X    disc->pos = *pos;
  638. X    disc->norm = *norm;
  639. X    /*
  640. X     * Compute plane constant.
  641. X     */
  642. X    disc->d = dotp(pos, norm);
  643. X    /*
  644. X     * Allocate new primitive
  645. X     */
  646. X    return disc;
  647. X}
  648. X
  649. XMethods *
  650. XDiscMethods()
  651. X{
  652. X    if (iDiscMethods == (Methods *)NULL) {
  653. X        iDiscMethods = MethodsCreate();
  654. X        iDiscMethods->name = DiscName;
  655. X        iDiscMethods->create = (GeomCreateFunc *)DiscCreate;
  656. X        iDiscMethods->methods = DiscMethods;
  657. X        iDiscMethods->intersect = DiscIntersect;
  658. X        iDiscMethods->normal = DiscNormal;
  659. X        iDiscMethods->uv = DiscUV;
  660. X        iDiscMethods->bounds = DiscBounds;
  661. X        iDiscMethods->stats = DiscStats;
  662. X        iDiscMethods->checkbounds = FALSE;
  663. X        iDiscMethods->closed = FALSE;
  664. X    }
  665. X    return iDiscMethods;
  666. X}
  667. X
  668. Xint
  669. XDiscIntersect(disc, ray, mindist, maxdist)
  670. XDisc *disc;
  671. XRay *ray;
  672. XFloat mindist, *maxdist;
  673. X{
  674. X    Vector hit;
  675. X    Float denom, dist;
  676. X
  677. X    DiscTests++;
  678. X
  679. X    denom = dotp(&disc->norm, &ray->dir);
  680. X    if (fabs(denom) < EPSILON)
  681. X        /* Edge-on intersection */
  682. X         return FALSE;
  683. X
  684. X    dist = (disc->d - dotp(&disc->norm, &ray->pos)) / denom;
  685. X    if (dist < mindist || dist > *maxdist)
  686. X        /* Too close or too far */
  687. X        return FALSE;
  688. X    /*
  689. X     *  Find difference between point of intersection and center of disc.
  690. X     */
  691. X    VecAddScaled(ray->pos, dist, ray->dir, &hit);
  692. X    VecSub(hit, disc->pos, &hit);
  693. X    /*
  694. X     * If hit point is <= disc->radius from center, we've hit the disc.
  695. X     */
  696. X    if (dotp(&hit, &hit) <= disc->radius) {
  697. X        *maxdist = dist;
  698. X        DiscHits++;
  699. X        return TRUE;
  700. X    }
  701. X    return FALSE;
  702. X}
  703. X
  704. Xint
  705. XDiscNormal(disc, pos, nrm, gnrm)
  706. XDisc *disc;
  707. XVector *pos, *nrm, *gnrm;
  708. X{
  709. X    *gnrm = *nrm = disc->norm;
  710. X    return FALSE;
  711. X}
  712. X
  713. Xvoid
  714. XDiscUV(disc, pos, norm, uv, dpdu, dpdv)
  715. XDisc *disc;
  716. XVector *pos, *norm, *dpdu, *dpdv;
  717. XVec2d *uv;
  718. X{
  719. X    Float dist, val;
  720. X
  721. X    dist =    (pos->x - disc->pos.x) * (pos->x - disc->pos.x) +
  722. X        (pos->y - disc->pos.y) * (pos->y - disc->pos.y) +
  723. X        (pos->z - disc->pos.z) * (pos->z - disc->pos.z);
  724. X
  725. X    if (dist < EPSILON) {
  726. X        uv->u = uv->v = 0.;
  727. X        return;
  728. X    }
  729. X
  730. X    dist = sqrt(dist);
  731. X    uv->v = dist / sqrt(disc->radius); /* should store r and r*r */
  732. X
  733. X    val = pos->x / dist;
  734. X
  735. X    if (fabs(val) > 1.)
  736. X        uv->u = 0.5;
  737. X    else {
  738. X        uv->u = acos(val) / TWOPI; 
  739. X        if (pos->y < 0.)
  740. X            uv->u = 1. - uv->u;
  741. X    }
  742. X
  743. X    if (dpdu) {
  744. X        VecSub(*pos, disc->pos, dpdv);
  745. X        /* dpdu = dpdv X norm */
  746. X        VecCross(dpdv, norm, dpdu);
  747. X    }
  748. X}
  749. X
  750. Xvoid
  751. XDiscBounds(disc, bounds)
  752. XDisc *disc;
  753. XFloat bounds[2][3];
  754. X{
  755. X    Float extent, rad;
  756. X
  757. X    rad = sqrt(disc->radius);
  758. X    /*
  759. X     * Project disc along each of X, Y and Z axes.
  760. X     */
  761. X    extent = rad * sqrt(1. - disc->norm.x * disc->norm.x);
  762. X    bounds[LOW][X] = disc->pos.x - extent;
  763. X    bounds[HIGH][X] = disc->pos.x + extent;
  764. X    extent = rad * sqrt(1. - disc->norm.y * disc->norm.y);
  765. X    bounds[LOW][Y] = disc->pos.y - extent;
  766. X    bounds[HIGH][Y] = disc->pos.y + extent;
  767. X    extent = rad * sqrt(1. - disc->norm.z * disc->norm.z);
  768. X    bounds[LOW][Z] = disc->pos.z - extent;
  769. X    bounds[HIGH][Z] = disc->pos.z + extent;
  770. X}
  771. X
  772. Xchar *
  773. XDiscName()
  774. X{
  775. X    return discName;
  776. X}
  777. X
  778. Xvoid
  779. XDiscStats(tests, hits)
  780. Xunsigned long *tests, *hits;
  781. X{
  782. X    *tests = DiscTests;
  783. X    *hits = DiscHits;
  784. X}
  785. X
  786. Xvoid
  787. XDiscMethodRegister(meth)
  788. XUserMethodType meth;
  789. X{
  790. X    if (iDiscMethods)
  791. X        iDiscMethods->user = meth;
  792. X}
  793. END_OF_FILE
  794. if test 4405 -ne `wc -c <'libray/libobj/disc.c'`; then
  795.     echo shar: \"'libray/libobj/disc.c'\" unpacked with wrong size!
  796. fi
  797. # end of 'libray/libobj/disc.c'
  798. fi
  799. if test -f 'libray/libobj/roots.c' -a "${1}" != "-c" ; then 
  800.   echo shar: Will not clobber existing file \"'libray/libobj/roots.c'\"
  801. else
  802. echo shar: Extracting \"'libray/libobj/roots.c'\" \(4798 characters\)
  803. sed "s/^X//" >'libray/libobj/roots.c' <<'END_OF_FILE'
  804. X/*
  805. X *  Roots3And4.c
  806. X *
  807. X *  Utility functions to find cubic and quartic roots,
  808. X *  coefficients are passed like this:
  809. X *
  810. X *      c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
  811. X *
  812. X *  The functions return the number of non-complex roots and
  813. X *  put the values into the s array.
  814. X *
  815. X *  Author:         Jochen Schwarze (schwarze@isa.de)
  816. X *
  817. X *  Jan 26, 1990    Version for Graphics Gems
  818. X *  Oct 11, 1990    Fixed sign problem for negative q's in SolveQuartic
  819. X *                  (reported by Mark Podlipec),
  820. X *                  Old-style function definitions,
  821. X *                  IsZero() as a macro
  822. X *  Nov 23, 1990    Some systems do not declare acos() and cbrt() in
  823. X *                  <math.h>, though the functions exist in the library.
  824. X *                  If large coefficients are used, EQN_EPS should be
  825. X *                  reduced considerably (e.g. to 1E-30), results will be
  826. X *                  correct but multiple roots might be reported more
  827. X *                  than once.
  828. X */
  829. X
  830. X#include "libcommon/common.h"
  831. X
  832. Xextern double   sqrt(), cbrt(), cos(), acos();
  833. X
  834. X/* epsilon surrounding for near zero values */
  835. X
  836. X/*
  837. X * In case M_PI isn't defined in math.h
  838. X */
  839. X#ifndef M_PI
  840. X#define M_PI PI
  841. X#endif
  842. X
  843. X#define     EQN_EPS     1e-9
  844. X#define        IsZero(x)    ((x) > -EQN_EPS && (x) < EQN_EPS)
  845. X
  846. X#ifndef CBRT
  847. X#define     cbrt(x)     ((x) > 0.0 ? pow((double)(x), 1.0/3.0) : \
  848. X              ((x) < 0.0 ? -pow((double)-(x), 1.0/3.0) : 0.0))
  849. X#endif
  850. X
  851. X
  852. Xint SolveQuadric(c, s)
  853. X    double c[ 3 ];
  854. X    double s[ 2 ];
  855. X{
  856. X    double p, q, D;
  857. X
  858. X    /* normal form: x^2 + px + q = 0 */
  859. X
  860. X    p = c[ 1 ] / (2 * c[ 2 ]);
  861. X    q = c[ 0 ] / c[ 2 ];
  862. X
  863. X    D = p * p - q;
  864. X
  865. X    if (IsZero(D))
  866. X    {
  867. X    s[ 0 ] = - p;
  868. X    return 1;
  869. X    }
  870. X    else if (D > 0)
  871. X    {
  872. X    double sqrt_D = sqrt(D);
  873. X
  874. X    s[ 0 ] =   sqrt_D - p;
  875. X    s[ 1 ] = - sqrt_D - p;
  876. X    return 2;
  877. X    }
  878. X    else /* if (D < 0) */
  879. X        return 0;
  880. X}
  881. X
  882. X
  883. Xint SolveCubic(c, s)
  884. X    double c[ 4 ];
  885. X    double s[ 3 ];
  886. X{
  887. X    int     i, num;
  888. X    double  sub;
  889. X    double  A, B, C;
  890. X    double  sq_A, p, q;
  891. X    double  cb_p, D;
  892. X
  893. X    /* normal form: x^3 + Ax^2 + Bx + C = 0 */
  894. X
  895. X    A = c[ 2 ] / c[ 3 ];
  896. X    B = c[ 1 ] / c[ 3 ];
  897. X    C = c[ 0 ] / c[ 3 ];
  898. X
  899. X    /*  substitute x = y - A/3 to eliminate quadric term:
  900. X    x^3 +px + q = 0 */
  901. X
  902. X    sq_A = A * A;
  903. X    p = 1.0/3 * (- 1.0/3 * sq_A + B);
  904. X    q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
  905. X
  906. X    /* use Cardano's formula */
  907. X
  908. X    cb_p = p * p * p;
  909. X    D = q * q + cb_p;
  910. X
  911. X    if (IsZero(D))
  912. X    {
  913. X    if (IsZero(q)) /* one triple solution */
  914. X    {
  915. X        s[ 0 ] = 0;
  916. X        num = 1;
  917. X    }
  918. X    else /* one single and one double solution */
  919. X    {
  920. X        double u = cbrt(-q);
  921. X        s[ 0 ] = 2 * u;
  922. X        s[ 1 ] = - u;
  923. X        num = 2;
  924. X    }
  925. X    }
  926. X    else if (D < 0) /* Casus irreducibilis: three real solutions */
  927. X    {
  928. X    double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
  929. X    double t = 2 * sqrt(-p);
  930. X
  931. X    s[ 0 ] =   t * cos(phi);
  932. X    s[ 1 ] = - t * cos(phi + M_PI / 3);
  933. X    s[ 2 ] = - t * cos(phi - M_PI / 3);
  934. X    num = 3;
  935. X    }
  936. X    else /* one real solution */
  937. X    {
  938. X    double sqrt_D = sqrt(D);
  939. X    double u = cbrt(sqrt_D - q);
  940. X    double v = - cbrt(sqrt_D + q);
  941. X
  942. X    s[ 0 ] = u + v;
  943. X    num = 1;
  944. X    }
  945. X
  946. X    /* resubstitute */
  947. X
  948. X    sub = 1.0/3 * A;
  949. X
  950. X    for (i = 0; i < num; ++i)
  951. X    s[ i ] -= sub;
  952. X
  953. X    return num;
  954. X}
  955. X
  956. X
  957. Xint SolveQuartic(c, s)
  958. X    double c[ 5 ]; 
  959. X    double s[ 4 ];
  960. X{
  961. X    double  coeffs[ 4 ];
  962. X    double  z, u, v, sub;
  963. X    double  A, B, C, D;
  964. X    double  sq_A, p, q, r;
  965. X    int     i, num;
  966. X
  967. X    /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
  968. X
  969. X    A = c[ 3 ] / c[ 4 ];
  970. X    B = c[ 2 ] / c[ 4 ];
  971. X    C = c[ 1 ] / c[ 4 ];
  972. X    D = c[ 0 ] / c[ 4 ];
  973. X
  974. X    /*  substitute x = y - A/4 to eliminate cubic term:
  975. X    x^4 + px^2 + qx + r = 0 */
  976. X
  977. X    sq_A = A * A;
  978. X    p = - 3.0/8 * sq_A + B;
  979. X    q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
  980. X    r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
  981. X
  982. X    if (IsZero(r))
  983. X    {
  984. X    /* no absolute term: y(y^3 + py + q) = 0 */
  985. X
  986. X    coeffs[ 0 ] = q;
  987. X    coeffs[ 1 ] = p;
  988. X    coeffs[ 2 ] = 0;
  989. X    coeffs[ 3 ] = 1;
  990. X
  991. X    num = SolveCubic(coeffs, s);
  992. X
  993. X    s[ num++ ] = 0;
  994. X    }
  995. X    else
  996. X    {
  997. X    /* solve the resolvent cubic ... */
  998. X
  999. X    coeffs[ 0 ] = 1.0/2 * r * p - 1.0/8 * q * q;
  1000. X    coeffs[ 1 ] = - r;
  1001. X    coeffs[ 2 ] = - 1.0/2 * p;
  1002. X    coeffs[ 3 ] = 1;
  1003. X
  1004. X    (void) SolveCubic(coeffs, s);
  1005. X
  1006. X    /* ... and take the one real solution ... */
  1007. X
  1008. X    z = s[ 0 ];
  1009. X
  1010. X    /* ... to build two quadric equations */
  1011. X
  1012. X    u = z * z - r;
  1013. X    v = 2 * z - p;
  1014. X
  1015. X    if (IsZero(u))
  1016. X        u = 0;
  1017. X    else if (u > 0)
  1018. X        u = sqrt(u);
  1019. X    else
  1020. X        return 0;
  1021. X
  1022. X    if (IsZero(v))
  1023. X        v = 0;
  1024. X    else if (v > 0)
  1025. X        v = sqrt(v);
  1026. X    else
  1027. X        return 0;
  1028. X
  1029. X    coeffs[ 0 ] = z - u;
  1030. X    coeffs[ 1 ] = q < 0 ? -v : v;
  1031. X    coeffs[ 2 ] = 1;
  1032. X
  1033. X    num = SolveQuadric(coeffs, s);
  1034. X
  1035. X    coeffs[ 0 ]= z + u;
  1036. X    coeffs[ 1 ] = q < 0 ? v : -v;
  1037. X    coeffs[ 2 ] = 1;
  1038. X
  1039. X    num += SolveQuadric(coeffs, s + num);
  1040. X    }
  1041. X
  1042. X    /* resubstitute */
  1043. X
  1044. X    sub = 1.0/4 * A;
  1045. X
  1046. X    for (i = 0; i < num; ++i)
  1047. X    s[ i ] -= sub;
  1048. X
  1049. X    return num;
  1050. X}
  1051. X
  1052. END_OF_FILE
  1053. if test 4798 -ne `wc -c <'libray/libobj/roots.c'`; then
  1054.     echo shar: \"'libray/libobj/roots.c'\" unpacked with wrong size!
  1055. fi
  1056. # end of 'libray/libobj/roots.c'
  1057. fi
  1058. if test -f 'libray/libobj/sphere.c' -a "${1}" != "-c" ; then 
  1059.   echo shar: Will not clobber existing file \"'libray/libobj/sphere.c'\"
  1060. else
  1061. echo shar: Extracting \"'libray/libobj/sphere.c'\" \(4775 characters\)
  1062. sed "s/^X//" >'libray/libobj/sphere.c' <<'END_OF_FILE'
  1063. X/*
  1064. X * sphere.c
  1065. X *
  1066. X * Copyright (C) 1989, 1991, Craig E. Kolb
  1067. X * All rights reserved.
  1068. X *
  1069. X * This software may be freely copied, modified, and redistributed
  1070. X * provided that this copyright notice is preserved on all copies.
  1071. X *
  1072. X * You may not distribute this software, in whole or in part, as part of
  1073. X * any commercial product without the express consent of the authors.
  1074. X *
  1075. X * There is no warranty or other guarantee of fitness of this software
  1076. X * for any purpose.  It is provided solely "as is".
  1077. X *
  1078. X * $Id: sphere.c,v 4.0 91/07/17 14:39:17 kolb Exp Locker: kolb $
  1079. X *
  1080. X * $Log:    sphere.c,v $
  1081. X * Revision 4.0  91/07/17  14:39:17  kolb
  1082. X * Initial version.
  1083. X * 
  1084. X */
  1085. X#include "geom.h"
  1086. X#include "sphere.h"
  1087. X
  1088. Xstatic Methods *iSphereMethods = NULL;
  1089. Xstatic char sphereName[] = "sphere";
  1090. X
  1091. Xunsigned long SphTests, SphHits;
  1092. X
  1093. X/*
  1094. X * Create & return reference to a sphere.
  1095. X */
  1096. XSphere *
  1097. XSphereCreate(r, pos)
  1098. XFloat r;
  1099. XVector *pos;
  1100. X{
  1101. X    Sphere *sphere;
  1102. X
  1103. X    if (r < EPSILON) {
  1104. X        RLerror(RL_WARN, "Degenerate sphere.\n");
  1105. X        return (Sphere *)NULL;
  1106. X    }
  1107. X
  1108. X    sphere = (Sphere *)share_malloc(sizeof(Sphere));
  1109. X    /*
  1110. X     * sphere->rsq holds the square of the radius.
  1111. X     */
  1112. X    sphere->r = r;
  1113. X    sphere->rsq = r*r;
  1114. X    sphere->x = pos->x;
  1115. X    sphere->y = pos->y;
  1116. X    sphere->z = pos->z;
  1117. X
  1118. X    return sphere;
  1119. X}
  1120. X
  1121. XMethods *
  1122. XSphereMethods()
  1123. X{
  1124. X    if (iSphereMethods == (Methods *)NULL) {
  1125. X        iSphereMethods = MethodsCreate();
  1126. X        iSphereMethods->create = (GeomCreateFunc *)SphereCreate;
  1127. X        iSphereMethods->methods = SphereMethods;
  1128. X        iSphereMethods->name = SphereName;
  1129. X        iSphereMethods->intersect = SphereIntersect;
  1130. X        iSphereMethods->normal = SphereNormal;
  1131. X        iSphereMethods->uv = SphereUV;
  1132. X        iSphereMethods->enter = SphereEnter;
  1133. X        iSphereMethods->bounds = SphereBounds;
  1134. X        iSphereMethods->stats = SphereStats;
  1135. X        iSphereMethods->checkbounds = TRUE;
  1136. X        iSphereMethods->closed = TRUE;
  1137. X    }
  1138. X    return iSphereMethods;
  1139. X}
  1140. X
  1141. X/*
  1142. X * Ray/sphere intersection test.
  1143. X */
  1144. Xint
  1145. XSphereIntersect(sph, ray, mindist, maxdist)
  1146. XSphere *sph;
  1147. XRay *ray;
  1148. XFloat mindist, *maxdist;
  1149. X{
  1150. X    Float xadj, yadj, zadj;
  1151. X    Float b, t, s;
  1152. X
  1153. X    SphTests++;
  1154. X    /*
  1155. X     * Translate ray origin to object space and negate everything.
  1156. X     * (Thus, we translate the sphere into ray space, which saves
  1157. X     * us a couple of negations below.)
  1158. X     */
  1159. X    xadj = sph->x - ray->pos.x;
  1160. X    yadj = sph->y - ray->pos.y;
  1161. X    zadj = sph->z - ray->pos.z;
  1162. X
  1163. X    /*
  1164. X     * Solve quadratic equation.
  1165. X     */
  1166. X    b = xadj * ray->dir.x + yadj * ray->dir.y + zadj * ray->dir.z;
  1167. X    t = b * b - xadj * xadj - yadj * yadj - zadj * zadj + sph->rsq;
  1168. X    if (t < 0.)
  1169. X        return FALSE;
  1170. X    t = (Float)sqrt((double)t);
  1171. X    s = b - t;
  1172. X    if (s > mindist) {
  1173. X        if (s < *maxdist) {
  1174. X            *maxdist = s;
  1175. X            SphHits++;
  1176. X            return TRUE;
  1177. X        }
  1178. X        return FALSE;
  1179. X    }
  1180. X    s = b + t;
  1181. X    if (s > mindist && s < *maxdist) {
  1182. X        *maxdist = s;
  1183. X        SphHits++;
  1184. X        return TRUE;
  1185. X    }
  1186. X    return FALSE;
  1187. X}
  1188. X
  1189. X/*
  1190. X * Compute normal to sphere at pos
  1191. X */
  1192. Xint
  1193. XSphereNormal(sphere, pos, nrm, gnrm)
  1194. XSphere *sphere;
  1195. XVector *pos, *nrm, *gnrm;
  1196. X{
  1197. X    nrm->x = (pos->x - sphere->x) / sphere->r;
  1198. X    nrm->y = (pos->y - sphere->y) / sphere->r;
  1199. X    nrm->z = (pos->z - sphere->z) / sphere->r;
  1200. X    *gnrm = *nrm;
  1201. X    return FALSE;
  1202. X}
  1203. X
  1204. X/*
  1205. X * Determine if ray enters (TRUE) or leaves (FALSE) sphere at pos
  1206. X */
  1207. Xint
  1208. XSphereEnter(sphere, ray, mind, hitd)
  1209. XSphere *sphere;
  1210. XRay *ray;
  1211. XFloat mind, hitd;
  1212. X{
  1213. X    Vector pos;
  1214. X
  1215. X    VecAddScaled(ray->pos, mind, ray->dir, &pos);
  1216. X    pos.x -= sphere->x;
  1217. X    pos.y -= sphere->y;
  1218. X    pos.z -= sphere->z;
  1219. X
  1220. X    return dotp(&pos, &pos) > sphere->rsq;
  1221. X}
  1222. X
  1223. X/*ARGSUSED*/
  1224. Xvoid
  1225. XSphereUV(sphere, pos, norm, uv, dpdu, dpdv)
  1226. XSphere *sphere;
  1227. XVector *pos, *norm, *dpdu, *dpdv;
  1228. XVec2d *uv;
  1229. X{
  1230. X    Float phi, theta;
  1231. X    Vector realnorm;
  1232. X
  1233. X    realnorm.x = pos->x - sphere->x;
  1234. X    realnorm.y = pos->y - sphere->y;
  1235. X    realnorm.z = pos->z - sphere->z;
  1236. X    VecNormalize( &realnorm );
  1237. X    if (realnorm.z > 1.)    /* roundoff */
  1238. X        phi = PI;
  1239. X    else if (realnorm.z < -1.)
  1240. X        phi = 0;
  1241. X    else
  1242. X        phi = acos(-realnorm.z);
  1243. X
  1244. X    uv->v = phi / PI;
  1245. X
  1246. X    if (fabs(uv->v) < EPSILON || equal(uv->v, 1.))
  1247. X        uv->u = 0.;
  1248. X    else {
  1249. X        theta = realnorm.x / sin(phi);
  1250. X        if (theta > 1.)
  1251. X            theta = 0.;
  1252. X        else if (theta < -1.)
  1253. X            theta = 0.5;
  1254. X        else
  1255. X            theta = acos(theta) / TWOPI;
  1256. X
  1257. X        if (realnorm.y > 0)
  1258. X            uv->u = theta;
  1259. X        else
  1260. X            uv->u = 1 - theta;
  1261. X    }
  1262. X    if (dpdu != (Vector *)0) {
  1263. X        dpdu->x = -realnorm.y;
  1264. X        dpdu->y = realnorm.x;
  1265. X        dpdu->z = 0.;
  1266. X        (void)VecNormalize(dpdu);
  1267. X        (void)VecNormCross(&realnorm, dpdu, dpdv);
  1268. X    }
  1269. X}
  1270. X
  1271. Xvoid
  1272. XSphereBounds(s, bounds)
  1273. XSphere *s;
  1274. XFloat bounds[2][3];
  1275. X{
  1276. X    bounds[LOW][X] = s->x - s->r;
  1277. X    bounds[HIGH][X] = s->x + s->r;
  1278. X    bounds[LOW][Y] = s->y - s->r;
  1279. X    bounds[HIGH][Y] = s->y + s->r;
  1280. X    bounds[LOW][Z] = s->z - s->r;
  1281. X    bounds[HIGH][Z] = s->z + s->r;
  1282. X}
  1283. X
  1284. Xchar *
  1285. XSphereName()
  1286. X{
  1287. X    return sphereName;
  1288. X}
  1289. X
  1290. Xvoid
  1291. XSphereStats(tests, hits)
  1292. Xunsigned long *tests, *hits;
  1293. X{
  1294. X    *tests = SphTests;
  1295. X    *hits = SphHits;
  1296. X}
  1297. X
  1298. Xvoid
  1299. XSphereMethodRegister(meth)
  1300. XUserMethodType meth;
  1301. X{
  1302. X    if (iSphereMethods)
  1303. X        iSphereMethods->user = meth;
  1304. X}
  1305. END_OF_FILE
  1306. if test 4775 -ne `wc -c <'libray/libobj/sphere.c'`; then
  1307.     echo shar: \"'libray/libobj/sphere.c'\" unpacked with wrong size!
  1308. fi
  1309. # end of 'libray/libobj/sphere.c'
  1310. fi
  1311. if test -f 'libray/libsurf/surfshade.c' -a "${1}" != "-c" ; then 
  1312.   echo shar: Will not clobber existing file \"'libray/libsurf/surfshade.c'\"
  1313. else
  1314. echo shar: Extracting \"'libray/libsurf/surfshade.c'\" \(4829 characters\)
  1315. sed "s/^X//" >'libray/libsurf/surfshade.c' <<'END_OF_FILE'
  1316. X/*
  1317. X * surfshade.c
  1318. X *
  1319. X * Copyright (C) 1989, 1991, Craig E. Kolb
  1320. X * All rights reserved.
  1321. X *
  1322. X * This software may be freely copied, modified, and redistributed
  1323. X * provided that this copyright notice is preserved on all copies.
  1324. X *
  1325. X * You may not distribute this software, in whole or in part, as part of
  1326. X * any commercial product without the express consent of the authors.
  1327. X *
  1328. X * There is no warranty or other guarantee of fitness of this software
  1329. X * for any purpose.  It is provided solely "as is".
  1330. X *
  1331. X * $Id: surfshade.c,v 4.0 91/07/17 14:41:15 kolb Exp Locker: kolb $
  1332. X *
  1333. X * $Log:    surfshade.c,v $
  1334. X * Revision 4.0  91/07/17  14:41:15  kolb
  1335. X * Initial version.
  1336. X * 
  1337. X */
  1338. X#include "libobj/geom.h"
  1339. X#include "surface.h"
  1340. X
  1341. X/*
  1342. X * Compute surface properties from given hitlist
  1343. X * Returns TRUE if ray is entering object, FALSE otherwise.
  1344. X */
  1345. Xint
  1346. XComputeSurfProps(hitlist, ray, pos, norm, gnorm, surf, smooth)
  1347. XHitList *hitlist;    /* Hit information (path through DAG) */
  1348. XRay *ray;        /* Ray in world space */
  1349. XVector *pos;        /* Intersection point */
  1350. XVector *norm, *gnorm;    /* shading normal, geometric normal (return values) */
  1351. XSurface *surf;        /* Copy of surface to use, texture-modified */
  1352. Xint *smooth;
  1353. X{
  1354. X    HitNode *hp;
  1355. X    int i;
  1356. X    Ray rtmp;
  1357. X    Geom *prim, *obj;
  1358. X    Float k, kp;
  1359. X    int texturing, transforming, entering;
  1360. X    Trans prim2model, world2model;
  1361. X
  1362. X    hp = hitlist->data;
  1363. X    prim = hp->obj;
  1364. X
  1365. X    /*
  1366. X     * Compute point of intersection in "primitive space".
  1367. X     */
  1368. X    VecAddScaled(hp->ray.pos, hp->dist, hp->ray.dir, pos);
  1369. X
  1370. X    /*
  1371. X     * Find normal to primitive at point of intersection.
  1372. X     */
  1373. X    *smooth = PrimNormal(prim, pos, norm, gnorm);
  1374. X
  1375. X    texturing = transforming = FALSE;
  1376. X
  1377. X    /*
  1378. X     * Walk down hit list, constructing world<-->primitive transformation
  1379. X     * and determining if we need to perform texture mapping.
  1380. X     * The last node is the World node, which cannot be textured or
  1381. X     * transformed, so we skip it.
  1382. X     */
  1383. X    for (i = 0, hp = hitlist->data; i < hitlist->nodes -1; hp++, i++) {
  1384. X        obj = hp->obj;
  1385. X        if (hp->dotrans) {
  1386. X            /*
  1387. X             * Here we're actually computing prim2world.
  1388. X             * When finished, we invert it.
  1389. X             */
  1390. X            if (transforming) {
  1391. X                TransCompose(&hp->trans, &world2model,
  1392. X                    &world2model);
  1393. X            } else {
  1394. X                TransCopy(&hp->trans, &world2model);
  1395. X            }
  1396. X            transforming = TRUE;
  1397. X        }
  1398. X        if (obj->texture)
  1399. X            texturing = TRUE;
  1400. X    }
  1401. X
  1402. X    /*
  1403. X     * Determine if we're entering or exiting the surface,
  1404. X     * flipping surface normals if necessary.
  1405. X     */
  1406. X    k = dotp(&hitlist->data[0].ray.dir, norm);
  1407. X    if (*smooth) {
  1408. X        /*
  1409. X         * If gnorm and shading norm differ and
  1410. X         * their dot products with the ray have
  1411. X         * different signs, use the geometric normal
  1412. X         * instead, ala Snyder & Barr's paper.
  1413. X         */
  1414. X        kp = dotp(&hitlist->data[0].ray.dir, gnorm);
  1415. X        if (k <= 0. && kp > 0. || k >= 0. && kp < 0.)
  1416. X            k = kp;
  1417. X    }
  1418. X
  1419. X    if (k > 0.) {
  1420. X        /* flip normals */
  1421. X        VecScale(-1., *gnorm, gnorm);
  1422. X        VecScale(-1., *norm, norm);
  1423. X        /*
  1424. X         * Normal indicates that we're exiting.
  1425. X         * Only set entering to TRUE if csg has indicated
  1426. X         * that the ray is, indeed, entering.
  1427. X         */
  1428. X        entering = (hitlist->data[0].enter == ENTERING);
  1429. X    } else {
  1430. X        /*
  1431. X         * Normal indicates that we're entering.
  1432. X         * Set entering flag as such unless csg has
  1433. X         * told us that we're exiting.
  1434. X         */
  1435. X        entering = !(hitlist->data[0].enter == EXITING);
  1436. X    }
  1437. X        
  1438. X    /*
  1439. X     * If there are no transformations, then world2model is identity.
  1440. X     */
  1441. X    if (!transforming)
  1442. X        TransInit(&world2model);
  1443. X    /*
  1444. X     * If we're not performing texturing, we simply need to compute
  1445. X     * the normal and point of intersection to world space.
  1446. X     */
  1447. X    if (!texturing) {
  1448. X        /*
  1449. X          * At this point 'world2model' is really 'prim2world'.
  1450. X         */
  1451. X        if (transforming) {
  1452. X            NormalTransform(norm, &world2model.itrans);
  1453. X            NormalTransform(gnorm, &world2model.itrans);
  1454. X            VecAddScaled(ray->pos,
  1455. X                     hitlist->data[hitlist->nodes -1].dist,
  1456. X                     ray->dir, pos);
  1457. X        }
  1458. X        return entering;
  1459. X    }
  1460. X    /*
  1461. X     * world2model currently transforms from primitive to world space.
  1462. X     * Invert it to get transformation from world to primitive space.
  1463. X     */
  1464. X    TransInvert(&world2model, &world2model);
  1465. X    TransInit(&prim2model);
  1466. X    rtmp = hitlist->data[0].ray;
  1467. X    /*
  1468. X     * Walk down hitlist.
  1469. X     */
  1470. X    for (hp = hitlist->data, i = 0; i < hitlist->nodes -1; i++, hp++) {
  1471. X        obj = hp->obj;
  1472. X        if (hp->dotrans) {
  1473. X            NormalTransform(norm, &hp->trans.itrans);
  1474. X            if (texturing) {
  1475. X                /*
  1476. X                 * Compose prim<-->model and world<-->model
  1477. X                 * with current transformation.
  1478. X                 */
  1479. X                TransCompose(&hp->trans, &prim2model,
  1480. X                    &prim2model);
  1481. X                TransCompose(&hp->trans, &world2model,
  1482. X                    &world2model);
  1483. X                /*
  1484. X                 * Transform point and ray to model space.
  1485. X                 */
  1486. X                PointTransform(pos, &hp->trans.trans);
  1487. X                (void)RayTransform(&rtmp, &hp->trans.trans);
  1488. X            }
  1489. X        }
  1490. X        /*
  1491. X         * Apply textures
  1492. X         */
  1493. X        if (obj->texture)
  1494. X            TextApply(obj->texture, prim, &rtmp, pos, norm,
  1495. X                gnorm, surf, &prim2model, &world2model);
  1496. X    }
  1497. X    return entering;
  1498. X}
  1499. END_OF_FILE
  1500. if test 4829 -ne `wc -c <'libray/libsurf/surfshade.c'`; then
  1501.     echo shar: \"'libray/libsurf/surfshade.c'\" unpacked with wrong size!
  1502. fi
  1503. # end of 'libray/libsurf/surfshade.c'
  1504. fi
  1505. if test -f 'libray/libtext/texture.c' -a "${1}" != "-c" ; then 
  1506.   echo shar: Will not clobber existing file \"'libray/libtext/texture.c'\"
  1507. else
  1508. echo shar: Extracting \"'libray/libtext/texture.c'\" \(4973 characters\)
  1509. sed "s/^X//" >'libray/libtext/texture.c' <<'END_OF_FILE'
  1510. X/*
  1511. X * texture.c
  1512. X *
  1513. X * Copyright (C) 1989, 1991, Craig E. Kolb
  1514. X * All rights reserved.
  1515. X *
  1516. X * This software may be freely copied, modified, and redistributed
  1517. X * provided that this copyright notice is preserved on all copies.
  1518. X *
  1519. X * You may not distribute this software, in whole or in part, as part of
  1520. X * any commercial product without the express consent of the authors.
  1521. X *
  1522. X * There is no warranty or other guarantee of fitness of this software
  1523. X * for any purpose.  It is provided solely "as is".
  1524. X *
  1525. X * $Id: texture.c,v 4.0 91/07/17 14:44:11 kolb Exp Locker: kolb $
  1526. X *
  1527. X * $Log:    texture.c,v $
  1528. X * Revision 4.0  91/07/17  14:44:11  kolb
  1529. X * Initial version.
  1530. X * 
  1531. X */
  1532. X#include "texture.h"
  1533. X
  1534. X/*
  1535. X * Transformation structures used to map from texture space to
  1536. X * model/primitive/world space.
  1537. X */
  1538. XTrans prim2model, model2text, prim2text, world2text;
  1539. X
  1540. X#define ApplyMapping(m,o,p,n,c,u,v)    (*m->method)(m, o, p, n, c, u, v)
  1541. X
  1542. XTexture *
  1543. XTextCreate(data, meth)
  1544. XTextRef data;
  1545. Xvoid (*meth)();
  1546. X{
  1547. X    Texture *res;
  1548. X
  1549. X    res = (Texture *)share_calloc(1, sizeof(Texture));
  1550. X    res->data = data;
  1551. X    res->method = meth;
  1552. X    res->trans = (Trans *)NULL; 
  1553. X    res->next = (Texture *)NULL;
  1554. X    res->animtrans = FALSE;
  1555. X    return res;
  1556. X}
  1557. X
  1558. X/*
  1559. X * Apply appropriate textures to a surface.
  1560. X */
  1561. Xvoid
  1562. XTextApply(tlist, prim, ray, pos, norm, gnorm, surf, p2model, world2model)
  1563. XTexture *tlist;                /* Textures */
  1564. XGeom *prim;
  1565. XRay *ray;
  1566. XVector *pos, *norm, *gnorm;        /* pos, shading norm, geo. norm */
  1567. XSurface *surf;
  1568. XTrans *p2model, *world2model;
  1569. X{
  1570. X    Vector ptmp;
  1571. X    Texture *ttmp;
  1572. X
  1573. X    prim2model = *p2model;
  1574. X    /*
  1575. X     * Walk down texture list, applying each in turn.
  1576. X     */
  1577. X    for (ttmp = tlist; ttmp; ttmp = ttmp->next) {
  1578. X        /*
  1579. X         * Make copies of pos & ray to pass to the texturing function.
  1580. X         */
  1581. X        ptmp = *pos;
  1582. X        if (ttmp->trans) {
  1583. X            /*
  1584. X             * 'take' the inverse of ttmp->trans, since
  1585. X             * transforming a texture means applying the
  1586. X             * inverse of the transformation
  1587. X             * to the point of intersection, etc.
  1588. X             */
  1589. X            if (ttmp->animtrans) {
  1590. X                /*
  1591. X                 * Resolve animated associations.
  1592. X                 * We currently do not store a time
  1593. X                 * for the texture, so we can't know if
  1594. X                 * we're already resolved for the current
  1595. X                 * ray->time.
  1596. X                 */
  1597. X                TransResolveAssoc(ttmp->trans);
  1598. X                TransComposeList(ttmp->trans, &model2text);
  1599. X                TransInvert(&model2text, &model2text);
  1600. X            } else
  1601. X                TransInvert(ttmp->trans, &model2text);
  1602. X            /*
  1603. X             * We compose ttmp->trans, which maps from model to
  1604. X             * texture space, with prim2model and world2model
  1605. X             * to get prim2text and world2text.
  1606. X             */
  1607. X            TransCompose(&model2text, &prim2model, &prim2text);
  1608. X            TransCompose(&model2text, world2model, &world2text);
  1609. X            /*
  1610. X             * Transform intersection point to texture space.
  1611. X             * Ray and normal are passed in model space.
  1612. X             */
  1613. X            ModelPointToText(&ptmp);
  1614. X        } else {
  1615. X            /*
  1616. X              * By default, texture and model space are identical.
  1617. X              */
  1618. X            TransInit(&model2text);
  1619. X            TransCopy(&prim2model, &prim2text);
  1620. X            TransCopy(world2model, &world2text);
  1621. X        }
  1622. X
  1623. X        /*
  1624. X         * Call texture function.
  1625. X         */
  1626. X        (*ttmp->method) (ttmp->data,prim,ray,&ptmp,norm,gnorm,surf);
  1627. X    }
  1628. X}
  1629. X
  1630. X/*
  1631. X * Compute UV at 'pos' on given primitive.
  1632. X */
  1633. XTextToUV(mapping, prim, pos, norm, u, v, dpdu, dpdv)
  1634. XMapping *mapping;
  1635. XGeom *prim;
  1636. XVector *pos, *norm, *dpdu, *dpdv;
  1637. XFloat *u, *v;
  1638. X{
  1639. X    Vec2d uv;
  1640. X    Vector ptmp;
  1641. X    RSMatrix t;
  1642. X
  1643. X    ptmp = *pos;
  1644. X
  1645. X    if (mapping->flags & PRIMSPACE) {
  1646. X        /*
  1647. X          * Convert point and normal to primitive space.
  1648. X          */
  1649. X        TextPointToPrim(&ptmp);
  1650. X    } else {
  1651. X        /*
  1652. X         * Convert point and normal to object space.
  1653. X         */
  1654. X        TextPointToModel(&ptmp);
  1655. X    }
  1656. X
  1657. X    ApplyMapping(mapping, prim, &ptmp, norm, &uv, dpdu, dpdv);
  1658. X
  1659. X    /*
  1660. X     * Transform UV by model2text.  We set X = u and Y = v,
  1661. X     * while Z = 0.
  1662. X     * Although the UV coordinates may be in prim space,
  1663. X     * we treat them as if they are model-space coords.
  1664. X     * This is due to the fact that we want the texture
  1665. X     * to be applied in model space.
  1666. X     */
  1667. X    ptmp.x = uv.u;
  1668. X    ptmp.y = uv.v;
  1669. X    ptmp.z = 0.;
  1670. X    PointTransform(&ptmp, &model2text.trans);
  1671. X    *u = ptmp.x;
  1672. X    *v = ptmp.y;
  1673. X    if (dpdu == (Vector *)NULL || dpdv == (Vector *)NULL)
  1674. X        return;
  1675. X    /*
  1676. X     * Here's the ugly part.
  1677. X     * Build initial UVN-->XYZ matrix...
  1678. X     */
  1679. X    ArbitraryMatrix(dpdu->x, dpdu->y, dpdu->z,
  1680. X             dpdv->x, dpdv->y, dpdv->z,
  1681. X             norm->x, norm->y, norm->z, 0., 0., 0., &t);
  1682. X    /*
  1683. X     * ...transform to model space...
  1684. X     */
  1685. X    MatrixMult(&t, &prim2model.trans, &t);
  1686. X    /*
  1687. X     * ... apply model2text in UVN space.
  1688. X     */
  1689. X    MatrixMult(&model2text.itrans, &t, &t);
  1690. X    dpdu->x = t.matrix[0][0];
  1691. X    dpdu->y = t.matrix[0][1];
  1692. X    dpdu->z = t.matrix[0][2];
  1693. X    dpdv->x = t.matrix[1][0];
  1694. X    dpdv->y = t.matrix[1][1];
  1695. X    dpdv->z = t.matrix[1][2];
  1696. X    (void)VecNormalize(dpdu);
  1697. X    (void)VecNormalize(dpdv);
  1698. X}
  1699. X
  1700. X/*
  1701. X * Append 'text' to the given linked list of textures.
  1702. X * Note that 'text' may be a list, too.
  1703. X */
  1704. XTexture *
  1705. XTextAppend(text, list)
  1706. XTexture *text, *list;
  1707. X{
  1708. X    Texture *tp;
  1709. X
  1710. X    if (list) {
  1711. X        /*
  1712. X         * Walk to the end of the list
  1713. X         */
  1714. X        for (tp = list;tp->next ;tp = tp->next)
  1715. X                ;
  1716. X        tp->next = text;
  1717. X        return list;
  1718. X    }
  1719. X    /* else */
  1720. X    return text;
  1721. X}
  1722. END_OF_FILE
  1723. if test 4973 -ne `wc -c <'libray/libtext/texture.c'`; then
  1724.     echo shar: \"'libray/libtext/texture.c'\" unpacked with wrong size!
  1725. fi
  1726. # end of 'libray/libtext/texture.c'
  1727. fi
  1728. if test -f 'libshade/misc.c' -a "${1}" != "-c" ; then 
  1729.   echo shar: Will not clobber existing file \"'libshade/misc.c'\"
  1730. else
  1731. echo shar: Extracting \"'libshade/misc.c'\" \(4080 characters\)
  1732. sed "s/^X//" >'libshade/misc.c' <<'END_OF_FILE'
  1733. X/*
  1734. X * misc.c
  1735. X *
  1736. X * Copyright (C) 1989, 1991, Craig E. Kolb
  1737. X * All rights reserved.
  1738. X *
  1739. X * This software may be freely copied, modified, and redistributed
  1740. X * provided that this copyright notice is preserved on all copies.
  1741. X *
  1742. X * You may not distribute this software, in whole or in part, as part of
  1743. X * any commercial product without the express consent of the authors.
  1744. X *
  1745. X * There is no warranty or other guarantee of fitness of this software
  1746. X * for any purpose.  It is provided solely "as is".
  1747. X *
  1748. X * $Id: misc.c,v 4.0 91/07/17 14:46:31 kolb Exp Locker: kolb $
  1749. X *
  1750. X * $Log:    misc.c,v $
  1751. X * Revision 4.0  91/07/17  14:46:31  kolb
  1752. X * Initial version.
  1753. X * 
  1754. X */
  1755. X#include "rayshade.h"
  1756. X#ifdef RUSAGE
  1757. X#include <sys/time.h>
  1758. X#include <sys/resource.h>
  1759. X#else
  1760. X#ifdef TIMES
  1761. X#include <sys/types.h>
  1762. X#include <sys/times.h>
  1763. X#include <sys/param.h>
  1764. X#endif
  1765. X#endif
  1766. X#include "options.h"
  1767. X#include "stats.h"
  1768. X
  1769. XFloat RSabstmp;    /* Temporary value used by fabs macro.  Ugly. */
  1770. Xstatic void RSmessage();
  1771. X
  1772. X/*
  1773. X * Open input file and call yyparse().
  1774. X */
  1775. Xvoid
  1776. XRSReadInputFile()
  1777. X{
  1778. X    extern FILE *yyin;    /* lex/yacc file pointer */
  1779. X    extern char yyfilename[];
  1780. X
  1781. X#if defined(CPPSTDIN) && defined(POPEN)
  1782. X    char cmd[BUFSIZ];
  1783. X
  1784. X    if (Options.cppargs != (char *)NULL)
  1785. X        sprintf(cmd, "%s %s ", CPPSTDIN, Options.cppargs);
  1786. X    else
  1787. X        /* fromstdin */
  1788. X        sprintf(cmd, "%s %s ", CPPSTDIN, CPPMINUS);
  1789. X
  1790. X    if (Options.inputname == (char *)NULL) {
  1791. X        (void)strcpy(yyfilename, "stdin");
  1792. X    } else {
  1793. X        (void)strcpy(yyfilename, Options.inputname);
  1794. X        (void)strcat(cmd, Options.inputname);
  1795. X    }
  1796. X    yyin = popen(cmd, "r");
  1797. X    if (yyin == (FILE *)NULL)
  1798. X        RLerror(RL_PANIC, "popen of \"%s\" failed!\n", cmd);
  1799. X#else
  1800. X    if (Options.inputname == (char *)NULL) {
  1801. X        yyin = stdin;
  1802. X        (void)strcpy(yyfilename, "stdin");
  1803. X    } else {
  1804. X        (void)strcpy(yyfilename, Options.inputname);
  1805. X        yyin = fopen(Options.inputname, "r");
  1806. X        if (yyin == (FILE *)NULL)
  1807. X            RLerror(RL_PANIC,
  1808. X                "Cannot open %s.\n",Options.inputname);
  1809. X    }
  1810. X#endif
  1811. X    /*
  1812. X     * Initialize symbol table.
  1813. X     */
  1814. X    SymtabInit();
  1815. X    (void)yyparse();
  1816. X}
  1817. X
  1818. Xvoid
  1819. XOpenStatsFile()
  1820. X{
  1821. X    if (Options.statsname == (char *)NULL || Stats.fstats != stderr)
  1822. X        return;        /* Not specified or already opened. */
  1823. X
  1824. X    Stats.fstats = fopen(Options.statsname, "w");
  1825. X    if (Stats.fstats == (FILE *)NULL) {
  1826. X        RLerror(RL_PANIC,
  1827. X            "Cannot open stats file %s.\n", Options.statsname);
  1828. X    }
  1829. X}
  1830. X
  1831. Xvoid
  1832. XRLerror(level, pat, arg1, arg2, arg3)
  1833. Xint level;
  1834. Xchar *pat, *arg1, *arg2, *arg3;
  1835. X{
  1836. X    switch (level) {
  1837. X        case RL_ADVISE:
  1838. X            if (!Options.quiet)
  1839. X                RSmessage("Warning", pat, arg1, arg2, arg3);
  1840. X            break;
  1841. X        case RL_WARN:
  1842. X            RSmessage("Warning", pat, arg1, arg2, arg3);
  1843. X            break;
  1844. X        case RL_ABORT:
  1845. X            RSmessage("Error", pat, arg1, arg2, arg3);
  1846. X            exit(1);
  1847. X            break;
  1848. X        case RL_PANIC:
  1849. X            RSmessage("Fatal error", pat, arg1, arg2, arg3);
  1850. X            exit(2);
  1851. X            break;
  1852. X        default:
  1853. X            RSmessage("Unknown error", pat, arg1, arg2, arg3);
  1854. X            exit(3);
  1855. X    }
  1856. X}
  1857. X
  1858. Xstatic void
  1859. XRSmessage(type, pat, arg1, arg2, arg3)
  1860. Xchar *type, *pat, *arg1, *arg2, *arg3;
  1861. X{
  1862. X    extern FILE *yyin;
  1863. X    extern int yylineno;
  1864. X    extern char yyfilename[];
  1865. X
  1866. X    if (yyin) {
  1867. X        /*
  1868. X         * cleanup() hasn't nulled yyin, so line #
  1869. X         * info is valid.
  1870. X         */
  1871. X        fprintf(stderr,"%s: %s: %s, line %d: ",
  1872. X            Options.progname, type,
  1873. X            yyfilename == (char *)NULL ? "stdin" :
  1874. X                yyfilename, yylineno);
  1875. X    } else {
  1876. X        fprintf(stderr,"%s: %s: ", Options.progname, type);
  1877. X    }
  1878. X    fprintf(stderr, pat, arg1, arg2, arg3);
  1879. X}
  1880. X        
  1881. X#ifdef RUSAGE
  1882. Xvoid
  1883. XRSGetCpuTime(usertime, systime)
  1884. XFloat *usertime, *systime;
  1885. X{
  1886. X    struct rusage usage;
  1887. X
  1888. X    getrusage(RUSAGE_SELF, &usage);
  1889. X
  1890. X    *usertime = (Float)usage.ru_utime.tv_sec +
  1891. X            (Float)usage.ru_utime.tv_usec / 1000000.;
  1892. X    *systime = (Float)usage.ru_stime.tv_sec +
  1893. X            (Float)usage.ru_stime.tv_usec / 1000000.;
  1894. X}
  1895. X
  1896. X#else
  1897. X#ifdef TIMES
  1898. X
  1899. Xvoid
  1900. XRSGetCpuTime(usertime, systime)
  1901. XFloat *usertime, *systime;
  1902. X{
  1903. X    extern CLOCKTYPE times();
  1904. X    struct tms time;
  1905. X
  1906. X    (void)times(&time);
  1907. X    *usertime = (Float)time.tms_utime / (Float)HZ;
  1908. X    *systime = (Float)time.tms_stime / (Float)HZ;
  1909. X}
  1910. X
  1911. X#else /* !RUSAGE && !TIMES */
  1912. X
  1913. Xvoid
  1914. XRSGetCpuTime(usertime, systime)
  1915. XFloat *usertime, *systime;
  1916. X{
  1917. X    *usertime = *systime = 0.;
  1918. X}
  1919. X
  1920. X#endif /* TIMES */
  1921. X#endif /* RUSAGE */
  1922. END_OF_FILE
  1923. if test 4080 -ne `wc -c <'libshade/misc.c'`; then
  1924.     echo shar: \"'libshade/misc.c'\" unpacked with wrong size!
  1925. fi
  1926. # end of 'libshade/misc.c'
  1927. fi
  1928. if test -f 'libshade/stats.c' -a "${1}" != "-c" ; then 
  1929.   echo shar: Will not clobber existing file \"'libshade/stats.c'\"
  1930. else
  1931. echo shar: Extracting \"'libshade/stats.c'\" \(4043 characters\)
  1932. sed "s/^X//" >'libshade/stats.c' <<'END_OF_FILE'
  1933. X/*
  1934. X * stats.c
  1935. X *
  1936. X * Copyright (C) 1989, 1991, Craig E. Kolb
  1937. X * All rights reserved.
  1938. X *
  1939. X * This software may be freely copied, modified, and redistributed
  1940. X * provided that this copyright notice is preserved on all copies.
  1941. X *
  1942. X * You may not distribute this software, in whole or in part, as part of
  1943. X * any commercial product without the express consent of the authors.
  1944. X *
  1945. X * There is no warranty or other guarantee of fitness of this software
  1946. X * for any purpose.  It is provided solely "as is".
  1947. X *
  1948. X * $Id: stats.c,v 4.0 91/07/17 14:47:41 kolb Exp Locker: kolb $
  1949. X *
  1950. X * $Log:    stats.c,v $
  1951. X * Revision 4.0  91/07/17  14:47:41  kolb
  1952. X * Initial version.
  1953. X * 
  1954. X */
  1955. X#include <ctype.h>
  1956. X#include "rayshade.h"
  1957. X#include "options.h"
  1958. X#include "stats.h"
  1959. X
  1960. XRSStats Stats;            /* Statistical information */
  1961. XGeom *GeomRep = NULL;    /* Linked list of object representatives */
  1962. X
  1963. Xstatic void PrintGeomStats();
  1964. X
  1965. Xvoid
  1966. XStatsPrint()
  1967. X{
  1968. X    extern void PrintMemoryStats();
  1969. X    unsigned long TotalRays;
  1970. X
  1971. X#ifndef LINDA
  1972. X    RSGetCpuTime(&Stats.Utime, &Stats.Stime);
  1973. X#endif
  1974. X    ShadowStats(&Stats.ShadowRays, &Stats.ShadowHits,
  1975. X            &Stats.CacheHits, &Stats.CacheMisses);
  1976. X    IntersectStats(&Stats.BVTests);
  1977. X    
  1978. X    TotalRays = Stats.EyeRays + Stats.ShadowRays + Stats.ReflectRays
  1979. X             + Stats.RefractRays;
  1980. X    Stats.ShadowHits += Stats.CacheHits;
  1981. X    Stats.HitRays += Stats.ShadowHits;
  1982. X#ifdef LINDA
  1983. X    fprintf(Stats.fstats,"Workers:\t\t\t%d\n",Options.workers);
  1984. X#endif
  1985. X    fprintf(Stats.fstats,"Eye rays:\t\t\t%lu\n", Stats.EyeRays);
  1986. X    fprintf(Stats.fstats,"Shadow rays:\t\t\t%lu\n",Stats.ShadowRays);
  1987. X    fprintf(Stats.fstats,"Reflected rays:\t\t\t%lu\n",Stats.ReflectRays);
  1988. X    fprintf(Stats.fstats,"Refracted rays:\t\t\t%lu\n",Stats.RefractRays);
  1989. X    fprintf(Stats.fstats,"Total rays:\t\t\t%lu\n", TotalRays);
  1990. X    if (TotalRays != 0)
  1991. X        fprintf(Stats.fstats,"Intersecting rays:\t\t%lu (%3.3f%%)\n",
  1992. X            Stats.HitRays,
  1993. X            100. * (float)Stats.HitRays / (float)TotalRays);
  1994. X    if (Stats.ShadowRays != 0) {
  1995. X        if (Options.cache)
  1996. X            fprintf(Stats.fstats,
  1997. X                "Shadow cache hits:\t\t%lu (%lu misses)\n",
  1998. X                Stats.CacheHits, Stats.CacheMisses);
  1999. X        fprintf(Stats.fstats,"Total shadow hits:\t\t%lu (%3.3f%%)\n",
  2000. X            Stats.ShadowHits, 100.*(float)Stats.ShadowHits /
  2001. X            (float)Stats.ShadowRays);
  2002. X    }
  2003. X    fprintf(Stats.fstats,"Supersampled pixels:\t\t%lu\n",
  2004. X        Stats.SuperSampled);
  2005. X    fprintf(Stats.fstats,"B.V. intersection tests:\t%lu\n",Stats.BVTests);
  2006. X    PrintGeomStats();
  2007. X#ifdef LINDA
  2008. X    fprintf(Stats.fstats,"Average CPU time/processor:\t");
  2009. X#else
  2010. X    fprintf(Stats.fstats,"Total CPU time (sec):\t\t");
  2011. X#endif
  2012. X    fprintf(Stats.fstats,"%2.2f (%2.2fu + %2.2fs)\n",
  2013. X        Stats.Utime+Stats.Stime, Stats.Utime, Stats.Stime);
  2014. X    if (TotalRays != 0.)
  2015. X        fprintf(Stats.fstats,"Seconds / ray:\t\t\t%4.4f\n",
  2016. X            (Stats.Utime + Stats.Stime) / (Float)TotalRays);
  2017. X    if (Stats.HitRays != 0.)
  2018. X        fprintf(Stats.fstats,"Seconds / intersecting ray:\t%4.4f\n",
  2019. X            (Stats.Utime + Stats.Stime)/(Float)Stats.HitRays);
  2020. X    PrintMemoryStats(Stats.fstats);
  2021. X}
  2022. X
  2023. Xstatic void
  2024. XPrintGeomStats()
  2025. X{
  2026. X    Geom *otmp;
  2027. X    unsigned long tests, hits, totaltests, totalhits;
  2028. X    char *name;
  2029. X    extern void GeomStats();
  2030. X
  2031. X    totaltests = totalhits = 0;
  2032. X
  2033. X    for (otmp = GeomRep; otmp; otmp = otmp->next) {
  2034. X        GeomStats(otmp, &tests, &hits);
  2035. X        if (tests <= 0)
  2036. X            continue;
  2037. X        name = GeomName(otmp);
  2038. X        fprintf(Stats.fstats,
  2039. X            "%c%s intersection tests:\t%lu (%lu hit, %f%%)\n",
  2040. X                toupper((int)name[0]), &name[1], tests, hits,
  2041. X                100.*(float)hits/(float)tests);
  2042. X        if (!IsAggregate(otmp)) {
  2043. X            totaltests += tests;
  2044. X            totalhits += hits;
  2045. X        }
  2046. X    }
  2047. X    fprintf(Stats.fstats,"Total prim. intersection tests:\t%lu",
  2048. X        totaltests);
  2049. X    if (totaltests == 0)
  2050. X        fprintf(Stats.fstats,"\n");
  2051. X    else
  2052. X        fprintf(Stats.fstats," (%lu hit, %f%%)\n", totalhits,
  2053. X            100.*(float)totalhits/(float)totaltests);
  2054. X}
  2055. X
  2056. Xvoid
  2057. XStatsAddRep(obj)
  2058. XGeom *obj;
  2059. X{
  2060. X    Geom *otmp;
  2061. X
  2062. X    for (otmp = GeomRep; otmp; otmp = otmp->next) {
  2063. X        if (otmp->methods->stats == obj->methods->stats)
  2064. X            return;
  2065. X    }
  2066. X
  2067. X    /*
  2068. X     * Stats method didn't match anything found so far.  Add
  2069. X     * a copy of obj to head of GeomRep list.
  2070. X     */
  2071. X    otmp = GeomCopy(obj);
  2072. X    otmp->next = GeomRep;
  2073. X    GeomRep = otmp;
  2074. X}
  2075. END_OF_FILE
  2076. if test 4043 -ne `wc -c <'libshade/stats.c'`; then
  2077.     echo shar: \"'libshade/stats.c'\" unpacked with wrong size!
  2078. fi
  2079. # end of 'libshade/stats.c'
  2080. fi
  2081. echo shar: End of archive 8 \(of 19\).
  2082. cp /dev/null ark8isdone
  2083. MISSING=""
  2084. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  2085.     if test ! -f ark${I}isdone ; then
  2086.     MISSING="${MISSING} ${I}"
  2087.     fi
  2088. done
  2089. if test "${MISSING}" = "" ; then
  2090.     echo You have unpacked all 19 archives.
  2091.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2092. else
  2093.     echo You still need to unpack the following archives:
  2094.     echo "        " ${MISSING}
  2095. fi
  2096. ##  End of shell archive.
  2097. exit 0
  2098.  
  2099. exit 0 # Just in case...
  2100.