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.