// --------------------------------------------------------------------------- // --------------------------------------------------------------------------- void LoadSceneScript (const char *ScriptName, CScene* pScene, vector<SDispCS> &DispCS, CVector &CameraStart, vector<CInstanceGroup*> &vIGs) { char nameIG[256]; float posx, posy, posz; float roti, rotj, rotk; FILE *f = fopen (CPath::lookup(ScriptName).c_str(),"rb"); fseek (f, 0, SEEK_END); uint file_size = ftell (f); fseek (f, 0, SEEK_SET); char *file_buf = (char*)malloc(file_size+1); if (fread (file_buf, 1, file_size, f) != file_size) nlwarning("Can't read %d elements", file_size); file_buf[file_size] = 0; ++file_size; fclose (f); char *buf_ptr = file_buf; sint nLastNbPlus = 0; vector<CInstanceGroup*> pile; pile.clear (); pile.push_back (pScene->getGlobalInstanceGroup()); pile.push_back (pScene->getGlobalInstanceGroup()); do { char Line[256], *line_ptr; sint nNbPlus = 0; line_ptr = &Line[0]; buf_ptr = readLine (line_ptr, buf_ptr); while ((*line_ptr == '\t') || (*line_ptr == ' ') || (*line_ptr == '+')) { if (*line_ptr == '+') ++nNbPlus; ++line_ptr; } if (strlen (line_ptr) == 0) continue; if (*line_ptr == '/') continue; posx = posy = posz = roti = rotj = rotk = 0.0f; sscanf (line_ptr, "%s %f %f %f %f %f %f", nameIG, &posx, &posy, &posz, &roti, &rotj, &rotk); if (stricmp (nameIG, "CAMERA_START") == 0) { CameraStart = CVector(posx, posy, posz); } else { if (nLastNbPlus >= nNbPlus) for (int i = 0; i < ((nLastNbPlus-nNbPlus)+1); ++i) pile.pop_back(); nLastNbPlus = nNbPlus; CInstanceGroup *father = pile.back(); CInstanceGroup *ITemp = LoadInstanceGroup (nameIG); if (ITemp != NULL) { SDispCS dcsTemp; dcsTemp.Name = ""; for (sint32 i = 0; i < (1+nNbPlus); ++i) dcsTemp.Name += " "; dcsTemp.Name += nameIG; dcsTemp.pIG = ITemp; DispCS.push_back (dcsTemp); ITemp->createRoot (*pScene); ITemp->setPos (CVector(posx, posy, posz)); ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::I, roti)); ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::J, rotj)); ITemp->setRotQuat (ITemp->getRotQuat() * CQuat(CVector::K, rotk)); ITemp->setClusterSystemForInstances (father); ITemp->addToScene (*pScene); vIGs.push_back (ITemp); } pile.push_back (ITemp); } } //while (strlen(buf_ptr) > 0); while (buf_ptr < (file_buf+file_size-1)); free (file_buf); }
/*********************************************************\ displayZone() \*********************************************************/ void displayZones() { const float zFarStep = 5.0f; const float tileNearStep = 10.0f; const float thresholdStep = 0.005f; ViewerCfg.TextContext.setHotSpot(CComputedString::MiddleMiddle); ViewerCfg.TextContext.setColor(CRGBA(255,255,255)); ViewerCfg.TextContext.setFontSize(20); CNELU::clearBuffers(CRGBA(0,0,0)); CNELU::swapBuffers(); // Create landscape CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Creating landscape..."); CNELU::swapBuffers(); Landscape = (CLandscapeModel*)CNELU::Scene->createModel(LandscapeModelId); Landscape->Landscape.setNoiseMode (ViewerCfg.LandscapeNoise); Landscape->Landscape.setTileNear(ViewerCfg.LandscapeTileNear); Landscape->Landscape.setThreshold(ViewerCfg.LandscapeThreshold); Landscape->Landscape.enableAutomaticLighting (ViewerCfg.AutoLight); Landscape->Landscape.setupAutomaticLightDir (ViewerCfg.LightDir); // Enable Additive Tiles. Landscape->enableAdditive(true); // HeightField. CBitmap heightBitmap; CIFile file(ViewerCfg.HeightFieldName); if( ViewerCfg.HeightFieldName!="" && heightBitmap.load(file) ) { CHeightMap heightMap; heightMap.buildFromBitmap(heightBitmap); heightMap.MaxZ= ViewerCfg.HeightFieldMaxZ; heightMap.OriginX= ViewerCfg.HeightFieldOriginX; heightMap.OriginY= ViewerCfg.HeightFieldOriginY; heightMap.SizeX = ViewerCfg.HeightFieldSizeX; heightMap.SizeY = ViewerCfg.HeightFieldSizeY; Landscape->Landscape.setHeightField(heightMap); } // Init TileBank. CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Initializing TileBanks..."); CNELU::swapBuffers(); try { CIFile bankFile (ViewerCfg.BanksPath + "/" + ViewerCfg.Bank); Landscape->Landscape.TileBank.serial(bankFile); } catch(Exception) { string tmp = string("Cant load bankfile ")+ViewerCfg.BanksPath + "/" + ViewerCfg.Bank; nlerror (tmp.c_str()); } if ((Landscape->Landscape.TileBank.getAbsPath ()=="")&&(ViewerCfg.TilesPath!="")) Landscape->Landscape.TileBank.setAbsPath (ViewerCfg.TilesPath + "/"); if (ViewerCfg.UseDDS) { Landscape->Landscape.TileBank.makeAllExtensionDDS(); } if (ViewerCfg.AllPathRelative) Landscape->Landscape.TileBank.makeAllPathRelative(); sint idx = (sint)ViewerCfg.Bank.find("."); string farBank = ViewerCfg.Bank.substr(0,idx); farBank += ".farbank"; try { CIFile farbankFile(ViewerCfg.BanksPath + "/" + farBank); Landscape->Landscape.TileFarBank.serial(farbankFile); } catch(Exception) { string tmp = string("Cant load bankfile ")+ViewerCfg.BanksPath + "/" + farBank; nlerror (tmp.c_str()); } if ( ! Landscape->Landscape.initTileBanks() ) { nlwarning( "You need to recompute bank.farbank for the far textures" ); } // Init light color CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Initializing Light..."); CNELU::swapBuffers(); Landscape->Landscape.setupStaticLight (ViewerCfg.LandDiffuse, ViewerCfg.LandAmbient, 1.1f); // Init collision manager CollisionManager.init( &(Landscape->Landscape), 200); // Preload of TileBank CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Loading TileBank..."); CNELU::swapBuffers(); for (int ts=0; ts<Landscape->Landscape.TileBank.getTileSetCount (); ts++) { CTileSet *tileSet=Landscape->Landscape.TileBank.getTileSet (ts); sint tl; for (tl=0; tl<tileSet->getNumTile128(); tl++) Landscape->Landscape.flushTiles (CNELU::Scene->getDriver(), (uint16)tileSet->getTile128(tl), 1); for (tl=0; tl<tileSet->getNumTile256(); tl++) Landscape->Landscape.flushTiles (CNELU::Scene->getDriver(), (uint16)tileSet->getTile256(tl), 1); for (tl=0; tl<CTileSet::count; tl++) Landscape->Landscape.flushTiles (CNELU::Scene->getDriver(), (uint16)tileSet->getTransition(tl)->getTile (), 1); } // Build zones. CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Loading zones..."); CNELU::swapBuffers(); uint32 i; for(i =0; i<ViewerCfg.Zones.size(); i++) { CZone zone; try { CIFile file(CPath::lookup(ViewerCfg.Zones[i])); zone.serial(file); file.close(); // Add it to landscape. Landscape->Landscape.addZone(zone); // Add it to collision manager. CollisionManager.addZone(zone.getZoneId()); } catch(Exception &e) { printf(e.what ()); } } // Load instance group. CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Loading objects..."); CNELU::swapBuffers(); for(i =0; i<ViewerCfg.Igs.size(); i++) { CInstanceGroup *group = new CInstanceGroup; try { CIFile file(CPath::lookup(ViewerCfg.Igs[i])); group->serial(file); file.close(); // Add it to the scene. group->addToScene (*CNELU::Scene); } catch(Exception &e) { printf(e.what ()); } } // Init collision Manager. CNELU::clearBuffers(CRGBA(0,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.5f,"Initializing collision manager..."); CNELU::swapBuffers(); CollisionManager.setCenter(ViewerCfg.Position); ViewerCfg.Position.z = 0.0f; CollisionManager.snapToGround( ViewerCfg.Position, 1000.0f ); // hide mouse cursor CNELU::Driver->showCursor(false); #ifdef NL_RELEASE CNELU::Driver->setCapture(true); #endif // Events management CNELU::EventServer.addEmitter(CNELU::Driver->getEventEmitter()); CNELU::AsyncListener.addToServer(CNELU::EventServer); MoveListener.init(CNELU::Scene, ViewerCfg.Width, ViewerCfg.Height, *CNELU::Camera); MoveListener.addToServer(CNELU::EventServer); MoveListener.setPos( ViewerCfg.Position ); CNELU::Camera->setPerspective (float(80.0*Pi/180.0), 1.33f, 0.1f, 1000.0f); bool showInfos = true; // initializing Z-Clip Far float left; float right; float bottom; float top; float znear; float zfar; CNELU::Camera->getFrustum(left, right, bottom, top, znear, zfar); zfar = ViewerCfg.ZFar; CNELU::Camera->setFrustum(left, right, bottom, top, znear, zfar); do { // Time mgt. //========== static sint64 t0 = (sint64)CTime::getLocalTime(); static sint64 t1 = (sint64)CTime::getLocalTime(); static sint64 ts = 0; t0 = t1; t1 = (sint64)CTime::getLocalTime(); sint64 dt64 = t1-t0; ts += dt64; float dt= ((float)dt64)*0.001f; CNELU::EventServer.pump(); // Manage movement and collision MoveListener.setLocalTime(CTime::getLocalTime()); CVector oldpos = MoveListener.getPos(); MoveListener.changeViewMatrix(); if(MoveListener.getMode()==CMoveListener::WALK) { CVector pos = MoveListener.getPos(); CollisionManager.snapToGround( pos , 1000.0f ); MoveListener.setPos( pos ); } CollisionManager.setCenter(MoveListener.getPos()); // Change move mode if(CNELU::AsyncListener.isKeyPushed(KeySPACE)) { MoveListener.swapMode(); } // Change displaying infos state if(CNELU::AsyncListener.isKeyPushed(KeyF1)) { showInfos = !showInfos; } // Change eyes height float eh = MoveListener.getEyesHeight(); if(CNELU::AsyncListener.isKeyPushed(KeyADD)) { ViewerCfg.EyesHeight.z += 0.1f; eh += 0.1f; } if(CNELU::AsyncListener.isKeyPushed(KeySUBTRACT)) { ViewerCfg.EyesHeight.z -= 0.1f; eh -= 0.1f; } if(ViewerCfg.EyesHeight.z<0.1f) ViewerCfg.EyesHeight.z = 0.1f; if(eh<0.1f) eh = 0.1f; MoveListener.setEyesHeight(eh); // Change TileNear float tileNear = Landscape->Landscape.getTileNear(); if(CNELU::AsyncListener.isKeyPushed(KeyHOME)) tileNear += tileNearStep; if(CNELU::AsyncListener.isKeyPushed(KeyEND)) tileNear -= tileNearStep; if(tileNear<0) tileNear = 0; Landscape->Landscape.setTileNear(tileNear); // Change Z-Far CNELU::Camera->getFrustum(left, right, bottom, top, znear, zfar); if(CNELU::AsyncListener.isKeyDown(KeyPRIOR)) zfar += zFarStep; if(CNELU::AsyncListener.isKeyDown(KeyNEXT)) zfar -= zFarStep; if(zfar<0) zfar = 0; CNELU::Camera->setFrustum(left, right, bottom, top, znear, zfar); // Change Threshold float threshold = Landscape->Landscape.getThreshold(); if(CNELU::AsyncListener.isKeyPushed(KeyINSERT)) threshold += thresholdStep; if(CNELU::AsyncListener.isKeyPushed(KeyDELETE)) threshold -= thresholdStep; if(threshold<0.001f) threshold = 0.001f; if(threshold>0.1f) threshold = 0.1f; Landscape->Landscape.setThreshold(threshold); // Switch between wired and filled scene display if(CNELU::AsyncListener.isKeyPushed(KeyF3)) { if (CNELU::Driver->getPolygonMode ()==IDriver::Filled) CNELU::Driver->setPolygonMode (IDriver::Line); else CNELU::Driver->setPolygonMode (IDriver::Filled); } // Switch between mouse move and keyboard-only move if(CNELU::AsyncListener.isKeyPushed(KeyRETURN)) { MoveListener.changeControlMode(); } // Render //======= CNELU::clearBuffers(ViewerCfg.Background); CNELU::Driver->clearZBuffer(); CNELU::Scene->render(); if(showInfos) { // black top quad CDRU::drawQuad(0,0.97f,1.0f,1.0f,*CNELU::Driver,CRGBA(0,0,0),CNELU::Scene->getViewport()); // black bottom quad CDRU::drawQuad(0,0,1.0f,0.03f,*CNELU::Driver,CRGBA(0,0,0),CNELU::Scene->getViewport()); ViewerCfg.TextContext.setFontSize(12); ViewerCfg.TextContext.setColor(CRGBA(255,255,255)); // Display fps. ViewerCfg.TextContext.printfAt(0.05f,0.98f,"%.1f fps",1/dt); // Display ms ViewerCfg.TextContext.printfAt(0.12f,0.98f,"%d ms",dt64); // Display Tile Near ViewerCfg.TextContext.printfAt(0.75f,0.98f,"Tile Near : %.1f",tileNear); //Display moving mode ViewerCfg.TextContext.setColor(CRGBA(255,0,0)); switch(MoveListener.getMode()) { case CMoveListener::WALK : ViewerCfg.TextContext.printfAt(0.5f,0.98f,"Walk Mode"); break; case CMoveListener::FREE : ViewerCfg.TextContext.printfAt(0.5f,0.98f,"Free-Look Mode"); break; default: break; } ViewerCfg.TextContext.setColor(CRGBA(255,255,255)); // Display Threshold ViewerCfg.TextContext.printfAt(0.3f,0.98f,"Threshold : %.3f",threshold); // Display Clip Far ViewerCfg.TextContext.printfAt(0.92f,0.98f,"Clip Far : %.1f",zfar); ViewerCfg.TextContext.setHotSpot(CComputedString::MiddleBottom); // Display current zone name CVector pos = MoveListener.getPos(); string zoneName = getZoneNameByCoord(pos.x, pos.y); ViewerCfg.TextContext.printfAt(0.3f,0.01f,"Zone : %s",zoneName.c_str()); // Position ViewerCfg.TextContext.printfAt(0.1f,0.01f,"Position : %d %d %d",(sint)pos.x,(sint)pos.y,(sint)pos.z); // Eyes height ViewerCfg.TextContext.printfAt(0.7f,0.01f,"Eyes : %.2f m",ViewerCfg.EyesHeight.z); // Display speed in km/h ViewerCfg.TextContext.setColor(CRGBA(255,0,0)); ViewerCfg.TextContext.printfAt(0.5f,0.01f,"Speed : %d km/h",(sint)(MoveListener.getSpeed()*3.6f)); ViewerCfg.TextContext.setColor(CRGBA(255,255,255)); // Heading sint heading = -(sint)(MoveListener.getRotZ()*180/Pi)%360; if(heading<0) heading += 360; ViewerCfg.TextContext.printfAt(0.9f,0.01f,"Heading : %d degrees",heading); // Display the cool compass. displayOrientation(); } CNELU::swapBuffers(); CNELU::screenshot(); } while(!CNELU::AsyncListener.isKeyPushed(KeyESCAPE)); ViewerCfg.Position = MoveListener.getPos(); CNELU::AsyncListener.removeFromServer(CNELU::EventServer); MoveListener.removeFromServer(CNELU::EventServer); CNELU::Driver->showCursor(true); #ifdef NL_RELEASE CNELU::Driver->setCapture(false); #endif }