Difference between revisions of "Example Application"
(New page: <source lang="c"> /* * R T E X A M P L E . C * * A trivial example of a program that uses librt. With comments. * * cc -I/path/to/include/brlcad -o rtexample rtexample.c librt.a ...) |
m |
||
Line 1: | Line 1: | ||
+ | [[category:Code examples]] | ||
<source lang="c"> | <source lang="c"> | ||
/* | /* |
Revision as of 09:49, 15 November 2009
<source lang="c"> /*
* R T E X A M P L E . C * * A trivial example of a program that uses librt. With comments. * * cc -I/path/to/include/brlcad -o rtexample rtexample.c librt.a -lm */
- include "common.h"
- include <stdio.h>
- include <math.h>
- include "machine.h" /* machine specific definitions */
- include "vmath.h" /* vector math macros */
- include "raytrace.h" /* librt interface definitions */
/* every application needs one of these */ struct application ap;
/* routines for shootray() to call on hit or miss */ extern int hit(struct application *ap, struct partition *PartHeadp, struct seg *segs); extern int miss(register struct application *ap);
char usage[] = "\ Usage: rtexample model.g objects...\n";
main(int argc, char **argv) {
static struct rt_i *rtip; /* rt_dirbuild returns this */ char idbuf[132]; /* First ID record info */
if( argc < 3 ) {
(void)fputs(usage, stderr); exit(1);
}
/* * Load database. * rt_dirbuild() returns an "instance" pointer which describes * the database to be ray traced. It also gives you back the * title string in the header (ID) record. */ if( (rtip=rt_dirbuild(argv[1], idbuf, sizeof(idbuf))) == RTI_NULL ) {
fprintf(stderr,"rtexample: rt_dirbuild failure\n"); exit(2);
} ap.a_rt_i = rtip; /* your application uses this instance */ fprintf(stderr, "db title: %s\n", idbuf);
/* Walk trees. * Here you identify any object trees in the database that you * want included in the ray trace. */ while( argc > 2 ) {
if( rt_gettree(rtip, argv[2]) < 0 ) fprintf(stderr,"rt_gettree(%s) FAILED\n", argv[0]); argc--; argv++;
} /* * This next call gets the database ready for ray tracing. * (it precomputes some values, sets up space partitioning, etc.) */ rt_prep_parallel(rtip,1);
/* * Set the ray start point and direction * rt_shootray() uses these two to determine what ray to fire. * In this case we simply shoot down the z axis toward the * origin from 10 meters away [librt assumes units of millimeters. * not that is really maters here, but an MGED database made with * units=mm will have the same values in the file (and thus in * librt) that you see displayed by MGED. */ VSET( ap.a_ray.r_pt, 0, 0, 10000 ); VSET( ap.a_ray.r_dir, 0, 0, -1 );
VPRINT( "Pnt", ap.a_ray.r_pt ); VPRINT( "Dir", ap.a_ray.r_dir );
/* Shoot Ray */ ap.a_hit = hit; /* where to go on a hit */ ap.a_miss = miss; /* where to go on a miss */ (void)rt_shootray( &ap ); /* do it */
/* * A real application would probably set up another * ray and fire again. */
return(0);
}
/*
* rt_shootray() was told to call this on a hit. He gives up the * application structure which describes the state of the world * (see raytrace.h), and a circular linked list of partitions, * each one describing one in and out segment of one region. */
hit(register struct application *ap, struct partition *PartHeadp, struct seg *segs) {
/* see raytrace.h for all of these guys */ register struct partition *pp; register struct hit *hitp; register struct soltab *stp; struct curvature cur; point_t pt; vect_t inormal; vect_t onormal;
/* examine each partition until we get back to the head */ for( pp=PartHeadp->pt_forw; pp != PartHeadp; pp = pp->pt_forw ) {
bu_log("\n--- Hit region %s (in %s, out %s)\n", pp->pt_regionp->reg_name, pp->pt_inseg->seg_stp->st_name, pp->pt_outseg->seg_stp->st_name );
/* inhit info */ hitp = pp->pt_inhit; stp = pp->pt_inseg->seg_stp;
VJOIN1( pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir );
/* This macro takes care of the flip flag and all that */ RT_HIT_NORMAL( inormal, hitp, stp, &(ap->a_ray), pp->pt_inflip );
rt_pr_hit( " In", hitp ); VPRINT( " Ipoint", pt ); VPRINT( " Inormal", inormal ); /* * This next macro fills in the curvature information * which consists on a principle direction vector, and * the inverse radii of curvature along that direction * and perpendicular to it. Positive curvature bends * toward the outward pointing normal. */ RT_CURVATURE( &cur, hitp, pp->pt_inflip, stp ); VPRINT("PDir", cur.crv_pdir ); bu_log(" c1=%g\n", cur.crv_c1); bu_log(" c2=%g\n", cur.crv_c2);
/* outhit info */ hitp = pp->pt_outhit; stp = pp->pt_outseg->seg_stp; VJOIN1( pt, ap->a_ray.r_pt, hitp->hit_dist, ap->a_ray.r_dir ); RT_HIT_NORMAL( onormal, hitp, stp, &(ap->a_ray), pp->pt_outflip );
rt_pr_hit( " Out", hitp ); VPRINT( " Opoint", pt ); VPRINT( " Onormal", onormal );
}
/* * A more complicated application would probably fill in a * new local application structure and describe say a reflected * or refracted ray, and then call rt_shootray with it. */
/* * This value is returned by rt_shootray * a hit usually returns 1, miss 0. */ return(1);
}
/*
* rt_shootray() was told to call this on a miss. */
miss(register struct application *ap) {
bu_log("missed\n"); return(0);
}
/*
* Local Variables: * mode: C * tab-width: 8 * c-basic-offset: 4 * indent-tabs-mode: t * End: * ex: shiftwidth=4 tabstop=8 */
</source>