#include #include #include #include #include #include #include #include #include #include #include "cache.h" struct _world { pfList *groupStack; pfGroup *currentGroup; cache *objectCache; }; static void parseLine(char *line,struct _world *world); static void addObject(char *line,struct _world *world); static void addObjectSequence(char *line,struct _world *world); static void addLight(char *line,struct _world *world); static void beginSCS(char *line,struct _world *world); static void endSCS(char *line,struct _world *world); static void pushGroup(pfGroup *group,struct _world *world); static void popGroup(struct _world *world); void loadWorld(char *worldFile,pfGroup *parent) { FILE *fp; char line[1024]; struct _world * world = new struct _world; fp = fopen(worldFile,"r"); if (!fp) { perror(worldFile); return; } world->groupStack = new pfList(sizeof(pfGroup *),4); world->currentGroup = parent; world->objectCache = new cache((cache::loadFunc)pfdLoadFile); while (fgets(line,1024,fp)) parseLine(line,world); fclose(fp); } static void parseLine(char *line,struct _world *world) { char type[256]; if (line[0] == '#') return; if (sscanf(line,"%s",type) > 0) { if (!strcasecmp(type,"object")) addObject(line,world); else if (!strcasecmp(type,"objectsequence")) addObjectSequence(line,world); else if (!strcasecmp(type,"light")) addLight(line,world); else if (!strcasecmp(type,"beginscs")) beginSCS(line,world); else if (!strcasecmp(type,"endscs")) endSCS(line,world); else if (!strcasecmp(type,"begingroup")) pushGroup(new pfGroup,world); else if (!strcasecmp(type,"endgroup")) popGroup(world); else fprintf(stderr,"loadWorld: Unknown token \"%s\"\n",type); } } static void addObject(char *line,struct _world *world) { char objectFile[256]; pfNode *obj; sscanf(line,"%*s%s", objectFile); if (obj = (pfNode*) world->objectCache->get(objectFile)) world->currentGroup->addChild(obj); } static void addObjectSequence(char *line,struct _world *world) { char objectPattern[256],objectFile[256]; int frame,startFrame=0,endFrame=0,step=1,numFrames,count; float duration=1.0; pfSequence *sequence; sscanf(line,"%*s%s%d%d%d%f", objectPattern, &startFrame, &endFrame, &step, &duration); if (step==0) { fprintf(stderr,"addObjectSequence: step of 0 is invalid\n"); return; } sequence = new pfSequence; world->currentGroup->addChild(sequence); numFrames = (endFrame+step - startFrame) / step; for (frame = startFrame, count=0; frame <= endFrame; frame += step) { pfNode *obj; sprintf(objectFile,objectPattern,frame); if (obj = (pfNode*) world->objectCache->get(objectFile)) { sequence->addChild(obj); sequence->setTime(count,duration/numFrames); count++; } } sequence->setDuration(1.0,-1); sequence->setMode(PFSEQ_START); } static void addLight(char *line,struct _world *world) { pfLightSource *light; float red=1.0,green=1.0,blue=1.0,xPos=0.0,yPos=0.0,zPos=0.0; sscanf(line,"%*s%f%f%f%f%f%f", &xPos, &yPos, &zPos, &red, &green, &blue); light = new pfLightSource; light->setPos(xPos,yPos,zPos,0.0); light->setColor(PFLT_DIFFUSE,red,green,blue); world->currentGroup->addChild(light); } static void beginSCS(char *line,struct _world *world) { float xPos=0.0,yPos=0.0,zPos=0.0,xRot=0.0,yRot=0.0,zRot=0.0,scale=1.0; pfCoord coord; pfMatrix matrix; pfSCS *scs; sscanf(line,"%*s%f%f%f%f%f%f%f", &xPos, &yPos, &zPos, &xRot, &yRot, &zRot, &scale); coord.xyz.set(xPos,yPos,zPos); coord.hpr.set(zRot,xRot,yRot); matrix.makeCoord(&coord); matrix.preScale(scale,scale,scale,matrix); scs = new pfSCS(matrix); pushGroup(scs,world); } static void endSCS(char *,struct _world *world) { popGroup(world); } static void pushGroup(pfGroup *group,struct _world *world) { world->groupStack->add(world->currentGroup); world->currentGroup->addChild(group); world->currentGroup = group; } static void popGroup(struct _world *world) { int last = world->groupStack->getNum() - 1; world->currentGroup = (pfGroup *) world->groupStack->get(last); world->groupStack->removeIndex(last); }