Rob Jenkins (robj++at++barney.reading.sgi.com)
Tue, 11 Jul 1995 16:56:42 +0100
I haven't had a chance to look through you code yet - I'll try to later.
Meanwhile aatched is intersect.c which I think Allan Schaffer wrote. If you
haven't seen this already then have alook - you may spot something yourself.
Let me know how you get on.
Cheers
Rob
-- ________________________________________________________________ Rob Jenkins, Software Support Group, Silicon Graphics UK Ltd. 1530 Arlington Business Park, Theale, Reading, UK, RG7 4SB. tel 01734 257736, fax 01734 257553, email robj++at++reading.sgi.com,
/* ////////////////////////////////////////////////////////////////////// */ /* */ /* callbacks.c - Intersection testing sample with callbacks */ /* Requires IRIS Performer 1.2 */ /* */ /* Available Fia anonymous FTP at ftp.sgi.com */ /* in the directory ~ftp/support/Pipeline */ /* */ /* To compile: */ /* cc -o callbacks callbacks.c -O2 -fullwarn -I/usr/include/Performer */ /* -L/usr/src/Performer/lib -lpfutil -lpf -lpr -lmpc -limage -lgl_s */ /* -lm -lfpe -lC */ /* */ /* To toggle the Statistics display, press the F1 or G keys. */ /* To toggle wireframe mode, press the W key. */ /* To toggle texturing, press the T key. */ /* To exit, press ESC. */ /* */ /* ////////////////////////////////////////////////////////////////////// */
#include <stdio.h> #include <math.h> #include <gl/gl.h> #include <gl/device.h> #include <Performer/pf.h> #include <Performer/pr.h> #include <fmclient.h>
typedef struct SharedData { int exitFlag; int showStats; float yval; float zval; } SharedData;
typedef struct PassData { float x,y,z; } PassData;
typedef struct NodeData { float offset; } NodeData;
static void CullChannel (pfChannel *chan, void *data); static void DrawChannel (pfChannel *chan, void *data); static void OpenPipeline (pfPipe *p); static long PreCullCallback (pfTraverser *trav, void *data); static long PreDrawCallback (pfTraverser *trav, void *data); static long PostDrawCallback (pfTraverser *trav, void *data);
SharedData *shared;
static pfVec3 scoords[] ={ { -1.0f, -1.0f, 1.0f }, { 1.0f, -1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, 1.0f }, { -2.0f, -2.0f, 0.0f }, { 2.0f, -2.0f, 0.0f }, { 2.0f, 2.0f, 0.0f }, { -2.0f, 2.0f, 0.0f }};
static ushort svindex[] ={ 0, 1, 2, 3, 0, 3, 7, 4, 4, 7, 6, 5, 1, 5, 6, 2, 3, 2, 6, 7, 0, 4, 5, 1};
static pfVec4 scolors[] ={ {1.0f, 0.0f, 0.0f, 0.5f}, {0.0f, 1.0f, 0.0f, 0.5f}, {0.0f, 0.0f, 1.0f, 0.5f}, {1.0f, 1.0f, 1.0f, 0.5f}};
static ushort scindex[] ={ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3};
/* ////////////////////////////////////////////////////////////////////// */
void main() { pfPipe *pipe; pfChannel *chan; pfScene *scene; pfEarthSky *eSky; pfGroup *root; pfGeoSet *gset; pfSCS *scs[10]; pfGeode *geode; pfMatrix mat; pfCoord view; pfSegSet segset; PassData *passdata; int loop;
printf("To toggle the Statistics display, press the F1 or G keys.\n"); printf("To toggle wireframe mode, press the W key.\n"); printf("To toggle texturing, press the T key.\n"); printf("To exit, press ESC.\n");
/* Initialize Performer */ pfInit();
/* Use default multiprocessing mode based on number of processors. */ pfMultiprocess (PFMP_DEFAULT);
/* Malloc storage in shared memory region for shared data */ shared = (SharedData *) pfMalloc(sizeof(SharedData),pfGetSharedArena());
/* Configure multiprocessing mode and start parallel processes */ pfConfig();
shared->exitFlag = 0; shared->showStats = 0;
/* ////////////////////////////////////////////////////////////// */ /* Configure and open GL window */ pipe = pfGetPipe(0); pfInitPipe (pipe, OpenPipeline);
pfFrameRate(30.0f);
/* Create & configure channel */ chan = pfNewChan(pipe); pfChanCullFunc (chan, CullChannel); pfChanDrawFunc (chan, DrawChannel); pfChanNearFar (chan, 0.1f, 10000.0f); pfChanFOV (chan, 45.0f, -1.0f); passdata = pfAllocChanData (chan, sizeof(PassData));
/* Add an earth/sky effect */ eSky = pfNewESky(); pfESkyMode(eSky, PFES_BUFFER_CLEAR, PFES_SKY_GRND); pfESkyAttr(eSky, PFES_GRND_HT, -0.1f); pfESkyColor(eSky, PFES_SKY_TOP, 1.0f, 1.0f, 1.0f, 1.0f); pfESkyColor(eSky, PFES_SKY_BOT, 0.0f, 0.0f, 0.0f, 1.0f); pfESkyColor(eSky, PFES_HORIZ, 0.0f, 0.0f, 0.0f, 1.0f); pfESkyColor(eSky, PFES_GRND_FAR, 0.3f, 0.1f, 0.0f, 1.0f); pfESkyColor(eSky, PFES_GRND_NEAR, 0.5f, 0.3f, 0.1f, 1.0f); pfChanESky(chan, eSky);
/* ////////////////////////////////////////////////////////////// */ /* Create pfScene node, attach it to channel */ scene = pfNewScene(); pfChanScene (chan, scene);
/* Create group node to hold SCS's; attach it to scene */ root = pfNewGroup(); pfAddChild (scene, root);
/* Create 10 SCS nodes, spaced equally apart. Make each one a child of 'root', and make 'geode' a child of each SCS */ geode = pfNewGeode(); for (loop=0; loop < 10; loop++) { NodeData *nodedata = pfMalloc (sizeof(NodeData), pfGetSharedArena()); nodedata->offset = (float) loop * 10.0f + 10.0f; pfMakeTransMat (mat, 0.0f, (float) loop * 10.0f + 10.0f, 0.0f); scs[loop] = pfNewSCS (mat); pfAddChild (scs[loop], geode); pfAddChild (root, scs[loop]);
/* set up SCS's (and their children) for intersections */ pfNodeTravMask (scs[loop], PFTRAV_ISECT, 1, PFTRAV_SELF, PF_SET);
/* Add a CULL traversal callback to each SCS */ pfNodeTravFuncs (scs[loop], PFTRAV_CULL, PreCullCallback, NULL); pfUserData (scs[loop], nodedata);
pfNodeTravFuncs (scs[loop], PFTRAV_DRAW, PreDrawCallback, PostDrawCallback); }
/* Create a GeoSet to hold the ramp geometry */ gset = pfNewGSet (pfGetSharedArena()); pfGSetAttr (gset, PFGS_COORD3, PFGS_PER_VERTEX, scoords, svindex); pfGSetAttr (gset, PFGS_COLOR4, PFGS_PER_VERTEX, scolors,scindex); pfGSetPrimType (gset, PFGS_QUADS); pfGSetNumPrims (gset, 6);
/* attach it to the parent geode */ pfAddGSet (geode, gset);
/* ////////////////////////////////////////////////////////////// */ /* set initial view position */ shared->yval=0.0f; shared->zval=0.5f;
/* set up intersection segment, pointing down for "terrain" following */ segset.activeMask = 1; segset.isectMask = 0xFFFF; segset.mode = PFTRAV_IS_PRIM|PFTRAV_IS_NORM|PFTRAV_IS_CULL_BACK; pfSetVec3(segset.segs[0].dir, 0.0f, 0.0f, -1.0f); segset.segs[0].length = 50000.0f;
/* ////////////////////////////////////////////////////////////// */ /* main loop */ while (!shared->exitFlag) { pfHit **hits[100]; long isect;
pfSetVec3(view.xyz, 0.0f, shared->yval, shared->zval); pfSetVec3(view.hpr, 0.0f, -5.0f, 0.0f);
passdata->x = 0.0f; passdata->y = shared->yval; passdata->z = shared->zval;
pfChanView (chan, view.xyz, view.hpr); pfPassChanData (chan); pfFrame();
/* increment view position; if too far, reset */ shared->yval += 0.1f; if (shared->yval > 110.0f) shared->yval = 0.0f;
/* update location of intersection segment */ pfSetVec3(segset.segs[0].pos, 0.0f, shared->yval,shared->zval);
/* do an intersection test against the scene graph */ isect = pfSegsIsectNode(root, &segset, hits);
/* if successful, set our height to that of the point of contact, plus a small offset */ if (isect) { pfVec3 pnt; pfQueryHit (*hits[0], PFQHIT_POINT, &pnt); shared->zval = pnt[PF_Z] + 0.5; } } pfExit(); }
/* ////////////////////////////////////////////////////////////////////// */ /* Pipe Initialization Callback to open and configure * GL window, and set up GL event handling */
static void OpenPipeline (pfPipe *p) { pfTexture *tex;
foreground(); prefposition(300, 700, 300, 700); winopen ("Terrain"); winconstraints(); pfInitGfx(p);
qdevice (ESCKEY); qdevice (F1KEY); qdevice (GKEY); qdevice (TKEY); qdevice (WKEY);
tex = pfNewTex (pfGetSharedArena()); pfFilePath ("/usr/demos/data/textures"); pfLoadTexFile (tex, "cafe.rgb"); pfApplyTex (tex); pfApplyTEnv (pfNewTEnv (pfGetSharedArena())); if (pfGetEnable (PFEN_TEXTURE)) pfEnable (PFEN_TEXTURE); }
/* ////////////////////////////////////////////////////////////////////// */ static long PreDrawCallback (pfTraverser *trav, void *data) { if (!pfGetEnable(PFEN_TEXTURE)) return 0;
texgen(TX_S, TG_SPHEREMAP, 0); texgen(TX_T, TG_SPHEREMAP, 0); texgen(TX_S, TG_ON, NULL); texgen(TX_T, TG_ON, NULL);
return 0; }
/* ////////////////////////////////////////////////////////////////////// */ static long PostDrawCallback (pfTraverser *trav, void *data) { if (!pfGetEnable(PFEN_TEXTURE)) return 0;
texgen(TX_S, TG_OFF, NULL); texgen(TX_T, TG_OFF, NULL);
return 0; }
/* ////////////////////////////////////////////////////////////////////// */ static long PreCullCallback (pfTraverser *trav, void *data) { PassData *pass = pfGetChanData (pfGetTravChan(trav)); NodeData *nodedata = pfGetUserData(pfGetTravNode(trav));
if (pfGetCullResult() & PFIS_FALSE) return PFTRAV_PRUNE;
if ((pass->z < 1.0) && (pass->y < nodedata->offset-10.0f)) return PFTRAV_PRUNE;
return PFTRAV_CONT; }
/* /////////////////////////////////////////////////////////////////////// */ /* Cull Process Callback to cull the channel. Custom traversal would be */ /* done here.. */
static void CullChannel (pfChannel *chan, void *data) { pfCull(); }
/* /////////////////////////////////////////////////////////////////////// */ /* Draw Process Callback to draw the channel and handle GL events */
static void DrawChannel (pfChannel *chan, void *data) { static pfMatrix tempmat; short dev,val; char string[40]; PassData *pass = (PassData*) data; /* clear and draw the channel */ pfClearChan (chan); pfDraw();
if (shared->showStats) pfDrawChanStats(chan);
zfunction (ZF_ALWAYS); /* HUD always drawn */ zwritemask (0x0);
pfPushState(); pfBasicState(); ortho2 (-0.5, 10.0, -0.5, 10.0); pfPushIdentMatrix(); cpack(0x000000); cmov2 (0.0, 0.0); sprintf(string, "x = %2.2f y = %2.2f z = %2.2f", pass->x, pass->y, pass->z); charstr (string); pfPopMatrix(); pfPopState(); zfunction (ZF_LEQUAL); /* the default */ zwritemask (0xffffffff);
while (qtest()) { dev = qread(&val); if (val) switch (dev) { case ESCKEY: shared->exitFlag=1; break; case F1KEY: case GKEY: shared->showStats = !shared->showStats; break; case TKEY: if (pfGetEnable(PFEN_TEXTURE)) pfDisable (PFEN_TEXTURE); else pfEnable (PFEN_TEXTURE); break; case WKEY: if (pfGetEnable(PFEN_WIREFRAME)) pfDisable (PFEN_WIREFRAME); else pfEnable (PFEN_WIREFRAME); break; } }
}
/* /////////////////////////////////////////////////////////////////////// */
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:51:40 PDT