home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume21 / rayshade / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-03-21  |  52.8 KB

  1. Subject:  v21i011:  A ray tracing program, Part04/08
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Craig Kolb <craig@weedeater.math.yale.edu>
  7. Posting-number: Volume 21, Issue 11
  8. Archive-name: rayshade/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 8)."
  17. # Contents:  src/Makefile src/malloc.c src/noise.c src/poly.c
  18. #   src/texture.c src/triangle.c
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'src/Makefile'\"
  22. else
  23. echo shar: Extracting \"'src/Makefile'\" \(7691 characters\)
  24. sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
  25. X#
  26. X# Makefile for rayshade.
  27. X#
  28. X# Craig Kolb
  29. X#
  30. X# $Id: Makefile,v 3.0 89/10/27 02:05:45 craig Exp $
  31. X#
  32. X# $Log:    Makefile,v $
  33. X# Revision 3.0  89/10/27  02:05:45  craig
  34. X# Baseline for first official release.
  35. X# 
  36. X# Location of Utah-raster library and include files, if appropriate.
  37. X# If you are compiling with -DNORLE, leave these two undefined.
  38. X#
  39. XRLELIB = /usr/u/utah/lib/librle.a
  40. XRLEINC = /usr/u/utah/include
  41. X#
  42. X# Linda compiler, if appropriate.
  43. X#
  44. X#LCC = /homes/systems/carriero/linda/v2.2/bin/clc
  45. X#
  46. X# Temporary file directory, bin direction, and executable name.
  47. X#
  48. XTMPDIR = /tmp
  49. XBINDIR = /usr/u/craig/bin
  50. XSHADENAME = rayshade
  51. X#
  52. X# Compiler flags.
  53. X#
  54. X# GENERIC (BSD):    CFLAGS = -I$(RLEINC) -DTMPDIR=\"$(TMPDIR)\"
  55. X# SYSV:            add -DSYSV
  56. X#
  57. X# Multimax (shared memory):
  58. X#            add -DMULTIMAX
  59. X# Linda:        add -DLINDA (and move raytrace.c to raytrace.cl)
  60. X#
  61. X# Long ago, rayshade was compiled on the Amiga using Aztec C and:
  62. X#            CFLAGS = +fi +C +D +L -DTMPDIR="t:" -DAZTEC
  63. X# 
  64. X# If you are not using the Utah Raster toolkit, add -DNORLE
  65. X# If your compiler doesn't understand the void type, add -DNOVOID
  66. X#
  67. X# If your compiler has trouble with the definitions of
  68. X# vecadd(), veccomb(), etc. in funcdefs.h, compile with -DDUMB_CPP
  69. X#
  70. X# Be sure to add any necessary floating-point hardware switches.
  71. X# 
  72. XCFLAGS = -I$(RLEINC) -DTMPDIR=\"$(TMPDIR)\" -O -DSYSV
  73. X#
  74. X# Libraries:
  75. X# BSD:        LIBS = $(RLELIB) -lm
  76. X# SYSV:        LIBS = $(RLELIB) -lm
  77. X# AZTEC C (amiga):
  78. X#        LIBS = $(RLELIB) -lUnixl32 -lmal32 -lml32 -lcl32
  79. X#
  80. X# Multimax:    LIBS = $(RLELIB) -lm -lpp
  81. X#
  82. X# If you have fast versions of malloc/free available, use them
  83. X# (e.g., -lmalloc on MIPS machines).
  84. X#
  85. XLIBS = $(RLELIB) -lm -lmalloc
  86. X#
  87. X# Uncomment the following line if you want the
  88. X# fast malloc routines in malloc.c to be used.
  89. X#
  90. X#MALLOC.O = malloc.o
  91. X
  92. X#
  93. X# Change "raytrace.o" to "raytrace.lo" below if using Linda.
  94. X#
  95. XOBJ =         main.o ray_options.o setup.o input.o input_yacc.o input_lex.o \
  96. X        viewing.o object.o bounds.o voxels.o list.o surface.o \
  97. X        raymath.o matrix.o raytrace.o intersect.o grid.o box.o cone.o \
  98. X        cylinder.o hf.o plane.o poly.o sphere.o superq.o triangle.o \
  99. X        texture.o noise.o shade.o atmosphere.o light.o outputp.o \
  100. X        memory.o version.o $(MALLOC.O)
  101. X
  102. XSRC =         main.c ray_options.c setup.c input.c input_yacc.c input_lex.c \
  103. X        viewing.c object.c bounds.c voxels.c list.c surface.c \
  104. X        raymath.c matrix.c raytrace.c intersect.c grid.c box.c cone.c \
  105. X        cylinder.c hf.c plane.c poly.c sphere.c superq.c triangle.c \
  106. X        texture.c noise.c shade.c atmosphere.c light.c outputp.c \
  107. X        memory.c version.c
  108. X#
  109. X# Change $(CC) below to $(LCC) if using Linda.
  110. X#
  111. X$(SHADENAME): $(OBJ)
  112. X    $(CC) $(CFLAGS) -o $(SHADENAME) $(OBJ) $(LIBS)
  113. X
  114. X#
  115. X# Uncomment the following rule if using Linda.
  116. X#
  117. X#raytrace.lo: raytrace.cl
  118. X#    $(LCC) $(CFLAGS) -c raytrace.cl
  119. X
  120. X#
  121. X# End of configuration section
  122. X#
  123. Xinstall:    $(SHADENAME)
  124. X        mv $(SHADENAME) $(BINDIR)/$(SHADENAME)
  125. X
  126. Xinput_yacc.c:    input_yacc.y
  127. X        yacc -d input_yacc.y
  128. X        mv y.tab.c input_yacc.c
  129. X
  130. Xinput_lex.c:    input_lex.l
  131. X        lex -t input_lex.l > input_lex.c
  132. X
  133. Xclean:
  134. X    @ /bin/rm -f $(OBJ) core
  135. X
  136. Xrealclean:
  137. X    @ /bin/rm -f $(OBJ) core input_lex.c input_yacc.c y.tab.h
  138. X
  139. Xlint:
  140. X    lint $(CFLAGS) $(SRC)
  141. X
  142. Xdepend:
  143. X    (sed '/^# DO NOT DELETE THIS LINE/q' Makefile && \
  144. X     cc -M ${CFLAGS} ${SRC} | sed 's/\.\///; /\//d' \
  145. X    ) >Makefile.new
  146. X    cp Makefile Makefile.bak
  147. X    cp Makefile.new Makefile
  148. X    rm -f Makefile.new
  149. X
  150. Xarchive:
  151. X    (cd .. ;  tar cvf ../rayshade.arch.tar .)
  152. X
  153. Xkit:
  154. X    (cd .. ; makekit -iPACKING_LIST -oMANIFEST)
  155. X
  156. X# DO NOT DELETE THIS LINE
  157. Xmain.o: main.c
  158. Xmain.o: constants.h
  159. Xmain.o: typedefs.h
  160. Xmain.o: datatypes.h
  161. Xmain.o: primobj.h
  162. Xmain.o: defaults.h
  163. Xray_options.o: ray_options.c
  164. Xray_options.o: constants.h
  165. Xray_options.o: typedefs.h
  166. Xray_options.o: datatypes.h
  167. Xray_options.o: primobj.h
  168. Xsetup.o: setup.c
  169. Xsetup.o: constants.h
  170. Xsetup.o: defaults.h
  171. Xsetup.o: typedefs.h
  172. Xsetup.o: datatypes.h
  173. Xsetup.o: primobj.h
  174. Xsetup.o: funcdefs.h
  175. Xinput.o: input.c
  176. Xinput.o: constants.h
  177. Xinput.o: typedefs.h
  178. Xinput.o: datatypes.h
  179. Xinput.o: primobj.h
  180. Xinput_yacc.o: input_yacc.c
  181. Xinput_yacc.o: constants.h
  182. Xinput_yacc.o: typedefs.h
  183. Xinput_yacc.o: datatypes.h
  184. Xinput_yacc.o: primobj.h
  185. Xinput_yacc.o: funcdefs.h
  186. Xinput_yacc.o: texture.h
  187. Xinput_lex.o: input_lex.c
  188. Xinput_lex.o: typedefs.h
  189. Xinput_lex.o: datatypes.h
  190. Xinput_lex.o: primobj.h
  191. Xinput_lex.o: y.tab.h
  192. Xviewing.o: viewing.c
  193. Xviewing.o: constants.h
  194. Xviewing.o: typedefs.h
  195. Xviewing.o: datatypes.h
  196. Xviewing.o: primobj.h
  197. Xviewing.o: funcdefs.h
  198. Xobject.o: object.c
  199. Xobject.o: constants.h
  200. Xobject.o: typedefs.h
  201. Xobject.o: datatypes.h
  202. Xobject.o: primobj.h
  203. Xobject.o: funcdefs.h
  204. Xobject.o: texture.h
  205. Xbounds.o: bounds.c
  206. Xbounds.o: constants.h
  207. Xbounds.o: typedefs.h
  208. Xbounds.o: datatypes.h
  209. Xbounds.o: primobj.h
  210. Xbounds.o: funcdefs.h
  211. Xvoxels.o: voxels.c
  212. Xvoxels.o: constants.h
  213. Xvoxels.o: typedefs.h
  214. Xvoxels.o: datatypes.h
  215. Xvoxels.o: primobj.h
  216. Xvoxels.o: funcdefs.h
  217. Xlist.o: list.c
  218. Xlist.o: constants.h
  219. Xlist.o: typedefs.h
  220. Xlist.o: datatypes.h
  221. Xlist.o: primobj.h
  222. Xlist.o: funcdefs.h
  223. Xsurface.o: surface.c
  224. Xsurface.o: constants.h
  225. Xsurface.o: typedefs.h
  226. Xsurface.o: datatypes.h
  227. Xsurface.o: primobj.h
  228. Xsurface.o: funcdefs.h
  229. Xraymath.o: raymath.c
  230. Xraymath.o: typedefs.h
  231. Xraymath.o: datatypes.h
  232. Xraymath.o: primobj.h
  233. Xraymath.o: constants.h
  234. Xraymath.o: funcdefs.h
  235. Xmatrix.o: matrix.c
  236. Xmatrix.o: typedefs.h
  237. Xmatrix.o: datatypes.h
  238. Xmatrix.o: primobj.h
  239. Xmatrix.o: constants.h
  240. Xmatrix.o: funcdefs.h
  241. Xraytrace.o: raytrace.c
  242. Xraytrace.o: typedefs.h
  243. Xraytrace.o: datatypes.h
  244. Xraytrace.o: primobj.h
  245. Xraytrace.o: constants.h
  246. Xraytrace.o: funcdefs.h
  247. Xraytrace.o: raytrace.h
  248. Xintersect.o: intersect.c
  249. Xintersect.o: typedefs.h
  250. Xintersect.o: datatypes.h
  251. Xintersect.o: primobj.h
  252. Xintersect.o: funcdefs.h
  253. Xintersect.o: constants.h
  254. Xgrid.o: grid.c
  255. Xgrid.o: constants.h
  256. Xgrid.o: typedefs.h
  257. Xgrid.o: datatypes.h
  258. Xgrid.o: primobj.h
  259. Xgrid.o: funcdefs.h
  260. Xbox.o: box.c
  261. Xbox.o: constants.h
  262. Xbox.o: typedefs.h
  263. Xbox.o: datatypes.h
  264. Xbox.o: primobj.h
  265. Xbox.o: funcdefs.h
  266. Xcone.o: cone.c
  267. Xcone.o: typedefs.h
  268. Xcone.o: datatypes.h
  269. Xcone.o: primobj.h
  270. Xcone.o: funcdefs.h
  271. Xcone.o: constants.h
  272. Xcylinder.o: cylinder.c
  273. Xcylinder.o: typedefs.h
  274. Xcylinder.o: datatypes.h
  275. Xcylinder.o: primobj.h
  276. Xcylinder.o: funcdefs.h
  277. Xcylinder.o: constants.h
  278. Xhf.o: hf.c
  279. Xhf.o: typedefs.h
  280. Xhf.o: datatypes.h
  281. Xhf.o: primobj.h
  282. Xhf.o: funcdefs.h
  283. Xhf.o: constants.h
  284. Xplane.o: plane.c
  285. Xplane.o: constants.h
  286. Xplane.o: typedefs.h
  287. Xplane.o: datatypes.h
  288. Xplane.o: primobj.h
  289. Xplane.o: funcdefs.h
  290. Xpoly.o: poly.c
  291. Xpoly.o: constants.h
  292. Xpoly.o: typedefs.h
  293. Xpoly.o: datatypes.h
  294. Xpoly.o: primobj.h
  295. Xpoly.o: funcdefs.h
  296. Xsphere.o: sphere.c
  297. Xsphere.o: constants.h
  298. Xsphere.o: typedefs.h
  299. Xsphere.o: datatypes.h
  300. Xsphere.o: primobj.h
  301. Xsphere.o: funcdefs.h
  302. Xsuperq.o: superq.c
  303. Xsuperq.o: constants.h
  304. Xsuperq.o: typedefs.h
  305. Xsuperq.o: datatypes.h
  306. Xsuperq.o: primobj.h
  307. Xsuperq.o: funcdefs.h
  308. Xtriangle.o: triangle.c
  309. Xtriangle.o: constants.h
  310. Xtriangle.o: typedefs.h
  311. Xtriangle.o: datatypes.h
  312. Xtriangle.o: primobj.h
  313. Xtriangle.o: funcdefs.h
  314. Xtexture.o: texture.c
  315. Xtexture.o: constants.h
  316. Xtexture.o: typedefs.h
  317. Xtexture.o: datatypes.h
  318. Xtexture.o: primobj.h
  319. Xtexture.o: funcdefs.h
  320. Xtexture.o: texture.h
  321. Xnoise.o: noise.c
  322. Xnoise.o: constants.h
  323. Xnoise.o: typedefs.h
  324. Xnoise.o: datatypes.h
  325. Xnoise.o: primobj.h
  326. Xnoise.o: funcdefs.h
  327. Xshade.o: shade.c
  328. Xshade.o: constants.h
  329. Xshade.o: typedefs.h
  330. Xshade.o: datatypes.h
  331. Xshade.o: primobj.h
  332. Xshade.o: funcdefs.h
  333. Xatmosphere.o: atmosphere.c
  334. Xatmosphere.o: typedefs.h
  335. Xatmosphere.o: datatypes.h
  336. Xatmosphere.o: primobj.h
  337. Xatmosphere.o: constants.h
  338. Xatmosphere.o: funcdefs.h
  339. Xlight.o: light.c
  340. Xlight.o: typedefs.h
  341. Xlight.o: datatypes.h
  342. Xlight.o: primobj.h
  343. Xlight.o: funcdefs.h
  344. Xlight.o: constants.h
  345. Xoutputp.o: outputp.c
  346. Xoutputp.o: typedefs.h
  347. Xoutputp.o: datatypes.h
  348. Xoutputp.o: primobj.h
  349. Xoutputp.o: constants.h
  350. Xoutputp.o: funcdefs.h
  351. Xmemory.o: memory.c
  352. Xmemory.o: typedefs.h
  353. Xmemory.o: datatypes.h
  354. Xmemory.o: primobj.h
  355. Xmemory.o: funcdefs.h
  356. Xversion.o: version.c
  357. Xversion.o: patchlevel.h
  358. END_OF_FILE
  359. if test 7691 -ne `wc -c <'src/Makefile'`; then
  360.     echo shar: \"'src/Makefile'\" unpacked with wrong size!
  361. fi
  362. # end of 'src/Makefile'
  363. fi
  364. if test -f 'src/malloc.c' -a "${1}" != "-c" ; then 
  365.   echo shar: Will not clobber existing file \"'src/malloc.c'\"
  366. else
  367. echo shar: Extracting \"'src/malloc.c'\" \(9119 characters\)
  368. sed "s/^X//" >'src/malloc.c' <<'END_OF_FILE'
  369. X#ifndef lint
  370. Xstatic char sccsid[] = "@(#)malloc.c    4.3 (Berkeley) 9/16/83";
  371. X#endif
  372. X
  373. X/*
  374. X * malloc.c (Caltech) 2/21/82
  375. X * Chris Kingsley, kingsley@cit-20.
  376. X *
  377. X * This is a very fast storage allocator.  It allocates blocks of a small
  378. X * number of different sizes, and keeps free lists of each size.  Blocks that
  379. X * don't exactly fit are passed up to the next larger size.  In this
  380. X * implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
  381. X * This is designed for use in a program that uses vast quantities of memory,
  382. X * but bombs when it runs out.
  383. X */
  384. X
  385. X#include <sys/types.h>
  386. X
  387. X#define    NULL 0
  388. X
  389. X/*
  390. X * The overhead on a block is at least 4 bytes.  When free, this space
  391. X * contains a pointer to the next free block, and the bottom two bits must
  392. X * be zero.  When in use, the first byte is set to MAGIC, and the second
  393. X * byte is the size index.  The remaining bytes are for alignment.
  394. X * If range checking is enabled and the size of the block fits
  395. X * in two bytes, then the top two bytes hold the size of the requested block
  396. X * plus the range checking words, and the header word MINUS ONE.
  397. X */
  398. Xunion    overhead {
  399. X    union    overhead *ov_next;    /* when free */
  400. X    struct {
  401. X        u_char    ovu_magic;    /* magic number */
  402. X        u_char    ovu_index;    /* bucket # */
  403. X#ifdef RCHECK
  404. X        u_short    ovu_size;    /* actual block size */
  405. X        u_int    ovu_rmagic;    /* range magic number */
  406. X#endif
  407. X    } ovu;
  408. X#define    ov_magic    ovu.ovu_magic
  409. X#define    ov_index    ovu.ovu_index
  410. X#define    ov_size        ovu.ovu_size
  411. X#define    ov_rmagic    ovu.ovu_rmagic
  412. X};
  413. X
  414. X#define    MAGIC        0xff        /* magic # on accounting info */
  415. X#define RMAGIC        0x55555555    /* magic # on range info */
  416. X#ifdef RCHECK
  417. X#define    RSLOP        sizeof (u_int)
  418. X#else
  419. X#define    RSLOP        0
  420. X#endif
  421. X
  422. X/*
  423. X * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
  424. X * smallest allocatable block is 8 bytes.  The overhead information
  425. X * precedes the data area returned to the user.
  426. X */
  427. X#define    NBUCKETS 30
  428. Xstatic    union overhead *nextf[NBUCKETS];
  429. Xextern    char *sbrk();
  430. X
  431. X#ifdef MSTATS
  432. X/*
  433. X * nmalloc[i] is the difference between the number of mallocs and frees
  434. X * for a given block size.
  435. X */
  436. Xstatic    u_int nmalloc[NBUCKETS];
  437. X#include <stdio.h>
  438. X#endif
  439. X
  440. X#ifdef debug
  441. X#define    ASSERT(p)   if (!(p)) botch("p"); else
  442. Xstatic
  443. Xbotch(s)
  444. X    char *s;
  445. X{
  446. X
  447. X    printf("assertion botched: %s\n", s);
  448. X    abort();
  449. X}
  450. X#else
  451. X#define    ASSERT(p)
  452. X#endif
  453. X
  454. Xchar *
  455. Xmalloc(nbytes)
  456. X    register unsigned nbytes;
  457. X{
  458. X      register union overhead *p;
  459. X      register int bucket = 0;
  460. X      register unsigned shiftr;
  461. X
  462. X    /*
  463. X     * Convert amount of memory requested into
  464. X     * closest block size stored in hash buckets
  465. X     * which satisfies request.  Account for
  466. X     * space used per block for accounting.
  467. X     */
  468. X      nbytes += sizeof (union overhead) + RSLOP;
  469. X      nbytes = (nbytes + 3) &~ 3;
  470. X      shiftr = (nbytes - 1) >> 2;
  471. X    /* apart from this loop, this is O(1) */
  472. X      while (shiftr >>= 1)
  473. X          bucket++;
  474. X    /*
  475. X     * If nothing in hash bucket right now,
  476. X     * request more memory from the system.
  477. X     */
  478. X      if (nextf[bucket] == NULL)
  479. X          morecore(bucket);
  480. X      if ((p = (union overhead *)nextf[bucket]) == NULL)
  481. X          return (NULL);
  482. X    /* remove from linked list */
  483. X      nextf[bucket] = nextf[bucket]->ov_next;
  484. X    p->ov_magic = MAGIC;
  485. X    p->ov_index= bucket;
  486. X#ifdef MSTATS
  487. X      nmalloc[bucket]++;
  488. X#endif
  489. X#ifdef RCHECK
  490. X    /*
  491. X     * Record allocated size of block and
  492. X     * bound space with magic numbers.
  493. X     */
  494. X      if (nbytes <= 0x10000)
  495. X        p->ov_size = nbytes - 1;
  496. X    p->ov_rmagic = RMAGIC;
  497. X      *((u_int *)((caddr_t)p + nbytes - RSLOP)) = RMAGIC;
  498. X#endif
  499. X      return ((char *)(p + 1));
  500. X}
  501. X
  502. X/*
  503. X * Allocate more memory to the indicated bucket.
  504. X */
  505. Xstatic
  506. Xmorecore(bucket)
  507. X    register bucket;
  508. X{
  509. X      register union overhead *op;
  510. X      register int rnu;       /* 2^rnu bytes will be requested */
  511. X      register int nblks;     /* become nblks blocks of the desired size */
  512. X    register int siz;
  513. X
  514. X      if (nextf[bucket])
  515. X          return;
  516. X    /*
  517. X     * Insure memory is allocated
  518. X     * on a page boundary.  Should
  519. X     * make getpageize call?
  520. X     */
  521. X      op = (union overhead *)sbrk(0);
  522. X      if ((int)op & 0x3ff)
  523. X          sbrk(1024 - ((int)op & 0x3ff));
  524. X    /* take 2k unless the block is bigger than that */
  525. X      rnu = (bucket <= 8) ? 11 : bucket + 3;
  526. X      nblks = 1 << (rnu - (bucket + 3));  /* how many blocks to get */
  527. X      if (rnu < bucket)
  528. X        rnu = bucket;
  529. X    op = (union overhead *)sbrk(1 << rnu);
  530. X    /* no more room! */
  531. X      if ((int)op == -1) {
  532. X        for (rnu=bucket; rnu < NBUCKETS; rnu++) {
  533. X            if (nextf[rnu]) break;
  534. X        }
  535. X        if (rnu >= NBUCKETS)
  536. X            return;
  537. X        /* Split into halves until bucket-sized */
  538. X        op = nextf[rnu];
  539. X        nextf[rnu] = op->ov_next;
  540. X        while (--rnu > bucket) {
  541. X            siz = 1 << (rnu + 3);
  542. X            op->ov_next = nextf[rnu]; /* == NULL */
  543. X            nextf[rnu] = op;
  544. X            op = (union overhead *)((caddr_t) op + siz);
  545. X        }
  546. X        nblks = 2;
  547. X    }
  548. X    /*
  549. X     * Round up to minimum allocation size boundary
  550. X     * and deduct from block count to reflect.
  551. X     */
  552. X      if ((int)op & 7) {
  553. X          op = (union overhead *)(((int)op + 8) &~ 7);
  554. X          nblks--;
  555. X      }
  556. X    /*
  557. X     * Add new memory allocated to that on
  558. X     * free list for this hash bucket.
  559. X     */
  560. X      nextf[bucket] = op;
  561. X      siz = 1 << (bucket + 3);
  562. X      while (--nblks > 0) {
  563. X        op->ov_next = (union overhead *)((caddr_t)op + siz);
  564. X        op = (union overhead *)((caddr_t)op + siz);
  565. X      }
  566. X    op->ov_next = NULL;
  567. X}
  568. X
  569. Xfree(cp)
  570. X    char *cp;
  571. X{
  572. X      register int size;
  573. X    register union overhead *op;
  574. X
  575. X      if (cp == NULL)
  576. X          return;
  577. X    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
  578. X#ifdef debug
  579. X      ASSERT(op->ov_magic == MAGIC);        /* make sure it was in use */
  580. X#else
  581. X    if (op->ov_magic != MAGIC)
  582. X        return;                /* sanity */
  583. X#endif
  584. X#ifdef RCHECK
  585. X      ASSERT(op->ov_rmagic == RMAGIC);
  586. X    if (op->ov_index <= 13)
  587. X        ASSERT(*(u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP) == RMAGIC);
  588. X#endif
  589. X      ASSERT(op->ov_index < NBUCKETS);
  590. X      size = op->ov_index;
  591. X    op->ov_next = nextf[size];
  592. X      nextf[size] = op;
  593. X#ifdef MSTATS
  594. X      nmalloc[size]--;
  595. X#endif
  596. X}
  597. X
  598. X/*
  599. X * When a program attempts "storage compaction" as mentioned in the
  600. X * old malloc man page, it realloc's an already freed block.  Usually
  601. X * this is the last block it freed; occasionally it might be farther
  602. X * back.  We have to search all the free lists for the block in order
  603. X * to determine its bucket: 1st we make one pass thru the lists
  604. X * checking only the first block in each; if that fails we search
  605. X * ``realloc_srchlen'' blocks in each list for a match (the variable
  606. X * is extern so the caller can modify it).  If that fails we just copy
  607. X * however many bytes was given to realloc() and hope it's not huge.
  608. X */
  609. Xint realloc_srchlen = -1;    /* -1 => search whole list */
  610. X
  611. Xchar *
  612. Xrealloc(cp, nbytes)
  613. X    char *cp;
  614. X    unsigned nbytes;
  615. X{
  616. X      register u_int onb;
  617. X    union overhead *op;
  618. X      char *res;
  619. X    register int i;
  620. X    int was_alloced = 0;
  621. X
  622. X      if (cp == NULL)
  623. X          return (malloc(nbytes));
  624. X    op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
  625. X    if (op->ov_magic == MAGIC) {
  626. X        was_alloced++;
  627. X        i = op->ov_index;
  628. X    } else {
  629. X        /*
  630. X         * Already free, doing "compaction".
  631. X         *
  632. X         * Search for the old block of memory on the
  633. X         * free list.  First, check the most common
  634. X         * case (last element free'd), then (this failing)
  635. X         * the last ``realloc_srchlen'' items free'd.
  636. X         * If all lookups fail, then assume the size of
  637. X         * the memory block being realloc'd is the
  638. X         * smallest possible.
  639. X         */
  640. X        if ((i = findbucket(op, 1)) < 0 &&
  641. X            (i = findbucket(op, realloc_srchlen)) < 0)
  642. X            i = 0;
  643. X    }
  644. X    onb = (1 << (i + 3)) - sizeof (*op) - RSLOP;
  645. X    /* avoid the copy if same size block */
  646. X    if (was_alloced &&
  647. X        nbytes <= onb && nbytes > (onb >> 1) - sizeof(*op) - RSLOP) {
  648. X#ifdef RCHECK
  649. X        op->ov_size = ((nbytes + sizeof(union overhead) + RSLOP) + 3 & ~3) -1;
  650. X        *((u_int *)((caddr_t)op + op->ov_size + 1 - RSLOP)) = RMAGIC;
  651. X#endif
  652. X        return(cp);
  653. X    }
  654. X      if ((res = malloc(nbytes)) == NULL)
  655. X          return (NULL);
  656. X      if (cp != res)            /* common optimization */
  657. X        bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
  658. X      if (was_alloced)
  659. X        free(cp);
  660. X      return (res);
  661. X}
  662. X
  663. X/*
  664. X * Search ``srchlen'' elements of each free list for a block whose
  665. X * header starts at ``freep''.  If srchlen is -1 search the whole list.
  666. X * Return bucket number, or -1 if not found.
  667. X */
  668. Xstatic
  669. Xfindbucket(freep, srchlen)
  670. X    union overhead *freep;
  671. X    int srchlen;
  672. X{
  673. X    register union overhead *p;
  674. X    register int i, j;
  675. X
  676. X    for (i = 0; i < NBUCKETS; i++) {
  677. X        j = 0;
  678. X        for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
  679. X            if (p == freep)
  680. X                return (i);
  681. X            j++;
  682. X        }
  683. X    }
  684. X    return (-1);
  685. X}
  686. X
  687. X#ifdef MSTATS
  688. X/*
  689. X * mstats - print out statistics about malloc
  690. X *
  691. X * Prints two lines of numbers, one showing the length of the free list
  692. X * for each size category, the second showing the number of mallocs -
  693. X * frees for each size category.
  694. X */
  695. Xmstats(s)
  696. X    char *s;
  697. X{
  698. X      register int i, j;
  699. X      register union overhead *p;
  700. X      int totfree = 0,
  701. X      totused = 0;
  702. X
  703. X      fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
  704. X      for (i = 0; i < NBUCKETS; i++) {
  705. X          for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
  706. X              ;
  707. X          fprintf(stderr, " %d", j);
  708. X          totfree += j * (1 << (i + 3));
  709. X      }
  710. X      fprintf(stderr, "\nused:\t");
  711. X      for (i = 0; i < NBUCKETS; i++) {
  712. X          fprintf(stderr, " %d", nmalloc[i]);
  713. X          totused += nmalloc[i] * (1 << (i + 3));
  714. X      }
  715. X      fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
  716. X        totused, totfree);
  717. X}
  718. X#endif
  719. END_OF_FILE
  720. if test 9119 -ne `wc -c <'src/malloc.c'`; then
  721.     echo shar: \"'src/malloc.c'\" unpacked with wrong size!
  722. fi
  723. # end of 'src/malloc.c'
  724. fi
  725. if test -f 'src/noise.c' -a "${1}" != "-c" ; then 
  726.   echo shar: Will not clobber existing file \"'src/noise.c'\"
  727. else
  728. echo shar: Extracting \"'src/noise.c'\" \(9494 characters\)
  729. sed "s/^X//" >'src/noise.c' <<'END_OF_FILE'
  730. X/*
  731. X * noise.c
  732. X *
  733. X * Copyright (C) 1989, Robert Skinner, Craig E. Kolb, F. Kenton Musgrave
  734. X *
  735. X * This software may be freely copied, modified, and redistributed,
  736. X * provided that this copyright notice is preserved on all copies.
  737. X *
  738. X * There is no warranty or other guarantee of fitness for this software,
  739. X * it is provided solely "as is".  Bug reports or fixes may be sent
  740. X * to the author, who may or may not act on them as he desires.
  741. X *
  742. X * You may not include this software in a program or other software product
  743. X * without supplying the source, or without informing the end-user that the
  744. X * source is available for no extra charge.
  745. X *
  746. X * If you modify this software, you should include a notice giving the
  747. X * name of the person performing the modification, the date of modification,
  748. X * and the reason for such modification.
  749. X *
  750. X * $Id: noise.c,v 3.0 89/10/27 02:05:57 craig Exp $
  751. X *
  752. X * $Log:    noise.c,v $
  753. X * Revision 3.0  89/10/27  02:05:57  craig
  754. X * Baseline for first official release.
  755. X * 
  756. X */
  757. X#include <stdio.h>
  758. X#include <math.h>
  759. X#include "constants.h"
  760. X#include "typedefs.h"
  761. X#include "funcdefs.h"
  762. X
  763. X#define MINX        -10000
  764. X#define MINY        MINX
  765. X#define MINZ        MINX
  766. X
  767. X#define SCURVE(a) ((a)*(a)*(3.0-2.0*(a)))
  768. X#define REALSCALE ( 2.0 / 65536.0 )
  769. X#define NREALSCALE ( 2.0 / 4096.0 )
  770. X#define Hash3d(a,b,c) hashTable[hashTable[hashTable[(a) & 0xfff] ^ ((b) & 0xfff)] ^ ((c) & 0xfff)]
  771. X#define Hash(a,b,c) (xtab[(xtab[(xtab[(a) & 0xff] ^ (b)) & 0xff] ^ (c)) & 0xff] & 0xff)
  772. X
  773. X#define INCRSUM(m,s,x,y,z)    ((s)*(RTable[m]*0.5        \
  774. X                    + RTable[m+1]*(x)    \
  775. X                    + RTable[m+2]*(y)    \
  776. X                    + RTable[m+3]*(z)))    \
  777. X
  778. X
  779. X#define MAXSIZE 267
  780. X
  781. Xdouble        RTable[MAXSIZE];
  782. Xstatic short    *hashTable;
  783. X
  784. Xstatic unsigned short xtab[256] =
  785. X{
  786. X   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
  787. X   0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
  788. X   0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
  789. X   0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
  790. X   0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
  791. X   0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
  792. X   0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
  793. X   0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
  794. X   0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
  795. X   0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
  796. X   0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
  797. X   0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
  798. X   0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
  799. X   0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
  800. X   0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
  801. X   0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
  802. X   0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
  803. X   0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
  804. X   0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
  805. X   0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
  806. X   0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
  807. X   0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
  808. X   0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
  809. X   0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
  810. X   0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
  811. X   0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
  812. X   0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
  813. X   0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
  814. X   0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
  815. X   0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
  816. X   0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
  817. X   0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
  818. X};
  819. X
  820. Xdouble Chaos(), Marble();
  821. X
  822. XInitTextureTable()
  823. X{
  824. X    int i, j, temp;
  825. X
  826. X#ifdef SYSV
  827. X    (void)srand48(0);
  828. X#else
  829. X    (void)srandom(0);
  830. X#endif
  831. X
  832. X    hashTable = (short int *) malloc(4096*sizeof(short int));
  833. X    for (i = 0; i < 4096; i++)
  834. X        hashTable[i] = i;
  835. X    for (i = 4095; i > 0; i--) {
  836. X        j = (int)(nrand() * 4096);
  837. X        temp = hashTable[i];
  838. X        hashTable[i] = hashTable[j];
  839. X        hashTable[j] = temp;
  840. X    }
  841. X}
  842. X
  843. X
  844. XInitRTable()
  845. X{
  846. X    int i;
  847. X    Vector rp;
  848. X
  849. X    InitTextureTable();
  850. X
  851. X    for (i = 0; i < MAXSIZE; i++) {
  852. X           rp.x = rp.y = rp.z = (double)i;
  853. X           RTable[i] = R(&rp)*REALSCALE - 1.0;
  854. X     }
  855. X}
  856. X
  857. X
  858. XR(v)
  859. XVector *v;
  860. X{
  861. X    v->x *= .12345;
  862. X    v->y *= .12345;
  863. X    v->z *= .12345;
  864. X
  865. X    return Crc16(v, sizeof(Vector));
  866. X}
  867. X
  868. X/*
  869. X * Note that passing a double to Crc16 and interpreting it as
  870. X * an array of chars means that machines with different floating-point
  871. X * representation schemes will evaluate Noise(point) differently.
  872. X */
  873. Xint
  874. XCrc16(buf, count)
  875. Xregister char *buf;
  876. Xregister int  count;
  877. X{
  878. X    register unsigned int crc = 0;
  879. X
  880. X    while (count--)
  881. X        crc = (crc >> 8) ^ xtab[ (unsigned char) (crc ^ *buf++) ];
  882. X
  883. X    return crc;
  884. X}
  885. X
  886. X
  887. X/*
  888. X * Robert's Skinner's Perlin-style "Noise" function
  889. X */
  890. Xdouble
  891. XNoise(point)
  892. XVector *point;
  893. X{
  894. X    register int    ix, iy, iz, jx, jy, jz;
  895. X    double        x, y, z;
  896. X    double    sx, sy, sz, tx, ty, tz;
  897. X    double    sum;
  898. X    short    m;
  899. X
  900. X
  901. X    /* ensures the values are positive. */
  902. X    x = point->x - MINX; y = point->y - MINY; z = point->z - MINZ;
  903. X
  904. X    /* its equivalent integer lattice point. */
  905. X    ix = (int)x; iy = (int)y; iz = (int)z;
  906. X    jx = ix+1; jy = iy + 1; jz = iz + 1;
  907. X
  908. X    sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
  909. X
  910. X    /* the complement values of sx,sy,sz */
  911. X    tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
  912. X
  913. X    /*
  914. X     *  interpolate!
  915. X     */
  916. X    m = Hash3d( ix, iy, iz ) & 0xFF;
  917. X    sum = INCRSUM(m,(tx*ty*tz),(x-ix),(y-iy),(z-iz));
  918. X
  919. X    m = Hash3d( jx, iy, iz ) & 0xFF;
  920. X    sum += INCRSUM(m,(sx*ty*tz),(x-jx),(y-iy),(z-iz));
  921. X
  922. X    m = Hash3d( ix, jy, iz ) & 0xFF;
  923. X    sum += INCRSUM(m,(tx*sy*tz),(x-ix),(y-jy),(z-iz));
  924. X
  925. X    m = Hash3d( jx, jy, iz ) & 0xFF;
  926. X    sum += INCRSUM(m,(sx*sy*tz),(x-jx),(y-jy),(z-iz));
  927. X
  928. X    m = Hash3d( ix, iy, jz ) & 0xFF;
  929. X    sum += INCRSUM(m,(tx*ty*sz),(x-ix),(y-iy),(z-jz));
  930. X
  931. X    m = Hash3d( jx, iy, jz ) & 0xFF;
  932. X    sum += INCRSUM(m,(sx*ty*sz),(x-jx),(y-iy),(z-jz));
  933. X
  934. X    m = Hash3d( ix, jy, jz ) & 0xFF;
  935. X    sum += INCRSUM(m,(tx*sy*sz),(x-ix),(y-jy),(z-jz));
  936. X
  937. X    m = Hash3d( jx, jy, jz ) & 0xFF;
  938. X    sum += INCRSUM(m,(sx*sy*sz),(x-jx),(y-jy),(z-jz));
  939. X
  940. X    return sum;
  941. X
  942. X} /* Noise() */
  943. X
  944. X/*
  945. X * Vector-valued "Noise"
  946. X */
  947. XDNoise(point, result)
  948. XVector *point, *result;
  949. X{
  950. X    register int    ix, iy, iz, jx, jy, jz;
  951. X    double        x, y, z;
  952. X    double px, py, pz, s;
  953. X    double    sx, sy, sz, tx, ty, tz;
  954. X    short    m;
  955. X
  956. X    /* ensures the values are positive. */
  957. X    x = point->x - MINX; y = point->y - MINY; z = point->z - MINZ;
  958. X
  959. X    /* its equivalent integer lattice point. */
  960. X    ix = (int)x; iy = (int)y; iz = (int)z;
  961. X    jx = ix+1; jy = iy + 1; jz = iz + 1;
  962. X
  963. X    sx = SCURVE(x - ix); sy = SCURVE(y - iy); sz = SCURVE(z - iz);
  964. X
  965. X    /* the complement values of sx,sy,sz */
  966. X    tx = 1.0 - sx; ty = 1.0 - sy; tz = 1.0 - sz;
  967. X
  968. X    /*
  969. X     *  interpolate!
  970. X     */
  971. X    m = Hash3d( ix, iy, iz ) & 0xFF;
  972. X    px = x-ix;  py = y-iy;  pz = z-iz;
  973. X    s = tx*ty*tz;
  974. X    result->x = INCRSUM(m,s,px,py,pz);
  975. X    result->y = INCRSUM(m+4,s,px,py,pz);
  976. X    result->z = INCRSUM(m+8,s,px,py,pz);
  977. X
  978. X    m = Hash3d( jx, iy, iz ) & 0xFF;
  979. X    px = x-jx;
  980. X    s = sx*ty*tz;
  981. X    result->x += INCRSUM(m,s,px,py,pz);
  982. X    result->y += INCRSUM(m+4,s,px,py,pz);
  983. X    result->z += INCRSUM(m+8,s,px,py,pz);
  984. X
  985. X    m = Hash3d( jx, jy, iz ) & 0xFF;
  986. X    py = y-jy;
  987. X    s = sx*sy*tz;
  988. X    result->x += INCRSUM(m,s,px,py,pz);
  989. X    result->y += INCRSUM(m+4,s,px,py,pz);
  990. X    result->z += INCRSUM(m+8,s,px,py,pz);
  991. X
  992. X    m = Hash3d( ix, jy, iz ) & 0xFF;
  993. X    px = x-ix;
  994. X    s = tx*sy*tz;
  995. X    result->x += INCRSUM(m,s,px,py,pz);
  996. X    result->y += INCRSUM(m+4,s,px,py,pz);
  997. X    result->z += INCRSUM(m+8,s,px,py,pz);
  998. X
  999. X    m = Hash3d( ix, jy, jz ) & 0xFF;
  1000. X    pz = z-jz;
  1001. X    s = tx*sy*sz;
  1002. X    result->x += INCRSUM(m,s,px,py,pz);
  1003. X    result->y += INCRSUM(m+4,s,px,py,pz);
  1004. X    result->z += INCRSUM(m+8,s,px,py,pz);
  1005. X
  1006. X    m = Hash3d( jx, jy, jz ) & 0xFF;
  1007. X    px = x-jx;
  1008. X    s = sx*sy*sz;
  1009. X    result->x += INCRSUM(m,s,px,py,pz);
  1010. X    result->y += INCRSUM(m+4,s,px,py,pz);
  1011. X    result->z += INCRSUM(m+8,s,px,py,pz);
  1012. X
  1013. X    m = Hash3d( jx, iy, jz ) & 0xFF;
  1014. X    py = y-iy;
  1015. X    s = sx*ty*sz;
  1016. X    result->x += INCRSUM(m,s,px,py,pz);
  1017. X    result->y += INCRSUM(m+4,s,px,py,pz);
  1018. X    result->z += INCRSUM(m+8,s,px,py,pz);
  1019. X
  1020. X    m = Hash3d( ix, iy, jz ) & 0xFF;
  1021. X    px = x-ix;
  1022. X    s = tx*ty*sz;
  1023. X    result->x += INCRSUM(m,s,px,py,pz);
  1024. X    result->y += INCRSUM(m+4,s,px,py,pz);
  1025. X    result->z += INCRSUM(m+8,s,px,py,pz);
  1026. X}
  1027. X
  1028. Xdouble
  1029. XMarble(vec)
  1030. XVector *vec;
  1031. X{
  1032. X    double i;
  1033. X
  1034. X    i = sin(8. * Chaos(vec, 6) + 7. * vec->z) + 1;
  1035. X    i *= 0.5;
  1036. X    i = pow(i, 0.77);
  1037. X    return i;
  1038. X}
  1039. X
  1040. Xdouble
  1041. XChaos(vec, octaves)
  1042. XVector *vec;
  1043. Xint octaves;
  1044. X{
  1045. X    double f, s, t;
  1046. X    int n;
  1047. X    Vector tp;
  1048. X
  1049. X    s = f = 1.0;
  1050. X    t = 0.;
  1051. X
  1052. X    for (n = 0; n < octaves; n++) {
  1053. X        tp.x = f * vec->x;
  1054. X        tp.y = f * vec->y;
  1055. X        tp.z = f * vec->z;
  1056. X        t += Noise(&tp) * s;
  1057. X        f *= 2.0;
  1058. X        s *= 0.5;
  1059. X    }
  1060. X
  1061. X    return t;
  1062. X}
  1063. X
  1064. XVfBm(vec, omega, lambda, octaves, ans)
  1065. XVector *vec, *ans;
  1066. Xdouble omega, lambda;
  1067. Xint octaves;
  1068. X{
  1069. X    register int i;
  1070. X    double l, o;
  1071. X    Vector tp, n;
  1072. X
  1073. X    ans->x = ans->y = ans->z = 0.;
  1074. X
  1075. X    l = o = 1.;
  1076. X    for (i = 0; i < octaves; i++) {
  1077. X        tp.x = l * vec->x;
  1078. X        tp.y = l * vec->y;
  1079. X        tp.z = l * vec->z;
  1080. X        DNoise(&tp, &n);
  1081. X        ans->x += o * n.x;
  1082. X        ans->y += o * n.y;
  1083. X        ans->z += o * n.z;
  1084. X        l *= lambda;
  1085. X        o *= omega;
  1086. X        if (o < EPSILON)
  1087. X            break;
  1088. X    }
  1089. X}
  1090. X
  1091. Xdouble
  1092. XfBm(vec, omega, lambda, octaves)
  1093. Xregister Vector *vec;
  1094. Xdouble omega, lambda;
  1095. Xint octaves;
  1096. X{
  1097. X    register int i;
  1098. X    double l, n, a, o;
  1099. X    Vector tp;
  1100. X
  1101. X    a = 0; l = o = 1.;
  1102. X    for (i = 0; i < octaves; i++) {
  1103. X        tp.x = l * vec->x;
  1104. X        tp.y = l * vec->y;
  1105. X        tp.z = l * vec->z;
  1106. X        n = o * Noise(&tp);
  1107. X        a += n;
  1108. X        l *= lambda;
  1109. X        o *= omega;
  1110. X    }
  1111. X    return a;
  1112. X}
  1113. END_OF_FILE
  1114. if test 9494 -ne `wc -c <'src/noise.c'`; then
  1115.     echo shar: \"'src/noise.c'\" unpacked with wrong size!
  1116. fi
  1117. # end of 'src/noise.c'
  1118. fi
  1119. if test -f 'src/poly.c' -a "${1}" != "-c" ; then 
  1120.   echo shar: Will not clobber existing file \"'src/poly.c'\"
  1121. else
  1122. echo shar: Extracting \"'src/poly.c'\" \(7502 characters\)
  1123. sed "s/^X//" >'src/poly.c' <<'END_OF_FILE'
  1124. X/*
  1125. X * poly.c
  1126. X *
  1127. X * Copyright (C) 1989, Craig E. Kolb
  1128. X *
  1129. X * This software may be freely copied, modified, and redistributed,
  1130. X * provided that this copyright notice is preserved on all copies.
  1131. X *
  1132. X * There is no warranty or other guarantee of fitness for this software,
  1133. X * it is provided solely .  Bug reports or fixes may be sent
  1134. X * to the author, who may or may not act on them as he desires.
  1135. X *
  1136. X * You may not include this software in a program or other software product
  1137. X * without supplying the source, or without informing the end-user that the
  1138. X * source is available for no extra charge.
  1139. X *
  1140. X * If you modify this software, you should include a notice giving the
  1141. X * name of the person performing the modification, the date of modification,
  1142. X * and the reason for such modification.
  1143. X *
  1144. X * $Id: poly.c,v 3.0 89/10/27 02:05:59 craig Exp $
  1145. X *
  1146. X * $Log:    poly.c,v $
  1147. X * Revision 3.0  89/10/27  02:05:59  craig
  1148. X * Baseline for first official release.
  1149. X * 
  1150. X */
  1151. X#include <stdio.h>
  1152. X#include <math.h>
  1153. X#include "constants.h"
  1154. X#include "typedefs.h"
  1155. X#include "funcdefs.h"
  1156. X
  1157. X/*
  1158. X * Create a reference to a polygon with vertices equal to those
  1159. X * on the linked-list "plist."
  1160. X */
  1161. XObject *
  1162. Xmakpoly(surf, plist, npoints)
  1163. Xchar *surf;
  1164. XPointList *plist;
  1165. Xint npoints;
  1166. X{
  1167. X    Polygon *poly;
  1168. X    Primitive *prim;
  1169. X    Object *newobj;
  1170. X    double indexval;
  1171. X    Vector edge1, edge2, anorm;
  1172. X    PointList *cur;
  1173. X    int i;
  1174. X    extern int yylineno, TrashBadPoly, Quiet;
  1175. X
  1176. X    prim = mallocprim();
  1177. X    prim->type = POLY;
  1178. X    prim->surf = find_surface(surf);
  1179. X    poly = (Polygon *)Malloc(sizeof(Polygon));
  1180. X    prim->objpnt.p_poly = poly;
  1181. X    newobj = new_object(NULL, POLY, (char *)prim, (Trans *)NULL);
  1182. X    /*
  1183. X     * Allocate space for the vertices.
  1184. X     */
  1185. X    poly->points = (Vector *)Malloc((unsigned)(npoints*sizeof(Vector)));
  1186. X    poly->npoints = npoints;
  1187. X
  1188. X    /*
  1189. X     * Copy the vertices from the linked list to the array, freeing
  1190. X     * the linked list as we go so that the caller doesn't have
  1191. X     * to worry about doing so.
  1192. X     */
  1193. X    i = npoints -1;
  1194. X    for(cur = plist;cur;cur = cur->next) {
  1195. X        poly->points[i--] = cur->vec;
  1196. X        free((char *)cur);
  1197. X    }
  1198. X    free((char *)plist);
  1199. X
  1200. X    /*
  1201. X     * Find normal to polygon.  Check all edges before giving
  1202. X     * up, just to be relatively nice about things.
  1203. X     */
  1204. X    vecsub(poly->points[1], poly->points[0], &edge1);
  1205. X    for(i = 1;i < poly->npoints;i++) {
  1206. X        if(dotp(&edge1, &edge1) == 0.) {
  1207. X            if (TrashBadPoly) {
  1208. X                free((char *)poly->points);
  1209. X                free((char *)poly);
  1210. X                free((char *)prim);
  1211. X                free((char *)newobj);
  1212. X                return (Object *)0;
  1213. X            }
  1214. X        }
  1215. X        vecsub(poly->points[(i+1)%npoints], poly->points[i], &edge2);
  1216. X        if(crossp(&poly->norm, &edge1, &edge2) != 0.)
  1217. X            break;
  1218. X        edge1 = edge2;
  1219. X    }
  1220. X
  1221. X    if(i >= poly->npoints) {
  1222. X        /*
  1223. X          * If we walked all the way through the list,
  1224. X         * then we didn't find a valid normal vector -- we
  1225. X         * must have a degenerate polygon of some sort.
  1226. X         */
  1227. X        fprintf(stderr,"Degenerate polygon (line %d).\n", yylineno);
  1228. X        free((char *)poly->points);
  1229. X        free((char *)poly);
  1230. X        free((char *)prim);
  1231. X        free((char *)newobj);
  1232. X        return (Object *)0;
  1233. X    }
  1234. X
  1235. X    /*
  1236. X     * Compute and store the plane constant.
  1237. X     */
  1238. X    poly->d = dotp(&poly->norm, &poly->points[0]);
  1239. X
  1240. X    /*
  1241. X     * Find which part of the normal vector is "dominant."  This
  1242. X     * is used to turn the point-in-polygon test into a 2D problem.
  1243. X     */
  1244. X    anorm.x = abs(poly->norm.x);
  1245. X    anorm.y = abs(poly->norm.y);
  1246. X    anorm.z = abs(poly->norm.z);
  1247. X    indexval = max(anorm.y, anorm.z);
  1248. X    indexval = max(anorm.x, indexval);
  1249. X
  1250. X    if(indexval == anorm.x)
  1251. X        poly->index = XNORMAL;
  1252. X    else if(indexval == anorm.y)
  1253. X        poly->index = YNORMAL;
  1254. X    else
  1255. X        poly->index = ZNORMAL;
  1256. X
  1257. X    return newobj;
  1258. X}
  1259. X
  1260. X/*
  1261. X * Quadrants are defined as:
  1262. X *        |
  1263. X *   1    |   0
  1264. X *        |
  1265. X * -------c--------
  1266. X *        |
  1267. X *   2    |   3
  1268. X *        |
  1269. X */
  1270. X#define quadrant(p, c) ((p.u<c.u) ? ((p.v<c.v) ? 2 : 1) : ((p.v<c.v) ? 3 : 0))
  1271. X
  1272. X/*
  1273. X * Project a point in 3-space to the plane whose normal is indicated by "i."
  1274. X */
  1275. X#define project(r, p, i)    {switch(i) { \
  1276. X                case XNORMAL: \
  1277. X                    r.u = p.y; \
  1278. X                    r.v = p.z; \
  1279. X                    break; \
  1280. X                case YNORMAL: \
  1281. X                    r.u = p.x; \
  1282. X                    r.v = p.z; \
  1283. X                    break; \
  1284. X                case ZNORMAL: \
  1285. X                    r.u = p.x; \
  1286. X                    r.v = p.y; \
  1287. X                    break; \
  1288. X                  } }
  1289. X/*
  1290. X * Perform ray-polygon intersection test.
  1291. X */
  1292. Xdouble
  1293. Xintpoly(pos, ray, obj)
  1294. XVector *pos, *ray;
  1295. XPrimitive *obj;
  1296. X{
  1297. X    register Polygon *poly;
  1298. X    register int winding, i;
  1299. X    int quad, lastquad;
  1300. X    double dist, left, right;
  1301. X    Vec2d center, cur, last;
  1302. X    extern unsigned long primtests[];
  1303. X
  1304. X    primtests[POLY]++;
  1305. X    poly = obj->objpnt.p_poly;
  1306. X    /*
  1307. X     * First, find where ray hits polygon plane, projecting
  1308. X     * along the polygon's dominant normal component.
  1309. X     */
  1310. X
  1311. X    dist = dotp(&poly->norm, ray);
  1312. X    if(dist == 0.)
  1313. X        /*
  1314. X          * No intersection with polygon plane.
  1315. X         */
  1316. X        return 0.;
  1317. X
  1318. X    dist = (poly->d - dotp(&poly->norm, pos)) / dist;
  1319. X    if(dist <= 0.)
  1320. X        /*
  1321. X         * The intersection point is behind the ray origin.
  1322. X         */
  1323. X        return 0.;
  1324. X
  1325. X    /*
  1326. X     * Compute the point of intersection, projected appropriately.
  1327. X     */
  1328. X    if(poly->index == XNORMAL) {
  1329. X        center.u = pos->y + dist * ray->y;
  1330. X        center.v = pos->z + dist * ray->z;
  1331. X    } else if(poly->index == YNORMAL) {
  1332. X        center.v = pos->z + dist * ray->z;
  1333. X        center.u = pos->x + dist * ray->x;
  1334. X    } else {
  1335. X        center.u = pos->x + dist * ray->x;
  1336. X        center.v = pos->y + dist * ray->y;
  1337. X    }
  1338. X
  1339. X    /*
  1340. X     * Is the point inside the polygon?
  1341. X     *
  1342. X     * Compute the winding number by finding the quadrant each
  1343. X     * polygon point lies in with respect to the the point in
  1344. X     * question, and computing a "delta" (winding number).  If we
  1345. X     * end up going around in a complete circle around
  1346. X     * the point (winding number is non-zero at the end), then
  1347. X     * we're inside.  Otherwise, the point is outside.
  1348. X     *
  1349. X     * Note that we can turn this into a 2D problem by projecting
  1350. X     * all the points along the axis defined by poly->index, which
  1351. X     * is the "dominant" part of the polygon's normal vector.
  1352. X     */
  1353. X    winding = 0;
  1354. X    project(last, poly->points[poly->npoints -1], poly->index);
  1355. X    lastquad = quadrant(last, center);
  1356. X    for(i = 0;i < poly->npoints; i++) {
  1357. X        project(cur, poly->points[i], poly->index);
  1358. X        quad = quadrant(cur, center);
  1359. X        if(quad != lastquad) {
  1360. X            if(((lastquad + 1) & 3) == quad)
  1361. X                winding++;
  1362. X            else if(((quad + 1) & 3) == lastquad)
  1363. X                winding--;
  1364. X            else {
  1365. X                /*
  1366. X                 * Find where edge crosses
  1367. X                 * center's X axis.
  1368. X                 */
  1369. X                right = last.u - cur.u;
  1370. X                left = last.v - cur.v;
  1371. X                left *= center.u - last.u;
  1372. X                if(left + last.v * right > right * center.v)
  1373. X                    winding += 2;
  1374. X                else
  1375. X                    winding -= 2;
  1376. X            }
  1377. X            lastquad = quad;
  1378. X        }
  1379. X        last = cur;
  1380. X
  1381. X    }
  1382. X    return (winding == 0 ? 0. : dist);
  1383. X}
  1384. X
  1385. X/*
  1386. X * Return the normal to the polygon surface.
  1387. X */
  1388. X/*ARGSUSED*/
  1389. Xnrmpoly(pos, obj, nrm)
  1390. XVector *pos, *nrm;
  1391. XPrimitive *obj;
  1392. X{
  1393. X    *nrm = obj->objpnt.p_poly->norm;
  1394. X}
  1395. X
  1396. X/*
  1397. X * Compute the extent of a polygon
  1398. X */
  1399. Xpolyextent(obj, bounds)
  1400. XPrimitive *obj;
  1401. Xdouble bounds[2][3];
  1402. X{
  1403. X    register Polygon *poly;
  1404. X    register int i;
  1405. X
  1406. X    poly = obj->objpnt.p_poly;
  1407. X
  1408. X    bounds[LOW][X] = bounds[HIGH][X] = poly->points[0].x;
  1409. X    bounds[LOW][Y] = bounds[HIGH][Y] = poly->points[0].y;
  1410. X    bounds[LOW][Z] = bounds[HIGH][Z] = poly->points[0].z;
  1411. X
  1412. X    for(i = 1;i < poly->npoints;i++) {
  1413. X        if(poly->points[i].x < bounds[LOW][X])
  1414. X            bounds[LOW][X] = poly->points[i].x;
  1415. X        if(poly->points[i].x > bounds[HIGH][X])
  1416. X            bounds[HIGH][X] = poly->points[i].x;
  1417. X        if(poly->points[i].y < bounds[LOW][Y])
  1418. X            bounds[LOW][Y] = poly->points[i].y;
  1419. X        if(poly->points[i].y > bounds[HIGH][Y])
  1420. X            bounds[HIGH][Y] = poly->points[i].y;
  1421. X        if(poly->points[i].z < bounds[LOW][Z])
  1422. X            bounds[LOW][Z] = poly->points[i].z;
  1423. X        if(poly->points[i].z > bounds[HIGH][Z])
  1424. X            bounds[HIGH][Z] = poly->points[i].z;
  1425. X    }
  1426. X}
  1427. END_OF_FILE
  1428. if test 7502 -ne `wc -c <'src/poly.c'`; then
  1429.     echo shar: \"'src/poly.c'\" unpacked with wrong size!
  1430. fi
  1431. # end of 'src/poly.c'
  1432. fi
  1433. if test -f 'src/texture.c' -a "${1}" != "-c" ; then 
  1434.   echo shar: Will not clobber existing file \"'src/texture.c'\"
  1435. else
  1436. echo shar: Extracting \"'src/texture.c'\" \(7557 characters\)
  1437. sed "s/^X//" >'src/texture.c' <<'END_OF_FILE'
  1438. X/*
  1439. X * texture.c
  1440. X *
  1441. X * Copyright (C) 1989, Craig E. Kolb
  1442. X *
  1443. X * This software may be freely copied, modified, and redistributed,
  1444. X * provided that this copyright notice is preserved on all copies.
  1445. X *
  1446. X * There is no warranty or other guarantee of fitness for this software,
  1447. X * it is provided solely .  Bug reports or fixes may be sent
  1448. X * to the author, who may or may not act on them as he desires.
  1449. X *
  1450. X * You may not include this software in a program or other software product
  1451. X * without supplying the source, or without informing the end-user that the
  1452. X * source is available for no extra charge.
  1453. X *
  1454. X * If you modify this software, you should include a notice giving the
  1455. X * name of the person performing the modification, the date of modification,
  1456. X * and the reason for such modification.
  1457. X *
  1458. X * $Id: texture.c,v 3.0 89/10/27 02:06:05 craig Exp $
  1459. X *
  1460. X * $Log:    texture.c,v $
  1461. X * Revision 3.0  89/10/27  02:06:05  craig
  1462. X * Baseline for first official release.
  1463. X * 
  1464. X */
  1465. X#include <stdio.h>
  1466. X#include <math.h>
  1467. X#include "constants.h"
  1468. X#include "typedefs.h"
  1469. X#include "funcdefs.h"
  1470. X#include "texture.h"
  1471. X
  1472. X/*
  1473. X * Array of texturing functions indexed by type.
  1474. X */
  1475. Xint (*textures[])() =
  1476. X    {CheckerText, BlotchText, BumpText, MarbleText, fBmText, fBmBumpText,
  1477. X     WoodText};
  1478. Xextern double Chaos(), Marble(), fBm(), Noise();
  1479. XColor    *read_colormap();
  1480. X
  1481. X/*
  1482. X * Return pointer to new texture structure.
  1483. X */
  1484. XTexture *
  1485. Xnew_texture(type)
  1486. Xchar type;
  1487. X{
  1488. X    Texture *new;
  1489. X
  1490. X    new = (Texture *)Malloc(sizeof(Texture));
  1491. X    new->type = type;
  1492. X    new->surf1 = (Surface *)NULL;
  1493. X    new->next = (Texture *)NULL;
  1494. X    new->trans = (Trans *)NULL;
  1495. X    return new;
  1496. X}
  1497. X
  1498. X/*
  1499. X * Apply appropriate textures to a surface.
  1500. X */
  1501. Xapply_textures(hitinfo, list)
  1502. XHitInfo *hitinfo;
  1503. XTexture *list;
  1504. X{
  1505. X    Texture *ttmp;
  1506. X    Vector ptmp;
  1507. X
  1508. X    for (ttmp = list; ttmp; ttmp = ttmp->next) {
  1509. X        ptmp = hitinfo->pos;
  1510. X        if (ttmp->trans) {
  1511. X            /*
  1512. X             * Transform position and normal to texture space.
  1513. X             */
  1514. X            transform_point(&ptmp,&ttmp->trans->world2obj);
  1515. X            TransformNormal(&hitinfo->norm,&ttmp->trans->obj2world);
  1516. X        }
  1517. X        /*
  1518. X         * Make sure to use a normalized normal.
  1519. X         */
  1520. X        (void)normalize(&hitinfo->norm);
  1521. X        (*textures[(int)ttmp->type])
  1522. X            (ttmp,&ptmp,&hitinfo->norm,&hitinfo->surf);
  1523. X        if (ttmp->trans) {
  1524. X            /*
  1525. X             * Transform the normal back to world-space.
  1526. X             */
  1527. X            TransformNormal(&hitinfo->norm,&ttmp->trans->world2obj);
  1528. X        }
  1529. X    }
  1530. X}
  1531. X
  1532. XTexture *
  1533. XNewWoodText()
  1534. X{
  1535. X    Texture *text;
  1536. X
  1537. X    text = new_texture(WOOD);
  1538. X    return text;
  1539. X}
  1540. X
  1541. XWoodText(text, pos, norm, surf)
  1542. XTexture *text;
  1543. XVector *pos, *norm;
  1544. XSurface *surf;
  1545. X{
  1546. X    double red, grn, blu;
  1547. X    double chaos, midBrown, brownLayer, greenLayer;
  1548. X    double perturb, brownPerturb, greenPerturb, grnPerturb;
  1549. X    double t;
  1550. X
  1551. X    chaos = Chaos(pos, 7);
  1552. X    t = sin(sin(8.*chaos + 7*pos->x +3.*pos->y));
  1553. X
  1554. X    greenLayer = brownLayer = abs(t);
  1555. X
  1556. X    perturb = fabs(sin(40.*chaos + 50*pos->z));
  1557. X
  1558. X    brownPerturb = .6*perturb + 0.3;
  1559. X    greenPerturb = .2*perturb + 0.8;
  1560. X    grnPerturb = .15*perturb + 0.85;
  1561. X    grn = 0.5 * pow(abs(brownLayer), 0.3);
  1562. X    brownLayer = pow(0.5 * (brownLayer+1.0), 0.6) * brownPerturb;
  1563. X    greenLayer = pow(0.5 * (greenLayer+1.0), 0.6) * greenPerturb;
  1564. X
  1565. X    red = (0.5*brownLayer + 0.35*greenLayer)*2.*grn;
  1566. X    blu = (0.25*brownLayer + 0.35*greenLayer)*2.0*grn;
  1567. X    grn *= max(brownLayer, greenLayer) * grnPerturb;
  1568. X
  1569. X    surf->diff.r *= red;
  1570. X    surf->diff.g *= grn;
  1571. X    surf->diff.b *= blu;
  1572. X
  1573. X    ScaleColor(0.3, surf->diff, &surf->amb);
  1574. X}
  1575. X
  1576. X/*
  1577. X * Create and return a reference to a "checker" texture.
  1578. X */
  1579. XTexture *
  1580. XNewCheckText(surf)
  1581. Xchar *surf;
  1582. X{
  1583. X    Texture *text;
  1584. X
  1585. X    text = new_texture(CHECKER);
  1586. X    text->surf1 = find_surface(surf);
  1587. X
  1588. X    return text;
  1589. X}
  1590. X
  1591. XTexture *
  1592. XNewfBmBumpText(offset, scale, h, lambda, octaves)
  1593. Xdouble h, lambda, scale, offset;
  1594. Xint octaves;
  1595. X{
  1596. X    Texture *text;
  1597. X
  1598. X    text = NewfBmText(offset, scale, h, lambda, octaves, 0., (char *)0);
  1599. X
  1600. X    text->type = FBMBUMP;
  1601. X
  1602. X    return text;
  1603. X}
  1604. X
  1605. XTexture *
  1606. XNewfBmText(offset, scale, h, lambda, octaves, thresh, mapname)
  1607. Xdouble h, lambda, scale, offset, thresh;
  1608. Xint octaves;
  1609. Xchar *mapname;
  1610. X{
  1611. X    double beta;
  1612. X    Texture *text;
  1613. X
  1614. X    text = new_texture(FBM);
  1615. X
  1616. X    text->args = (double *)Malloc(5 * sizeof(double));
  1617. X    beta = 1. + 2 * h;
  1618. X    text->args[0] = pow(lambda, -0.5 * beta);    /* omega */
  1619. X    text->args[1] = lambda;
  1620. X    text->args[2] = scale;
  1621. X    text->args[3] = offset;
  1622. X    text->args[4] = thresh;
  1623. X    text->size = (double)octaves;
  1624. X    if (mapname != (char *)0)
  1625. X        text->colormap = read_colormap(mapname);
  1626. X
  1627. X    return text;
  1628. X}
  1629. X
  1630. X/*
  1631. X * Create and return a reference to a "bump" texture.
  1632. X */
  1633. XTexture *
  1634. XNewBumpText(size)
  1635. Xdouble size;
  1636. X{
  1637. X    Texture *text;
  1638. X
  1639. X    text = new_texture(BUMP);
  1640. X    text->size = size;
  1641. X
  1642. X    return text;
  1643. X}
  1644. X
  1645. X/*
  1646. X * Create and return a reference to a "blotch" texture.
  1647. X */
  1648. XTexture *
  1649. XNewBlotchText(scale, surf)
  1650. Xdouble scale;
  1651. Xchar *surf;
  1652. X{
  1653. X    Texture *text;
  1654. X
  1655. X    text = new_texture(BLOTCH);
  1656. X    text->size = scale;
  1657. X    text->surf1 = find_surface(surf);
  1658. X
  1659. X    return text;
  1660. X}
  1661. X
  1662. XTexture *
  1663. XNewMarbleText(mapname)
  1664. Xchar *mapname;
  1665. X{
  1666. X    Texture *text;
  1667. X
  1668. X    text = new_texture(MARBLE);
  1669. X    if (mapname)
  1670. X        text->colormap = read_colormap(mapname);
  1671. X    return text;
  1672. X}
  1673. X
  1674. X/*
  1675. X * Apply "blotch" texture.
  1676. X */
  1677. XBlotchText(text, pos, norm, surf)
  1678. XTexture *text;
  1679. XVector *pos, *norm;
  1680. XSurface *surf;
  1681. X{
  1682. X    double val;
  1683. X
  1684. X    /*
  1685. X     * "size" represents the 'average' noise value at a point.
  1686. X     */
  1687. X    val = Noise(pos);
  1688. X    if (val > text->size) {
  1689. X        val = (val - text->size) / (1. - text->size);
  1690. X        blend_surface(surf, text->surf1, 1. - val, val);
  1691. X    }
  1692. X}
  1693. X
  1694. XfBmText(text, pos, norm, surf)
  1695. XTexture *text;
  1696. XVector *pos, *norm;
  1697. XSurface *surf;
  1698. X{
  1699. X    double val;
  1700. X    int index;
  1701. X
  1702. X    val = fBm(pos, text->args[0], text->args[1], (int)text->size);
  1703. X    if (val < text->args[4])
  1704. X        val = 0.;
  1705. X    else
  1706. X        val = text->args[3] + text->args[2] * (val - text->args[4]);
  1707. X    if (text->colormap) {
  1708. X        index = 255. * val;
  1709. X        if (index > 255) index = 255;
  1710. X        if (index < 0) index = 0;
  1711. X        surf->diff = text->colormap[index];
  1712. X        ScaleColor(.2, surf->diff, &surf->amb);
  1713. X    } else {
  1714. X        ScaleColor(val, surf->diff, &surf->diff);
  1715. X        ScaleColor(val, surf->amb, &surf->amb);
  1716. X    }
  1717. X}
  1718. X
  1719. X/*
  1720. X * Apply a "checker" texture.
  1721. X */
  1722. XCheckerText(text, pos, norm, surf)
  1723. XTexture *text;
  1724. XVector *pos, *norm;
  1725. XSurface *surf;
  1726. X{
  1727. X    int xp, yp, zp;
  1728. X
  1729. X    xp = pos->x > 0. ? pos->x : 1. - pos->x;
  1730. X    yp = pos->y > 0. ? pos->y : 1. - pos->y;
  1731. X    zp = pos->z > 0. ? pos->z : 1. - pos->z;
  1732. X
  1733. X    if ((xp + yp + zp) % 2)
  1734. X        *surf = *text->surf1;
  1735. X    /* else surface stays the same. */
  1736. X}
  1737. X
  1738. XfBmBumpText(text, pos, norm, surf)
  1739. XTexture *text;
  1740. XVector *pos, *norm;
  1741. XSurface *surf;
  1742. X{
  1743. X    Vector disp;
  1744. X    double w;
  1745. X
  1746. X    VfBm(pos, text->args[0], text->args[1], (int)text->size, &disp);
  1747. X    w = text->args[2];
  1748. X    norm->x += text->args[3] + disp.x * w;
  1749. X    norm->y += text->args[3] + disp.y * w;
  1750. X    norm->z += text->args[3] + disp.z * w;
  1751. X}
  1752. X
  1753. X/*
  1754. X * Apply a "bump" texture.
  1755. X */
  1756. XBumpText(text, pos, norm, surf)
  1757. XTexture *text;
  1758. XVector *pos, *norm;
  1759. XSurface *surf;
  1760. X{
  1761. X    Vector disp;
  1762. X
  1763. X    DNoise(pos, &disp);
  1764. X    norm->x += disp.x * text->size;
  1765. X    norm->y += disp.y * text->size;
  1766. X    norm->z += disp.z * text->size;
  1767. X    (void)normalize(norm);
  1768. X}
  1769. X
  1770. XMarbleText(text, pos, norm, surf)
  1771. XTexture *text;
  1772. XVector *pos, *norm;
  1773. XSurface *surf;
  1774. X{
  1775. X    double val;
  1776. X    int index;
  1777. X
  1778. X    val = Marble(pos);
  1779. X    if (text->colormap) {
  1780. X        index = (int)(255. * val);
  1781. X        surf->diff = text->colormap[index];
  1782. X    } else {
  1783. X        ScaleColor(val, surf->amb, &surf->amb);
  1784. X        ScaleColor(val, surf->diff, &surf->diff);
  1785. X    }
  1786. X}
  1787. X
  1788. XColor *
  1789. Xread_colormap(filename)
  1790. Xchar *filename;
  1791. X{
  1792. X    FILE *fp;
  1793. X    Color *map;
  1794. X    char buf[BUFSIZ];
  1795. X    int i;
  1796. X
  1797. X    fp = fopen(filename, "r");
  1798. X    if (fp == (FILE *)NULL)
  1799. X        yyerror("Cannot open colormap file.");
  1800. X
  1801. X    map = (Color *)Calloc(256, sizeof(Color));
  1802. X
  1803. X    for (i = 0; fgets(buf,BUFSIZ,fp) != NULL && i < 256; i++) {
  1804. X        sscanf(buf,"%lf %lf %lf",&map[i].r, &map[i].g, &map[i].b);
  1805. X        ScaleColor(1. / 255., map[i], &map[i]);
  1806. X    }
  1807. X    return map;
  1808. X}
  1809. END_OF_FILE
  1810. if test 7557 -ne `wc -c <'src/texture.c'`; then
  1811.     echo shar: \"'src/texture.c'\" unpacked with wrong size!
  1812. fi
  1813. # end of 'src/texture.c'
  1814. fi
  1815. if test -f 'src/triangle.c' -a "${1}" != "-c" ; then 
  1816.   echo shar: Will not clobber existing file \"'src/triangle.c'\"
  1817. else
  1818. echo shar: Extracting \"'src/triangle.c'\" \(7297 characters\)
  1819. sed "s/^X//" >'src/triangle.c' <<'END_OF_FILE'
  1820. X/*
  1821. X * triangle.c
  1822. X *
  1823. X * Copyright (C) 1989, Craig E. Kolb
  1824. X *
  1825. X * This software may be freely copied, modified, and redistributed,
  1826. X * provided that this copyright notice is preserved on all copies.
  1827. X *
  1828. X * There is no warranty or other guarantee of fitness for this software,
  1829. X * it is provided solely .  Bug reports or fixes may be sent
  1830. X * to the author, who may or may not act on them as he desires.
  1831. X *
  1832. X * You may not include this software in a program or other software product
  1833. X * without supplying the source, or without informing the end-user that the
  1834. X * source is available for no extra charge.
  1835. X *
  1836. X * If you modify this software, you should include a notice giving the
  1837. X * name of the person performing the modification, the date of modification,
  1838. X * and the reason for such modification.
  1839. X *
  1840. X * $Id: triangle.c,v 3.0 89/10/27 02:06:07 craig Exp $
  1841. X *
  1842. X * $Log:    triangle.c,v $
  1843. X * Revision 3.0  89/10/27  02:06:07  craig
  1844. X * Baseline for first official release.
  1845. X * 
  1846. X */
  1847. X#include <stdio.h>
  1848. X#include <math.h>
  1849. X#include "constants.h"
  1850. X#include "typedefs.h"
  1851. X#include "funcdefs.h"
  1852. X
  1853. X#define within(x, a)        (((a) <= 0 && (x) >= (a) && (x) <= 0) || \
  1854. X                    ((a) > 0 && (x) >= 0 && (x) <= (a)))
  1855. X/*
  1856. X * Create and return reference to a triangle.
  1857. X */
  1858. XObject *
  1859. Xmaktri(type, surf, p1, p2, p3, n1, n2, n3)
  1860. Xint    type;
  1861. Xchar    *surf;
  1862. XVector    *p1, *p2, *p3, *n1, *n2, *n3;
  1863. X{
  1864. X    Triangle *triangle;
  1865. X    Primitive *prim;
  1866. X    Vector vc1, vc2, vc3, ptmp, anorm;
  1867. X    Object *newobj;
  1868. X    double indexval;
  1869. X    extern int yylineno, Quiet;
  1870. X
  1871. X    prim = mallocprim();
  1872. X    triangle = (Triangle *)Malloc(sizeof(Triangle));
  1873. X    prim->objpnt.p_triangle = triangle;
  1874. X    newobj = new_object(NULL, (char)type, (char *)prim, (Trans *)NULL);
  1875. X    prim->surf = find_surface(surf);
  1876. X
  1877. X    if (type == PHONGTRI) {
  1878. X        prim->type = PHONGTRI;
  1879. X        (void)normalize(n1);
  1880. X        (void)normalize(n2);
  1881. X        (void)normalize(n3);
  1882. X        triangle->vnorm = (Vector *)Malloc(3 * sizeof(Vector));
  1883. X        triangle->vnorm[0] = *n1;
  1884. X        triangle->vnorm[1] = *n2;
  1885. X        triangle->vnorm[2] = *n3;
  1886. X        triangle->b = (double *)Malloc(3 * sizeof(double));
  1887. X    }
  1888. X    else
  1889. X        prim->type = TRIANGLE;
  1890. X
  1891. X    vecsub(*p2, *p1, &vc1);
  1892. X    vecsub(*p3, *p2, &vc2);
  1893. X    vecsub(*p1, *p3, &vc3);
  1894. X
  1895. X    /* Find plane normal. */
  1896. X    rawcrossp(&triangle->nrm, &vc1, &vc2);
  1897. X    ptmp = triangle->nrm;
  1898. X    if (normalize(&ptmp) == 0.) {
  1899. X        if (!Quiet)
  1900. X            fprintf(stderr,"Degenerate triangle (line %d).\n",
  1901. X                            yylineno);
  1902. X        free((char *)prim);
  1903. X        free((char *)triangle);
  1904. X        free((char *)newobj);
  1905. X        return (Object *)0;
  1906. X    }
  1907. X
  1908. X    triangle->d = dotp(&triangle->nrm, p1);
  1909. X
  1910. X    triangle->p1 = *p1;
  1911. X    triangle->p2 = *p2;
  1912. X    triangle->p3 = *p3;
  1913. X
  1914. X    triangle->e1 = vc1;
  1915. X    triangle->e2 = vc2;
  1916. X    triangle->e3 = vc3;
  1917. X
  1918. X    if (type == PHONGTRI && dotp(&triangle->vnorm[0], &ptmp) < 0.) {
  1919. X        /*
  1920. X         * Reverse direction of surface normal on Phong
  1921. X         * triangle if the surface normal points "away"
  1922. X         * from the first vertex normal.
  1923. X         */
  1924. X        scalar_prod(-1., triangle->nrm, &triangle->nrm);
  1925. X        triangle->d = -triangle->d;
  1926. X        scalar_prod(-1., triangle->e1, &triangle->e1);
  1927. X        scalar_prod(-1., triangle->e2, &triangle->e2);
  1928. X        scalar_prod(-1., triangle->e3, &triangle->e3);
  1929. X    }
  1930. X    /*
  1931. X     * Find "dominant" part of normal vector.
  1932. X     */
  1933. X    anorm.x = abs(triangle->nrm.x);
  1934. X    anorm.y = abs(triangle->nrm.y);
  1935. X    anorm.z = abs(triangle->nrm.z);
  1936. X    indexval = max(anorm.y, anorm.z);
  1937. X    indexval = max(anorm.x, indexval);
  1938. X    if (indexval == anorm.x)
  1939. X        triangle->index = XNORMAL;
  1940. X    else if (indexval == anorm.y)
  1941. X        triangle->index = YNORMAL;
  1942. X    else
  1943. X        triangle->index = ZNORMAL;
  1944. X
  1945. X    return newobj;
  1946. X}
  1947. X
  1948. X/*
  1949. X * Intersect ray with triangle.  See Snyder & Barr for details on
  1950. X * how this works.
  1951. X */
  1952. Xdouble
  1953. Xinttri(pos, ray, obj)
  1954. Xregister Vector           *pos, *ray;
  1955. XPrimitive       *obj;
  1956. X{
  1957. X    register Triangle     *triangle;
  1958. X    double qi1, qi2, s, k, b1, b2, b3;
  1959. X    extern unsigned long primtests[];
  1960. X
  1961. X    primtests[obj->type]++;
  1962. X
  1963. X    triangle = obj->objpnt.p_triangle;
  1964. X    /*
  1965. X     * Plane intersection.
  1966. X     */
  1967. X    k = dotp(&triangle->nrm, ray);
  1968. X    if (k == 0.)
  1969. X        return 0.;
  1970. X    s = (triangle->d - dotp(&triangle->nrm, pos)) / k;
  1971. X    if (s <= 0.)
  1972. X        return 0.;
  1973. X
  1974. X    if (triangle->index == XNORMAL) {
  1975. X        qi1 = pos->y + s * ray->y;
  1976. X        qi2 = pos->z + s * ray->z;
  1977. X        b1 = triangle->e2.y * (qi2 - triangle->p2.z) -
  1978. X                triangle->e2.z * (qi1 - triangle->p2.y);
  1979. X        if (!within(b1, triangle->nrm.x))
  1980. X            return 0.;
  1981. X        b2 = triangle->e3.y * (qi2 - triangle->p3.z) -
  1982. X                triangle->e3.z * (qi1 - triangle->p3.y);
  1983. X        if (!within(b2, triangle->nrm.x))
  1984. X            return 0.;
  1985. X        b3 = triangle->e1.y * (qi2 - triangle->p1.z) -
  1986. X                triangle->e1.z * (qi1 - triangle->p1.y);
  1987. X        if (!within(b3, triangle->nrm.x))
  1988. X            return 0.;
  1989. X    } else if (triangle->index == YNORMAL) {
  1990. X        qi1 = pos->x + s * ray->x;
  1991. X        qi2 = pos->z + s * ray->z;
  1992. X        b1 = triangle->e2.z * (qi1 - triangle->p2.x) -
  1993. X            triangle->e2.x * (qi2 - triangle->p2.z);
  1994. X        if (!within(b1, triangle->nrm.y))
  1995. X            return 0.;
  1996. X        b2 = triangle->e3.z * (qi1 - triangle->p3.x) -
  1997. X            triangle->e3.x * (qi2 - triangle->p3.z);
  1998. X        if (!within(b2, triangle->nrm.y))
  1999. X            return 0.;
  2000. X        b3 = triangle->e1.z * (qi1 - triangle->p1.x) -
  2001. X            triangle->e1.x * (qi2 - triangle->p1.z);
  2002. X        if (!within(b3, triangle->nrm.y))
  2003. X            return 0.;
  2004. X    } else {
  2005. X        qi1 = pos->x + s * ray->x;
  2006. X        qi2 = pos->y + s * ray->y;
  2007. X        b1 = triangle->e2.x * (qi2 - triangle->p2.y) -
  2008. X                triangle->e2.y * (qi1 - triangle->p2.x);
  2009. X        if (!within(b1, triangle->nrm.z))
  2010. X            return 0.;
  2011. X
  2012. X        b2 = triangle->e3.x * (qi2 - triangle->p3.y) -
  2013. X                triangle->e3.y * (qi1 - triangle->p3.x);
  2014. X        if (!within(b2, triangle->nrm.z))
  2015. X            return 0.;
  2016. X
  2017. X        b3 = triangle->e1.x * (qi2 - triangle->p1.y) -
  2018. X                triangle->e1.y * (qi1 - triangle->p1.x);
  2019. X        if (!within(b3, triangle->nrm.z))
  2020. X            return 0.;
  2021. X    }
  2022. X    /*
  2023. X     * Take abs value if there was an intersection.
  2024. X     */
  2025. X    if (obj->type == PHONGTRI) {
  2026. X        triangle->b[0] = abs(b1);
  2027. X        triangle->b[1] = abs(b2);
  2028. X        triangle->b[2] = abs(b3);
  2029. X    }
  2030. X    return s;
  2031. X}
  2032. X
  2033. Xnrmtri(pos, obj, nrm)
  2034. XVector           *pos, *nrm;
  2035. XPrimitive       *obj;
  2036. X{
  2037. X    Triangle *tri;
  2038. X
  2039. X    /*
  2040. X     * Normals will be normalized later...
  2041. X     */
  2042. X    if (obj->type == TRIANGLE) {
  2043. X        *nrm = obj->objpnt.p_triangle->nrm;
  2044. X    } else {
  2045. X        /*
  2046. X         * Interpolate normals of Phong-shaded triangles.
  2047. X         */
  2048. X        tri = obj->objpnt.p_triangle;
  2049. X        nrm->x = tri->b[0]*tri->vnorm[0].x+tri->b[1]*tri->vnorm[1].x+
  2050. X            tri->b[2]*tri->vnorm[2].x;
  2051. X        nrm->y = tri->b[0]*tri->vnorm[0].y+tri->b[1]*tri->vnorm[1].y+
  2052. X            tri->b[2]*tri->vnorm[2].y;
  2053. X        nrm->z = tri->b[0]*tri->vnorm[0].z+tri->b[1]*tri->vnorm[1].z+
  2054. X            tri->b[2]*tri->vnorm[2].z;
  2055. X    }
  2056. X}
  2057. X
  2058. Xtriextent(o, bounds)
  2059. XPrimitive *o;
  2060. Xdouble bounds[2][3];
  2061. X{
  2062. X    Triangle *tri;
  2063. X
  2064. X    tri = o->objpnt.p_triangle;
  2065. X
  2066. X    bounds[LOW][X] = bounds[HIGH][X] = tri->p1.x;
  2067. X    bounds[LOW][Y] = bounds[HIGH][Y] = tri->p1.y;
  2068. X    bounds[LOW][Z] = bounds[HIGH][Z] = tri->p1.z;
  2069. X
  2070. X    if (tri->p2.x < bounds[LOW][X]) bounds[LOW][X] = tri->p2.x;
  2071. X    if (tri->p2.x > bounds[HIGH][X]) bounds[HIGH][X] = tri->p2.x;
  2072. X    if (tri->p3.x < bounds[LOW][X]) bounds[LOW][X] = tri->p3.x;
  2073. X    if (tri->p3.x > bounds[HIGH][X]) bounds[HIGH][X] = tri->p3.x;
  2074. X
  2075. X    if (tri->p2.y < bounds[LOW][Y]) bounds[LOW][Y] = tri->p2.y;
  2076. X    if (tri->p2.y > bounds[HIGH][Y]) bounds[HIGH][Y] = tri->p2.y;
  2077. X    if (tri->p3.y < bounds[LOW][Y]) bounds[LOW][Y] = tri->p3.y;
  2078. X    if (tri->p3.y > bounds[HIGH][Y]) bounds[HIGH][Y] = tri->p3.y;
  2079. X
  2080. X    if (tri->p2.z < bounds[LOW][Z]) bounds[LOW][Z] = tri->p2.z;
  2081. X    if (tri->p2.z > bounds[HIGH][Z]) bounds[HIGH][Z] = tri->p2.z;
  2082. X    if (tri->p3.z < bounds[LOW][Z]) bounds[LOW][Z] = tri->p3.z;
  2083. X    if (tri->p3.z > bounds[HIGH][Z]) bounds[HIGH][Z] = tri->p3.z;
  2084. X}
  2085. END_OF_FILE
  2086. if test 7297 -ne `wc -c <'src/triangle.c'`; then
  2087.     echo shar: \"'src/triangle.c'\" unpacked with wrong size!
  2088. fi
  2089. # end of 'src/triangle.c'
  2090. fi
  2091. echo shar: End of archive 4 \(of 8\).
  2092. cp /dev/null ark4isdone
  2093. MISSING=""
  2094. for I in 1 2 3 4 5 6 7 8 ; do
  2095.     if test ! -f ark${I}isdone ; then
  2096.     MISSING="${MISSING} ${I}"
  2097.     fi
  2098. done
  2099. if test "${MISSING}" = "" ; then
  2100.     echo You have unpacked all 8 archives.
  2101.     rm -f ark[1-9]isdone
  2102. else
  2103.     echo You still need to unpack the following archives:
  2104.     echo "        " ${MISSING}
  2105. fi
  2106. ##  End of shell archive.
  2107. exit 0
  2108.  
  2109.  
  2110.