Ogre::String TerrainGeometryManager::getPageHeightmap(int x, int z) { DataStreamPtr ds = getPageConfig(x, z); if (ds.isNull()) return ""; char buf[4096]; ds->readLine(buf, 4096); return String(buf); }
//----------------------------------------------------------------------- void OldMaterialReader::parseScript(DataStreamPtr& stream) { String line; MaterialPtr pMat; char tempBuf[512]; while(!stream->eof()) { line = stream->getLine(); // Ignore comments & blanks if (!(line.length() == 0 || line.substr(0,2) == "//")) { if (pMat.isNull()) { // No current material // So first valid data should be a material name pMat = MaterialManager::getSingleton().create(line, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); // Skip to and over next { stream->readLine(tempBuf, 511, "{"); } else { // Already in a material if (line == "}") { // Finished material pMat.setNull(); } else if (line == "{") { // new pass parseNewTextureLayer(stream, pMat); } else { // Attribute StringUtil::toLowerCase(line); parseAttrib(line, pMat); } } } } }
//----------------------------------------------------------------------- void RenderSystemCapabilitiesSerializer::parseScript(DataStreamPtr& stream) { // reset parsing data to NULL mCurrentLineNumber = 0; mCurrentLine = 0; mCurrentStream.reset(); mCurrentCapabilities = 0; mCurrentStream = stream; // parser operating data String line; ParseAction parseAction = PARSE_HEADER; StringVector tokens; bool parsedAtLeastOneRSC = false; // collect capabilities lines (i.e. everything that is not header, "{", "}", // comment or empty line) for further processing CapabilitiesLinesList capabilitiesLines; // for reading data char tmpBuf[OGRE_STREAM_TEMP_SIZE]; // TODO: build a smarter tokenizer so that "{" and "}" // don't need separate lines while (!stream->eof()) { stream->readLine(tmpBuf, OGRE_STREAM_TEMP_SIZE-1); line = String(tmpBuf); StringUtil::trim(line); // keep track of parse position mCurrentLine = &line; mCurrentLineNumber++; tokens = StringUtil::split(line); // skip empty and comment lines // TODO: handle end of line comments if (tokens[0] == "" || tokens[0].substr(0,2) == "//") continue; switch (parseAction) { // header line must look like this: // render_system_capabilities "Vendor Card Name Version xx.xxx" case PARSE_HEADER: if(tokens[0] != "render_system_capabilities") { logParseError("The first keyword must be render_system_capabilities. RenderSystemCapabilities NOT created!"); return; } else { // the rest of the tokens are irrevelant, beause everything between "..." is one name String rscName = line.substr(tokens[0].size()); StringUtil::trim(rscName); // the second argument must be a "" delimited string if (!StringUtil::match(rscName, "\"*\"")) { logParseError("The argument to render_system_capabilities must be a quote delimited (\"...\") string. RenderSystemCapabilities NOT created!"); return; } else { // we have a valid header // remove quotes rscName = rscName.substr(1); rscName = rscName.substr(0, rscName.size() - 1); // create RSC mCurrentCapabilities = OGRE_NEW RenderSystemCapabilities(); // RSCManager is responsible for deleting mCurrentCapabilities RenderSystemCapabilitiesManager::getSingleton()._addRenderSystemCapabilities(rscName, mCurrentCapabilities); LogManager::getSingleton().logMessage("Created RenderSystemCapabilities" + rscName); // do next action parseAction = FIND_OPEN_BRACE; parsedAtLeastOneRSC = true; } } break; case FIND_OPEN_BRACE: if (tokens[0] != "{" || tokens.size() != 1) { logParseError("Expected '{' got: " + line + ". Continuing to next line."); } else { parseAction = COLLECT_LINES; } break; case COLLECT_LINES: if (tokens[0] == "}") { // this render_system_capabilities section is over // let's process the data and look for the next one parseCapabilitiesLines(capabilitiesLines); capabilitiesLines.clear(); parseAction = PARSE_HEADER; } else capabilitiesLines.push_back(CapabilitiesLinesList::value_type(line, mCurrentLineNumber)); break; } } // Datastream is empty // if we are still looking for header, this means that we have either // finished reading one, or this is an empty file if(parseAction == PARSE_HEADER && parsedAtLeastOneRSC == false) { logParseError ("The file is empty"); } if(parseAction == FIND_OPEN_BRACE) { logParseError ("Bad .rendercaps file. Were not able to find a '{'"); } if(parseAction == COLLECT_LINES) { logParseError ("Bad .rendercaps file. Were not able to find a '}'"); } }
// if terrain is set, we operate on the already loaded terrain void TerrainGeometryManager::loadLayers(int x, int z, Terrain *terrain) { if (pageConfigFormat.empty()) return; DataStreamPtr ds = getPageConfig(x, z); if (ds.isNull()) return; char line[4096]; ds->readLine(line, 4096); String heightmapImage = String(line); ds->readLine(line, 4096); terrainLayers = PARSEINT(String(line)); if (terrainLayers == 0) return; Ogre::Terrain::ImportData &defaultimp = mTerrainGroup->getDefaultImportSettings(); if (!terrain) defaultimp.layerList.resize(terrainLayers); blendInfo.clear(); blendInfo.resize(terrainLayers); int layer = 0; while (!ds->eof()) { size_t ll = ds->readLine(line, 4096); if (ll==0 || line[0]=='/' || line[0]==';') continue; StringVector args = StringUtil::split(String(line), ","); if (args.size() < 3) { LOG("invalid page config line: '" + String(line) + "'"); continue; } StringUtil::trim(args[1]); StringUtil::trim(args[2]); float worldSize = PARSEREAL(args[0]); if (!terrain) { defaultimp.layerList[layer].worldSize = worldSize; defaultimp.layerList[layer].textureNames.push_back(args[1]); defaultimp.layerList[layer].textureNames.push_back(args[2]); } else { terrain->setLayerWorldSize(layer, worldSize); terrain->setLayerTextureName(layer, 0, args[1]); terrain->setLayerTextureName(layer, 1, args[2]); } blendLayerInfo_t &bi = blendInfo[layer]; bi.blendMode = 'R'; bi.alpha = 'R'; if (args.size() > 3) { StringUtil::trim(args[3]); bi.blendMapTextureFilename = args[3]; } if (args.size() > 4) { StringUtil::trim(args[4]); bi.blendMode = args[4][0]; } if (args.size() > 5) bi.alpha = PARSEREAL(args[5]); layer++; if (layer >= terrainLayers) break; } LOG("done loading page: loaded " + TOSTRING(layer) + " layers"); }
Airfoil::Airfoil(Ogre::String const& fname) { for (int i = 0; i < 3601; i++) //init in case of bad things { cl[i] = 0; cd[i] = 0; cm[i] = 0; } char line[1024]; //we load directly X-Plane AFL file format!!! bool process = false; bool neg = true; int lastia = -1; ResourceGroupManager& rgm = ResourceGroupManager::getSingleton(); String group = ""; try { group = rgm.findGroupContainingResource(fname); } catch (...) { } if (group == "") { LOG(String("Airfoil error: could not load airfoil ")+fname); return; } DataStreamPtr ds = rgm.openResource(fname, group); while (!ds->eof()) { size_t ll = ds->readLine(line, 1023); if (ll == 0) continue; // fscanf(fd," %[^\n\r]",line); if (!strncmp("alpha", line, 5)) { process = true; continue; }; if (process) { float l, d, m; int a, b; sscanf(line, "%i.%i %f %f %f", &a, &b, &l, &d, &m); if (neg) b = -b; if (a == 0 && b == 0) neg = false; int ia = (a * 10 + b) + 1800; if (ia == 3600) { process = false; }; cl[ia] = l; cd[ia] = d; cm[ia] = m; if (lastia != -1 && ia - lastia > 1) { //we have to interpolate previous elements (linear interpolation) int i; for (i = 0; i < ia - lastia - 1; i++) { cl[lastia + 1 + i] = cl[lastia] + (float)(i + 1) * (cl[ia] - cl[lastia]) / (float)(ia - lastia); cd[lastia + 1 + i] = cd[lastia] + (float)(i + 1) * (cd[ia] - cd[lastia]) / (float)(ia - lastia); cm[lastia + 1 + i] = cm[lastia] + (float)(i + 1) * (cm[ia] - cm[lastia]) / (float)(ia - lastia); } } lastia = ia; } } }
//----------------------------------------------------------------------- void Quake3ShaderManager::parseScript(DataStreamPtr& stream, const String& group) { String line; Quake3Shader* pShader; char tempBuf[512]; pShader = 0; bool dummy = false; while(!stream->eof()) { line = stream->getLine(); // Ignore comments & blanks if (!(line.length() == 0 || line.substr(0,2) == "//")) { if (pShader == 0) { // No current shader if (getByName(line) == 0) { dummy = false; } else { // Defined before, parse but ignore // Q3A has duplicates in shaders, doh dummy = true; } // So first valid data should be a shader name pShader = create(line); // Skip to and over next { stream->readLine(tempBuf, 511, "{"); } else { // Already in a shader if (line == "}") { // Finished shader if (dummy && pShader) { OGRE_DELETE pShader; } pShader = 0; } else if (line == "{") { // new pass parseNewShaderPass(stream, pShader); } else { // Attribute StringUtil::toLowerCase(line); parseShaderAttrib(line, pShader); } } } } }
void TerrainObjectManager::loadObjectConfigFile(Ogre::String odefname) { proceduralManager = new ProceduralManager(); objcounter = 0; free_localizer = 0; ProceduralObject po; po.loadingState = -1; int r2oldmode = 0; int lastprogress = -1; bool proroad = false; DataStreamPtr ds; try { ds = ResourceGroupManager::getSingleton().openResource(odefname, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); } catch(...) { LOG("Error opening object configuration: " + odefname); return; } int mapsizex = terrainManager->getGeometryManager()->getMaxTerrainSize().x; int mapsizez = terrainManager->getGeometryManager()->getMaxTerrainSize().z; Vector3 r2lastpos=Vector3::ZERO; Quaternion r2lastrot=Quaternion::IDENTITY; int r2counter=0; //long line = 0; char line[4096] = ""; while (!ds->eof()) { int progress = ((float)(ds->tell()) / (float)(ds->size())) * 100.0f; if (progress-lastprogress > 20) { #ifdef USE_MYGUI LoadingWindow::getSingleton().setProgress(progress, _L("Loading Terrain Objects")); #endif //MYGUI lastprogress = progress; } char oname[1024] = {}; char type[256] = {}; char name[256] = {}; Vector3 pos(Vector3::ZERO); Vector3 rot(Vector3::ZERO); size_t ll = ds->readLine(line, 1023); if (line[0]=='/' || line[0]==';' || ll==0) continue; //comments if (!strcmp("end",line)) break; if (!strncmp(line,"collision-tris", 14)) { long amount = Collisions::MAX_COLLISION_TRIS; sscanf(line, "collision-tris %ld", &amount); gEnv->collisions->resizeMemory(amount); } if (!strncmp(line,"grid", 4)) { sscanf(line, "grid %f, %f, %f", &pos.x, &pos.y, &pos.z); Ogre::ColourValue BackgroundColour = Ogre::ColourValue::White;//Ogre::ColourValue(0.1337f, 0.1337f, 0.1337f, 1.0f); Ogre::ColourValue GridColour = Ogre::ColourValue(0.2f, 0.2f, 0.2f, 1.0f); Ogre::ManualObject *mReferenceObject = new Ogre::ManualObject("ReferenceGrid"); mReferenceObject->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST); Ogre::Real step = 1.0f; unsigned int count = 50; unsigned int halfCount = count / 2; Ogre::Real full = (step * count); Ogre::Real half = full / 2; Ogre::Real y = 0; Ogre::ColourValue c; for (unsigned i=0;i < count+1;i++) { if (i == halfCount) c = Ogre::ColourValue(1,0,0,1.0f); else c = GridColour; mReferenceObject->position(-half,y,-half+(step*i)); mReferenceObject->colour(BackgroundColour); mReferenceObject->position(0,y,-half+(step*i)); mReferenceObject->colour(c); mReferenceObject->position(0,y,-half+(step*i)); mReferenceObject->colour(c); mReferenceObject->position(half,y,-half+(step*i)); mReferenceObject->colour(BackgroundColour); if (i == halfCount) c = Ogre::ColourValue(0,0,1,1.0f); else c = GridColour; mReferenceObject->position(-half+(step*i),y,-half); mReferenceObject->colour(BackgroundColour); mReferenceObject->position(-half+(step*i),y,0); mReferenceObject->colour(c); mReferenceObject->position(-half+(step*i),y,0); mReferenceObject->colour(c); mReferenceObject->position(-half+(step*i),y, half); mReferenceObject->colour(BackgroundColour); } mReferenceObject->end(); mReferenceObject->setCastShadows(false); SceneNode *n = gEnv->sceneManager->getRootSceneNode()->createChildSceneNode(); n->setPosition(pos); n->attachObject(mReferenceObject); n->setVisible(true); } #ifdef USE_PAGED //ugly stuff to parse trees :) if (!strncmp("trees", line, 5)) { if (terrainManager->getPagedMode() == 0) continue; char ColorMap[256] = {}; char DensityMap[256] = {}; char treemesh[256] = {}; char treeCollmesh[256] = {}; float gridspacing = 0.0f; float yawfrom = 0.0f, yawto = 0.0f; float scalefrom = 0.0f, scaleto = 0.0f; float highdens = 1.0f; int minDist = 90, maxDist = 700; sscanf(line, "trees %f, %f, %f, %f, %f, %d, %d, %s %s %s %f %s", &yawfrom, &yawto, &scalefrom, &scaleto, &highdens, &minDist, &maxDist, treemesh, ColorMap, DensityMap, &gridspacing, treeCollmesh); if (strnlen(ColorMap, 3) == 0) { LOG("tree ColorMap map zero!"); continue; } if (strnlen(DensityMap, 3) == 0) { LOG("tree DensityMap zero!"); continue; } Forests::DensityMap *densityMap = Forests::DensityMap::load(DensityMap, Forests::CHANNEL_COLOR); if (!densityMap) { LOG("could not load densityMap: "+String(DensityMap)); continue; } densityMap->setFilter(Forests::MAPFILTER_BILINEAR); //densityMap->setMapBounds(TRect(0, 0, mapsizex, mapsizez)); paged_geometry_t paged; paged.geom = new PagedGeometry(); paged.geom->setTempDir(SSETTING("User Path", "") + "cache" + SSETTING("dirsep", "\\")); paged.geom->setCamera(gEnv->mainCamera); paged.geom->setPageSize(50); paged.geom->setInfinite(); Ogre::TRect<Ogre::Real> bounds = TBounds(0, 0, mapsizex, mapsizez); paged.geom->setBounds(bounds); //Set up LODs //trees->addDetailLevel<EntityPage>(50); float min = minDist * terrainManager->getPagedDetailFactor(); if (min<10) min = 10; paged.geom->addDetailLevel<BatchPage>(min, min/2); float max = maxDist * terrainManager->getPagedDetailFactor(); if (max<10) max = 10; paged.geom->addDetailLevel<ImpostorPage>(max, max/10); TreeLoader2D *treeLoader = new TreeLoader2D(paged.geom, TBounds(0, 0, mapsizex, mapsizez)); paged.geom->setPageLoader(treeLoader); treeLoader->setHeightFunction(&getTerrainHeight); if (String(ColorMap) != "none") { treeLoader->setColorMap(ColorMap); } Entity *curTree = gEnv->sceneManager->createEntity(String("paged_")+treemesh+TOSTRING(pagedGeometry.size()), treemesh); if (gridspacing > 0) { // grid style for (float x=0; x < mapsizex; x += gridspacing) { for (float z=0; z < mapsizez; z += gridspacing) { float density = densityMap->_getDensityAt_Unfiltered(x, z, bounds); if (density < 0.8f) continue; float nx = x + gridspacing * 0.5f; float nz = z + gridspacing * 0.5f; float yaw = Math::RangeRandom(yawfrom, yawto); float scale = Math::RangeRandom(scalefrom, scaleto); Vector3 pos = Vector3(nx, 0, nz); treeLoader->addTree(curTree, pos, Degree(yaw), (Ogre::Real)scale); if (strlen(treeCollmesh)) { pos.y = gEnv->terrainManager->getHeightFinder()->getHeightAt(pos.x, pos.z); scale *= 0.1f; gEnv->collisions->addCollisionMesh(String(treeCollmesh), pos, Quaternion(Degree(yaw), Vector3::UNIT_Y), Vector3(scale, scale, scale)); } } } } else { float gridsize = 10; if (gridspacing < 0 && gridspacing != 0) { gridsize = -gridspacing; } float hd = highdens; // normal style, random for (float x=0; x < mapsizex; x += gridsize) { for (float z=0; z < mapsizez; z += gridsize) { if (highdens < 0) hd = Math::RangeRandom(0, -highdens); float density = densityMap->_getDensityAt_Unfiltered(x, z, bounds); int numTreesToPlace = (int)((float)(hd) * density * terrainManager->getPagedDetailFactor()); float nx=0, nz=0; while(numTreesToPlace-->0) { nx = Math::RangeRandom(x, x + gridsize); nz = Math::RangeRandom(z, z + gridsize); float yaw = Math::RangeRandom(yawfrom, yawto); float scale = Math::RangeRandom(scalefrom, scaleto); Vector3 pos = Vector3(nx, 0, nz); treeLoader->addTree(curTree, pos, Degree(yaw), (Ogre::Real)scale); if (strlen(treeCollmesh)) { pos.y = gEnv->terrainManager->getHeightFinder()->getHeightAt(pos.x, pos.z); gEnv->collisions->addCollisionMesh(String(treeCollmesh),pos, Quaternion(Degree(yaw), Vector3::UNIT_Y), Vector3(scale, scale, scale)); } } } } } paged.loader = (void*)treeLoader; pagedGeometry.push_back(paged); } //ugly stuff to parse grass :) if (!strncmp("grass", line, 5) || !strncmp("grass2", line, 6)) { // is paged geometry disabled by configuration? if (terrainManager->getPagedMode() == 0) continue; int range = 80; float SwaySpeed=0.5, SwayLength=0.05, SwayDistribution=10.0, minx=0.2, miny=0.2, maxx=1, maxy=0.6, Density=0.6, minH=-9999, maxH=9999; char grassmat[256]=""; char colorMapFilename[256]=""; char densityMapFilename[256]=""; int growtechnique = 0; int techn = GRASSTECH_CROSSQUADS; if (!strncmp("grass2", line, 6)) sscanf(line, "grass2 %d, %f, %f, %f, %f, %f, %f, %f, %f, %d, %f, %f, %d, %s %s %s", &range, &SwaySpeed, &SwayLength, &SwayDistribution, &Density, &minx, &miny, &maxx, &maxy, &growtechnique, &minH, &maxH, &techn, grassmat, colorMapFilename, densityMapFilename); else if (!strncmp("grass", line, 5)) sscanf(line, "grass %d, %f, %f, %f, %f, %f, %f, %f, %f, %d, %f, %f, %s %s %s", &range, &SwaySpeed, &SwayLength, &SwayDistribution, &Density, &minx, &miny, &maxx, &maxy, &growtechnique, &minH, &maxH, grassmat, colorMapFilename, densityMapFilename); //Initialize the PagedGeometry engine try { paged_geometry_t paged; PagedGeometry *grass = new PagedGeometry(gEnv->mainCamera, 30); //Set up LODs grass->addDetailLevel<GrassPage>(range * terrainManager->getPagedDetailFactor()); // original value: 80 //Set up a GrassLoader for easy use GrassLoader *grassLoader = new GrassLoader(grass); grass->setPageLoader(grassLoader); grassLoader->setHeightFunction(&getTerrainHeight); // render grass at first grassLoader->setRenderQueueGroup(RENDER_QUEUE_MAIN-1); GrassLayer* grassLayer = grassLoader->addLayer(grassmat); grassLayer->setHeightRange(minH, maxH); grassLayer->setLightingEnabled(true); grassLayer->setAnimationEnabled((SwaySpeed>0)); grassLayer->setSwaySpeed(SwaySpeed); grassLayer->setSwayLength(SwayLength); grassLayer->setSwayDistribution(SwayDistribution); //String grassdensityTextureFilename = String(DensityMap); grassLayer->setDensity(Density * terrainManager->getPagedDetailFactor()); if (techn>10) grassLayer->setRenderTechnique(static_cast<GrassTechnique>(techn-10), true); else grassLayer->setRenderTechnique(static_cast<GrassTechnique>(techn), false); grassLayer->setMapBounds(TBounds(0, 0, mapsizex, mapsizez)); if (strcmp(colorMapFilename,"none") != 0) { grassLayer->setColorMap(colorMapFilename); grassLayer->setColorMapFilter(MAPFILTER_BILINEAR); } if (strcmp(densityMapFilename,"none") != 0) { grassLayer->setDensityMap(densityMapFilename); grassLayer->setDensityMapFilter(MAPFILTER_BILINEAR); } //grassLayer->setMinimumSize(0.5,0.5); //grassLayer->setMaximumSize(1.0, 1.0); grassLayer->setMinimumSize(minx, miny); grassLayer->setMaximumSize(maxx, maxy); // growtechnique if (growtechnique == 0) grassLayer->setFadeTechnique(FADETECH_GROW); else if (growtechnique == 1) grassLayer->setFadeTechnique(FADETECH_ALPHAGROW); else if (growtechnique == 2) grassLayer->setFadeTechnique(FADETECH_ALPHA); paged.geom = grass; paged.loader = (void*)grassLoader; pagedGeometry.push_back(paged); } catch(...) { LOG("error loading grass!"); } continue; } #endif //USE_PAGED { // ugly stuff to parse procedural roads if (!strncmp("begin_procedural_roads", line, 22)) { po = ProceduralObject(); po.loadingState = 1; r2oldmode = 1; proroad = true; continue; } if (!strncmp("end_procedural_roads", line, 20)) { if (r2oldmode) { if (proceduralManager) proceduralManager->addObject(po); po = ProceduralObject(); } proroad = false; continue; } if (proroad) { float rwidth, bwidth, bheight; //position x,y,z rotation rx,ry,rz, width, border width, border height, type int r = sscanf(line, "%f, %f, %f, %f, %f, %f, %f, %f, %f, %s",&pos.x,&pos.y,&pos.z, &rot.x, &rot.y, &rot.z, &rwidth, &bwidth, &bheight, oname); Quaternion rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X)*Quaternion(Degree(rot.y), Vector3::UNIT_Y)*Quaternion(Degree(rot.z), Vector3::UNIT_Z); int roadtype=Road2::ROAD_AUTOMATIC; int pillartype = 0; if (!strcmp(oname, "flat")) roadtype=Road2::ROAD_FLAT; if (!strcmp(oname, "left")) roadtype=Road2::ROAD_LEFT; if (!strcmp(oname, "right")) roadtype=Road2::ROAD_RIGHT; if (!strcmp(oname, "both")) roadtype=Road2::ROAD_BOTH; if (!strcmp(oname, "bridge")) {roadtype=Road2::ROAD_BRIDGE;pillartype=1;} if (!strcmp(oname, "monorail")) {roadtype=Road2::ROAD_MONORAIL;pillartype=2;} if (!strcmp(oname, "monorail2")) {roadtype=Road2::ROAD_MONORAIL;pillartype=0;} if (!strcmp(oname, "bridge_no_pillars")) {roadtype=Road2::ROAD_BRIDGE;pillartype=0;} if (r2oldmode) { //fill object ProceduralPoint pp; pp.bheight = bheight; pp.bwidth = bwidth; pp.pillartype = pillartype; pp.position = pos; pp.rotation = rotation; pp.type = roadtype; pp.width = rwidth; po.points.push_back(pp); } continue; } } //end of the ugly (somewhat) strcpy(name, "generic"); memset(oname, 0, 255); memset(type, 0, 255); memset(name, 0, 255); int r = sscanf(line, "%f, %f, %f, %f, %f, %f, %s %s %s",&pos.x,&pos.y,&pos.z, &rot.x, &rot.y, &rot.z, oname, type, name); if (r < 6) continue; if ((!strcmp(oname, "truck")) || (!strcmp(oname, "load") || (!strcmp(oname, "machine")) || (!strcmp(oname, "boat")) || (!strcmp(oname, "truck2")) )) { if (!strcmp(oname, "boat") && !terrainManager->getWater()) { // no water so do not load boats! continue; } String group = ""; String truckname(type); if (!RoR::Application::GetCacheSystem()->checkResourceLoaded(truckname, group)) { LOG("Error while loading Terrain: truck " + String(type) + " not found. ignoring."); continue; } truck_prepare_t tempTruckPreload; //this is a truck or load declaration tempTruckPreload.px = pos.x; tempTruckPreload.py = pos.y; tempTruckPreload.pz = pos.z; tempTruckPreload.freePosition = (!strcmp(oname, "truck2")); tempTruckPreload.ismachine = (!strcmp(oname, "machine")); tempTruckPreload.rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X)*Quaternion(Degree(rot.y), Vector3::UNIT_Y)*Quaternion(Degree(rot.z), Vector3::UNIT_Z); strcpy(tempTruckPreload.name, truckname.c_str()); truck_preload.push_back(tempTruckPreload); continue; } if ( !strcmp(oname, "road") || !strcmp(oname, "roadborderleft") || !strcmp(oname, "roadborderright") || !strcmp(oname, "roadborderboth") || !strcmp(oname, "roadbridgenopillar") || !strcmp(oname, "roadbridge")) { int pillartype = !(strcmp(oname, "roadbridgenopillar") == 0); // okay, this is a job for roads2 int roadtype=Road2::ROAD_AUTOMATIC; if (!strcmp(oname, "road")) roadtype=Road2::ROAD_FLAT; Quaternion rotation; rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X)*Quaternion(Degree(rot.y), Vector3::UNIT_Y)*Quaternion(Degree(rot.z), Vector3::UNIT_Z); if (pos.distance(r2lastpos) > 20.0f) { // break the road if (r2oldmode != 0) { // fill object ProceduralPoint pp; pp.bheight = 0.2; pp.bwidth = 1.4; pp.pillartype = pillartype; pp.position = r2lastpos + r2lastrot * Vector3(10.0f, 0.0f, 0.9f); pp.rotation = r2lastrot; pp.type = roadtype; pp.width = 8; po.points.push_back(pp); // finish it and start new object if (proceduralManager) proceduralManager->addObject(po); po = ProceduralObject(); r2oldmode = 1; } r2oldmode = 1; // beginning of new ProceduralPoint pp; pp.bheight = 0.2; pp.bwidth = 1.4; pp.pillartype = pillartype; pp.position = pos; pp.rotation = rotation; pp.type = roadtype; pp.width = 8; po.points.push_back(pp); } else { // fill object ProceduralPoint pp; pp.bheight = 0.2; pp.bwidth = 1.4; pp.pillartype = pillartype; pp.position = pos; pp.rotation = rotation; pp.type = roadtype; pp.width = 8; po.points.push_back(pp); } r2lastpos=pos; r2lastrot=rotation; continue; } loadObject(oname, pos, rot, bakeNode, name, type); } // ds closes automatically, so do not close it explicitly here: ds->close(); // finish the last road if (r2oldmode != 0) { // fill object ProceduralPoint pp; pp.bheight = 0.2; pp.bwidth = 1.4; pp.pillartype = 1; pp.position = r2lastpos+r2lastrot*Vector3(10.0,0,0); pp.rotation = r2lastrot; pp.type = Road2::ROAD_AUTOMATIC; pp.width = 8; po.points.push_back(pp); // finish it and start new object if (proceduralManager) proceduralManager->addObject(po); } }