LIBRT(3V)

NAME
librt - library for raytracing a GED file

SYNOPSIS
#include ``raytrace.h''	/* assumes /vld/include is searched */
#include ``vmath.h''		/* assumes /vld/include is searched */

extern int ged_fd;			/* file descriptor of GED file */
extern int one_hit_flag;		/* non-zero to return first hit only */
extern int debug;			/* non-zero for debugging, bit encoded */
extern long nsolids;			/* total # of solids participating */
extern long nregions;			/* total # of regions participating */
extern long nshots;			/* # of calls to ft_shot() */
extern long nmiss_model;		/* rays missed model RPP */
extern long nmiss_tree;			/* rays missed sub-tree RPP */
extern long nmiss_solid;		/* rays missed solid RPP */
extern long nmiss;			/* solid ft_shot() returned a miss */
extern long nhits;			/* solid ft_shot() returned a hit */
extern struct seg *FreeSeg;		/* head of freelist */
extern struct functab functab[];	/* table of solid-specific functions */
extern struct soltab *HeadSolid;	/* pointer to list of solids in model */
extern struct partition *FreePart;	/* head of freelist */
extern vect_t model_min;		/* min corner of model bounding RPP */
extern vect_t model_max;		/* max corner of model bounding RPP */

dir_build( ged_file_name )
char *ged_file_name;

get_tree( object_name )
char *object_name;

shootray( ap )
struct application *ap;

void timer_prep()

double timer_print( msg )
char *msg;

void pr_partitions( phead, title )
struct partition *phead;
char *title;

void pr_seg( segp );
struct seg *segp;

void rtbomb( msg )
char *msg;

void mat_zero( m )		/* fill matrix m with zeros */
matp_t m;

void mat_idn( m )		/* fill matrix m with identity matrix */
matp_t m;

void mat_copy( o, i )		/* copy matrix i to matrix o */
matp_t o, i;

void mat_mul( o, i1, i2 )	/* multiply i1 by i2 and store in o */
matp_t o, i1, i2;

void matXvec( ov, m, iv )	/* multiply m by vector iv, store in ov */
matp_t ov, m, iv;

void mat_inv( o, i )		/* invert matrix i, store result in o */
matp_t o, i;

void mat_print( title, m )	/* print matrix m, (with title) on stdout */
char *title;
matp_t m;

void mat_trn( o, i )		/* transpose matrix i into matrix o */
matp_t o, i;

void mat_ae( o, a, e )		/* rotation matrix o from azimuth+elevation */
matp_t o;
double a, e;

void mat_angles( o, a, b, g )	/* rotation matrix o from angles a, b, g */
matp_t o;
double a, b, g;

void vtoh_move( v, h )		/* homogeneous vector from ordinary vector */
vectp_t v, h;

void htov_move( h, v )		/* ordinary vector from homogeneous vector */
vectp_t h, v;

DESCRIPTION
Dir_build opens ged_file_name and builds a directory for quick lookup of objects. The file descriptor is kept open in the external ged_fd. All objects (groups and regions) which are to be included in the description to be raytraced must be preprocessed with get_tree. Too fire a ray at the description, an application structure must be filled in and its address passed to shootray. To obtain a report of cpu usage for a portion or portions of your program, frame the statements with calls to timer_prep and timer_print. The msg string passed to timer_print is prepended to the report for identification purposes. Each call to timer_prep will reset the logging process. Rtbomb can be used to exit your program with msg appended to the string rt FATAL ERROR which is followed by a newline and printed on the standard error output.

EXIT CODE
All fatal errors detected by the library use rtbomb to exit with a status of 12.

DEFINITION
RPP - Rectangular parallel-piped often used as a rough estimate of a solid object's position in 3-space.

DISCUSSION
You should study the structures in raytrace.h, in particular, the application, the partition structure and its component structures to get an idea of what information is handed to/from shootray. Shootray may be called recursively as from your a_hit routine (good for doing bounced rays). If you only care about the first object hit along the path of the ray, set the one_hit_flag before calling shootray. Helpful in generation a grid of ray origins, the bounding RPP of the model is computed as get_tree is called and stored in model_min and model_max.

EXAMPLE(S)
    A program can be loaded as follows:

    $ cc -I/vld/include main.c /vld/lib/librt.a -lm

    Here is a portion of a hypethetical program which uses the library:

    #include <vmath.h>
    #include <raytrace.h>
    static int nullf() {}
    main( argc, argv )				/* m a i n ( ) */
    int argc;
    char *argv[];
    	{
    	extern int optind;			/* Used by getopt(3C) */
    	extern int do_if_hit(), do_if_miss();	/* Application routines */
    	register int h, v;
    	int grid_sz;
    	structure application ap;		/* Set up for shootray() */
    	...
    	/* Build the directory.	*/
    	dir_build( argv[optind++] );
    	/* Load the desired portion of the model. */
    	objects = &argv[optind];
    	while( argv[optind] != NULL )
    		{
    		get_tree( argv[optind++] );
    		}
    	}
    	ap.a_hit = do_if_hit;		/* Supply routine for hit */
    	ap.a_miss = do_if_missed;	/* Supply routine for miss */
    	ap.a_init = ap.a_eol = ap.a_end = nullf;
    	one_hit_flag = 1;		/* Return only closest object hit */
    	for(	v = 0;			/* First scanline.	*/
    		v < grid_sz;		/* Check for end.	*/
    		++v			/* Next scanline.	*/
    		)
    		{
    		for( h = 0; h < grid_sz; ++h )
    			{
    			/* Set up ray origin. */
    			VMOVE( ap.a_ray.r_pt, get_grid( h, v ) );
    			/* Compute ray direction. */
    			VMOVE( ap.a_ray.r_dir, get_dir( h, v ) );
    			VUNITIZE( ap.a_ray.r_dir ); /* Must be unit vector. */
    			(void) shootray( &ap );
    			}
    		}
    	}
    static int
    do_if_hit( ap, PartHeadp )
    register struct application *ap;
    struct partition *PartHeadp;
    	{
    	register struct partition	*pp = PartHeadp->pt_forw;
    	/* Check for flipped normal and fix (if you intend to use it) */
    	if( pp->pt_inflip )
    		{ /* Reverse direction of surface normal */
    		ScaleVec( pp->pt_inhit->hit_normal, -1.0 );
    		}
    	if( pp->pt_outflip )
    		{ /* Reverse direction of exit normal */
    		ScaleVec( pp->pt_outhit->hit_normal, -1.0 );
    		}
    	/* Do something based on information in partition structure
    		such as output a pixel to the frame buffer
             */
    	light_model( pp->pt_inhit->hit_normal );
    	...
    	return	1; /* Report hit to main routine */
    	}
    /*ARGSUSED*/
    static int
    do_if_miss( ap, PartHeadp )
    register struct application *ap;
    struct partition *PartHeadp;
    	{
    	return	0; /* Report miss to main routine */
    	}

SEE ALSO
mged(1V), rt(1V)

DIAGNOSTICS
Dir_build and get_tree return -1 for failure and 0 for success.
Shootray returns the value of the user-supplied function passed in the application structure.
Timer_print returns the real elapsed seconds since timer_prep was called.

AUTHOR(S)
Mike J. Muuss, BRL/SECAD-CSMB

BUGS
There are instabilities with the root finder that will cause erroneous results and verbose messages to that effect.