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.