// Performer navigation and picking and moving of objects example. // (C) 1997 Jason Leigh jleigh@eecs.uic.edu #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "spider.h" #define BASEMENTSCALE 3 #define DOORWIDTH 2.5 #define SPEED .1 #define MAX_SPIDERS 256 #define XROOM 25 #define NEGXROOM -3 #define YROOM 8 #define NEGYROOM -8 #define XLIVROOM -0.5 #define NEGXLIVROOM -9.4 #define YLIVROOM 18 #define NEGYLIVROOM 8 #define BUTTONDELAY 3.0 int ilevel = 0; int navType = 0; Spider * spiderarray[MAX_SPIDERS]; SpiderData * spidermatrix[MAX_SPIDERS][9]; int spidercount = 0; pfGroup *masterParent; float lastbutton = 0; static int moveEnv(pfTraverser *trav, void *); float xfromorg = 0; float yfromorg = 0; float zfromorg = 4.5; void updateSpiders(); void nextLevel(); void makeNewSpider(); void updateSpiders() { //printf("updating spider\n"); float x,y,z; for(int i=0; i< spidercount+1; i++) { x = spidermatrix[i][8]->getx(); y = spidermatrix[i][8]->gety(); z = spidermatrix[i][8]->getz(); //printf("spider %d, %f %f %f\n", i,x,y,z); x += spidermatrix[i][8]->getDestx(); y += spidermatrix[i][8]->getDesty(); float newlx = x; float newly = y; float newdx=0, newdy=0; if ( x < NEGXROOM || x > XROOM ) { newdx = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; newdx *= .07; //newlx = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; //newly *= 5; } if ( y < NEGYROOM || y > YROOM ) { newdy = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; newdy *= .07; //newly = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; //newly *= 5; } for(int j=0;j<9;j++) { if ( x < NEGXROOM || x > XROOM ) { spidermatrix[i][j]->setDestx(newdx); } if ( y < NEGYROOM || y > YROOM ) { spidermatrix[i][j]->setDesty(newdy); } // spidermatrix[i][j]->setRot( pfGetTime()*5 ); spidermatrix[i][j]->doRot(); spidermatrix[i][j]->setLoc( newlx, newly, z ); } } //printf("done\n"); } void loadObjects(int argc, char **argv, pfGroup *parent, pfScene *scene) { pfNode *obj; pfDCS *dcsbody; masterParent = parent; // load environment dcsbody = new pfDCS; obj = pfdLoadFile("basement7.iv"); dcsbody->setTravFuncs(PFTRAV_APP, moveEnv, NULL); dcsbody->setScale( BASEMENTSCALE, BASEMENTSCALE, BASEMENTSCALE ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("treeBox.iv"); dcsbody->setTrans( 20, 4, 1.5 ); dcsbody->setRot( -42, 0, 0 ); dcsbody->setScale( .6,.6,.6 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("genericBox.iv"); dcsbody->setTrans( 17, 4.7, 0.85 ); dcsbody->setRot( 69, 0, 0 ); dcsbody->setScale( .4,.4,.4 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("genericBox.iv"); dcsbody->setTrans( 0, -6.5, .7 ); dcsbody->setRot( 23, 0, 0 ); dcsbody->setScale( .6,.5,.4 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("genericBox.iv"); dcsbody->setTrans( -1.1, -7, 0.75 ); dcsbody->setRot( 29, 0, 0 ); dcsbody->setScale( .5,.7,.5 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("shelves.iv"); dcsbody->setTrans( 4.35, 8.35, 2.3 ); //dcsbody->setRot( 29, 0, 0 ); dcsbody->setScale( .7,.7, .7 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("lightFixture.iv"); dcsbody->setTrans( 10, 5, 8.4 ); //dcsbody->setRot( 29, 0, 0 ); dcsbody->setScale( 2, 1, 1 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("lightFixture.iv"); dcsbody->setTrans( 10, -5, 8.4 ); //dcsbody->setRot( 29, 0, 0 ); dcsbody->setScale( 2, 1, 1 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("couch.iv"); dcsbody->setTrans( -5, 17, 7.5 ); //dcsbody->setRot( 29, 0, 0 ); dcsbody->setScale( .9, .9, .9 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("furnace.iv"); dcsbody->setTrans( 24, -6, 3.3 ); dcsbody->setRot( -120, 0, 0 ); dcsbody->setScale( .6, .6, 1.1 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("table.iv"); dcsbody->setTrans( -7, 14, 6.3); dcsbody->setRot( 90, 0, 0 ); dcsbody->setScale( 1., 2., 1.7 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("spiderWeb.iv"); dcsbody->setTrans( 10.5, 0, 7.7 ); dcsbody->setRot( 0, 0, 270 ); dcsbody->setScale( 1, 1, 1 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("floorLamp.iv"); dcsbody->setTrans( -8.5, 11, 8.3 ); //dcsbody->setRot( 0, 0, 0 ); dcsbody->setScale( .7, .7, .7 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); dcsbody = new pfDCS; obj = pfdLoadFile("spiderWeb.iv"); dcsbody->setTrans( -3.5, 0, 7.7 ); dcsbody->setRot( 0, 0, 180 ); dcsbody->setScale( 1, 1, 1 ); dcsbody->addChild(obj); masterParent->addChild(dcsbody); // NULL out spiderarray for( int i = 0; i < MAX_SPIDERS; i++ ) { spiderarray[i] = NULL; } //spiderarray[spidercount] = new Spider( masterParent, spidercount, // spidermatrix[spidercount] ); //spidercount++; //spiderarray[spidercount++] = new Spider( masterParent, 5, 5, 0.6, // spidercount, spidermatrix[spidercount] ); //spidercount++; } static int moveEnv(pfTraverser *trav, void *) { pfDCS *dcs = (pfDCS *) trav->getNode(); // get a pointer to DCS node dcs->setTrans(-4, 0, 4.6); return PFTRAV_CONT; } pfDCS * createScene(pfChannel *chan, int argc, char **argv, pfScene *scene) { pfGeoState *gstate = new pfGeoState; pfDCS *dcs = new pfDCS; gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); gstate->setMode(PFSTATE_CULLFACE, PFCF_OFF); gstate->setMode(PFSTATE_TRANSPARENCY,PFTR_HIGH_QUALITY); scene->setGState(gstate); // Add a light source to the scene as well as the dcs pfLightSource *myLightSource1 = new pfLightSource; myLightSource1->setAmbient(.10f, .10f, .10f); myLightSource1->setColor(PFLT_DIFFUSE, .5f, .5f, .5f); myLightSource1->setPos(3, 2, 6, 1); scene->addChild(myLightSource1); pfLightSource *myLightSource2 = new pfLightSource; myLightSource2->setAmbient(.10f, .10f, .10f); myLightSource2->setColor(PFLT_DIFFUSE, 1.0f, 1.0f, 1.0f); myLightSource2->setPos(-3, 10, 14, 1); scene->addChild(myLightSource2); // pfLightSource *myLightSource3 = new pfLightSource; // myLightSource3->setPos(5, 7, 15, 1); // myLightSource3->setSpotDir(5, 0, 0); // scene->addChild(myLightSource3); scene->addChild(dcs); loadObjects(argc, argv, dcs, scene); chan->setBinSort(PFSORT_TRANSP_BIN, PFSORT_BACK_TO_FRONT, NULL); chan->setScene(scene); return dcs; } void handleButtons(pfScene *scene) { // If button pressed: if (CAVEBUTTON1) { // make sure we arn't increasing too fast if( pfGetTime() - lastbutton < BUTTONDELAY) { return; } lastbutton = pfGetTime(); ilevel++; nextLevel(); } else if (CAVEBUTTON2) { //navType = !navType; } else if (CAVEBUTTON3) { ////////////////// Take this out! exit(42); } if (CAVEButtonChange(3) == -1) CAVENavLoadIdentity(); } void navigate(pfDCS *dcs) { if (navType) { //printf("nav1\n"); // Do normal CAVE navigation - FLY float jx = CAVE_JOYSTICK_X, jy = CAVE_JOYSTICK_Y; printf("jx: %f jy: %f \n",jx,jy ); if (fabs(jx) > 0.2) { CAVENavRot(-2.0f * jx, 'z'); } if (fabs(jy) > 0.2) { float w[3]; CAVEGetVector(CAVE_WAND_FRONT, w); //printf("ymove %f speed %f\n", w[1] * jy * SPEED, SPEED); CAVENavTranslate(w[0] * jy * SPEED, w[1] * jy * SPEED, w[2] * jy * SPEED); } } else { //printf("nav0\n"); // Do normal CAVE navigation - WALK float jx = CAVE_JOYSTICK_X, jy = CAVE_JOYSTICK_Y; if (fabs(jx) > 0.2) CAVENavRot(-2.0f * jx, 'z'); if (fabs(jy) > 0.2) { float w[3]; CAVEGetVector(CAVE_WAND_FRONT, w); float xoffset = w[0] * jy * SPEED; float yoffset = w[1] * jy * SPEED; float zoffset = 0; float wandori[3]; float headpos[3]; float perpos[3]; CAVENavConvertVectorCAVEToWorld( w, wandori ); //printf("wandori: %f %f %f\n", // wandori[0],wandori[1],wandori[2]); CAVEGetPosition(CAVE_HEAD, headpos); //printf("headpos: %f %f %f\n", // headpos[0],headpos[1],headpos[2]); CAVENavConvertCAVEToWorld(headpos, perpos); //printf("perpos: %f %f %f\n", // perpos[0],perpos[1],perpos[2]); if(perpos[0] < NEGXROOM && (wandori[0]*yoffset) < 0) { // if not in living room stop them if (perpos[1] < YROOM) { yoffset = 0; } else { if (perpos[0] < NEGXLIVROOM) yoffset = 0; } } if(perpos[0] > XROOM && (wandori[0]*yoffset) > 0) yoffset = 0; if(perpos[1] < NEGYROOM && (wandori[1]*yoffset) < 0) yoffset = 0; if(perpos[0] < NEGXROOM - 0.1 && perpos[1] < 10 && (wandori[1]*yoffset) < 0 ) yoffset = 0; if(perpos[0] > XLIVROOM && perpos[1] > YROOM && (wandori[0]*yoffset) > 0 ) yoffset = 0; if(perpos[1] > YROOM && (wandori[1]*yoffset) > 0) { // If we're not at the door, stop them if(perpos[0] > NEGXROOM + DOORWIDTH + 0.2) yoffset = 0; else if (perpos[1] > YLIVROOM) yoffset = 0; } // DO Z STUFF if (perpos[0] < NEGXROOM + DOORWIDTH && perpos[1] > 4 && perpos[1] < 5) { zoffset = 5.5 - zfromorg; zfromorg = 5.5; } else if (perpos[0] < NEGXROOM + DOORWIDTH && perpos[1] > 5 && perpos[1] < 6) { zoffset = 6.5 - zfromorg; zfromorg = 6.5; } else if (perpos[0] < NEGXROOM + DOORWIDTH && perpos[1] > 6 && perpos[1] < 7) { zoffset = 7.5 - zfromorg; zfromorg = 7.5; } else if (perpos[0] < NEGXROOM + DOORWIDTH && perpos[1] > 7 && perpos[1] < YROOM) { zoffset = 8.5 - zfromorg; zfromorg = 8.5; } else if (perpos[1] > YROOM && perpos[0] < XLIVROOM + 0.1 ) { zoffset = 10.5 - zfromorg; zfromorg = 10.5; } else { zoffset = 4.5 - zfromorg; zfromorg = 4.5; } CAVENavTranslate(xoffset, yoffset, zoffset); } } // Store the CAVE navigation in the DCS pfCAVEDCSNavTransform(dcs); } int main(int argc,char **argv) { pfDCS *nav_dcs; pfInit(); pfCAVEConfig(&argc,argv,NULL); CAVEFar = 6000; // Load all loader DSO's before pfConfig() forks pfdInitConverter(argv[1]); pfConfig(); pfCAVEInitChannels(); pfChannel *chan; pfTransparency(PFTR_HIGH_QUALITY); // Create the scene with a DCS at the top pfScene *scene = new pfScene; chan = pfCAVEMasterChan(); nav_dcs = createScene(chan, argc, argv, scene); //pfEarthSky *sky1, *sky2; pfEarthSky *sky2; sky2 = new pfEarthSky(); sky2->setMode(PFES_BUFFER_CLEAR, PFES_FAST); sky2->setColor(PFES_CLEAR, .1f, .1f, .1f, 1.0f); chan->setESky(sky2); // initial viewpoint CAVENavTranslate( 0, 0, -1.5 ); CAVENavTranslate( -4, 10, 6 ); zfromorg = 10.5; while (!CAVEgetbutton(CAVE_ESCKEY)) { updateSpiders(); pfSync(); pfCAVEPreFrame(); pfFrame(); pfCAVEPostFrame(); // Update the navigation navigate(nav_dcs); // Check buttons handleButtons(scene); // Check sabre // check_sabre(); } CAVEHalt(); pfExit(); return 0; } void nextLevel() { int i,j,k; switch(ilevel) { case 0: printf("Level 0\n"); break; case 1: printf("Level 1\n"); makeNewSpider(); break; case 2: printf("Level 2\n"); makeNewSpider(); break; case 3: printf("Level 3\n"); for(i=0;i<2;i++) makeNewSpider(); break; case 4: printf("Level 4\n"); for(j=0;j<5;j++) makeNewSpider(); break; case 5: printf("Level 5\n"); for(k=0;k<7;k++) makeNewSpider(); break; default: printf("Level %d\n", ilevel); for(k=0;k<10;k++) makeNewSpider(); break; } } void makeNewSpider() { float randomx = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; float randomy = ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5; spiderarray[spidercount] = new Spider( masterParent, 24+randomx, 7+randomy, .6, spidercount, spidermatrix[spidercount] ); randomx = ( ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5) * .2; randomy = ( ( (float)(rand()/(RAND_MAX+1.0)) ) - 0.5) * .2; for (int i=0;i<9;i++) { spidermatrix[spidercount][i]->setDest( randomx, randomy, 0); } spidercount++; }