home *** CD-ROM | disk | FTP | other *** search
-
-
-
-
-
-
-
-
- QRT Technical Reference
-
-
- INTRODUCTION
-
- The QRT ray tracing system has been designed to make the code
- easily maintainable and expandable. An object oriented design
- philosophy was used for the program, and the resulting code has
- been made as robust as practical given time constraints.
-
- This document explains the design of QRT. First, the function of
- each QRT C file will be listed. Next, the QRT data structures
- will be explained, and finally, some details of code
- implementation discussed.
-
-
- QRT C CODE FILES
-
- The QRT code is broken down into 16 C files and 3 header files,
- each containing a group of related functions. The files are, in
- alphabetical order:
-
- FILE FUNCTION
-
- bbox.c bounding box intersection routines
- error.c error reporting routines
- inout.c recursive decent input parser
- instance.c file for INSTANCE primitives
- intersect.c object intersection routines
- lexer.c simple lexical analyzer
- mth.c vector math support
- norm.c normal finding functions for objects
- offset.c offsets a primitive by dx, dy, dz
- pattern.c finds pattern info for objects
- patternio.c auxiliary parser for patterns
- precomp.c pre-computes some info for objects
- qrt.c main routine and initialization code
- ray.c actual ray tracing algorithims
- relpos.c finds relative position on an object
- resize.c resize any primitive
- stack.c stack and object creation routines
-
- header.h instantiations of some global variables
- pattern.h pattern info
- qrt.h main data structure definitions
-
-
- The function of each group of routines will be discussed in
- greater detail in rest of this document.
-
-
- QRT Ray Tracer Page 1 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- DATA STRUCTURES
-
- All QRT data structures are defined in qrt.h. This file is
- broken down into sections, as follows:
-
- OBJECT TYPE DEFINITIONS:
-
- C #define statements for each object type (sphere, lamp,
- observer, etc).
-
-
- MISC DEFINES
-
- Other #defines for screen size, etc.
-
-
- VECTOR data structure
-
- A floating point 3-tuple vector definition.
-
-
- COLOR VECTOR data structure
-
- A red,green,blue integer 3-tuple structure.
-
-
- COLOR INFO structure
-
- This is an important structure. It lists color information for
- an object, including ambient and diffuse light
- characteristics, reflection and transmission data, Phong
- specular reflection coefficient, index of refraction, and
- object dithering data.
-
-
- PRECOMPUTE structure
-
- This contains some fields which can be filled with precomputed
- information before the ray-tracing is begun. This saves time
- by eliminating redundant calculations for every line/object
- intersection. The use of these fields is up to the
- intersection routines. Each object also has a 'precompute'
- routine which fills this structure.
-
-
- PATTERN structure
-
- The pattern definition structure contains a color info
- structure. It is used to change the characteristics of a
-
-
- QRT Ray Tracer Page 2 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
- primitive object over the surface of that object. For
- example, checkered, brick, or tile patterns may be defined.
-
-
- OBJECT structure
-
- The base structure of QRT. All objects are defined as an
- object structure. This structure contains:
-
- A) A location vector for the object
- B) 3 directional vectors
- C) The object type flag
- D) Some constants for QUADRATIC objects
- E) A color info structure
- F) Sibling and child pointers for the object tree
- G) A pointer to a pattern structure
- H) A pointer to a pattern for the REMOVE command
- I) x and y multipliers for pattern sizing
- J) A name field for the object
-
-
- WORLD structure
-
- This structure contains all data about the world. It contains
- pointers to the object tree, the lamp list, the observer, and
- the sky, and the pattern stack. It also contains statistic
- information, such as total number of rays traced, and the
- output file name and pointer.
-
-
- OBJECT_DATA structure
-
- The header.h file contains an array of this structure, one
- array element per object type. The structure itself contains
- pointers to functions that perform known operations on object
- structures. This design allows much cleaner code and easier
- addition of object types. The object function pointers are:
-
- ColTest: Tests for object collisions
-
- FindNorm: Finds normal to surface at a given position
-
- FindBbox: Computes size of bounding box for object
-
- RelPos: Finds relative position on object surface
- given a position in space
-
- PreComp: Stuffs 'precomp' structure for each object
- before ray-tracing is begun. The precomp and
- intersect routines must agree on the exact usage
- of the fields in this structure.
-
-
- QRT Ray Tracer Page 3 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
-
- Offset: Moves a primitive by dx, dy, dz. This is used
- for instances.
-
- Resize: Resizes a primitive ( and scales its location
- vector). This is also used for instances.
-
- This structure permits expressions such as:
-
- (*(ObjData[CurrObj->type].ColTest))(line,Currobj,&t);
-
- which means:
-
- (collision func for this obj type )(parameters);
-
- instead of a large case statement. Execution is faster, and
- if new objects are added, the code does not have to be
- changed. If a certain operation is illegal for a certain
- object type, the ObjData entry points to an Err() function.
- This way, if something goes wrong, execution is terminated
- gracefully instead of jumping to a random location in memory.
-
-
- MATH defines
-
- MIN, MAX, SQRT, DotProd macros
-
-
- DEFAULT structure
-
- Keeps default color information, and a few other things, like
- resolution and aspect ratio.
-
-
- ERROR codes
-
- Defines for all possible error conditions
-
-
- ROBUST flag
-
- There are many sections of code of the form:
-
- # ifdef ROBUST
- code
- # endif
-
- such that, if ROBUST is defined, the bounds-checking code will
- be compiled. It is recommended that this flag be always set,
- although SLIGHTLY faster execution is possible with it reset.
-
-
-
- QRT Ray Tracer Page 4 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
-
- CODE DESCRIPTION
-
- The function of each section of code will be described in more
- detail here.
-
-
- BBOX.C
-
- Contains code for each object type that will determine the
- size of the bounding box for that object. Bounding boxes are
- logical objects that contain other objects. If a ray does not
- strike a bounding box, it cannot possibly strike any object
- inside the box. This can increase execution speed if used
- correctly.
-
- Routines in BBOX.C are of the form:
-
- BboxSphere(v1,v2,obj)
- VECT_PTR v1,v2;
- OBJ_PTR obj;
-
- where v1 and v2 are vectors for the two corners of the
- bounding box, and obj is a pointer to an object.
-
- The functions are called based upon their pointer in the
- ObjData structure.
-
-
- ERROR.C
-
- This is a simple file that contains just two routines. The
- first one is the Err() routine that fills empty places in the
- ObjData structure. The second routine is the actual error
- reporting routine. It takes two arguments: an error number,
- and an error code. The error number is a #define such as
- 'SYNTAX_ERROR' or 'INTERNAL_ERROR'. The error code is an
- integer used to find the routine in which the error occurred.
- The error code number is arbitrary but should be unique
- throughout the program. A convention has been set up that all
- routines within one C file return an error code with the same
- first digit (501, 502, 503...). If the error occurred while
- parsing the input file, the offending line number is printed.
- Execution is always terminated after calling this routine.
-
-
- INOUT.C
-
- This is a recursive decent parser for the input language. The
- parser was hand coded, since YACC or a similar compiler tool
- was not available. The input routines perform syntax
-
-
- QRT Ray Tracer Page 5 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
- checking, and some bounds checking. The bounds checking will
- catch some errors; however, it has not been idiot-proofed. It
- is up to the user to not make strange entries (radius=0, etc).
- Most of these illogical errors will be caught in the run-time
- bounds checking.
-
- INOUT has one routine for each non-terminal in the grammar.
- The routine accepts parameters, in any order, and branches to
- another routine, or inputs a value. This is the largest
- individual file, at over 1000 lines.
-
-
- INSTANCE.C
-
- This contains the routines to input instance definitions,
- create a copy of a sub-tree, offset the subtree, and scale the
- subtree.
-
-
- INTERSECT.C
-
- This file contains routines to perform line/object
- intersection tests. Each routine is of the form:
-
- int LineSphere(line, sphere, t)
- OBJ_PTR line, sphere;
- float *t;
-
- where line and sphere are inputs, and t is an output. Line is
- always a line object, but the second parameter may be a
- pointer a different object for a different intersection
- routine. The routine must compute the parameter T for the
- intersection point on the line, if any, and return TRUE if the
- line hits the object, or FALSE if it does not.
-
- The functions are called based upon their pointer in the
- ObjData structure.
-
-
- LEXER.C
-
- This is a simple tokenizer for the input language. In this
- implementation, #include directives for the input language are
- not implemented, but they belong in this routine. This module
- also contains some bounds checking code, and code to map
- values of the range 0..1 to 0..CNUM. The light
- characteristics are stored as an integer from 0 to CNUM, but
- the input values are a floating point value from 0 to 1, so
- these routines perform the conversion.
-
-
-
-
- QRT Ray Tracer Page 6 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
- MTH.C
-
- MTH contains support routines for vector math, such as vector
- addition, subtraction, and cross product.
-
-
- NORM.C
-
- These routines find the normal vector to an object at a given
- location in space. They are called based upon the pointer in
- the ObjData structure. A typical entry is:
-
- SphereNorm(norm, object, position)
- VECT_PTR norm, position;
- OBJ_PTR object;
-
- where object and position are input, and norm is output.
-
- Often, several objects share one routine. This happens, for
- example, with planar objects, since the code to find the
- normal to a plane is the same regardless of the shape of the
- planar object.
-
-
- OFFSET.C
-
- These routines are called by the object_data structure. One
- routine exists per primitive type, and they offset the
- primitive by the given amount.
-
-
- PATTERN.C
-
- When a ray/object intersection is found, the pattern function
- is called. If the objects pattern pointer is NULL, the
- default color info for that object is returned. If it is not
- NULL, the the relative position on the surface of that object
- is found, and the color info for the pattern at that location
- is returned. If the relative location is not inside any
- sub-pattern, then the object's default color info is returned.
-
- To determine if a given point is inside a sub-pattern, a
- similar strategy to the object intersection routines is used.
- There are several sub-pattern types (RECTANGLE, CIRCLE, etc),
- and there is a table listing pointers to containment test
- routines for each type. This makes it easy to add sub-pattern
- types.
-
-
-
-
-
-
- QRT Ray Tracer Page 7 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
- PATTERNIO.C
-
- An auxiliary parser for patterns, created because INOUT was
- getting too large to comfortably edit. This file also
- contains routines to copy subtrees, as well as to offset and
- scale subtrees by calling routines from offset.c and resize.c
-
-
- PRECOMP.C
-
- Contains routines to stuff the 'precomp' structure for
- objects. See the documentation for the qrt.h file for more
- details. This structure saves time by computing some
- expressions that do not change with each line/object
- intersection test.
-
-
- QRT.C
-
- This module contains initialization code, and the main routine
- that loads the 'world' and performs the ray tracing. It is
- quite short.
-
-
- RAY.C
-
- All of the ray tracing logic is in this module. The basic
- routine is Ray_Trace. Ray_Trace looks for a ray/object
- intersection. If it finds one, various color routines are
- called to compute the color of the object at this point. Some
- of these color routines may call Ray_Trace recursively (for
- reflection or transmission).
-
- Another important routine, called by Ray_Trace, is Ray_Hit.
- This actually tests to see if the ray hits an object by
- walking through the object tree. If the 'first' flag is set,
- the routine will quit after it finds one object intersection
- (used to see if a surface is in the shadow of another object).
- Otherwise, all intersections are sorted in order of increasing
- parameter T, and the first such intersection returned.
-
-
- RELPOS.C
-
- Routines in RELPOS are called by the entry in the ObjData
- array. A typical routine is:
-
-
- SpherePos(obj,loc,pos1,pos2)
- OBJ_PTR obj;
- VECT_PTR loc;
-
-
- QRT Ray Tracer Page 8 Technical Reference
-
-
-
-
-
-
-
-
-
-
-
-
- float *pos1, *pos2;
-
-
- where obj and loc are input, and the routine must compute the
- coordinates pos1 and pos2 on the surface of the object. This
- is used to map patterns onto the surface of arbitrary objects.
- It is straightforward for planar surfaces. For other
- surfaces, a mapping of the form:
-
- 3-tuple(x,y,z) --> 2-tuple(x,y)
-
- must be created for the object.
-
-
- RESIZE.C
-
- These routines resize objects, and scale the location vector.
- One routine exists per object. They are used by the instance
- routines (as are routines from offset.c).
-
-
- STACK.C
-
- This file contains support code for object tree and list
- manipulations. The name "STACK" is partially historical; the
- initial implementation of the program did not permit arbitrary
- object trees, only linear lists. STACK also contains an
- object creation routine, and a routine to print world
- statistics at the end of the ray tracing session.
-
- Note that in the files that contain object manipulation
- routines (indexed by the object_data structure array), there
- is often a common routine for several similar objects. For
- example, all planar objects (PARALLELOGRAM, RING, TRIANGLE)
- share a common normal finding routine. If one of them should
- suddenly need a different routine, just create it, and change
- the object_data pointer for that object.
-
- Patterns are dealt with in the same manner as objects. There
- are currently three types of pattern primitives (RECTANGLE,
- CIRCLE, and POLYGON). There is a structure (like the
- object_data structure) for patterns. This structure currently
- contains only one entry: a pointer to a collision function.
- Future capabilities may be added later, along with more
- primitive types.
-
-
-
-
-
-
-
-
- QRT Ray Tracer Page 9 Technical Reference
-
-
-
-
-
-
-