[comp.sources.amiga] v90i254: DKBTrace 2.01 - DKBtrace Ray-Tracer, Part06/10

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 254
Archive-name: applications/dkbtrace-2.01/part06

#!/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 6 (of 10)."
# Contents:  src/dkbproto.h src/tokenize.c src/triangle.c
# Wrapped by tadguy@abcfd20 on Mon Sep  3 19:21:20 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/dkbproto.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dkbproto.h'\"
else
echo shar: Extracting \"'src/dkbproto.h'\" \(16900 characters\)
sed "s/^X//" >'src/dkbproto.h' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                  dkbproto.h
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This module defines the prototypes for all system-independent functions.
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/* Prototypes for functions defined in trace.c */
Xvoid close_all PARAMS((void));
Xvoid get_defaults PARAMS((void));
Xvoid read_options PARAMS((char *file_name));
Xvoid parse_option PARAMS((char *Option_String));
Xvoid parse_file_name PARAMS((char *File_Name));
Xvoid Print_Options PARAMS((void));
Xvoid print_stats PARAMS((void));
X
X/* Prototypes for functions defined in render.c */
Xvoid Create_Ray PARAMS((RAY *ray, int width, int height, DBL x, DBL y));
Xvoid Write_Line PARAMS((COLOUR *Line, int y));
Xvoid Supersample PARAMS((COLOUR *result, int x, int y, int Width, int Height));
Xvoid Start_Tracing PARAMS((void));
Xvoid Trace PARAMS((RAY *Ray, COLOUR *Colour));
X
X/* Prototypes for functions defined in tokenize.c */
Xvoid Tokenize PARAMS((char *name, FILE *in, FILE *symbol, FILE *out));
Xint Process_Token PARAMS((void));
Xint Skip_Spaces PARAMS((void));
Xint Parse_Comments PARAMS((void));
Xvoid Begin_String PARAMS((void));
Xvoid Stuff_Character PARAMS((char c));
Xvoid End_String PARAMS((void));
Xint Read_Float PARAMS((void));
Xint Parse_String PARAMS((void));
Xint Read_Include PARAMS((void));
Xint Read_Symbol PARAMS((void));
Xint Find_Reserved PARAMS((void));
Xint Find_Symbol PARAMS((void));
Xvoid Write_Token PARAMS((enum Token_Type Token_Id));
Xvoid Token_Error PARAMS((char *str));
X
X/* Prototypes for functions defined in parse.c */
Xvoid Parse PARAMS((FILE *File, FRAME *Frame_Ptr));
Xvoid Token_Init PARAMS((void));
Xint Get_Token PARAMS((void));
Xvoid Unget_Token PARAMS((void));
Xvoid Frame_Init PARAMS((void));
XCOMPOSITE *Get_Composite_Object PARAMS((void));
XSPHERE *Get_Sphere_Shape PARAMS((void));
XQUADRIC *Get_Quadric_Shape PARAMS((void));
XPLANE *Get_Plane_Shape PARAMS((void));
XTRIANGLE *Get_Triangle_Shape PARAMS((void));
XSMOOTH_TRIANGLE *Get_Smooth_Triangle_Shape PARAMS((void));
XCSG_SHAPE *Get_CSG_Shape PARAMS((void));
XCSG_SHAPE *Get_CSG_Union PARAMS((void));
XCSG_SHAPE *Get_CSG_Intersection PARAMS((void));
XCSG_SHAPE *Get_CSG_Difference PARAMS((void));
Xvoid Set_CSG_Parents PARAMS((CSG_SHAPE *, OBJECT *));
XOBJECT *Get_Object PARAMS((void));
XTEXTURE *Get_Texture PARAMS((void));
XVIEWPOINT *Get_Viewpoint PARAMS((void));
XCOLOUR *Get_Colour PARAMS((void));
XVECTOR *Get_Vector PARAMS((void));
XDBL *Get_Float PARAMS((void));
XTRANSFORMATION *Get_Transformation PARAMS((void));
XDBL Parse_Float PARAMS((void));
Xvoid Parse_Vector PARAMS((VECTOR *Given_Vector));
Xvoid Parse_Colour PARAMS((COLOUR *Given_Colour));
XCOLOUR_MAP *Parse_Colour_Map PARAMS((void));
XTEXTURE *Copy_Texture PARAMS((TEXTURE *Texture));
XTEXTURE *Parse_Texture PARAMS((TEXTURE *Old_Texture));
XSHAPE *Parse_Sphere PARAMS((void));
XSHAPE *Parse_Plane PARAMS((void));
XSHAPE *Parse_Triangle PARAMS((void));
XSHAPE *Parse_Smooth_Triangle PARAMS((void));
XSHAPE *Parse_Quadric PARAMS((void));
XCSG_SHAPE *Parse_CSG PARAMS((int type, OBJECT *Parent_Object));
XSHAPE *Parse_Shape PARAMS((OBJECT *Object));
XOBJECT *Parse_Object PARAMS((void));
XOBJECT *Parse_Composite PARAMS((void));
Xvoid Parse_Fog PARAMS((void));
Xvoid Parse_Frame PARAMS((void));
Xvoid Parse_Viewpoint PARAMS((VIEWPOINT *Given_Vp));
Xvoid Parse_Declare PARAMS((void));
Xvoid Init_Viewpoint PARAMS((VIEWPOINT *vp));
Xvoid Link PARAMS((OBJECT *New_Object,
X          OBJECT **Field,
X          OBJECT **Old_Object_List));
XCONSTANT Find_Constant PARAMS((void));
Xchar *Get_Token_String PARAMS((TOKEN Token_Id));
Xvoid Parse_Error PARAMS((TOKEN Token_Id));
Xvoid Type_Error PARAMS((void));
Xvoid Undeclared PARAMS((void));
Xvoid Error PARAMS((char *str));
X
X/* Prototypes for functions defined in objects.c */
XINTERSECTION *Object_Intersect PARAMS((OBJECT *Object, RAY *Ray));
Xint All_Composite_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint All_Object_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Inside_Basic_Object PARAMS((VECTOR *Point, OBJECT *Object)); 
Xint Inside_Composite_Object PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid *Copy_Basic_Object PARAMS((OBJECT *Object));
Xvoid *Copy_Composite_Object PARAMS((OBJECT *Object));
Xvoid Translate_Basic_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Basic_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Basic_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Translate_Composite_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Composite_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Composite_Object PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_Basic_Object PARAMS((OBJECT *Object));
Xvoid Invert_Composite_Object PARAMS((OBJECT *Object));
X
X/* Prototypes for functions defined in spheres.c */
Xint All_Sphere_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Intersect_Sphere PARAMS((RAY *Ray, SPHERE *Sphere, DBL *Depth1, DBL *Depth2));
Xint Inside_Sphere PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid Sphere_Normal PARAMS((VECTOR *Result, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid *Copy_Sphere PARAMS((OBJECT *Object));
Xvoid Translate_Sphere PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Sphere PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Sphere PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_Sphere PARAMS((OBJECT *Object));
X
X/* Prototypes for functions defined in quadrics.c */
Xint All_Quadric_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Intersect_Quadric PARAMS((RAY *Ray, QUADRIC *Shape, DBL *Depth1, DBL *Depth2));
Xint Inside_Quadric PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid Quadric_Normal PARAMS((VECTOR *Result, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid *Copy_Quadric PARAMS((OBJECT *Object));
Xvoid Transform_Quadric PARAMS((QUADRIC *Shape, TRANSFORMATION *Transformation));
Xvoid Quadric_To_Matrix PARAMS((QUADRIC *Quadric, MATRIX *Matrix));
Xvoid Matrix_To_Quadric PARAMS((MATRIX *Matrix, QUADRIC *Quadric));
Xvoid Translate_Quadric PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Quadric PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Quadric PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_Quadric PARAMS((OBJECT *Object));
X
X/* Prototypes for functions defined in triangle.c */
Xvoid Find_Triangle_Dominant_Axis PARAMS((TRIANGLE *Triangle));
Xint Compute_Triangle  PARAMS((TRIANGLE *Triangle));
Xvoid Compute_Smooth_Triangle  PARAMS((SMOOTH_TRIANGLE *Triangle));
Xint All_Triangle_Intersections  PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Intersect_Triangle  PARAMS((RAY *Ray, TRIANGLE *Triangle, DBL *Depth));
Xint Inside_Triangle  PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid Triangle_Normal  PARAMS((VECTOR *Result, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid *Copy_Triangle  PARAMS((OBJECT *Object));
Xvoid Translate_Triangle  PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Triangle  PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Triangle  PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_Triangle  PARAMS((OBJECT *Object));
Xvoid Smooth_Triangle_Normal  PARAMS((VECTOR *Result, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid *Copy_Smooth_Triangle PARAMS((OBJECT *Object));
Xvoid Rotate_Smooth_Triangle  PARAMS((OBJECT *Object, VECTOR *Vector));
X
X
X/* Prototypes for functions defined in lighting.c */
Xvoid Colour_At PARAMS((COLOUR *Colour, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid Perturb_Normal PARAMS((VECTOR *New_Normal, OBJECT *Object, VECTOR *Intersection_Point,
X                    VECTOR *Surface_Normal));
Xvoid Ambient PARAMS((OBJECT *Object, VECTOR *Intersection_Point, COLOUR *Surface_Colour,
X             COLOUR *Colour));
Xvoid Diffuse PARAMS((OBJECT *Object, VECTOR *Intersection_Point, RAY *Eye, VECTOR *Surface_Normal,
X             COLOUR *Surface_Colour, COLOUR *Colour));
Xvoid Transmit PARAMS((OBJECT *Object, VECTOR *Intersection_Point, RAY *Ray,
X              VECTOR *Surface_Normal, COLOUR *Surface_Colour, COLOUR *Colour));
Xvoid Reflect PARAMS((OBJECT *Object, VECTOR *Intersection_Point, RAY *Ray, 
X             VECTOR *Surface_Normal, COLOUR *Colour));
Xvoid Refract PARAMS((OBJECT *Object, VECTOR *Intersection_Point, RAY *Ray,
X             VECTOR *Surface_Normal, COLOUR *Colour));
Xvoid Fog PARAMS((DBL Distance, COLOUR *Fog_Colour, DBL Fog_Distance, COLOUR *Colour));
X
X/* Prototypes for functions defined in prioq.c */
Xvoid pq_init PARAMS((void));
XPRIOQ *pq_alloc PARAMS((void));
Xvoid pq_free PARAMS((PRIOQ *pq));
XPRIOQ *pq_new PARAMS((int index_size));
Xvoid pq_balance PARAMS((PRIOQ *q, unsigned int entry_pos1));
Xvoid pq_add PARAMS((PRIOQ *q, INTERSECTION *entry));
XINTERSECTION *pq_get_highest PARAMS((PRIOQ *q));
Xint pq_is_empty PARAMS((PRIOQ *q));
Xvoid pq_delete_highest PARAMS((PRIOQ *q));
X
X/* Prototypes for functions defined in texture.c */
Xvoid Compute_Colour PARAMS((COLOUR *Colour, COLOUR_MAP *Colour_Map, DBL value));
Xvoid Initialize_Noise PARAMS((void));
Xvoid InitTextureTable PARAMS((void));
Xvoid InitRTable PARAMS((void));
Xint R PARAMS((VECTOR *v));
Xint Crc16 PARAMS((char *buf, int count));
XDBL Noise PARAMS((DBL x, DBL y, DBL z));
Xvoid DNoise PARAMS((VECTOR *result, DBL x, DBL y, DBL z));
XDBL cycloidal PARAMS((DBL value));
XDBL Triangle_Wave PARAMS((DBL value));
XDBL Turbulence PARAMS((DBL x, DBL y, DBL z));
Xvoid DTurbulence PARAMS((VECTOR *result, DBL x, DBL y, DBL z));
Xint Bozo PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *Colour));
Xint marble PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *colour));
Xvoid ripples PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, VECTOR *Vector));
Xvoid waves PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, VECTOR *Vector));
Xint wood PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *colour));
Xvoid checker PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *colour));
Xvoid spotted PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *Colour));
Xvoid bumps PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, VECTOR *normal));
Xvoid dents PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, VECTOR *normal));
Xvoid agate PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *colour));
Xvoid wrinkles PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, VECTOR *normal));
Xvoid granite PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *Colour));
Xvoid gradient PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *Colour));
Xvoid texture_map PARAMS((DBL x, DBL y, DBL z, OBJECT *Object, COLOUR *colour));
X
X/* Prototypes for functions defined in csg.c */
Xint All_CSG_Union_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint All_CSG_Intersection_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue)); 
Xint All_CSG_Difference_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Inside_CSG_Union PARAMS((VECTOR *Point, OBJECT *Object));
Xint Inside_CSG_Intersection PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid *Copy_CSG PARAMS((OBJECT *Object));
Xvoid Translate_CSG PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_CSG PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_CSG PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_CSG PARAMS((OBJECT *Object)); 
X
X/* Prototypes for functions defined in colour.c */
XDBL Colour_Distance PARAMS((COLOUR *colour1, COLOUR *colour2));
Xvoid Add_Colour PARAMS((COLOUR *result, COLOUR *colour1, COLOUR *colour2));
Xvoid Scale_Colour PARAMS((COLOUR *result, COLOUR *colour, DBL factor));
Xvoid Clip_Colour PARAMS((COLOUR *result, COLOUR *colour)); 
X
X/* Prototypes for functions defined in viewpnt.c */
Xvoid *Copy_Viewpoint PARAMS((OBJECT *Object));
Xvoid Translate_Viewpoint PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Viewpoint PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Viewpoint PARAMS((OBJECT *Object, VECTOR *Vector));
X
X/* Prototypes for functions defined in ray.c */
Xvoid Make_Ray PARAMS((RAY *r));
Xvoid Initialize_Ray_Containers PARAMS((RAY *Ray));
Xvoid Copy_Ray_Containers PARAMS((RAY *Dest_Ray, RAY *Source_Ray));
Xvoid Ray_Enter PARAMS((RAY *ray, OBJECT *object));
Xvoid Ray_Exit PARAMS((RAY *ray));
X
X/* Prototypes for functions defined in planes.c */
Xint All_Plane_Intersections PARAMS((OBJECT *Object, RAY *Ray, PRIOQ *Depth_Queue));
Xint Intersect_Plane PARAMS((RAY *Ray, PLANE *Plane, DBL *Depth));
Xint Inside_Plane PARAMS((VECTOR *Point, OBJECT *Object));
Xvoid Plane_Normal PARAMS((VECTOR *Result, OBJECT *Object, VECTOR *Intersection_Point));
Xvoid *Copy_Plane PARAMS((OBJECT *Object));
Xvoid Translate_Plane PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Rotate_Plane PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Scale_Plane PARAMS((OBJECT *Object, VECTOR *Vector));
Xvoid Invert_Plane PARAMS((OBJECT *Object));
X
X/* Prototypes for functions defined in raw.c */
Xint read_raw_byte PARAMS((FILE *f));
Xint read_raw_word PARAMS((FILE *f));
Xvoid read_raw_image PARAMS((IMAGE *Image, char *filename));
X
X/* Prototypes for functions defined in iff.c */
Xvoid iff_error PARAMS((void));
Xint read_byte PARAMS((FILE *f));
Xint read_word PARAMS((FILE *f));
Xlong read_long PARAMS((FILE *f));
Xvoid Read_Chunk_Header PARAMS((FILE *f, CHUNK_HEADER *dest)); 
Xvoid read_iff_image PARAMS((IMAGE *Image, char *filename));
X
X/* Prototypes for functions defined in gif.c */
Xint out_line PARAMS((char *pixels, int linelen));
Xint get_byte PARAMS((void));
Xvoid read_gif_image PARAMS((IMAGE *Image, char *filename));
X
X/* Prototypes for functions defined in gifdecod.c */
Xshort init_exp PARAMS((short size));
Xshort get_next_code PARAMS((void));
Xshort decoder PARAMS((short linewidth));
X
X/* Prototypes for functions defined in amiga.c */
Xvoid display_finished PARAMS((void));
Xvoid display_init PARAMS((void));
Xvoid display_close PARAMS((void));
Xvoid display_plot PARAMS((int x, int y, char Red, char Green, char Blue));
X
X/* Prototypes for functions defined in matrices.c */
Xvoid MZero PARAMS((MATRIX *result));
Xvoid MIdentity PARAMS((MATRIX *result));
Xvoid MTimes PARAMS((MATRIX *result, MATRIX *matrix1, MATRIX *matrix2));
Xvoid MAdd PARAMS((MATRIX *result, MATRIX *matrix1, MATRIX *matrix2));
Xvoid MSub PARAMS((MATRIX *result, MATRIX *matrix1, MATRIX *matrix2));
Xvoid MScale PARAMS((MATRIX *result, MATRIX *matrix1, DBL amount));
Xvoid MTranspose PARAMS((MATRIX *result, MATRIX *matrix1));
Xvoid MTransformVector PARAMS((VECTOR *result, VECTOR *vector, TRANSFORMATION *transformation));
Xvoid MInverseTransformVector PARAMS((VECTOR *result, VECTOR *vector, TRANSFORMATION *transformation));
Xvoid Get_Scaling_Transformation PARAMS((TRANSFORMATION *result, VECTOR *vector));
Xvoid Get_Inversion_Transformation PARAMS((TRANSFORMATION *result));
Xvoid Get_Translation_Transformation PARAMS((TRANSFORMATION *transformation, VECTOR *vector));
Xvoid Get_Rotation_Transformation PARAMS((TRANSFORMATION *transformation, VECTOR *vector));
Xvoid Get_Look_At_Transformation PARAMS((TRANSFORMATION *transformation, VECTOR *Look_At, VECTOR *Up, VECTOR *Right));
Xvoid Compose_Transformations PARAMS((TRANSFORMATION *Original_Transformation, TRANSFORMATION *New_Transformation));
END_OF_FILE
if test 16900 -ne `wc -c <'src/dkbproto.h'`; then
    echo shar: \"'src/dkbproto.h'\" unpacked with wrong size!
fi
# end of 'src/dkbproto.h'
fi
if test -f 'src/tokenize.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/tokenize.c'\"
else
echo shar: Extracting \"'src/tokenize.c'\" \(17489 characters\)
sed "s/^X//" >'src/tokenize.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                     tokenize.c
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This module implements the first part of a two part parser for the scene
X*  description files.  This phase changes the input file into tokens.
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 <ctype.h>
X#include "frame.h"
X#include "dkbproto.h"
X
X/* This module tokenizes the input file to create a token file to be read
Xby the parser (the second stage). Tokens written to the file contain a
Xtoken ID, the line number of the token, and if necessary, some data for
Xthe token.  */
X
X#define MAX_STRING_INDEX 20
Xchar String[MAX_STRING_INDEX];
Xint String_Index;
Xint Line_Number = 1;
X
X/* Here are the reserved words.  If you need to add new words, be sure
Xto declare them in frame.h */
X
Xstruct Reserved_Word_Struct Reserved_Words [LAST_TOKEN] = {
XAGATE_TOKEN, "AGATE",
XALPHA_TOKEN, "ALPHA",
XAMBIENT_TOKEN, "AMBIENT",
XAMPERSAND_TOKEN, "&",
XAT_TOKEN, "@",
XBACK_QUOTE_TOKEN, "`",
XBACK_SLASH_TOKEN, "\\",
XBAR_TOKEN, "|",
XBLUE_TOKEN, "BLUE",
XBRILLIANCE_TOKEN, "BRILLIANCE",
XBOZO_TOKEN, "BOZO",
XBOUNDED_TOKEN, "BOUNDED_BY",
XBUMPS_TOKEN, "BUMPS",
XCHECKER_TOKEN, "CHECKER",
XCOLON_TOKEN, ":",
XCOLOR_TOKEN, "COLOR",
XCOLOUR_TOKEN, "COLOUR",
XCOLOR_MAP_TOKEN, "COLOR_MAP",
XCOLOUR_MAP_TOKEN, "COLOUR_MAP",
XCOMMA_TOKEN, ",",
XCOMPOSITE_TOKEN, "COMPOSITE",
XDASH_TOKEN, "-",
XDECLARE_TOKEN, "DECLARE",
XDENTS_TOKEN, "DENTS",
XDIFFERENCE_TOKEN, "DIFFERENCE",
XDIFFUSE_TOKEN, "DIFFUSE",
XDIRECTION_TOKEN, "DIRECTION",
XDOLLAR_TOKEN, "$",
XEND_BOUNDED_TOKEN, "END_BOUND",
XEND_COLOR_MAP_TOKEN, "END_COLOR_MAP",
XEND_COLOUR_MAP_TOKEN, "END_COLOUR_MAP",
XEND_COMPOSITE_TOKEN, "END_COMPOSITE",
XEND_DIFFERENCE_TOKEN, "END_DIFFERENCE",
XEND_FOG_TOKEN, "END_FOG",
XEND_INTERSECTION_TOKEN, "END_INTERSECTION",
XEND_OBJECT_TOKEN, "END_OBJECT",
XEND_OF_FILE_TOKEN, "End of File",
XEND_PLANE_TOKEN, "END_PLANE",
XEND_POINTS_TOKEN, "END_POINTS",
XEND_POLYGON_TOKEN, "END_POLYGON",
XEND_QUADRIC_TOKEN, "END_QUADRIC",
XEND_SHAPE_TOKEN, "END_SHAPE",
XEND_SPHERE_TOKEN, "END_SPHERE",
XEND_TEXTURE_TOKEN, "END_TEXTURE",
XEND_TRIANGLE_TOKEN, "END_TRIANGLE",
XEND_UNION_TOKEN, "END_UNION",
XEND_VIEW_POINT_TOKEN, "END_VIEW_POINT",
XEQUALS_TOKEN, "=",
XEXCLAMATION_TOKEN, "!",
XFLOAT_TOKEN, "FLOAT",
XFOG_TOKEN, "FOG",
XFREQUENCY_TOKEN, "FREQUENCY",
XGIF_TOKEN, "GIF",
XGRANITE_TOKEN, "GRANITE",
XGRADIENT_TOKEN, "GRADIENT",
XGREEN_TOKEN, "GREEN",
XHASH_TOKEN, "#",
XHAT_TOKEN, "^",
XIDENTIFIER_TOKEN, "IDENTIFIER",
XIFF_TOKEN, "IFF",
XIMAGEMAP_TOKEN, "IMAGEMAP",
XINCLUDE_TOKEN, "INCLUDE",
XINTERSECTION_TOKEN, "INTERSECTION",
XINVERSE_TOKEN, "INVERSE",
XIOR_TOKEN, "IOR",
XLEFT_ANGLE_TOKEN, "<",
XLEFT_BRACKET_TOKEN, "{",
XLEFT_SQUARE_TOKEN, "[",
XLIGHT_SOURCE_TOKEN, "LIGHT_SOURCE",
XLOCATION_TOKEN, "LOCATION",
XLOOK_AT_TOKEN, "LOOK_AT",
XMARBLE_TOKEN, "MARBLE",
XOBJECT_TOKEN, "OBJECT",
XONCE_TOKEN, "ONCE",
XPERCENT_TOKEN, "%",
XPHASE_TOKEN, "PHASE",
XPHONG_TOKEN, "PHONG",
XPHONGSIZE_TOKEN, "PHONGSIZE",
XPLANE_TOKEN, "PLANE",
XPLUS_TOKEN, "+",
XPOINTS_TOKEN, "POINTS",
XPOLYGON_TOKEN, "POLYGON",
XQUADRIC_TOKEN, "QUADRIC",
XQUESTION_TOKEN, "?",
XRAW_TOKEN, "RAW",
XRED_TOKEN, "RED",
XREFLECTION_TOKEN, "REFLECTION",
XREFRACTION_TOKEN, "REFRACTION",
XREVOLVE_TOKEN, "REVOLVE",
XRIGHT_TOKEN, "RIGHT",
XRIGHT_ANGLE_TOKEN, ">",
XRIGHT_BRACKET_TOKEN, ")",
XRIGHT_SQUARE_TOKEN, "]",
XRIPPLES_TOKEN, "RIPPLES",
XROTATE_TOKEN, "ROTATE",
XROUGHNESS_TOKEN, "ROUGHNESS",
XSCALE_TOKEN, "SCALE",
XSEMI_COLON_TOKEN, ";",
XSHAPE_TOKEN, "SHAPE",
XSKY_TOKEN, "SKY",
XSINGLE_QUOTE_TOKEN, "'",
XSIZE_TOKEN, "SIZE",
XSLASH_TOKEN, "/",
XSMOOTH_TRIANGLE_TOKEN, "SMOOTH_TRIANGLE",
XSPECULAR_TOKEN, "SPECULAR",
XSPHERE_TOKEN, "SPHERE",
XSPOTTED_TOKEN, "SPOTTED",
XSTAR_TOKEN, "*",
XSTRING_TOKEN, "STRING",
XTEXTURE_TOKEN, "TEXTURE",
XTILDE_TOKEN, "~",
XTRANSLATE_TOKEN, "TRANSLATE",
XTRIANGLE_TOKEN, "TRIANGLE",
XTURBULENCE_TOKEN, "TURBULENCE",
XUNION_TOKEN, "UNION",
XUP_TOKEN, "UP",
XVIEW_POINT_TOKEN, "VIEW_POINT",
XWAVES_TOKEN, "WAVES",
XWOOD_TOKEN, "WOOD",
XWRINKLES_TOKEN, "WRINKLES"
X  };
X
X/* Make a table for user-defined symbols.  200 symbols should be more
Xthan enough. */
X
X#define MAX_SYMBOLS 200
X
X/* Hard code symbols to be a maximum of 40 characters long */
Xchar Symbol_Table[MAX_SYMBOLS][40];
Xint Number_Of_Symbols;
X
Xchar File_Name[FILE_NAME_LENGTH];
X
Xextern FILE *Data_File, *Token_File, *Symbol_File;
X#define CALL(x) { if (!(x)) return (FALSE); }
X
X/* The main tokenizing routine.  Set up the files and continue parsing
Xuntil the end of file */
X
Xvoid Tokenize (name, in, symbol, out)
X  char *name;
X  FILE *in, *symbol, *out;
X  {
X/* Keep track of the file name so we don't get confused when we
X    return from INCLUDE files */
X
X  strcpy (File_Name, name);
X  Data_File = in;
X  Token_File = out;
X  Symbol_File = symbol;
X  Number_Of_Symbols = 0;
X
X/* Let the parser know the name of the file we are tokenizing */
X  strcpy (String, name);
X  Write_Token (INCLUDE_TOKEN);
X
X  while (Process_Token()) ;
X  }
X
X/* This function performs most of the work involved in tokenizing.  It
X   reads the first character of the token and decides which function to
X   call to tokenize the rest.  For simple tokens, it simply writes them
X   out to the token file.  */
X
Xint Process_Token ()
X  {
X  register int c;
X
X  Skip_Spaces ();
X
X  c = getc(Data_File);
X  if (c == EOF)
X    return (FALSE);
X
X  String[0] = '\0';
X
X  switch (c)
X    {
X    case '\n': Line_Number++;
X               break;
X
X    case '{' : Parse_Comments();
X               break;
X
X    case '@' : Write_Token (AT_TOKEN);
X               break;
X
X    case '&' : Write_Token (AMPERSAND_TOKEN);
X               break;
X
X    case '`' : Write_Token (BACK_QUOTE_TOKEN);
X               break;
X
X    case '\\': Write_Token (BACK_SLASH_TOKEN);
X               break;
X
X    case '|' : Write_Token (BAR_TOKEN);
X               break;
X
X    case ':' : Write_Token (COLON_TOKEN);
X               break;
X
X    case ',' : Write_Token (COMMA_TOKEN);
X               break;
X
X    case '-' : Write_Token (DASH_TOKEN);
X               break;
X
X    case '$' : Write_Token (DOLLAR_TOKEN);
X               break;
X
X    case '=' : Write_Token (EQUALS_TOKEN);
X               break;
X
X    case '!' : Write_Token (EXCLAMATION_TOKEN);
X               break;
X
X    case '#' : Write_Token (HASH_TOKEN);
X               break;
X
X    case '^' : Write_Token (HAT_TOKEN);
X               break;
X
X    case '<' : Write_Token (LEFT_ANGLE_TOKEN);
X               break;
X
X    case '(' : Write_Token (LEFT_BRACKET_TOKEN);
X               break;
X
X    case '[' : Write_Token (LEFT_SQUARE_TOKEN);
X               break;
X
X    case '%' :  Write_Token (PERCENT_TOKEN);
X               break;
X
X    case '+' : Write_Token (PLUS_TOKEN);
X               break;
X
X    case '?' : Write_Token (QUESTION_TOKEN);
X               break;
X
X    case '>' : Write_Token (RIGHT_ANGLE_TOKEN);
X               break;
X
X    case ')' : Write_Token (RIGHT_BRACKET_TOKEN);
X               break;
X
X    case ']' : Write_Token (RIGHT_SQUARE_TOKEN);
X               break;
X
X    case ';' : Write_Token (SEMI_COLON_TOKEN);
X               break;
X
X    case '\'': Write_Token (SINGLE_QUOTE_TOKEN);
X               break;
X
X    case '/' : Write_Token (SLASH_TOKEN);
X               break;
X
X    case '*' : Write_Token (STAR_TOKEN);
X               break;
X
X    case '~' : Write_Token (TILDE_TOKEN);
X               break;
X
X    case '"' : Parse_String ();
X               break;
X
X    case '0':   case '1':   case '2':   case '3':   case '4':   case '5':
X    case '6':   case '7':   case '8':   case '9':
X               ungetc (c, Data_File);
X               CALL (Read_Float ());
X               break;
X
X    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
X    case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
X    case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
X    case 'v': case 'w': case 'x': case 'y': case 'z':
X    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
X    case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
X    case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
X    case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_':
X               ungetc (c, Data_File);
X               CALL (Read_Symbol ());
X               break;
X
X    default:
X      printf ("Error on line %d\n", Line_Number);
X      printf ("Illegal character in input file, value is %02x\n", c);
X      break;
X    }
X  return (TRUE);
X  }
X
X
X/* Skip over spaces in the input file */
X
Xint Skip_Spaces ()
X  {
X  register int c;
X
X  while (TRUE)
X    {
X    c = getc(Data_File);
X    if (c == EOF)
X      return (FALSE);
X
X    if (!isspace(c))
X      break;
X
X    if (c == '\n')
X       Line_Number++;
X    }
X
X  ungetc (c, Data_File);
X  return (TRUE);
X  }
X
X/* Comments start with an open brace ({) and end with a close brace (}).
X   The open brace has been read already.  Continue reading until a close
X   brace is encountered. Be sure to count the lines while you're at it.
X   Incidently, nested comments are supported (in case you do such esoteric
X   things) */
X
Xint Parse_Comments ()
X  {
X  register int c;
X  int End_Of_Comment;
X  
X  End_Of_Comment = FALSE;
X  while (!End_Of_Comment)
X    {
X    c = getc (Data_File);
X    if (c == EOF)
X      {
X      Token_Error ("No closing comment found");
X      return (FALSE);
X      }
X
X    if (c == (int) '\n')
X      Line_Number++;
X
X    if (c == (int) '{')
X      CALL (Parse_Comments())
X    else
X      End_Of_Comment = (c == (int) '}');
X    }
X
X  return (TRUE);
X  }
X
X/* The following routines make it easier to handle strings.  They stuff
X   characters into a string buffer one at a time making all the proper
X   range checks.  Call Begin_String to start, Stuff_Character to put
X   characters in, and End_String to finish.  The String variable contains
X   the final string. */
X
Xvoid Begin_String()
X  {
X  String_Index = 0;
X  }
X
Xvoid Stuff_Character (c)
X  char c;
X  {
X  if (String_Index < MAX_STRING_INDEX)
X    {
X    String [String_Index++] = c;
X    if (String_Index >= MAX_STRING_INDEX)
X      {
X      Token_Error ("String too long");
X      String [String_Index-1] = '\0';
X      }
X    }
X  }
X
Xvoid End_String ()
X  {
X  Stuff_Character ('\0');
X  }
X
X/* Read a float from the input file and tokenize it as one token. The phase
X   variable is 0 for the first character, 1 for all subsequent characters
X   up to the decimal point, and 2 for all characters after the decimal
X   point.  This helps to insure that the number is formatted properly. */
X
Xint Read_Float()
X  {
X  register int c, Finished, Phase;
X
X  Finished = FALSE;
X  Phase = 0;
X
X  Begin_String();
X  while (!Finished)
X    {
X    c = getc(Data_File);
X    if (c == EOF)
X      {
X      Token_Error ("Unexpected end of file");
X      return (FALSE);
X      }
X
X    switch (Phase)
X      {
X      case 0: if (isdigit(c))
X                Stuff_Character((char) c);
X              else
X                Token_Error ("Error in decimal number");
X              Phase = 1;
X              break;
X     
X      case 1: if (isdigit(c))
X                Stuff_Character((char) c);
X              else if (c == (int) '.')
X                {
X                Stuff_Character((char) c);
X                Phase = 2;
X                }
X              else
X                Finished = TRUE;
X              break;
X
X      case 2: if (isdigit(c))
X                Stuff_Character((char) c);
X              else
X                Finished = TRUE;
X              break;
X      }
X    }
X
X  ungetc (c, Data_File);
X  End_String();
X
X  Write_Token (FLOAT_TOKEN);
X  return (TRUE);
X  }
X
X/* Parse a string from the input file into a token. */
Xint Parse_String ()
X  {
X  register int c;
X
X  Begin_String();
X  while (TRUE)
X    {
X    c = getc(Data_File);
X    if (c == EOF)
X      {
X      Token_Error ("No end quote for string");
X      return (FALSE);
X      }
X
X    if (c != (int) '"')
X      Stuff_Character ((char) c);
X    else
X      break;
X    }
X  End_String();
X
X  Write_Token (STRING_TOKEN);
X
X  return (TRUE);
X  }
X
X/* Read an include file.  This can be a bit tricky.  The old files are saved
X   in local variables while the include file is being read.  We have to
X   write out an INCLUDE token when we start to tell the parser the name of
X   the file we're in.  We have to write another INCLUDE token when we finish
X   to tell the parser that we're back.  */
X
Xint Read_Include ()
X  {
X  register int c;
X  FILE *new_file, *original_file;
X  register int Old_Line_Number;
X  char Old_File_Name[FILE_NAME_LENGTH];
X
X  Skip_Spaces();
X  if (getc(Data_File) != (int) '\"') {
X     printf ("Start quote expected\n");
X     exit (0);
X     }
X
X  Begin_String();
X  while (TRUE)
X    {
X    c = getc(Data_File);
X    if (c == EOF)
X      {
X      Token_Error ("No end quote for string");
X      return (FALSE);
X      }
X
X    if (c != (int) '"')
X      Stuff_Character ((char) c);
X    else
X      break;
X    }
X  End_String();
X
X  if ((new_file = fopen (String, "r")) == NULL) {
X     printf ("Cannot open include file %s\n", String);
X     close_all();
X     exit(1);
X     }
X
X  Write_Token (INCLUDE_TOKEN);
X  Old_Line_Number = Line_Number;
X  Line_Number = 1;
X  original_file = Data_File;
X  strcpy (Old_File_Name, File_Name);
X
X  Tokenize (String, new_file, Symbol_File, Token_File);
X
X  fclose (new_file);
X  Data_File = original_file;
X  Line_Number = Old_Line_Number;
X  strcpy (File_Name, Old_File_Name);
X  strcpy (String, Old_File_Name);
X  Write_Token (INCLUDE_TOKEN);
X  return (TRUE);
X  }
X
X/* Read	in a symbol from the input file.  Check to see if it is a reserved
X   word.  If it is, write out the appropriate token.  Otherwise, write the
X   symbol out to the Symbol file and write out an IDENTIFIER token. An
X   Identifier token is a token whose token number is greater than the
X   highest reserved word. */
X
Xint Read_Symbol ()
X  {
X  register int c, Symbol_Id;
X
X  Begin_String();
X  while (TRUE)
X    {
X    c = getc(Data_File);
X    if (c == EOF)
X      {
X      Token_Error ("Unexpected end of file");
X      return (FALSE);
X      }
X
X    if (isalpha(c) || isdigit(c) || c == (int) '_')
X      Stuff_Character ((char) c);
X    else
X      {
X      ungetc (c, Data_File);
X      break;
X      }
X    }
X  End_String();
X
X  if ((Symbol_Id = Find_Reserved()) != -1)
X
X/* INCLUDE is a reserved word, but we want to handle it separately */
X
X    if (Symbol_Id == INCLUDE_TOKEN)
X       Read_Include();
X    else
X       Write_Token (Symbol_Id);
X  else
X    {
X    if ((Symbol_Id = Find_Symbol()) == -1)
X      if (++Number_Of_Symbols < MAX_SYMBOLS)
X        {
X        strncpy (&Symbol_Table[Number_Of_Symbols][0], &String[0], 39);
X	Symbol_Table[Number_Of_Symbols][39] = '\0';
X        fprintf (Symbol_File, "%s%\n", &String[0]);
X        Symbol_Id = Number_Of_Symbols;
X        }
X      else
X        {
X        printf ("\nToo many symbols\n");
X        exit(0);
X        }
X
X    Write_Token (LAST_TOKEN + Symbol_Id);
X    }
X
X  return (TRUE);
X  }
X
X/* Return the index the token in the reserved words table or -1 if it
X   isn't there. */
X
Xint Find_Reserved ()
X  {
X  register int i;
X
X  for (i = 0 ; i < LAST_TOKEN ; i++)
X    if (strcmp (Reserved_Words[i].Token_Name, &(String[0])) == 0)
X      return (Reserved_Words[i].Token_Number);
X
X  return (-1);
X  }
X
X/* Check to see if a symbol already exists with this name.  If so, return
X    its symbol ID. */
X
Xint Find_Symbol ()
X  {
X  register int i;
X
X  for (i = 1 ; i <= Number_Of_Symbols ; i++)
X    if (strcmp (&Symbol_Table[i][0], &(String[0])) == 0)
X      return (i);
X
X  return (-1);
X  }
X
X/* Write a token out to the token file */
Xvoid Write_Token (Token_Id)
X  TOKEN Token_Id;
X  {
X  fprintf (Token_File, "%d %d %s\n", Token_Id, Line_Number, String);
X  }					/* Was (long) Token_Id... */
X
X/* Report an error */
Xvoid Token_Error (str)
X  char *str;
X  {
X  printf ("Error on line %d\n", Line_Number);
X  puts(str);
X  puts("\n\n");
X  }
END_OF_FILE
if test 17489 -ne `wc -c <'src/tokenize.c'`; then
    echo shar: \"'src/tokenize.c'\" unpacked with wrong size!
fi
# end of 'src/tokenize.c'
fi
if test -f 'src/triangle.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/triangle.c'\"
else
echo shar: Extracting \"'src/triangle.c'\" \(17931 characters\)
sed "s/^X//" >'src/triangle.c' <<'END_OF_FILE'
X/*****************************************************************************
X*
X*                                      triangle.c
X*
X*   from DKBTrace (c) 1990  David Buck
X*
X*  This module implements primitives for triangles and smooth triangles.
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
XMETHODS Triangle_Methods = {
X     Object_Intersect, All_Triangle_Intersections,
X     Inside_Triangle, Triangle_Normal,
X     Copy_Triangle,
X     Translate_Triangle, Rotate_Triangle,
X     Scale_Triangle, Invert_Triangle};
X
XMETHODS Smooth_Triangle_Methods = {
X     Object_Intersect, All_Triangle_Intersections,
X     Inside_Triangle, Smooth_Triangle_Normal,
X     Copy_Smooth_Triangle,
X     Translate_Triangle, Rotate_Smooth_Triangle,
X     Scale_Triangle, Invert_Triangle};
X
Xextern TRIANGLE *Get_Triangle_Shape();
X
Xextern RAY *VP_Ray;
Xextern long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
X
X#define max3(x,y,z) ((x>y)?((x>z)?1:3):((y>z)?2:3))
X
Xvoid Find_Triangle_Dominant_Axis(Triangle)
X   TRIANGLE *Triangle;
X   {
X   DBL x, y, z;
X
X   x = fabs(Triangle->Normal_Vector.x);
X   y = fabs (Triangle->Normal_Vector.y);
X   z = fabs (Triangle->Normal_Vector.z);
X   switch (max3(x, y, z)) {
X      case 1: Triangle->Dominant_Axis = X_AXIS;
X              break;
X      case 2: Triangle->Dominant_Axis = Y_AXIS;
X              break;
X      case 3: Triangle->Dominant_Axis = Z_AXIS;
X              break;
X      }
X   }
X
Xvoid Compute_Smooth_Triangle (Triangle)
X   SMOOTH_TRIANGLE *Triangle;
X   {
X   VECTOR P3MinusP2, VTemp1, VTemp2;
X   DBL x, y, z, uDenominator, Proj;
X
X   VSub (P3MinusP2, Triangle->P3, Triangle->P2);
X   x = fabs (P3MinusP2.x);
X   y = fabs (P3MinusP2.y);
X   z = fabs (P3MinusP2.z);
X
X   switch (max3 (x, y, z)) {
X      case 1:  Triangle->vAxis = X_AXIS;
X               Triangle->BaseDelta = P3MinusP2.x;
X               break;
X
X      case 2:  Triangle->vAxis = Y_AXIS;
X               Triangle->BaseDelta = P3MinusP2.y;
X               break;
X
X      case 3:  Triangle->vAxis = Z_AXIS;
X               Triangle->BaseDelta = P3MinusP2.z;
X               break;
X      }   
X
X   VSub (VTemp1, Triangle->P2, Triangle->P3);
X   VNormalize (VTemp1, VTemp1);
X   VSub (VTemp2, Triangle->P1, Triangle->P3);
X   VDot (Proj, VTemp2, VTemp1);
X   VScale (VTemp1, VTemp1, Proj);
X   VSub (Triangle->Perp, VTemp1, VTemp2);
X   VNormalize (Triangle->Perp, Triangle->Perp);
X   VDot (uDenominator, VTemp2, Triangle->Perp);
X   uDenominator = -1.0 / uDenominator;
X   VScale (Triangle->Perp, Triangle->Perp, uDenominator);
X   }
X
Xint Compute_Triangle (Triangle)
X   TRIANGLE *Triangle;
X   {
X   VECTOR V1, V2, Temp;
X   DBL Length;
X
X   VSub (V1, Triangle->P1, Triangle->P2);
X   VSub (V2, Triangle->P3, Triangle->P2);
X   VCross (Triangle->Normal_Vector, V1, V2);
X   VLength (Length, Triangle->Normal_Vector);
X   if (Length < 1.0e-9)
X      return (0);
X
X   VDot (Triangle->Distance, Triangle->Normal_Vector, Triangle->P1);
X   Triangle->Distance *= -1.0;
X   Find_Triangle_Dominant_Axis(Triangle);
X
X   switch (Triangle->Dominant_Axis) {
X      case X_AXIS:
X         if ((Triangle->P2.y - Triangle->P3.y)*(Triangle->P2.z - Triangle->P1.z) <
X             (Triangle->P2.z - Triangle->P3.z)*(Triangle->P2.y - Triangle->P1.y)) {
X
X             Temp = Triangle->P2;
X             Triangle->P2 = Triangle->P1;
X             Triangle->P1 = Temp;
X             }
X          break;
X
X      case Y_AXIS:
X         if ((Triangle->P2.x - Triangle->P3.x)*(Triangle->P2.z - Triangle->P1.z) <
X             (Triangle->P2.z - Triangle->P3.z)*(Triangle->P2.x - Triangle->P1.x)) {
X
X             Temp = Triangle->P2;
X             Triangle->P2 = Triangle->P1;
X             Triangle->P1 = Temp;
X             }
X          break;
X
X      case Z_AXIS:
X         if ((Triangle->P2.x - Triangle->P3.x)*(Triangle->P2.y - Triangle->P1.y) <
X             (Triangle->P2.y - Triangle->P3.y)*(Triangle->P2.x - Triangle->P1.x)) {
X
X             Temp = Triangle->P2;
X             Triangle->P2 = Triangle->P1;
X             Triangle->P1 = Temp;
X             }
X          break;
X      }
X
X   if (Triangle->Type == SMOOTH_TRIANGLE_TYPE)
X      Compute_Smooth_Triangle((SMOOTH_TRIANGLE *) Triangle);
X   return (1);
X   }
X
Xint All_Triangle_Intersections (Object, Ray, Depth_Queue)
X  OBJECT *Object;
X  RAY *Ray;
X  PRIOQ *Depth_Queue;
X  {
X  TRIANGLE *Shape = (TRIANGLE *) Object;
X  DBL Depth;
X  VECTOR Intersection_Point;
X  INTERSECTION Local_Element;
X
X  if (Intersect_Triangle (Ray, Shape, &Depth))
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  return (FALSE);
X  }
X
Xint Intersect_Triangle (Ray, Triangle, Depth)
X   RAY *Ray;
X   TRIANGLE *Triangle;
X   DBL *Depth;
X   {
X   DBL NormalDotOrigin, NormalDotDirection;
X   DBL s, t;
X
X   Ray_Triangle_Tests++;
X   if (Ray == VP_Ray) {
X      if (!Triangle->VPCached) {
X         VDot (Triangle->VPNormDotOrigin, Triangle->Normal_Vector, Ray->Initial);
X         Triangle->VPNormDotOrigin += Triangle->Distance;
X         Triangle->VPNormDotOrigin *= -1.0;
X         Triangle->VPCached = TRUE;
X         }
X
X      VDot (NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
X      if ((NormalDotDirection < Small_Tolerance) &&
X          (NormalDotDirection > -Small_Tolerance))
X	     return (FALSE);
X
X      *Depth = Triangle->VPNormDotOrigin / NormalDotDirection;
X      }
X   else {
X      VDot (NormalDotOrigin, Triangle->Normal_Vector, Ray->Initial);
X      NormalDotOrigin += Triangle->Distance;
X      NormalDotOrigin *= -1.0;
X
X      VDot (NormalDotDirection, Triangle->Normal_Vector, Ray->Direction);
X      if ((NormalDotDirection < Small_Tolerance) &&
X          (NormalDotDirection > -Small_Tolerance))
X            return (FALSE);
X
X      *Depth = NormalDotOrigin / NormalDotDirection;
X      }
X
X   if ((*Depth < Small_Tolerance) || (*Depth > Max_Distance))
X      return (FALSE);
X
X   switch (Triangle->Dominant_Axis) {
X      case X_AXIS:
X         s = Ray->Initial.y + *Depth * Ray->Direction.y;
X         t = Ray->Initial.z + *Depth * Ray->Direction.z;
X
X         if ((Triangle->P2.y - s)*(Triangle->P2.z - Triangle->P1.z) <
X             (Triangle->P2.z - t)*(Triangle->P2.y - Triangle->P1.y))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P3.y - s)*(Triangle->P3.z - Triangle->P2.z) <
X             (Triangle->P3.z - t)*(Triangle->P3.y - Triangle->P2.y))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P1.y - s)*(Triangle->P1.z - Triangle->P3.z) <
X             (Triangle->P1.z - t)*(Triangle->P1.y - Triangle->P3.y))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if (!(int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X      case Y_AXIS:
X         s = Ray->Initial.x + *Depth * Ray->Direction.x;
X         t = Ray->Initial.z + *Depth * Ray->Direction.z;
X
X         if ((Triangle->P2.x - s)*(Triangle->P2.z - Triangle->P1.z) <
X             (Triangle->P2.z - t)*(Triangle->P2.x - Triangle->P1.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P3.x - s)*(Triangle->P3.z - Triangle->P2.z) <
X             (Triangle->P3.z - t)*(Triangle->P3.x - Triangle->P2.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P1.x - s)*(Triangle->P1.z - Triangle->P3.z) <
X             (Triangle->P1.z - t)*(Triangle->P1.x - Triangle->P3.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if (!(int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X      case Z_AXIS:
X         s = Ray->Initial.x + *Depth * Ray->Direction.x;
X         t = Ray->Initial.y + *Depth * Ray->Direction.y;
X
X         if ((Triangle->P2.x - s)*(Triangle->P2.y - Triangle->P1.y) <
X             (Triangle->P2.y - t)*(Triangle->P2.x - Triangle->P1.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P3.x - s)*(Triangle->P3.y - Triangle->P2.y) <
X             (Triangle->P3.y - t)*(Triangle->P3.x - Triangle->P2.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if ((Triangle->P1.x - s)*(Triangle->P1.y - Triangle->P3.y) <
X             (Triangle->P1.y - t)*(Triangle->P1.x - Triangle->P3.x))
X            if ((int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X         if (!(int) Triangle->Inverted) {
X               Ray_Triangle_Tests_Succeeded++;
X               return (TRUE);
X               }
X            else
X               return (FALSE);
X
X      }
X   return (FALSE);
X   }
X
Xint Inside_Triangle (Point, Object)
X   VECTOR *Point;
X   OBJECT *Object;
X   {
X   return (FALSE);
X   }
X
Xvoid Triangle_Normal (Result, Object, Intersection_Point)
X   OBJECT *Object;
X   VECTOR *Result, *Intersection_Point;
X   {
X   TRIANGLE *Triangle = (TRIANGLE *) Object;
X
X   *Result = Triangle->Normal_Vector;
X   Perturb_Normal (Result, Triangle->Parent_Object,
X                   Intersection_Point, Result);
X   }
X
Xvoid *Copy_Triangle (Object)
X   OBJECT *Object;
X   {
X   TRIANGLE *New_Shape;
X
X   New_Shape = Get_Triangle_Shape ();
X   *New_Shape = * ((TRIANGLE *)Object);
X   New_Shape -> Next_Object = NULL;
X   return (New_Shape);
X   }
X
Xvoid Translate_Triangle (Object, Vector)
X   OBJECT *Object;
X   VECTOR *Vector;
X   {
X   TRIANGLE *Triangle = (TRIANGLE *) Object;
X   VECTOR Translation;
X
X   VEvaluate (Translation, Triangle->Normal_Vector, *Vector);
X   Triangle->Distance -= Translation.x + Translation.y + Translation.z;
X   VAdd (Triangle->P1, Triangle->P1, *Vector)
X   VAdd (Triangle->P2, Triangle->P2, *Vector)
X   VAdd (Triangle->P3, Triangle->P3, *Vector)
X   }
X
Xvoid Rotate_Triangle (Object, Vector)
X   OBJECT *Object;
X   VECTOR *Vector;
X   {
X   TRANSFORMATION Transformation;
X   TRIANGLE *Triangle = (TRIANGLE *) Object;
X
X   Get_Rotation_Transformation (&Transformation, Vector);
X   MTransformVector (&Triangle->Normal_Vector,
X                     &Triangle->Normal_Vector, &Transformation);
X   MTransformVector (&Triangle->P1, &Triangle->P1, &Transformation);
X   MTransformVector (&Triangle->P2, &Triangle->P2, &Transformation);
X   MTransformVector (&Triangle->P3, &Triangle->P3, &Transformation);
X   Compute_Triangle (Triangle);
X   }
X
Xvoid Scale_Triangle (Object, Vector)
X   OBJECT *Object;
X   VECTOR *Vector;
X   {
X   TRIANGLE *Triangle = (TRIANGLE *) Object;
X   DBL Length;
X
X   Triangle->Normal_Vector.x = Triangle->Normal_Vector.x / Vector->x;
X   Triangle->Normal_Vector.y = Triangle->Normal_Vector.y / Vector->y;
X   Triangle->Normal_Vector.z = Triangle->Normal_Vector.z / Vector->z;
X
X   VLength(Length, Triangle->Normal_Vector);
X   VScale (Triangle->Normal_Vector, Triangle->Normal_Vector, 1.0 / Length);
X   Triangle->Distance /= Length;
X
X   VEvaluate (Triangle->P1, Triangle->P1, *Vector);
X   VEvaluate (Triangle->P2, Triangle->P2, *Vector);
X   VEvaluate (Triangle->P3, Triangle->P3, *Vector);
X   }
X
X 
Xvoid Invert_Triangle (Object)
X   OBJECT *Object;
X   {
X   TRIANGLE *Triangle = (TRIANGLE  *) Object;
X
X   Triangle->Inverted ^= TRUE;
X   }
X
X/* Calculate the Phong-interpolated vector within the triangle
X   at the given intersection point. The math for this is a bit
X   bizarre:
X
X    -         P1
X    |        /|\ \
X    |       / |Perp\
X    |      /  V  \   \
X    |     /   |    \   \
X  u |    /____|_____PI___\
X    |   /     |       \    \
X    -  P2-----|--------|----P3
X              Pbase    PIntersect
X        |-------------------|
X                       v
X
X   Triangle->Perp is a unit vector from P1 to Pbase. We calculate
X
X   u = (PI - P1) DOT Perp / ((P3 - P1) DOT Perp).
X
X   We then calculate where the line from P1 to PI intersects the line P2 to P3:
X   PIntersect = (PI - P1)/u.
X
X   We really only need one coordinate of PIntersect.  We then calculate v as:
X
X      v = PIntersect.x / (P3.x - P2.x)
X or   v = PIntersect.y / (P3.y - P2.y)
X or   v = PIntersect.z / (P3.z - P2.z)
X
X   depending on which calculation will give us the best answers.
X
X   Once we have u and v, we can perform the normal interpolation as:
X
X     NTemp1 = N1 + u(N2 - N1);
X     NTemp2 = N1 + u(N3 - N1);
X     Result = normalize (NTemp1 + v(NTemp2 - NTemp1))
X
X   As always, any values which are constant for the triangle are cached
X   in the triangle.
X*/
X
Xvoid Smooth_Triangle_Normal (Result, Object, Intersection_Point)
X   OBJECT *Object;
X   VECTOR *Result, *Intersection_Point;
X   {
X   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
X   VECTOR PIMinusP1, NTemp1, NTemp2;
X   DBL u, v;
X
X   VSub (PIMinusP1, *Intersection_Point, Triangle->P1);
X   VDot (u, PIMinusP1, Triangle->Perp);
X   if (u < 1.0e-9) {
X      *Result = Triangle->N1;
X      return;
X      }
X
X   /* BaseDelta contains P3.x-P2.x,  P3.y-P2.y, or P3.z-P2.z depending on the
X      value of vAxis. */
X
X   switch (Triangle->vAxis) {
X      case X_AXIS:  v = (PIMinusP1.x/u + Triangle->P1.x - Triangle->P2.x) / Triangle->BaseDelta;
X               break;
X
X      case Y_AXIS:  v = (PIMinusP1.y/u + Triangle->P1.y - Triangle->P2.y) / Triangle->BaseDelta;
X               break;
X
X      case Z_AXIS:  v = (PIMinusP1.z/u + Triangle->P1.z - Triangle->P2.z)/ Triangle->BaseDelta;
X               break;
X      }
X
X   VScale (NTemp1, Triangle->DN12, u);
X   VAdd (NTemp1, NTemp1, Triangle->N1);
X   VScale (NTemp2, Triangle->DN13, u);
X   VAdd (NTemp2, NTemp2, Triangle->N1);
X   VSub (*Result, NTemp2, NTemp1);
X   VScale (*Result, *Result, v);
X   VAdd (*Result, *Result, NTemp1); 
X   VNormalize (*Result, *Result);
X   Perturb_Normal (Result, Triangle->Parent_Object,
X                   Intersection_Point, Result);
X   }
X
Xvoid *Copy_Smooth_Triangle (Object)
X   OBJECT *Object;
X   {
X   SMOOTH_TRIANGLE *New_Shape;
X
X   New_Shape = Get_Smooth_Triangle_Shape ();
X   *New_Shape = * ((SMOOTH_TRIANGLE *)Object);
X   New_Shape -> Next_Object = NULL;
X   return (New_Shape);
X   }
X
Xvoid Rotate_Smooth_Triangle (Object, Vector)
X   OBJECT *Object;
X   VECTOR *Vector;
X   {
X   TRANSFORMATION Transformation;
X   SMOOTH_TRIANGLE *Triangle = (SMOOTH_TRIANGLE *) Object;
X
X   Get_Rotation_Transformation (&Transformation, Vector);
X   MTransformVector (&Triangle->Normal_Vector,
X                     &Triangle->Normal_Vector, &Transformation);
X   MTransformVector (&Triangle->P1, &Triangle->P1, &Transformation);
X   MTransformVector (&Triangle->P2, &Triangle->P2, &Transformation);
X   MTransformVector (&Triangle->P3, &Triangle->P3, &Transformation);
X   MTransformVector (&Triangle->N1, &Triangle->N1, &Transformation);
X   MTransformVector (&Triangle->DN12, &Triangle->DN12, &Transformation);
X   MTransformVector (&Triangle->DN13, &Triangle->DN13, &Transformation);
X   Compute_Triangle ((TRIANGLE *) Triangle);
X   }
END_OF_FILE
if test 17931 -ne `wc -c <'src/triangle.c'`; then
    echo shar: \"'src/triangle.c'\" unpacked with wrong size!
fi
# end of 'src/triangle.c'
fi
echo shar: End of archive 6 \(of 10\).
cp /dev/null ark6isdone
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.