amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (09/04/90)
Submitted-by: David Schanen <mtv@milton.u.washington.edu> Posting-number: Volume 90, Issue 251 Archive-name: applications/dkbtrace-2.01/part03 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 10)." # Contents: src/Sculpt2dkb.c src/amiga.c src/csg.c src/gif.c # src/iffw.c src/matrices.c src/planes.c src/spheres.c # Wrapped by tadguy@abcfd20 on Mon Sep 3 19:21:17 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/Sculpt2dkb.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/Sculpt2dkb.c'\" else echo shar: Extracting \"'src/Sculpt2dkb.c'\" \(7547 characters\) sed "s/^X//" >'src/Sculpt2dkb.c' <<'END_OF_FILE' X/***************************************************************************** X* X* Sculpt2dat.c X* X* from DKBTrace (c) 1990 David Buck X* X* This program reads a Sculpt-Animate 3D format scene file and generates an X* output file that may be read in to DKBTrace. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X X#include <stdio.h> X#include "frame.h" X#include "dkbproto.h" X Xvoid read_iff_file(void); X XIMAGE_COLOUR *iff_colour_map; Xint colourmap_size; XFILE *f, *out; X Xstatic CHUNK_HEADER Chunk_Header; X XDBL *vertices_x, *vertices_y, *vertices_z; XDBL max_x, max_y, max_z, min_x, min_y, min_z; X#define FABS(x) ((x<0.0)?-x:x) X X#define FORM 0x464f524dL X#define SC3D 0x53433344L X#define VERT 0x56455254L X#define FACE 0x46414345L X X#define CMPNONE 0 X Xchar *Textures[7] = {"Dull", "Shiny", "Mirror", "Luminous", "Glass", "Metal", "Glass2"}; X Xvoid iff_error () X { X printf ("Invalid iff file\n"); X exit(1); X } X Xint read_byte(f) X FILE *f; X { X int c; X if ((c = getc(f)) == EOF) X iff_error(); X return (c); X } X Xint read_word(f) X FILE *f; X { X int result; X X result = read_byte(f)*256; X result += read_byte(f); X return (result); X } X Xlong read_long(f) X FILE *f; X { X int i; X long result; X X result = 0; X for (i = 0 ; i < 4 ; i++) X result = result * 256 + read_byte(f); X X return (result); X } X Xvoid Read_Chunk_Header (f, dest) X FILE *f; X CHUNK_HEADER *dest; X { X dest->name = read_long(f); X dest->size = (int) read_long(f); X } X Xvoid read_iff_file() X { X int i; X int vert1, vert2, vert3; X unsigned int texture; X DBL red, green, blue; X X max_x = max_y = max_z = -10000000.0; X min_x = min_y = min_z = 10000000.0; X X while (1) { X Read_Chunk_Header(f, &Chunk_Header); X switch ((int) Chunk_Header.name) { X case FORM: if (read_long(f) != SC3D) X iff_error(); X break; X X case VERT: vertices_x = (DBL *) X malloc (Chunk_Header.size * (sizeof(DBL)/sizeof(long))); X vertices_y = (DBL *) X malloc (Chunk_Header.size * (sizeof(DBL)/sizeof(long))); X vertices_z = (DBL *) X malloc (Chunk_Header.size * (sizeof(DBL)/sizeof(long))); X for (i = 0 ; i < Chunk_Header.size/12 ; i++) { X vertices_x[i] = read_long(f) / 10000.0; X if (vertices_x[i] < min_x) X min_x = vertices_x[i]; X if (vertices_x[i] > max_x) X max_x = vertices_x[i]; X X vertices_y[i] = read_long(f) / 10000.0; X if (vertices_y[i] < min_y) X min_y = vertices_y[i]; X if (vertices_y[i] > max_y) X max_y = vertices_y[i]; X X vertices_z[i] = read_long(f) / 10000.0; X if (vertices_z[i] < min_z) X min_z = vertices_z[i]; X if (vertices_z[i] > max_z) X max_z = vertices_z[i]; X } X break; X X case FACE: for (i = 0 ; i < Chunk_Header.size/16 ; i++) { X vert1 = (int) read_long(f); X vert2 = (int) read_long(f); X vert3 = (int) read_long(f); X red = read_byte(f) / 255.0; X green = read_byte(f) / 255.0; X blue = read_byte(f) / 255.0; X X texture = read_byte(f); X texture &= 0x07; /* mask upper bits */ X X fprintf (out, "OBJECT TRIANGLE <%f %f %f> <%f %f %f> <%f %f %f> END_TRIANGLE COLOUR RED %f GREEN %f BLUE %f TEXTURE %s END_TEXTURE END_OBJECT\n", X vertices_x[vert1], vertices_y[vert1], vertices_z[vert1], X vertices_x[vert2], vertices_y[vert2], vertices_z[vert2], X vertices_x[vert3], vertices_y[vert3], vertices_z[vert3], X red, green, blue, Textures[texture]); X } X return; X X default: X for (i = 0 ; i < Chunk_Header.size ; i++) X if (getc(f) == EOF) X iff_error(); X break; X } X } X } X Xvoid main (argc, argv) X int argc; X char **argv; X { X if (argc != 3) { X printf ("Usage: %s <scene-file> <output-file>\n", argv[0]); X exit (1); X } X X if ((f = fopen(argv[1], "rb")) == NULL) { X printf ("Cannot open IFF file %s\n", argv[1]); X exit(1); X } X X if ((out = fopen(argv[2], "w")) == NULL) { X printf ("Cannot open output file %s\n", argv[1]); X exit(1); X } X X fprintf(out, "COMPOSITE\n"); X read_iff_file(); X fprintf(out, " BOUNDED_BY\n INTERSECTION\n"); X fprintf(out, " PLANE <1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(max_x) * 1.01); X fprintf(out, " PLANE <-1.0 0.0 0.0> %1.02f END_PLANE\n", FABS(min_x) * 1.01); X fprintf(out, " PLANE <0.0 1.0 0.0> %1.02f END_PLANE\n", FABS(max_y) * 1.01); X fprintf(out, " PLANE <0.0 -1.0 0.0> %1.02f END_PLANE\n", FABS(min_y) * 1.01); X fprintf(out, " PLANE <0.0 0.0 1.0> %1.02f END_PLANE\n", FABS(max_z) * 1.01); X fprintf(out, " PLANE <0.0 0.0 -1.0> %1.02f END_PLANE\n", FABS(min_z) * 1.01); X fprintf(out, " END_INTERSECTION\n END_BOUND\n \nEND_COMPOSITE\n"); X printf ("X values range from %f to %f\n", min_x, max_x); X printf ("Y values range from %f to %f\n", min_y, max_y); X printf ("Z values range from %f to %f\n", min_z, max_z); X fclose(f); X fclose(out); X } END_OF_FILE if test 7547 -ne `wc -c <'src/Sculpt2dkb.c'`; then echo shar: \"'src/Sculpt2dkb.c'\" unpacked with wrong size! fi # end of 'src/Sculpt2dkb.c' fi if test -f 'src/amiga.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/amiga.c'\" else echo shar: Extracting \"'src/amiga.c'\" \(6939 characters\) sed "s/^X//" >'src/amiga.c' <<'END_OF_FILE' X/***************************************************************************** X* X* amiga.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module handles all of the Amiga-specific code for the raytracer. X* X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X#include "frame.h" X#include "dkbproto.h" X X#include <proto/exec.h> X#include <proto/intuition.h> X#include <proto/graphics.h> X#include <proto/dos.h> X#include <exec/types.h> X#include <intuition/intuition.h> X#include <graphics/display.h> X Xvoid geta4(void); Xvoid Requestor_Handler(void); Xvoid Amiga_open(void); Xvoid Amiga_close(void); Xvoid open_requestor(void); Xvoid close_requestor(void); Xextern int Options; X X#define INT_REV 29L X#define GR_REV 29L X Xstruct IntuitionBase *IntuitionBase; Xstruct GfxBase *GfxBase; Xstruct Screen *s; Xstruct Window *w; Xstruct Task *Requestor_Task; X Xvolatile int Requestor_Running; Xvolatile extern int Stop_Flag; X X#define SCREEN_WIDTH 320 X#define SCREEN_HEIGHT 400 X Xstruct NewScreen MyScreen = X { X 0, 0, X SCREEN_WIDTH, SCREEN_HEIGHT, X 6, X 0, 1, X INTERLACE | HAM, X SCREENQUIET, X NULL, X (UBYTE *) "DKB Ray Trace", X NULL, X NULL X }; X Xstruct Window *Requestor_Window; Xstruct MsgPort *Requestor_Port; X Xstruct IntuiText Body_Text = X {0, 1, JAM1, 5, 10, NULL, (UBYTE *) "Click to abort the picture", NULL}; X Xstruct IntuiText Abort_Text = X {0, 1, JAM1, 5, 3, NULL, (UBYTE *) "Abort", NULL}; X XUWORD ColorTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666, X 0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd, X 0xeee, 0xfff }; X XLONG last_red = 0, last_green = 0, last_blue = 0, last_y = -1; X Xvoid Requestor_Handler () X { X Requestor_Port = CreatePort ("ray trace port", 0L); X Requestor_Window = BuildSysRequest X (NULL, &Body_Text, NULL, &Abort_Text, GADGETUP, 280L, 60L); X Wait ((1 << Requestor_Port -> mp_SigBit) X | (1 << Requestor_Window -> UserPort -> mp_SigBit)); X X Requestor_Running = FALSE; X Stop_Flag = TRUE; X } X Xvoid Amiga_open() X { X IntuitionBase = (struct IntuitionBase *) OpenLibrary ("intuition.library",INT_REV); X if (IntuitionBase == NULL) X exit(FALSE); X X GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", GR_REV); X if (GfxBase == NULL) X exit(FALSE); X Requestor_Running = FALSE; X } X Xvoid Amiga_close() X { X if (Requestor_Running) { X Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit); X Delay (2L); X } X X if (Requestor_Window) X FreeSysRequest (Requestor_Window); X X Requestor_Window = NULL; X X CloseLibrary (GfxBase) ; X CloseLibrary (IntuitionBase) ; X } X Xvoid open_requestor() X { X Requestor_Window = NULL; X Stop_Flag = FALSE; X Requestor_Running = TRUE; X Requestor_Task = CreateTask ("Raytrace Requestor", 2L, X (APTR) Requestor_Handler, 20000L); X } X Xvoid display_finished () X { X if (Requestor_Running) { X Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit); X Delay (2L); X } X X if (Requestor_Window) X FreeSysRequest (Requestor_Window); X X Requestor_Window = NULL; X if (Options & PROMPTEXIT) X { X printf ("Finished.\nPress CR to quit.\n"); X getchar(); X } X } X Xvoid display_init () X { X Amiga_open(); X open_requestor(); X X Delay (10); X if ((s = (struct Screen *) OpenScreen (&MyScreen)) == NULL) X exit (FALSE); X X ShowTitle (s, FALSE); X X LoadRGB4 (&(s->ViewPort), ColorTbl, 16L); X SetAPen (&(s->RastPort), 7L); X RectFill (&(s -> RastPort), 0L, 0L, 319L, 399L); X } X Xvoid display_close () X { X if (Requestor_Running) { X Signal (Requestor_Task, 1 << Requestor_Port -> mp_SigBit); X Delay (2L); X } X X if (Requestor_Window) X FreeSysRequest (Requestor_Window); X X Requestor_Window = NULL; X X CloseScreen (s); X } X X#define absdif(x,y) ((x > y) ? (x - y) : (y - x)) X#define max3(x,y,z) ((x>y)?((x>z)?1:3):((y>z)?2:3)) X Xvoid display_plot (x, y, Red, Green, Blue) X int x, y; X char Red, Green, Blue; X { X register LONG delta_red, delta_green, delta_blue, colour; X static int Last_Colour = 0; X X if ((x >= SCREEN_WIDTH-1 ) || (y >= SCREEN_HEIGHT)) X return; X X Red = (Red >> 4) & 0x0F; X Green = (Green >> 4) & 0x0F; X Blue = (Blue >> 4) & 0x0F; X X if (last_y != y) { X last_y = y; X last_red = last_green = last_blue = 0; X Last_Colour = 0; X SetAPen (&(s -> RastPort), 0); X WritePixel (&(s -> RastPort), 0, y); X } X X delta_red = absdif (Red, last_red); X delta_green = absdif (Green, last_green); X delta_blue = absdif (Blue, last_blue); X X switch (max3(delta_red, delta_green, delta_blue)) { X case 1: X last_red = Red; X colour = 0x20 + Red; X break; X case 2: X last_green = Green; X colour = 0x30 + Green; X break; X case 3: X last_blue = Blue; X colour = 0x10 + Blue; X break; X } X X if (colour != Last_Colour) X { X SetAPen (&(s -> RastPort), colour); X Last_Colour = colour; X } X WritePixel (&(s -> RastPort), x+1, y); X } X END_OF_FILE if test 6939 -ne `wc -c <'src/amiga.c'`; then echo shar: \"'src/amiga.c'\" unpacked with wrong size! fi # end of 'src/amiga.c' fi if test -f 'src/csg.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/csg.c'\" else echo shar: Extracting \"'src/csg.c'\" \(7895 characters\) sed "s/^X//" >'src/csg.c' <<'END_OF_FILE' X/***************************************************************************** X* X* csg.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module implements routines for constructive solid geometry. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X X#include "frame.h" X#include "vector.h" X#include "dkbproto.h" X XMETHODS CSG_Union_Methods = X { Object_Intersect, All_CSG_Union_Intersections, X Inside_CSG_Union, NULL, X Copy_CSG, X Translate_CSG, Rotate_CSG, X Scale_CSG, Invert_CSG}; X XMETHODS CSG_Intersection_Methods = X { Object_Intersect, All_CSG_Intersection_Intersections, X Inside_CSG_Intersection, NULL, X Copy_CSG, X Translate_CSG, Rotate_CSG, X Scale_CSG, Invert_CSG}; X Xextern RAY *VP_Ray; Xextern unsigned long Options; X Xint All_CSG_Union_Intersections (Object, Ray, Depth_Queue) X OBJECT *Object; X RAY *Ray; X PRIOQ *Depth_Queue; X { X register int Intersection_Found; X CSG_SHAPE *Shape = (CSG_SHAPE *) Object; X SHAPE *Local_Shape; X X Intersection_Found = FALSE; X for (Local_Shape = Shape -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X if (All_Intersections ((OBJECT *) Local_Shape, Ray, Depth_Queue)) X Intersection_Found = TRUE; X X return (Intersection_Found); X } X Xint All_CSG_Intersection_Intersections (Object, Ray, Depth_Queue) X OBJECT *Object; X RAY *Ray; X PRIOQ *Depth_Queue; X { X int Intersection_Found, Any_Intersection_Found; X CSG_SHAPE *Shape = (CSG_SHAPE *) Object; X SHAPE *Local_Shape, *Shape2; X PRIOQ *Local_Depth_Queue; X INTERSECTION *Local_Intersection; X X Local_Depth_Queue = pq_new (128); X X Any_Intersection_Found = FALSE; X X for (Local_Shape = Shape -> Shapes ; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) { X X All_Intersections ((OBJECT *) Local_Shape, Ray, Local_Depth_Queue); X X for (Local_Intersection = pq_get_highest (Local_Depth_Queue); X Local_Intersection != NULL ; X pq_delete_highest (Local_Depth_Queue), X Local_Intersection = pq_get_highest (Local_Depth_Queue)) { X X Intersection_Found = TRUE; X X for (Shape2 = Shape -> Shapes; X Shape2 != NULL ; X Shape2 = Shape2 -> Next_Object) X X if (Shape2 != Local_Shape) X if (!Inside (&Local_Intersection -> Point, (OBJECT *) Shape2)) { X Intersection_Found = FALSE; X break; X } X X if (Intersection_Found) { X pq_add (Depth_Queue, Local_Intersection); X Any_Intersection_Found = TRUE; X } X } X } X X pq_free (Local_Depth_Queue); X X return (Any_Intersection_Found); X } X Xint Inside_CSG_Union (Point, Object) X VECTOR *Point; X OBJECT *Object; X { X CSG_SHAPE *Shape = (CSG_SHAPE *) Object; X SHAPE *Local_Shape; X X for (Local_Shape = Shape -> Shapes ; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X if (Inside (Point, (OBJECT *) Local_Shape)) X return (TRUE); X return (FALSE); X } X Xint Inside_CSG_Intersection (Point, Object) X OBJECT *Object; X VECTOR *Point; X { X SHAPE *Local_Shape; X CSG_SHAPE *Shape = (CSG_SHAPE *) Object; X X for (Local_Shape = Shape -> Shapes ; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X if (!Inside (Point, (OBJECT *) Local_Shape)) X return (FALSE); X X return (TRUE); X } X Xvoid *Copy_CSG (Object) X OBJECT *Object; X { X CSG_SHAPE *Shape = (CSG_SHAPE *) Object; X CSG_SHAPE *New_Shape; X SHAPE *Local_Shape, *Copied_Shape; X X New_Shape = Get_CSG_Shape (); X New_Shape->Methods = Shape->Methods; X New_Shape->Type = Shape->Type; X New_Shape -> Next_Object = NULL; X New_Shape -> Shapes = NULL; X X for (Local_Shape = Shape -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) { X X Copied_Shape = (SHAPE *) Copy ((OBJECT *) Local_Shape); X Link ((OBJECT *) Copied_Shape, X (OBJECT **) &(Copied_Shape -> Next_Object), X (OBJECT **) &(New_Shape -> Shapes)); X } X return (New_Shape); X } X Xvoid Translate_CSG (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X SHAPE *Local_Shape; X X for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X Translate ((OBJECT *) Local_Shape, Vector); X } X Xvoid Rotate_CSG (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X SHAPE *Local_Shape; X X for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X Rotate ((OBJECT *) Local_Shape, Vector); X } X Xvoid Scale_CSG (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X SHAPE *Local_Shape; X X for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X Scale ((OBJECT *) Local_Shape, Vector); X } X Xvoid Invert_CSG (Object) X OBJECT *Object; X { X SHAPE *Local_Shape; X CSG_SHAPE *Csg = (CSG_SHAPE *) Object; X X if (Csg->Type == CSG_INTERSECTION_TYPE) { X Csg->Type = CSG_UNION_TYPE; X Csg->Methods = &CSG_Union_Methods; X } X else if (Csg->Type == CSG_UNION_TYPE) { X Csg->Type = CSG_INTERSECTION_TYPE; X Csg->Methods = &CSG_Intersection_Methods; X } X X for (Local_Shape = Csg -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) X X Invert ((OBJECT *) Local_Shape); X } X Xvoid Set_CSG_Parents (Shape, Object) X CSG_SHAPE *Shape; X OBJECT *Object; X { X SHAPE *Local_Shape; X X for (Local_Shape = Shape -> Shapes; X Local_Shape != NULL ; X Local_Shape = Local_Shape -> Next_Object) { X X Local_Shape->Parent_Object = Object; X if ((Local_Shape->Type == CSG_UNION_TYPE) || X (Local_Shape->Type == CSG_INTERSECTION_TYPE)) X Set_CSG_Parents((CSG_SHAPE *)Local_Shape, Object); X } X } X END_OF_FILE if test 7895 -ne `wc -c <'src/csg.c'`; then echo shar: \"'src/csg.c'\" unpacked with wrong size! fi # end of 'src/csg.c' fi if test -f 'src/gif.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/gif.c'\" else echo shar: Extracting \"'src/gif.c'\" \(7511 characters\) sed "s/^X//" >'src/gif.c' <<'END_OF_FILE' X/***************************************************************************** X* X* gif.c X* X* from DKBTrace (c) 1990 David Buck X* X* Gif-format file reader. X* X* NOTE: Portions of this module were written by Steve Bennett and are used X* here with his permission. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X/* X The following routines were borrowed freely from FRACTINT, and represent X a generalized GIF file decoder. This seems the best, most universal format X for reading in Bitmapped images. GIF is a Copyright of Compuserve, Inc. X Swiped and converted to entirely "C" coded routines by AAC for the most X in future portability! X*/ X X#include "frame.h" X#include "dkbproto.h" X Xstatic IMAGE *Current_Image; Xstatic int Bitmap_Line; Xstatic FILE *Bit_File; Xunsigned char *decoderline /* [2049] */ ; /* write-line routines use this */ X Xstatic IMAGE_COLOUR *gif_colour_map; Xstatic int colourmap_size; X Xint out_line (pixels, linelen) X unsigned char *pixels; X int linelen; X { X register int x; X register unsigned addr; X X addr = linelen * Bitmap_Line--; X X for (x = 0; x < linelen; x++) { X Current_Image->red[addr+x] = gif_colour_map[*pixels].Red; X Current_Image->green[addr+x] = gif_colour_map[*pixels].Green; X Current_Image->blue[addr+x] = gif_colour_map[*pixels].Blue; X pixels++; X } X X return (0); X } X X#define READ_ERROR -1 X Xint get_byte() /* get byte from file, return the next byte or an error */ X { X register int byte; X X if ((byte = getc(Bit_File)) != EOF) X return (byte); X else { X printf ("Premature end of file reading GIF image\n"); X exit (1); X } X return (0); /* Keep the compiler happy */ X } X X/* Main GIF file decoder. */ X Xvoid read_gif_image(Image, filename) X IMAGE *Image; X char *filename; X { X register int i, j, status; X unsigned finished, planes; X unsigned char buffer[16]; X X status = 0; X Current_Image = Image; X X if ((Bit_File = fopen(filename, "rb")) == NULL) { X printf ("Cannot open GIF file %s\n", filename); X exit(1); X } X X /* zero out the full write-line */ X if ((decoderline = (unsigned char *) malloc (2049)) == NULL) { X printf ("Cannot allocate space for gif decoder line\n"); X fclose (Bit_File); X exit (1); X } X X for (i = 0; i < 2049; i++) X decoderline[i] = (unsigned char) 0; X X /* Get the screen description */ X for (i = 0; i < 13; i++) X buffer[i] = (unsigned char)get_byte(); X X if (strncmp(buffer,"GIF87a",3) || /* use updated GIF specs */ X buffer[3] < '0' || buffer[3] > '9' || X buffer[4] < '0' || buffer[4] > '9' || X buffer[5] < 'A' || buffer[5] > 'z' ) { X X printf ("Invalid GIF file format: %s\n", filename); X fclose(Bit_File); X exit (1); X } X X planes = ((unsigned)buffer[10] & 0x0F) + 1; X colourmap_size = (int)(1 << planes); X if ((gif_colour_map = (IMAGE_COLOUR *) X malloc (colourmap_size * sizeof (IMAGE_COLOUR))) == NULL) { X printf ("Cannot allocate gif colour map\n"); X fclose (Bit_File); X exit (1); X } X X if ((buffer[10] & 0x80) == 0) { /* color map (better be!) */ X printf ("Invalid GIF file format: %s\n", filename); X fclose(Bit_File); X exit (1); X } X X for (i = 0; i < colourmap_size ; i++) { X gif_colour_map[i].Red = (unsigned char)get_byte(); X gif_colour_map[i].Green = (unsigned char)get_byte(); X gif_colour_map[i].Blue = (unsigned char)get_byte(); X } X X /* Now display one or more GIF objects */ X finished = FALSE; X while (!finished) { X switch (get_byte()) { X case ';': /* End of the GIF dataset */ X finished = TRUE; X status = 0; X break; X X case '!': /* GIF Extension Block */ X get_byte(); /* read (and ignore) the ID */ X while ((i = get_byte()) > 0) /* get data len*/ X for (j = 0; j < i; j++) X get_byte(); /* flush data */ X break; X X case ',': /* Start of image object. get description */ X for (i = 0; i < 9; i++) { X if ((buffer[i] = (unsigned char)get_byte()) < 0) { X status = -1; X break; X } X } X X if (status < 0) { X finished = TRUE; X break; X } X X Image->iwidth = buffer[4] | (buffer[5] << 8); X Image->iheight = buffer[6] | (buffer[7] << 8); X Image->width = (DBL) Image->iwidth; X Image->height = (DBL) Image->iheight; X X if (Image->iwidth > BITMAP_X_SIZE || X Image->iheight > BITMAP_Y_SIZE) { X printf("\nBitmap File TOO BIG!!\n"); X fclose(Bit_File); X exit (1); X } X X Bitmap_Line = Image->iheight - 1; X X if (((Image->red = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) || X ((Image->green = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL) || X ((Image->blue = (unsigned char *) malloc(Image->iwidth*Image->iheight))==NULL)) { X printf ("Cannot allocate memory for picture\n"); X exit(1); X } X X /* Setup the color palette for the image */ X status = decoder ((short) Image->iwidth); /*put bytes in Buf*/ X finished = TRUE; X break; X X default: X status = -1; X finished = TRUE; X break; X } X } X X free (decoderline); X free (gif_colour_map); X fclose(Bit_File); X } END_OF_FILE if test 7511 -ne `wc -c <'src/gif.c'`; then echo shar: \"'src/gif.c'\" unpacked with wrong size! fi # end of 'src/gif.c' fi if test -f 'src/iffw.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/iffw.c'\" else echo shar: Extracting \"'src/iffw.c'\" \(7573 characters\) sed "s/^X//" >'src/iffw.c' <<'END_OF_FILE' X/*----------------------------------------------------------------------* X * IFFW.C Support routines for writing IFF-85 files. 1/23/86 X * (IFF is Interchange Format File.) X * X * By Jerry Morrison and Steve Shaw, Electronic Arts. X * This software is in the public domain. X * X * This version for the Commodore-Amiga computer. X *----------------------------------------------------------------------*/ X#include "iff/iff.h" X#include "iff/gio.h" X X/* ---------- IFF Writer -----------------------------------------------*/ X X/* A macro to test if a chunk size is definite, i.e. not szNotYetKnown.*/ X#define Known(size) ( (size) != szNotYetKnown ) X X/* Yet another weird macro to make the source code simpler...*/ X#define IfIffp(expr) {if (iffp == IFF_OKAY) iffp = (expr);} X X/* ---------- OpenWIFF -------------------------------------------------*/ X XIFFP OpenWIFF(file, new0, limit) BPTR file; GroupContext *new0; LONG limit; { X register GroupContext *new = new0; X register IFFP iffp = IFF_OKAY; X X new->parent = NULL; X new->clientFrame = NULL; X new->file = file; X new->position = 0; X new->bound = limit; X new->ckHdr.ckID = NULL_CHUNK; /* indicates no current chunk */ X new->ckHdr.ckSize = new->bytesSoFar = 0; X X if (0 > Seek(file, 0, OFFSET_BEGINNING)) /* Go to start of the file.*/ X iffp = DOS_ERROR; X else if ( Known(limit) && IS_ODD(limit) ) X iffp = CLIENT_ERROR; X return(iffp); X } X X/* ---------- StartWGroup ----------------------------------------------*/ XIFFP StartWGroup(parent, groupType, groupSize, subtype, new) X GroupContext *parent, *new; ID groupType, subtype; LONG groupSize; { X register IFFP iffp; X X iffp = PutCkHdr(parent, groupType, groupSize); X IfIffp( IFFWriteBytes(parent, (BYTE *)&subtype, sizeof(ID)) ); X IfIffp( OpenWGroup(parent, new) ); X return(iffp); X } X X/* ---------- OpenWGroup -----------------------------------------------*/ XIFFP OpenWGroup(parent0, new0) GroupContext *parent0, *new0; { X register GroupContext *parent = parent0; X register GroupContext *new = new0; X register LONG ckEnd; X register IFFP iffp = IFF_OKAY; X X new->parent = parent; X new->clientFrame = parent->clientFrame; X new->file = parent->file; X new->position = parent->position; X new->bound = parent->bound; X new->ckHdr.ckID = NULL_CHUNK; X new->ckHdr.ckSize = new->bytesSoFar = 0; X X if ( Known(parent->ckHdr.ckSize) ) { X ckEnd = new->position + ChunkMoreBytes(parent); X if ( new->bound == szNotYetKnown || new->bound > ckEnd ) X new->bound = ckEnd; X }; X X if ( parent->ckHdr.ckID == NULL_CHUNK || /* not currently writing a chunk*/ X IS_ODD(new->position) || X (Known(new->bound) && IS_ODD(new->bound)) ) X iffp = CLIENT_ERROR; X return(iffp); X } X X/* ---------- CloseWGroup ----------------------------------------------*/ XIFFP CloseWGroup(old0) GroupContext *old0; { X register GroupContext *old = old0; X IFFP iffp = IFF_OKAY; X X if ( old->ckHdr.ckID != NULL_CHUNK ) /* didn't close the last chunk */ X iffp = CLIENT_ERROR; X else if ( old->parent == NULL ) { /* top level file context */ X if (GWriteFlush(old->file) < 0) iffp = DOS_ERROR; X } X else { /* update parent context */ X old->parent->bytesSoFar += old->position - old->parent->position; X old->parent->position = old->position; X }; X return(iffp); X } X X/* ---------- EndWGroup ------------------------------------------------*/ XIFFP EndWGroup(old) GroupContext *old; { X register GroupContext *parent = old->parent; X register IFFP iffp; X X iffp = CloseWGroup(old); X IfIffp( PutCkEnd(parent) ); X return(iffp); X } X X/* ---------- PutCk ----------------------------------------------------*/ XIFFP PutCk(context, ckID, ckSize, data) X GroupContext *context; ID ckID; LONG ckSize; BYTE *data; { X register IFFP iffp = IFF_OKAY; X X if ( ckSize == szNotYetKnown ) X iffp = CLIENT_ERROR; X IfIffp( PutCkHdr(context, ckID, ckSize) ); X IfIffp( IFFWriteBytes(context, data, ckSize) ); X IfIffp( PutCkEnd(context) ); X return(iffp); X } X X/* ---------- PutCkHdr -------------------------------------------------*/ XIFFP PutCkHdr(context0, ckID, ckSize) X GroupContext *context0; ID ckID; LONG ckSize; { X register GroupContext *context = context0; X LONG minPSize = sizeof(ChunkHeader); /* physical chunk >= minPSize bytes*/ X X /* CLIENT_ERROR if we're already inside a chunk or asked to write X * other than one FORM, LIST, or CAT at the top level of a file */ X /* Also, non-positive ID values are illegal and used for error codes.*/ X /* (We could check for other illegal IDs...)*/ X if ( context->ckHdr.ckID != NULL_CHUNK || ckID <= 0 ) X return(CLIENT_ERROR); X else if (context->parent == NULL) { X switch (ckID) { X case FORM: case LIST: case CAT: break; X default: return(CLIENT_ERROR); X } X if (context->position != 0) X return(CLIENT_ERROR); X } X X if ( Known(ckSize) ) { X if ( ckSize < 0 ) X return(CLIENT_ERROR); X minPSize += ckSize; X }; X if ( Known(context->bound) && X context->position + minPSize > context->bound ) X return(CLIENT_ERROR); X X context->ckHdr.ckID = ckID; X context->ckHdr.ckSize = ckSize; X context->bytesSoFar = 0; X if (0 > X GWrite(context->file, (BYTE *)&context->ckHdr, sizeof(ChunkHeader)) X ) X return(DOS_ERROR); X context->position += sizeof(ChunkHeader); X return(IFF_OKAY); X } X X/* ---------- IFFWriteBytes ---------------------------------------------*/ XIFFP IFFWriteBytes(context0, data, nBytes) X GroupContext *context0; BYTE *data; LONG nBytes; { X register GroupContext *context = context0; X X if ( context->ckHdr.ckID == NULL_CHUNK || /* not in a chunk */ X nBytes < 0 || /* negative nBytes */ X (Known(context->bound) && /* overflow context */ X context->position + nBytes > context->bound) || X (Known(context->ckHdr.ckSize) && /* overflow chunk */ X context->bytesSoFar + nBytes > context->ckHdr.ckSize) ) X return(CLIENT_ERROR); X X if (0 > GWrite(context->file, data, nBytes)) X return(DOS_ERROR); X X context->bytesSoFar += nBytes; X context->position += nBytes; X return(IFF_OKAY); X } X X/* ---------- PutCkEnd -------------------------------------------------*/ XIFFP PutCkEnd(context0) GroupContext *context0; { X register GroupContext *context = context0; X WORD zero = 0; /* padding source */ X X if ( context->ckHdr.ckID == NULL_CHUNK ) /* not in a chunk */ X return(CLIENT_ERROR); X X if ( context->ckHdr.ckSize == szNotYetKnown ) { X /* go back and set the chunk size to bytesSoFar */ X if ( 0 > XGSeek(context->file, -(context->bytesSoFar + sizeof(LONG)), OFFSET_CURRENT) || X 0 > XGWrite(context->file, (BYTE *)&context->bytesSoFar, sizeof(LONG)) || X 0 > XGSeek(context->file, context->bytesSoFar, OFFSET_CURRENT) ) X return(DOS_ERROR); X } X else { /* make sure the client wrote as many bytes as planned */ X if ( context->ckHdr.ckSize != context->bytesSoFar ) X return(CLIENT_ERROR); X }; X X /* Write a pad byte if needed to bring us up to an even boundary. X * Since the context end must be even, and since we haven't X * overwritten the context, if we're on an odd position there must X * be room for a pad byte. */ X if ( IS_ODD(context->bytesSoFar) ) { X if ( 0 > GWrite(context->file, (BYTE *)&zero, 1) ) X return(DOS_ERROR); X context->position += 1; X }; X X context->ckHdr.ckID = NULL_CHUNK; X context->ckHdr.ckSize = context->bytesSoFar = 0; X return(IFF_OKAY); X } X END_OF_FILE if test 7573 -ne `wc -c <'src/iffw.c'`; then echo shar: \"'src/iffw.c'\" unpacked with wrong size! fi # end of 'src/iffw.c' fi if test -f 'src/matrices.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/matrices.c'\" else echo shar: Extracting \"'src/matrices.c'\" \(9507 characters\) sed "s/^X//" >'src/matrices.c' <<'END_OF_FILE' X/***************************************************************************** X* X* matrices.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module contains code to manipulate 4x4 matrices. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X X#include "frame.h" X#include "vector.h" X#include "dkbproto.h" X X#ifndef PI X#define PI 3.141592653689793 X#endif X Xvoid MZero (result) X MATRIX *result; X { X/* Initialize the matrix to the following values: X 0.0 0.0 0.0 0.0 X 0.0 0.0 0.0 0.0 X 0.0 0.0 0.0 0.0 X 0.0 0.0 0.0 0.0 X*/ X register int i, j; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X (*result)[i][j] = 0.0; X } X Xvoid MIdentity (result) X MATRIX *result; X { X/* Initialize the matrix to the following values: X 1.0 0.0 0.0 0.0 X 0.0 1.0 0.0 0.0 X 0.0 0.0 1.0 0.0 X 0.0 0.0 0.0 1.0 X*/ X register int i, j; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X if (i == j) X (*result)[i][j] = 1.0; X else X (*result)[i][j] = 0.0; X } X Xvoid MTimes (result, matrix1, matrix2) X MATRIX *result, *matrix1, *matrix2; X { X register int i, j, k; X MATRIX temp_matrix; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) { X temp_matrix[i][j] = 0.0; X for (k = 0 ; k < 4 ; k++) X temp_matrix[i][j] += (*matrix1)[i][k] * (*matrix2)[k][j]; X } X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X (*result)[i][j] = temp_matrix[i][j]; X } X X Xvoid MAdd (result, matrix1, matrix2) X MATRIX *result, *matrix1, *matrix2; X { X register int i, j; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X (*result)[i][j] = (*matrix1)[i][j] + (*matrix2)[i][j]; X } X Xvoid MSub (result, matrix1, matrix2) X MATRIX *result, *matrix1, *matrix2; X { X register int i, j; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X (*result)[i][j] = (*matrix1)[i][j] - (*matrix2)[i][j]; X } X Xvoid MScale (result, matrix1, amount) XMATRIX *result, *matrix1; XDBL amount; X{ X register int i, j; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X if (amount == 1.0) X (*result)[i][j] = (*matrix1)[i][j]; /* just copy */ X else X (*result)[i][j] = (*matrix1)[i][j] * amount; X return; X} X Xvoid MTranspose (result, matrix1) X MATRIX *result, *matrix1; X { X register int i, j; X MATRIX temp_matrix; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X temp_matrix[i][j] = (*matrix1)[j][i]; X X for (i = 0 ; i < 4 ; i++) X for (j = 0 ; j < 4 ; j++) X (*result)[i][j] = temp_matrix[i][j]; X } X X Xvoid MTransformVector (result, vector, transformation) X VECTOR *result, *vector; X TRANSFORMATION *transformation; X { X register int i; X DBL answer_array[4]; X MATRIX *matrix; X X matrix = &transformation -> matrix; X X for (i = 0 ; i < 4 ; i++) X answer_array[i] = vector -> x * (*matrix)[0][i] X + vector -> y * (*matrix)[1][i] X + vector -> z * (*matrix)[2][i] X + (*matrix)[3][i]; X X result -> x = answer_array[0]; X result -> y = answer_array[1]; X result -> z = answer_array[2]; X } X Xvoid MInverseTransformVector (result, vector, transformation) X VECTOR *result, *vector; X TRANSFORMATION *transformation; X { X register int i; X DBL answer_array[4]; X MATRIX *matrix; X X matrix = &transformation -> inverse; X X for (i = 0 ; i < 4 ; i++) X answer_array[i] = vector -> x * (*matrix)[0][i] X + vector -> y * (*matrix)[1][i] X + vector -> z * (*matrix)[2][i] X + (*matrix)[3][i]; X X result -> x = answer_array[0]; X result -> y = answer_array[1]; X result -> z = answer_array[2]; X } X Xvoid Get_Scaling_Transformation (result, vector) X TRANSFORMATION *result; X VECTOR *vector; X { X MIdentity (&result -> matrix); X (result -> matrix)[0][0] = vector -> x; X (result -> matrix)[1][1] = vector -> y; X (result -> matrix)[2][2] = vector -> z; X X MIdentity (&result -> inverse); X (result -> inverse)[0][0] = 1.0 / vector -> x; X (result -> inverse)[1][1]= 1.0 / vector -> y; X (result -> inverse)[2][2] = 1.0 / vector -> z; X } X Xvoid Get_Inversion_Transformation (result) X TRANSFORMATION *result; X { X MIdentity (&result -> matrix); X (result -> matrix)[0][0] = -1.0; X (result -> matrix)[1][1] = -1.0; X (result -> matrix)[2][2] = -1.0; X (result -> matrix)[3][3] = -1.0; X X X (result -> inverse)[0][0] = -1.0; X (result -> inverse)[1][1] = -1.0; X (result -> inverse)[2][2] = -1.0; X (result -> inverse)[3][3] = -1.0; X } X Xvoid Get_Translation_Transformation (transformation, vector) X TRANSFORMATION *transformation; X VECTOR *vector; X { X MIdentity (&transformation -> matrix); X (transformation -> matrix)[3][0] = vector -> x; X (transformation -> matrix)[3][1] = vector -> y; X (transformation -> matrix)[3][2] = vector -> z; X X MIdentity (&transformation -> inverse); X (transformation -> inverse)[3][0] = 0.0 - vector -> x; X (transformation -> inverse)[3][1] = 0.0 - vector -> y; X (transformation -> inverse)[3][2] = 0.0 - vector -> z; X } X Xvoid Get_Rotation_Transformation (transformation, vector) X TRANSFORMATION *transformation; X VECTOR *vector; X { X MATRIX Matrix; X VECTOR Radian_Vector; X register DBL cosx, cosy, cosz, sinx, siny, sinz; X X VScale (Radian_Vector, *vector, PI/180.0); X MIdentity (&transformation -> matrix); X cosx = cos (Radian_Vector.x); X sinx = sin (Radian_Vector.x); X cosy = cos (Radian_Vector.y); X siny = sin (Radian_Vector.y); X cosz = cos (Radian_Vector.z); X sinz = sin (Radian_Vector.z); X X (transformation -> matrix) [1][1] = cosx; X (transformation -> matrix) [2][2] = cosx; X (transformation -> matrix) [1][2] = 0.0 - sinx; X (transformation -> matrix) [2][1] = sinx; X MTranspose (&transformation -> inverse, &transformation -> matrix); X X MIdentity (&Matrix); X Matrix [0][0] = cosy; X Matrix [2][2] = cosy; X Matrix [0][2] = siny; X Matrix [2][0] = 0.0 - siny; X MTimes (&transformation -> matrix, &transformation -> matrix, &Matrix); X MTranspose (&Matrix, &Matrix); X MTimes (&transformation -> inverse, &Matrix, &transformation -> inverse); X X MIdentity (&Matrix); X Matrix [0][0] = cosz; X Matrix [1][1] = cosz; X Matrix [0][1] = 0.0 - sinz; X Matrix [1][0] = sinz; X MTimes (&transformation -> matrix, &transformation -> matrix, &Matrix); X MTranspose (&Matrix, &Matrix); X MTimes (&transformation -> inverse, &Matrix, &transformation -> inverse); X } X Xvoid Get_Look_At_Transformation (result, Look_At, Up, Right) X TRANSFORMATION *result; X VECTOR *Look_At, *Up, *Right; X { X MIdentity (&result -> inverse); X (result -> matrix)[0][0] = Right->x; X (result -> matrix)[0][1] = Right->y; X (result -> matrix)[0][2] = Right->z; X (result -> matrix)[1][0] = Up->x; X (result -> matrix)[1][1] = Up->y; X (result -> matrix)[1][2] = Up->z; X (result -> matrix)[2][0] = Look_At->x; X (result -> matrix)[2][1] = Look_At->y; X (result -> matrix)[2][2] = Look_At->z; X X MIdentity (&result -> matrix); X MTranspose (&result -> matrix, &result -> inverse); X } X Xvoid Compose_Transformations (Original_Transformation, New_Transformation) X TRANSFORMATION *Original_Transformation, *New_Transformation; X { X MTimes (&Original_Transformation -> matrix, X &Original_Transformation -> matrix, X &New_Transformation -> matrix); X X MTimes (&Original_Transformation -> inverse, X &New_Transformation -> inverse, X &Original_Transformation -> inverse); X } END_OF_FILE if test 9507 -ne `wc -c <'src/matrices.c'`; then echo shar: \"'src/matrices.c'\" unpacked with wrong size! fi # end of 'src/matrices.c' fi if test -f 'src/planes.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/planes.c'\" else echo shar: Extracting \"'src/planes.c'\" \(6704 characters\) sed "s/^X//" >'src/planes.c' <<'END_OF_FILE' X/***************************************************************************** X* X* planes.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module implements functions that manipulate planes. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X X#include "frame.h" X#include "vector.h" X#include "dkbproto.h" X XMETHODS Plane_Methods = X { Object_Intersect, All_Plane_Intersections, X Inside_Plane, Plane_Normal, X Copy_Plane, X Translate_Plane, Rotate_Plane, X Scale_Plane, Invert_Plane}; X X#define Small_Tolerance 0.001 X Xextern PLANE *Get_Plane_Shape(); X Xextern RAY *VP_Ray; Xextern long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded; X Xint All_Plane_Intersections (Object, Ray, Depth_Queue) X OBJECT *Object; X RAY *Ray; X PRIOQ *Depth_Queue; X { X PLANE *Shape = (PLANE *) Object; X DBL Depth; X VECTOR Intersection_Point; X INTERSECTION Local_Element; X X if (Intersect_Plane (Ray, Shape, &Depth)) X if (Depth > Small_Tolerance) X { X Local_Element.Depth = Depth; X Local_Element.Object = Shape -> Parent_Object; X VScale (Intersection_Point, Ray -> Direction, Depth); X VAdd (Intersection_Point, Intersection_Point, Ray -> Initial); X Local_Element.Point = Intersection_Point; X Local_Element.Shape = (SHAPE *)Shape; X pq_add (Depth_Queue, &Local_Element); X return (TRUE); X } X X return (FALSE); X } X Xint Intersect_Plane (Ray, Plane, Depth) X RAY *Ray; X PLANE *Plane; X DBL *Depth; X { X DBL NormalDotOrigin, NormalDotDirection; X X Ray_Plane_Tests++; X if (Ray == VP_Ray) { X if (!Plane->VPCached) { X VDot (Plane->VPNormDotOrigin, Plane->Normal_Vector, Ray->Initial); X Plane->VPNormDotOrigin += Plane->Distance; X Plane->VPNormDotOrigin *= -1.0; X Plane->VPCached = TRUE; X } X X VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction); X if ((NormalDotDirection < Small_Tolerance) && X (NormalDotDirection > -Small_Tolerance)) X return (FALSE); X X *Depth = Plane->VPNormDotOrigin / NormalDotDirection; X if ((*Depth >= Small_Tolerance) || (*Depth <= Max_Distance)) { X Ray_Plane_Tests_Succeeded++; X return (TRUE); X } X else X return (FALSE); X } X else { X VDot (NormalDotOrigin, Plane->Normal_Vector, Ray->Initial); X NormalDotOrigin += Plane->Distance; X NormalDotOrigin *= -1.0; X X VDot (NormalDotDirection, Plane->Normal_Vector, Ray->Direction); X if ((NormalDotDirection < Small_Tolerance) && X (NormalDotDirection > -Small_Tolerance)) X return (FALSE); X X *Depth = NormalDotOrigin / NormalDotDirection; X if ((*Depth >= Small_Tolerance) || (*Depth <= Max_Distance)) { X Ray_Plane_Tests_Succeeded++; X return (TRUE); X } X else X return (FALSE); X } X } X Xint Inside_Plane (Point, Object) X VECTOR *Point; X OBJECT *Object; X { X PLANE *Plane = (PLANE *) Object; X DBL Temp; X X VDot (Temp, *Point, Plane->Normal_Vector); X return ((Temp + Plane->Distance) <= Small_Tolerance); X } X Xvoid Plane_Normal (Result, Object, Intersection_Point) X OBJECT *Object; X VECTOR *Result, *Intersection_Point; X { X PLANE *Plane = (PLANE *) Object; X X *Result = Plane->Normal_Vector; X Perturb_Normal (Result, Plane->Parent_Object, X Intersection_Point, Result); X } X Xvoid *Copy_Plane (Object) X OBJECT *Object; X { X PLANE *New_Shape; X X New_Shape = Get_Plane_Shape (); X *New_Shape = * ((PLANE *)Object); X New_Shape -> Next_Object = NULL; X return (New_Shape); X } X Xvoid Translate_Plane (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X PLANE *Plane = (PLANE *) Object; X VECTOR Translation; X X VEvaluate (Translation, Plane->Normal_Vector, *Vector); X Plane->Distance -= Translation.x + Translation.y + Translation.z; X } X Xvoid Rotate_Plane (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X TRANSFORMATION Transformation; X X Get_Rotation_Transformation (&Transformation, Vector); X MTransformVector (&((PLANE *) Object)->Normal_Vector, X &((PLANE *) Object)->Normal_Vector, &Transformation); X } X Xvoid Scale_Plane (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X DBL Length; X PLANE *Plane = (PLANE *) Object; X X Plane->Normal_Vector.x = Plane->Normal_Vector.x / Vector->x; X Plane->Normal_Vector.y = Plane->Normal_Vector.y / Vector->y; X Plane->Normal_Vector.z = Plane->Normal_Vector.z / Vector->z; X X VLength(Length, Plane->Normal_Vector); X VScale (Plane->Normal_Vector, Plane->Normal_Vector, 1.0 / Length); X Plane->Distance /= Length; X } X Xvoid Invert_Plane (Object) X OBJECT *Object; X { X PLANE *Plane = (PLANE *) Object; X X VScale (Plane->Normal_Vector, Plane->Normal_Vector, -1.0); X Plane->Distance *= -1.0; X } X END_OF_FILE if test 6704 -ne `wc -c <'src/planes.c'`; then echo shar: \"'src/planes.c'\" unpacked with wrong size! fi # end of 'src/planes.c' fi if test -f 'src/spheres.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/spheres.c'\" else echo shar: Extracting \"'src/spheres.c'\" \(7715 characters\) sed "s/^X//" >'src/spheres.c' <<'END_OF_FILE' X/***************************************************************************** X* X* spheres.c X* X* from DKBTrace (c) 1990 David Buck X* X* This module implements the sphere primitive. X* X* This software is freely distributable. The source and/or object code may be X* copied or uploaded to communications services so long as this notice remains X* at the top of each file. If any changes are made to the program, you must X* clearly indicate in the documentation and in the programs startup message X* who it was who made the changes. The documentation should also describe what X* those changes were. This software may not be included in whole or in X* part into any commercial package without the express written consent of the X* author. It may, however, be included in other public domain or freely X* distributed software so long as the proper credit for the software is given. X* X* This software is provided as is without any guarantees or warranty. Although X* the author has attempted to find and correct any bugs in the software, he X* is not responsible for any damage caused by the use of the software. The X* author is under no obligation to provide service, corrections, or upgrades X* to this package. X* X* Despite all the legal stuff above, if you do find bugs, I would like to hear X* about them. Also, if you have any comments or questions, you may contact me X* at the following address: X* X* David Buck X* 22C Sonnet Cres. X* Nepean Ontario X* Canada, K2H 8W7 X* X* I can also be reached on the following bulleton boards: X* X* ATX (613) 526-4141 X* OMX (613) 731-3419 X* Mystic (613) 731-0088 or (613) 731-6698 X* X* Fidonet: 1:163/109.9 X* Internet: David_Buck@Carleton.CA X* X* IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es: X* X* Lattice BBS (708) 916-1200 X* The Information Exchange BBS (708) 945-5575 X* Stillwaters BBS (708) 403-2826 X* X*****************************************************************************/ X X#include "frame.h" X#include "vector.h" X#include "dkbproto.h" X X#define Small_Tolerance 0.001 X XMETHODS Sphere_Methods = X { Object_Intersect, All_Sphere_Intersections, X Inside_Sphere, Sphere_Normal, X Copy_Sphere, X Translate_Sphere, Rotate_Sphere, X Scale_Sphere, Invert_Sphere}; X Xextern SPHERE *Get_Sphere_Shape(); X Xextern RAY *VP_Ray; Xextern long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded; X Xint All_Sphere_Intersections (Object, Ray, Depth_Queue) X OBJECT *Object; X RAY *Ray; X PRIOQ *Depth_Queue; X { X DBL Depth1, Depth2; X VECTOR Intersection_Point; X INTERSECTION Local_Element; X register int Intersection_Found; X SPHERE *Shape = (SPHERE *) Object; X X Intersection_Found = FALSE; X if (Intersect_Sphere (Ray, Shape, &Depth1, &Depth2)) X { X Local_Element.Depth = Depth1; X Local_Element.Object = Shape -> Parent_Object; X VScale (Intersection_Point, Ray -> Direction, Depth1); X VAdd (Intersection_Point, Intersection_Point, Ray -> Initial); X Local_Element.Point = Intersection_Point; X Local_Element.Shape = (SHAPE *)Shape; X pq_add (Depth_Queue, &Local_Element); X Intersection_Found = TRUE; X X if (Depth2 != Depth1) X { X Local_Element.Depth = Depth2; X Local_Element.Object = Shape -> Parent_Object; X VScale (Intersection_Point, Ray -> Direction, Depth2); X VAdd (Intersection_Point, Intersection_Point, Ray -> Initial); X Local_Element.Point = Intersection_Point; X Local_Element.Shape = (SHAPE *) Shape; X pq_add (Depth_Queue, &Local_Element); X Intersection_Found = TRUE; X } X } X return (Intersection_Found); X } X Xint Intersect_Sphere (Ray, Sphere, Depth1, Depth2) X RAY *Ray; X SPHERE *Sphere; X DBL *Depth1, *Depth2; X { X VECTOR Origin_To_Center; X DBL OCSquared, t_Closest_Approach, Half_Chord, t_Half_Chord_Squared; X short inside; X X Ray_Sphere_Tests++; X if (Ray == VP_Ray) { X if (!Sphere->VPCached) { X VSub (Sphere->VPOtoC, Sphere->Center, Ray->Initial); X VDot (Sphere->VPOCSquared, Sphere->VPOtoC, Sphere->VPOtoC); X Sphere->VPinside = (Sphere->VPOCSquared < Sphere->Radius_Squared); X Sphere->VPCached = TRUE; X } X VDot (t_Closest_Approach, Sphere->VPOtoC, Ray->Direction); X if (!Sphere->VPinside && (t_Closest_Approach < Small_Tolerance)) X return (FALSE); X t_Half_Chord_Squared = Sphere->Radius_Squared - Sphere->VPOCSquared + X (t_Closest_Approach * t_Closest_Approach); X } X else { X VSub (Origin_To_Center, Sphere->Center, Ray->Initial); X VDot (OCSquared, Origin_To_Center, Origin_To_Center); X inside = (OCSquared < Sphere->Radius_Squared); X VDot (t_Closest_Approach, Origin_To_Center, Ray->Direction); X if (!inside && (t_Closest_Approach < Small_Tolerance)) X return (FALSE); X X t_Half_Chord_Squared = Sphere->Radius_Squared - OCSquared + X (t_Closest_Approach * t_Closest_Approach); X } X X if (t_Half_Chord_Squared < Small_Tolerance) X return (FALSE); X X Half_Chord = sqrt (t_Half_Chord_Squared); X *Depth1 = t_Closest_Approach + Half_Chord; X *Depth2 = t_Closest_Approach - Half_Chord; X X if ((*Depth1 < Small_Tolerance) || (*Depth1 > Max_Distance)) X if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance)) X return (FALSE); X else X *Depth1 = *Depth2; X else X if ((*Depth2 < Small_Tolerance) || (*Depth2 > Max_Distance)) X *Depth2 = *Depth1; X X Ray_Sphere_Tests_Succeeded++; X return (TRUE); X } X Xint Inside_Sphere (Point, Object) X VECTOR *Point; X OBJECT *Object; X { X VECTOR Origin_To_Center; X DBL OCSquared; X SPHERE *Sphere = (SPHERE *) Object; X X VSub (Origin_To_Center, Sphere->Center, *Point); X VDot (OCSquared, Origin_To_Center, Origin_To_Center); X X if (Sphere->Inverted) X return (OCSquared - Sphere->Radius_Squared > Small_Tolerance); X else X return (OCSquared - Sphere->Radius_Squared < Small_Tolerance); X } X Xvoid Sphere_Normal (Result, Object, Intersection_Point) X OBJECT *Object; X VECTOR *Result, *Intersection_Point; X { X SPHERE *Sphere = (SPHERE *) Object; X X VSub (*Result, *Intersection_Point, Sphere->Center); X VScale (*Result, *Result, Sphere->Inverse_Radius); X Perturb_Normal (Result, Sphere -> Parent_Object, X Intersection_Point, Result); X } X Xvoid *Copy_Sphere (Object) X OBJECT *Object; X { X SPHERE *New_Shape; X X New_Shape = Get_Sphere_Shape (); X *New_Shape = *((SPHERE *) Object); X New_Shape -> Next_Object = NULL; X return (New_Shape); X } X Xvoid Translate_Sphere (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X VAdd (((SPHERE *) Object)->Center, ((SPHERE *) Object)->Center, *Vector); X } X Xvoid Rotate_Sphere (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X TRANSFORMATION Transformation; X X Get_Rotation_Transformation (&Transformation, Vector); X MTransformVector (&((SPHERE *) Object)->Center, X &((SPHERE *) Object)->Center, &Transformation); X } X Xvoid Scale_Sphere (Object, Vector) X OBJECT *Object; X VECTOR *Vector; X { X SPHERE *Sphere = (SPHERE *) Object; X X if ((Vector->x != Vector->y) || X (Vector->x != Vector->z)) { X printf ("Error - you cannot scale a sphere unevenly\n"); X exit (1); X } X X VScale (Sphere->Center, Sphere->Center, Vector->x); X Sphere->Radius *= Vector->x; X Sphere->Radius_Squared = Sphere->Radius * Sphere->Radius; X Sphere->Inverse_Radius = 1.0 / Sphere->Radius; X } X Xvoid Invert_Sphere (Object) X OBJECT *Object; X { X ((SPHERE *) Object)->Inverted ^= TRUE; X } END_OF_FILE if test 7715 -ne `wc -c <'src/spheres.c'`; then echo shar: \"'src/spheres.c'\" unpacked with wrong size! fi # end of 'src/spheres.c' fi echo shar: End of archive 3 \(of 10\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 10 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.