#include "CAVERN.h++"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gl/device.h>
#include <Performer/pf/pfChannel.h>
#include <Performer/pf/pfLightSource.h>
#include <Performer/pf/pfDCS.h>
#include <Performer/pf/pfGeode.h>
#include <Performer/pfutil.h>
#include <Performer/pr/pfTexture.h>
#include <pfcave.h>
#include <pthread.h>
pfuSmoke *smoke;
pfVec3 origin, dir;
pfGeode *node;
pfSphere bsph;
pfDCS * create_scene(pfChannel *chan);
void create_smoke(pfGroup *parent);
int smoke_draw(pfTraverser *trav,void *data);
/// -------------------------------------------------------------
/// CAVERN CAVERN CAVERN CAVERN CAVERN CAVERN
CAVERN CAVERN CAVERN
/// -------------------------------------------------------------
/// Callback that fires when A_KEY gets filled
with new data.
void A_keyCB(CAVERN_irbKey_c::CAVERN_irbKeyEvent_t
event,
CAVERN_irbKey_c
*thisKey,
void* userData)
{
int size;
CAVERN_irbKey_c::status_t
status;
// Grab the data from the key.
// Recall userData is really a reference to the "movement" variable
// declared in main(). You passed it in as a parameter to trigger().
// Fill size with the amount of data we want to grab from the key.
size = sizeof(float);
// Get the data. userData is filled with the data. size returns
// with the amount of data grabbed.
thisKey->get((char*) userData,
&size, &status);
}
int main(int argc,char **argv)
{
if (argc < 2) {
printf("usage: %s ipAddress\n",argv[0]);
exit(1);
}
pfDCS *nav_dcs;
pfInit();
pfCAVEConfig(&argc,argv,NULL);
int arg;
CAVEFar = 1000;
pfuInitSmokes();
pfConfig();
pfCAVEInitChannels();
nav_dcs = create_scene(pfCAVEMasterChan());
/// -------------------------------------------------------------
/// CAVERN CAVERN CAVERN CAVERN CAVERN CAVERN
CAVERN CAVERN CAVERN
/// -------------------------------------------------------------
CAVERN_irb_c::status_t
irbStatus;
CAVERN_irbId_c
remoteIRBId;
CAVERN_irbChannel_c::status_t
channelRetStatus;
CAVERN_irbKey_c::status_t
keyStatus;
/// Startup CAVERN.
CAVERN_irb_c
*personalIRB = CAVERNInit(&argc,
&argv, NULL);
if (!personalIRB)
{
CAVEHalt();
pfExit();
return 0;
}
/// Create a channel over which communication will occur.
CAVERN_irbChannel_c
*aChannel = personalIRB->createChannel();
/// Open the channel to a remote IRB specified on the command line.
remoteIRBId.setAddress(argv[1]);
aChannel->open(&remoteIRBId,NULL,CAVERN_irbChannel_c::RELIABLE,
&channelRetStatus);
/// Define the local key (called A_KEY)
CAVERN_irbKeyId_c
aKeyId, remote_aKeyId;
aKeyId.setName("A_KEY");
remote_aKeyId.setName("A_KEY");
CAVERN_irbKey_c *aKey = personalIRB->define(&aKeyId, NULL, &irbStatus);
/// Notify me when A_KEY gets changed by a remote client.
float movement = 0;
aKey->trigger(A_keyCB,(void*)
&movement);
/// Create a link to link the local key named A_KEY with the remote key
/// also named A_KEY.
CAVERN_linkAttrib_c
linkAttribute;
CAVERN_irbLink_c
*aLink = aChannel->link(aKey, &remote_aKeyId, &linkAttribute);
if (aLink == NULL)
{
printf("Yo dude! The link didn't work!\n");
fflush(stdout);
}
/// -------------------------------------------------------------
while (!CAVEgetbutton(CAVE_ESCKEY)){
pfSync();
pfCAVEPreFrame();
pfFrame();
pfCAVEPostFrame();
pfVec3 eye;
pfCAVEGetPosition(CAVE_WAND,eye.vec);
eye.vec[0] = movement;
pfuSmokeOrigin(smoke,eye,0.25f);
}
CAVEHalt();
pfExit();
return 0;
}
int smoke_draw(pfTraverser *trav,void *data)
{
pfVec3 eye;
// pfCAVEGetPosition(CAVE_WAND,eye.vec);
CAVEGetPosition(CAVEEye,eye.vec);
pfuDrawSmokes(eye);
return PFTRAV_CONT;
}
#define SPEED 2.0f
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)
{
origin[0] = origin[2]
= 0; origin[1] = 5;
dir[0] = dir[2] =
1; dir[1] = 0;
smoke = pfuNewSmoke();
pfuSmokeType(smoke,PFUSMOKE_SMOKE);
pfuSmokeOrigin(smoke,origin,1.0f);
pfuSmokeVelocity(smoke,3.0f,0.2f);
pfuSmokeDir(smoke,dir);
pfuSmokeMode(smoke,PFUSMOKE_START);
pfuSmokeDuration(smoke,50000.0f);
pfuSmokeDensity(smoke,1,1,0.5);
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);
}