#include #include #include #include #include #include #include #include #include #include pfDCS * create_scene(pfChannel *chan); void navigate(pfDCS *dcs); void create_smoke(pfGroup *parent); int smoke_draw(pfTraverser *trav,void *data); int main(int argc,char **argv) { pfDCS *nav_dcs; pfInit(); pfCAVEConfig(&argc,argv,NULL); CAVEFar = 1000; pfuInitSmokes(); pfConfig(); pfCAVEInitChannels(); nav_dcs = create_scene(pfCAVEMasterChan()); while (!CAVEgetbutton(CAVE_ESCKEY)) { pfSync(); pfCAVEPreFrame(); pfFrame(); pfCAVEPostFrame(); navigate(nav_dcs); } pfCAVEHalt(); pfExit(); return 0; } int smoke_draw(pfTraverser *,void *) { pfVec3 eye; CAVEGetPosition(CAVEEye,eye.vec); pfuDrawSmokes(eye); return PFTRAV_CONT; } #define SPEED 2.0f void navigate(pfDCS *dcs) { float jx=CAVE_JOYSTICK_X,jy=CAVE_JOYSTICK_Y; if (fabs(jx) > 0.2) CAVENavRot(1.0f*jx,'z'); if (fabs(jy) > 0.2) { float w[3]; CAVEGetVector(CAVE_WAND_FRONT,w); CAVENavTranslate(w[0]*jy*SPEED,w[1]*jy*SPEED,w[2]*jy*SPEED); } if (CAVEBUTTON3) CAVENavLoadIdentity(); pfCAVEDCSNavTransform(dcs); } pfDCS * create_scene(pfChannel *chan) { pfScene *scene = new pfScene; pfGeoState *gstate = new pfGeoState; pfDCS *dcs = new pfDCS; gstate->setMode(PFSTATE_ENLIGHTING, PF_ON); gstate->setMode(PFSTATE_CULLFACE, PFCF_OFF); scene->setGState(gstate); scene->addChild(new pfLightSource); scene->addChild(dcs); chan->setScene(scene); create_smoke(dcs); return dcs; } void create_smoke(pfGroup *parent) { pfuSmoke *smoke; pfVec3 origin, dir; pfGeode *node; pfSphere bsph; origin[0] = origin[2] = 0; origin[1] = 5; dir[0] = dir[2] = 1; dir[1] = 1; smoke = pfuNewSmoke(); pfuSmokeType(smoke,PFUSMOKE_SMOKE); pfuSmokeOrigin(smoke,origin,1.0f); pfuSmokeVelocity(smoke,3.0f,2.0f); pfuSmokeDir(smoke,dir); pfuSmokeMode(smoke,PFUSMOKE_START); pfuSmokeDuration(smoke,300.0f); node = new pfGeode; parent->addChild(node); bsph.radius = 100.0f; bsph.center = origin; node->setBound(&bsph,PFBOUND_STATIC); node->setTravFuncs(PFTRAV_DRAW,smoke_draw,NULL); node->setTravData(PFTRAV_DRAW,smoke); }