int Landusemap::loadConfig(Ogre::String filename) { Vector3 mapsize = gEnv->terrainManager->getMaxTerrainSize(); std::map<unsigned int, String> usemap; String textureFilename = ""; LOG("Parsing landuse config: '"+filename+"'"); String group = ""; try { group = ResourceGroupManager::getSingleton().findGroupContainingResource(filename); }catch(...) { // we wont catch anything, since the path could be absolute as well, then the group is not found } Ogre::ConfigFile cfg; try { // try to load directly otherwise via resource group if (group == "") cfg.loadDirect(filename); else cfg.loadFromResourceSystem(filename, group, "\x09:=", true); } catch(Ogre::Exception& e) { ErrorUtils::ShowError(_L("Error while loading landuse config"), e.getFullDescription()); return 1; } Ogre::ConfigFile::SectionIterator seci = cfg.getSectionIterator(); Ogre::String secName, kname, kvalue; while (seci.hasMoreElements()) { secName = seci.peekNextKey(); Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext(); Ogre::ConfigFile::SettingsMultiMap::iterator i; for (i = settings->begin(); i != settings->end(); ++i) { kname = i->first; kvalue = i->second; // we got all the data available now, processing now if (secName == "general" || secName == "config") { // set some class properties accoring to the information in this section if (kname == "texture") textureFilename = kvalue; else if (kname == "frictionconfig" || kname == "loadGroundModelsConfig") gEnv->collisions->loadGroundModelsConfigFile(kvalue); else if (kname == "defaultuse") default_ground_model = gEnv->collisions->getGroundModelByString(kvalue); } else if (secName == "use-map") { if (kname.size() != 10) { LOG("invalid color in landuse line in " + filename); continue; } char *ptr; //not used unsigned int color = strtoul(kname.c_str(), &ptr, 16); usemap[color] = kvalue; } } } #ifdef USE_PAGED // process the config data and load the buffers finally try { Forests::ColorMap *colourMap = Forests::ColorMap::load(textureFilename, Forests::CHANNEL_COLOR); colourMap->setFilter(Forests::MAPFILTER_NONE); /* // debug things below printf("found ground use definitions:\n"); for (std::map < uint32, String >::iterator it=usemap.begin(); it!=usemap.end(); it++) { printf(" 0x%Lx : %s\n", it->first, it->second.c_str()); } */ bool bgr = colourMap->getPixelBox().format == PF_A8B8G8R8; Ogre::TRect<Ogre::Real> bounds = Forests::TBounds(0, 0, mapsize.x, mapsize.z); // now allocate the data buffer to hold pointers to ground models data = new ground_model_t*[(int)(mapsize.x * mapsize.z)]; ground_model_t **ptr = data; //std::map < String, int > counters; for (int z=0; z<mapsize.z; z++) { for (int x=0; x<mapsize.x; x++) { unsigned int col = colourMap->getColorAt(x, z, bounds); if (bgr) { // Swap red and blue values unsigned int cols = col & 0xFF00FF00; cols |= (col & 0xFF) << 16; cols |= (col & 0xFF0000) >> 16; col = cols; } String use = usemap[col]; //if (use!="") // counters[use]++; // store the pointer to the ground model in the data slot *ptr = gEnv->collisions->getGroundModelByString(use); ptr++; } } } catch (...) { Log("Landuse: Failed to load texture: " + textureFilename); } #endif // USE_PAGED return 0; }
// ------------------------------------------------------------------------- void Terrain_Demo::init(Ogre::Root *root, Ogre::RenderWindow *win, OgreBulletApplication *application) { mCameraMove = 1; mHelpKeys.clear(); mHelpKeys.push_back(BASIC_HELP_INFO0); mHelpKeys.push_back(BASIC_HELP_INFO1); mHelpKeys.push_back(BASIC_HELP_INFO2); mHelpKeys.push_back(BASIC_HELP_INFO3); mHelpKeys.push_back(BASIC_HELP_INFO4); mHelpKeys.push_back(BASIC_HELP_INFO5); mHelpKeys.push_back(BASIC_HELP_INFO6); mHelpKeys.push_back("Use Arrow Key to move Car."); // reset for (int i = 0; i < 4; i++) { mWheelsEngine[i] = 0; mWheelsSteerable[i] = 0; } mWheelsEngineCount = 2; mWheelsEngine[0] = 0; mWheelsEngine[1] = 1; mWheelsEngine[2] = 2; mWheelsEngine[3] = 3; mWheelsSteerableCount = 2; mWheelsSteerable[0] = 0; mWheelsSteerable[1] = 1; //mWheelsSteerable[2] = 2; //mWheelsSteerable[3] = 3; mWheelEngineStyle = 0; mWheelSteeringStyle = 0; mSteeringLeft = false; mSteeringRight = false; mEngineForce = 0; mSteering = 0; // ------------------------ // Start OgreScene mSceneMgr = root->createSceneManager("TerrainSceneManager", "BulletTerrain"); mCamera = mSceneMgr->createCamera("Cam"); //mCamera->setFOVy(Degree(90)); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(1000); Viewport *vp = win->addViewport(mCamera); vp->setBackgroundColour(ColourValue(0,0,0)); // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio( Real(vp->getActualWidth()) / Real(vp->getActualHeight())); mCamera->setPosition(CameraStart + terrain_Shift); mCamera->lookAt(CarPosition + terrain_Shift); // Create a terrain std::string terrain_cfg("terrain.cfg"); mSceneMgr->setWorldGeometry(terrain_cfg); OgreBulletListener::init(root, win, application); // ------------------------ // add lights setBasicLight(); // ------------------------ // Add the Gui setPhysicGUI(); // ------------------------ // Start Bullet initWorld(); // ------------------------ // Add the ground // 0.1, 0.8 //addStaticPlane(0.3, 0.8); { Ogre::ConfigFile config; config.loadFromResourceSystem(terrain_cfg, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, "=", true); unsigned page_size = Ogre::StringConverter::parseUnsignedInt(config.getSetting("PageSize")); Ogre::Vector3 terrainScale(Ogre::StringConverter::parseReal(config.getSetting("PageWorldX")) / (page_size - 1), Ogre::StringConverter::parseReal(config.getSetting("MaxHeight")), Ogre::StringConverter::parseReal(config.getSetting("PageWorldZ")) / (page_size - 1)); Ogre::String terrainfileName = config.getSetting("Heightmap.image"); float *heights = new float[page_size*page_size]; Ogre::Image terrainHeightMap; terrainHeightMap.load(terrainfileName, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); for (unsigned y = 0; y < page_size; ++y) { for (unsigned x = 0; x < page_size; ++x) { Ogre::ColourValue color = terrainHeightMap.getColourAt(x, y, 0); heights[x + y * page_size] = color.r; } } mTerrainShape = new HeightmapCollisionShape(page_size, page_size, terrainScale, heights, true); RigidBody *defaultTerrainBody = new RigidBody("Terrain", mWorld); const float terrainBodyRestitution = 0.1f; const float terrainBodyFriction = 0.8f; Ogre::Vector3 terrainShiftPos( (terrainScale.x * (page_size - 1) / 2), \ 0, (terrainScale.z * (page_size - 1) / 2)); terrainShiftPos.y = terrainScale.y / 2 * terrainScale.y; Ogre::SceneNode* pTerrainNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); defaultTerrainBody->setStaticShape (pTerrainNode, mTerrainShape, terrainBodyRestitution, terrainBodyFriction, terrainShiftPos); mBodies.push_back(defaultTerrainBody); mShapes.push_back(mTerrainShape); } // create obstacle in front of car addCube("obstacle", Ogre::Vector3(13, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(15, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(17, -5.25, -5) + terrain_Shift , Quaternion(Radian(Degree(22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(13, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(15, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(17, -5.25, -10) + terrain_Shift , Quaternion(Radian(Degree(-22.5)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); // create obstacle a bit aside addCube("obstacle", Ogre::Vector3(-2, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(0, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(2, 0, -5) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(-2, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(0, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(2, 0, -10) + terrain_Shift , Quaternion(Radian(Degree(-45.0)), Ogre::Vector3::UNIT_X), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); // create obstacle just for fun addCube("obstacle", Ogre::Vector3(25, -10, -25) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(25, -10, -27) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); addCube("obstacle", Ogre::Vector3(25, -10, -29) + terrain_Shift , Quaternion(Radian(Degree(45.0)), Ogre::Vector3::UNIT_Z), Ogre::Vector3(1, 1, 1), 0.3, 0.8, 0); /// create vehicle { const Ogre::Vector3 chassisShift(0, 1.0, 0); float connectionHeight = 0.7f; mChassis = mSceneMgr->createEntity( "chassis" + StringConverter::toString(mNumEntitiesInstanced++), "chassis.mesh"); SceneNode *node = mSceneMgr->getRootSceneNode ()->createChildSceneNode (); SceneNode *chassisnode = node->createChildSceneNode (); chassisnode->attachObject (mChassis); chassisnode->setPosition (chassisShift); mChassis->setQueryFlags (GEOMETRY_QUERY_MASK); #if (OGRE_VERSION < ((1 << 16) | (5 << 8) | 0)) // only applicable before shoggoth (1.5.0) mChassis->setNormaliseNormals(true); #endif mChassis->setCastShadows(true); CompoundCollisionShape* compound = new CompoundCollisionShape(); BoxCollisionShape* chassisShape = new BoxCollisionShape(Ogre::Vector3(1.f,0.75f,2.1f)); compound->addChildShape(chassisShape, chassisShift); mCarChassis = new WheeledRigidBody("carChassis", mWorld); mCarChassis->setShape(node, compound, 0.6, //restitution 0.6, //friction 800, //bodyMass CarPosition + terrain_Shift, Quaternion::IDENTITY); mCarChassis->setDamping(0.2, 0.2); mCarChassis->disableDeactivation(); mTuning = new VehicleTuning(gSuspensionStiffness, gSuspensionCompression, gSuspensionDamping, gMaxSuspensionTravelCm, gMaxSuspensionForce, gFrictionSlip); mVehicleRayCaster = new VehicleRayCaster(mWorld); mVehicle = new RaycastVehicle(mCarChassis, mTuning, mVehicleRayCaster); { int rightIndex = 0; int upIndex = 1; int forwardIndex = 2; mVehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex); Ogre::Vector3 wheelDirectionCS0(0,-1,0); Ogre::Vector3 wheelAxleCS(-1,0,0); for (size_t i = 0; i < 4; i++) { mWheels[i] = mSceneMgr->createEntity( "wheel" + StringConverter::toString(mNumEntitiesInstanced++), "wheel.mesh"); mWheels[i]->setQueryFlags (GEOMETRY_QUERY_MASK); #if (OGRE_VERSION < ((1 << 16) | (5 << 8) | 0)) // only applicable before shoggoth (1.5.0) mWheels[i]->setNormaliseNormals(true); #endif mWheels[i]->setCastShadows(true); mWheelNodes[i] = mSceneMgr->getRootSceneNode ()->createChildSceneNode (); mWheelNodes[i]->attachObject (mWheels[i]); } { bool isFrontWheel = true; Ogre::Vector3 connectionPointCS0 ( CUBE_HALF_EXTENTS-(0.3*gWheelWidth), connectionHeight, 2*CUBE_HALF_EXTENTS-gWheelRadius); mVehicle->addWheel( mWheelNodes[0], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( -CUBE_HALF_EXTENTS+(0.3*gWheelWidth), connectionHeight, 2*CUBE_HALF_EXTENTS-gWheelRadius); mVehicle->addWheel( mWheelNodes[1], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( -CUBE_HALF_EXTENTS+(0.3*gWheelWidth), connectionHeight, -2*CUBE_HALF_EXTENTS+gWheelRadius); isFrontWheel = false; mVehicle->addWheel( mWheelNodes[2], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); connectionPointCS0 = Ogre::Vector3( CUBE_HALF_EXTENTS-(0.3*gWheelWidth), connectionHeight, -2*CUBE_HALF_EXTENTS+gWheelRadius); mVehicle->addWheel( mWheelNodes[3], connectionPointCS0, wheelDirectionCS0, wheelAxleCS, gSuspensionRestLength, gWheelRadius, isFrontWheel, gWheelFriction, gRollInfluence); //mVehicle->setWheelsAttached(); } } } }