/* network1.c /* An example of a static networked CAVE environment. The world is that /* of navigate1.c, except that the balls do not bounce (as that would /* require synchronization of the different CAVEs). This program does not /* use any networked application data; it merely uses the networked /* tracking data in drawing the remote users. */ #include #include #include void init_gl(void),draw_world(void); void navigate(void); void draw_user(volatile CAVE_USER_ST *user); void draw_head(volatile CAVE_USER_ST *user); void draw_wand(volatile CAVE_USER_ST *user); main(int argc,char **argv) { CAVEConfigure(&argc,argv,NULL); CAVEInit(); CAVEInitApplication(init_gl,0); CAVEDisplay(draw_world,0); while (1) { navigate(); printf("%d users\n",*CAVENumUsers); sginap(50); } CAVEExit(); } #define SPEED 5.0f /* Max navigation speed in feet per second */ /* navigate - perform the navigation calculations. This checks the joystick state and uses that to move and rotate. The Y position of the joystick determines the speed of motion in the direction of the wand. The X position of the joystick determines the speed of rotation about the CAVE's Y axis. Joystick values in the range -.2 to .2 are ignored; this provides a dead zone to eliminate noise. The motion is scaled by dt, the time passed since the last call to navigate(), in order to maintain a smooth speed. */ void navigate(void) { float jx=CAVE_JOYSTICK_X,jy=CAVE_JOYSTICK_Y,dt,t; static float prevtime = 0; t = CAVEGetTime(); dt = t - prevtime; prevtime = t; if (fabs(jy)>0.2) { float wandFront[3]; CAVEGetVector(CAVE_WAND_FRONT,wandFront); CAVENavTranslate(wandFront[0]*jy*SPEED*dt, wandFront[1]*jy*SPEED*dt, wandFront[2]*jy*SPEED*dt); } if (fabs(jx)>0.2) CAVENavRot(-jx*90.0f*dt,'y'); } /* init_gl - initialize GL lighting & materials */ void init_gl(void) { float redMaterial[] = { DIFFUSE, 1, 0, 0, LMNULL }; float blueMaterial[] = { DIFFUSE, 0, 0, 1, LMNULL }; lmdef(DEFLMODEL,1,0,NULL); lmbind(LMODEL,1); lmdef(DEFLIGHT,1,0,NULL); lmbind(LIGHT0,1); lmdef(DEFMATERIAL,1,0,redMaterial); lmdef(DEFMATERIAL,2,0,blueMaterial); } /* draw_world - draw the world - the two balls, and the networked users */ void draw_world(void) { float sphereParam0[] = { 2, 3, -5, 1}; float sphereParam1[] = { -2, 1, -5, 1}; int i; czclear(0,getgdesc(GD_ZMAX)); /* Apply the navigation transformation */ pushmatrix(); CAVENavTransform(); lmbind(MATERIAL,0); cpack(0xff088018); pushmatrix(); rot(-90.0,'x'); rectf(-100.0,-100.0,100.0,100.0); popmatrix(); lmbind(MATERIAL,1); sphdraw(sphereParam0); lmbind(MATERIAL,2); sphdraw(sphereParam1); lmbind(MATERIAL,0); /* Draw all the remote users (but not the local user; hence count from 1) */ popmatrix(); for (i=1; i<*CAVENumUsers; i++) draw_user(CAVEUser[i]); } /* draw_user - draw the given user's head and wand */ void draw_user(volatile CAVE_USER_ST *user) { pushmatrix(); CAVESensorTransform(CAVENETSENSOR(user,0)); draw_head(user); popmatrix(); pushmatrix(); CAVESensorTransform(CAVENETSENSOR(user,1)); draw_wand(user); popmatrix(); } /* draw_head - draw the given user's head, using a few spheres for a head, eyes, and nose */ void draw_head(volatile CAVE_USER_ST *user) { float sparam0[4] = {0,0,0,.5},sparam1[4]={0,0.1,-.5,.1}, sparam2[4] = {-0.2,0.3,-.3,.1},sparam3[4]={0.2,0.3,-.3,.1}; cpack(0xff808080); sphdraw(sparam0); cpack(0xff0000bd); sphdraw(sparam1); cpack(0xffbd0000); sphdraw(sparam2); sphdraw(sparam3); } /* draw_wand - draw the given user's wand as a small sphere */ void draw_wand(volatile CAVE_USER_ST *user) { float sparam0[4] = {0,0,0,.1}; cpack(0xff0000ff); sphdraw(sparam0); }