int MyTerrain::GetSelectAreaID( Ogre::Ray ray ) { Ogre::TerrainGroup::RayResult result=m_pTerrainGroup->rayIntersects(ray); if(!result.hit) return -1; //m_pSceneMgr->getSceneNode("test")->setPosition(result.position); bool nosign=false; Ogre::Terrain* terrain = m_pTerrainGroup->getTerrain(0,0); int size= terrain->getLayerBlendMapSize(); int x=result.position.x*m_EdgeImage.width()/(float)terrain->getWorldSize(); int y=result.position.z*m_EdgeImage.height()/(float)terrain->getWorldSize(); QRgb resultrgb=m_AreaImage.pixel(x,y); int gray=qGray(m_EdgeImage.pixel(x,y)); if(gray!=255) { return -1; } else { int id=qGreen(resultrgb)*256+qBlue(resultrgb); if(id<65535) return id; else return -1; } }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::_calculatesmoothingfactor(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float& avg, int& sample_count) { Ogre::Rect brushrect, maprect; editpos.x *= (float)(mMapSize->get() - 1); editpos.y *= (float)(mMapSize->get() - 1); avg = 0.0f; sample_count = 0; if(!_getEditRect(editpos, brushrect, maprect, mMapSize->get())) return; Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle()); float *mHeightData = terrain->getHeightData(); int mapPos; for(int j = maprect.top;j < maprect.bottom;j++) { mapPos = (j * mMapSize->get()) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { avg += mHeightData[mapPos]; ++mapPos; } } sample_count = (maprect.right - maprect.left) * (maprect.bottom - maprect.top); }
void MyTerrain::InitHydrax() { if(Global::UseHydrax) { m_pHydrax=new Hydrax::Hydrax(m_pSceneMgr,MyGameApp::GetSingleton().GetMainCamera(),MyGameApp::GetSingleton().GetRenderWindow()->getViewport(0)); Hydrax::Module::ProjectedGrid *mModule = new Hydrax::Module::ProjectedGrid( m_pHydrax, new Hydrax::Noise::Perlin(/*Generic one*/), Ogre::Plane(Ogre::Vector3(0,1,0), Ogre::Vector3(0,0,0)), Hydrax::MaterialManager::NM_VERTEX, Hydrax::Module::ProjectedGrid::Options(/*264 /*Generic one*/)); m_pHydrax->setModule(static_cast<Hydrax::Module::Module*>(mModule)); m_pHydrax->loadCfg("Hydrax.hdx"); auto ti=m_pTerrainGroup->getTerrainIterator(); while(ti.hasMoreElements()) { Ogre::Terrain* t = ti.getNext()->instance; Ogre::MaterialPtr pMat = t->getMaterial(); m_pHydrax->getMaterialManager()->addDepthTechnique(pMat->createTechnique()); } m_pHydrax->create(); } }
void EmberTerrainGroup::handleResponse(const WorkQueue::Response* res, const WorkQueue* srcQ) { --sLoadingTaskNum; LoadRequest lreq = any_cast<LoadRequest>(res->getRequest()->getData()); if (res->succeeded()) { TerrainSlot* slot = lreq.slot; Ogre::Terrain* terrain = slot->instance; if (terrain) { terrain->setPosition(getTerrainSlotPosition(slot->x, slot->y)); if (mAutoUpdateLod) { terrain->load(-1, false); } else { terrain->load(0, true); } for (int i = -1; i <= 1; ++i) { for (int j = -1; j <= 1; ++j) { if (i != 0 || j != 0) { connectNeighbour(slot, i, j); } } } } } else { S_LOG_FAILURE("Failed to prepare terrain at " << lreq.slot->x << ", " << lreq.slot->y << ". Error: " << res->getMessages()); lreq.slot->freeInstance(); } }
Ogre::Vector2 MyTerrain::GetWorldPointFromImagePoint( Ogre::Vector2 point ) { Ogre::Vector2 v; Ogre::Terrain* terrain = m_pTerrainGroup->getTerrain(0,0); v.x=point.x*m_EdgeImage.width()/(float)terrain->getWorldSize(); v.y=point.y*m_EdgeImage.height()/(float)terrain->getWorldSize(); return v; }
void ManipulatorTerrain::SetLayerTexture( int nLayer, int diffuseMapID ) { Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); assert(nLayer >=0 && nLayer<(int)pTerrain->getLayerCount()); Ogre::String filename, path; Ogre::StringUtil::splitFilename(m_vecLayerTex[diffuseMapID], filename, path); SetLayerTexture(nLayer, filename); }
void TerrainProjectionMarker::FindProjectedTerrainMaterials(Array<string>& matNames) { auto& pos = GetPositionAbsolute(); Vector3 orientedSize = Ogre::Quaternion(Ogre::Degree(-90),Ogre::Vector3::UNIT_X) * GetOrientationAbsolute() * Vector3(_halfSize.x, 0.f, _halfSize.y); // Check which terrain cells are occupied by marker's corners // ( assume its smaller than terrain cell ) auto map = GameWorld::GlobalWorld->GetMap(); auto terrainGrid = GameWorld::GlobalWorld->GetMap()->GetTerrain()->GetTerrainGrid(); Ogre::Terrain* terrain; uint32 xMin = (uint32)std::max(0.f, std::min(pos.x - orientedSize.x, pos.x + orientedSize.x)); uint32 xMax = (uint32)std::min(map->GetTerrainSize().x, std::max(pos.x - orientedSize.x, pos.x + orientedSize.x)); uint32 zMin = (uint32)std::max(0.f, std::max(pos.z - orientedSize.y, pos.z + orientedSize.y)); uint32 zMax = (uint32)std::min(map->GetTerrainSize().y, std::max(pos.z - orientedSize.z, pos.z + orientedSize.z)); // Check minimal corner terrain terrain = terrainGrid->GetTerrainFromPosition(xMin, zMin); if( _lastProjectedTerrains[0] != terrain ) { // Terrain cell changed ( or its 1st call ) _lastProjectedTerrains[0] = terrain; matNames.push_back(terrain->getMaterialName()); } // Check maximal corner terrain terrain = terrainGrid->GetTerrainFromPosition(xMax, zMax); if( _lastProjectedTerrains[0] != terrain ) { // Marker on multiple cells if( _lastProjectedTerrains[3] != terrain ) { _lastProjectedTerrains[3] = terrain; matNames.push_back(terrain->getMaterialName()); } terrain = terrainGrid->GetTerrainFromPosition(xMax, zMin); if( _lastProjectedTerrains[1] != terrain ) { _lastProjectedTerrains[1] = terrain; matNames.push_back(terrain->getMaterialName()); } terrain = terrainGrid->GetTerrainFromPosition(xMin, zMax); if( _lastProjectedTerrains[2] != terrain ) { _lastProjectedTerrains[2] = terrain; matNames.push_back(terrain->getMaterialName()); } } else { // Max and min corner falls into same cell, so we'll have only one terrain _lastProjectedTerrains[1] = terrain; _lastProjectedTerrains[2] = terrain; _lastProjectedTerrains[3] = terrain; } }
void ManipulatorTerrain::SetLayerTexture( int nLayer, const std::string& diffuseMapName ) { Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); assert(nLayer >=0 && nLayer<(int)pTerrain->getLayerCount()); Ogre::String name = diffuseMapName.substr(0, diffuseMapName.find("diffuse")); //diffuse map pTerrain->setLayerTextureName(nLayer, 0, name + "diffusespecular.dds"); //normal map pTerrain->setLayerTextureName(nLayer, 1, name + "normalheight.dds"); }
TerrainGenerator::TerrainGenerator(Ogre::SceneManager *scene) : terrains_imported_(false), scene_manager_(scene) { /*mCamera->setPosition(Ogre::Vector3(1683, 50, 2116)); mCamera->lookAt(Ogre::Vector3(1963, 50, 1660)); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(50000);*/ Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(Ogre::TFO_ANISOTROPIC); Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(7); Ogre::Light* light = scene_manager_->createLight("tstLight"); light->setDiffuseColour(Ogre::ColourValue::White); light->setSpecularColour(Ogre::ColourValue(1, 1, 1)); scene_manager_->setAmbientLight(Ogre::ColourValue(0.9, 0.9, 0.9)); light->setAttenuation(100000, 1, 1, 1); terrain_globals_ = OGRE_NEW Ogre::TerrainGlobalOptions(); terrain_group_ = OGRE_NEW Ogre::TerrainGroup(scene_manager_, Ogre::Terrain::ALIGN_X_Z, 513, 12000.0f); terrain_group_->setFilenameConvention(Ogre::String("BasicTutorial3Terrain"), Ogre::String("dat")); terrain_group_->setOrigin(Ogre::Vector3::ZERO); configureTerrainDefaults(light); for (long x = 0; x <= 0; ++x) for (long y = 0; y <= 0; ++y) defineTerrain(x, y); // sync load since we want everything in place when we start terrain_group_->loadAllTerrains(true); if (terrains_imported_) { Ogre::TerrainGroup::TerrainIterator ti = terrain_group_->getTerrainIterator(); while(ti.hasMoreElements()) { Ogre::Terrain* t = ti.getNext()->instance; t->setPosition(Ogre::Vector3(0, -315, 0)); initBlendMaps(t); } } terrain_group_->freeTemporaryResources(); scene_manager_->setSkyDome(true, "Examples/CloudySky", 5, 8); //Optional skybox //Graphics::instance()->getSceneManager()->setSkyDome(true, "Examples/CloudySky", 5, 8); }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::_deform(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed) { Ogre::Rect brushrect, maprect; editpos.x *= (float)(mMapSize->get() - 1); editpos.y *= (float)(mMapSize->get() - 1); if(!_getEditRect(editpos, brushrect, maprect, mMapSize->get())) return; handle->_notifyModification(-1, maprect); Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle()); float *mHeightData = terrain->getHeightData(); if(mEditDirection) timePassed *= -1.0f; float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize; float brushPos; int mapPos; for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.left; mapPos = (j * mMapSize->get()) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { assert(mapPos < (mMapSize->get() * mMapSize->get()) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); float val = mHeightData[mapPos] + (mBrushData[(int)brushPos] * mBrushIntensity * timePassed); assert(val < 10000.0f); assert(val > -10000.0f); mHeightData[mapPos] = val; ++mapPos; brushPos += mRatio; } } terrain->dirtyRect(maprect); }
void MyTerrain::UpdateTexture() { Ogre::Terrain* terrain = m_pTerrainGroup->getTerrain(0,0); int size= terrain->getLayerBlendMapSize(); Ogre::TerrainLayerBlendMap* blendMap3 = terrain->getLayerBlendMap(4); float* pBlend3 = blendMap3->getBlendPointer(); for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y) { for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x) { float tx, ty; blendMap3->convertImageToTerrainSpace(x, y, &tx, &ty); QRgb rgb=m_AreaImage.pixel(x*m_AreaImage.width()/size,y*m_AreaImage.height()/size); int gray=qGray(m_EdgeImage.pixel(x*m_AreaImage.width()/size,y*m_AreaImage.height()/size)); int r=qRed(rgb); int g=qGreen(rgb); int b=qBlue(rgb); int id=g*256+b; if(gray==255&&rgb!=qRgb(255,255,255)) { if(m_AreaVector[id]->m_bHighLight) { *pBlend3=0.2; } else { *pBlend3=0; } } else { *pBlend3=0; } pBlend3++; } } blendMap3->dirty(); blendMap3->update(); }
void Scene::setup(Sim* sim) { mSim = sim; mSim->scene = this; // Lighting and sky mSceneMgr->setAmbientLight(Ogre::ColourValue(0.4, 0.4, 0.4)); Ogre::Vector3 lightDir(0.55, -0.3f, 0.75); lightDir.normalise(); sun = mSceneMgr->createLight("SunLight"); sun->setType(Ogre::Light::LT_DIRECTIONAL); sun->setDirection(lightDir); sun->setDiffuseColour(Ogre::ColourValue::White); sun->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4)); mSceneMgr->setSkyDome(true, "CloudySky"); // Terrain mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions(); mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(mSceneMgr, Ogre::Terrain::ALIGN_X_Z, terrSize, worldSize); configureTerrainDefaults(); defineTerrain(); mTerrainGroup->loadAllTerrains(true); Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); while (ti.hasMoreElements()) { Ogre::Terrain* t = ti.getNext()->instance; t->setVisibilityFlags(RV_Terrain); } mTerrainGroup->freeTemporaryResources(); createBulletTerrain(); // Road // setupRoad(); // Objects setupObjects(); }
void TerrainManager::CreatePhysicsShape(void) { Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator(); while (ti.hasMoreElements()) { Ogre::Terrain *t = ti.getNext()->instance; LoadTerrainGeometry(t->getMaterialName(), t->getHeightData(), t->getSize(), t->getWorldSize(), t->getMinHeight(), t->getMaxHeight(), t->getPosition()); } }
void Scene::createBulletTerrain() { Ogre::Terrain* baseTerrain = mTerrainGroup->getTerrain(0, 0); btHeightfieldTerrainShape* hfShape = new btHeightfieldTerrainShape( baseTerrain->getSize(), baseTerrain->getSize(), baseTerrain->getHeightData(), 1, 0, 0, 2, PHY_FLOAT, false); // Min and max height were set to 0 to force the terrain to be completely flat hfShape->setUseDiamondSubdivision(true); // This scale is based on the tutorial, but it may not be true... float metersBetweenVerts = baseTerrain->getWorldSize() / (baseTerrain->getSize() - 1); btVector3 scale(metersBetweenVerts, metersBetweenVerts, 1); hfShape->setLocalScaling(scale); hfShape->setUserPointer((void*) SU_Terrain); btCollisionObject* colObj = new btCollisionObject(); colObj->setCollisionShape(hfShape); colObj->setFriction(0.9); colObj->setRestitution(0.0); colObj->setCollisionFlags(colObj->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT); mSim->getCollisionWorld()->getDynamicsWorld()->addCollisionObject(colObj); mSim->getCollisionWorld()->addShape(hfShape); // Border planes const float px[4] = {-1, 1, 0, 0}; const float py[4] = { 0, 0,-1, 1}; for (int i = 0; i < 4; ++i) { btVector3 vpl(px[i], py[i], 0); btCollisionShape* shp = new btStaticPlaneShape(vpl, 0); shp->setUserPointer((void*) SU_Border); btTransform tr; tr.setIdentity(); tr.setOrigin(vpl * -0.5 * worldSize); btCollisionObject* col = new btCollisionObject(); col->setCollisionShape(shp); col->setWorldTransform(tr); col->setFriction(0.3); //+ col->setRestitution(0.0); col->setCollisionFlags(col->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT | btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT); mSim->getCollisionWorld()->getDynamicsWorld()->addCollisionObject(col); mSim->getCollisionWorld()->addShape(shp); } }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::_splat(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed) { Ogre::Rect brushrect, maprect; Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle()); int mBlendMapSize = terrain->getLayerBlendMapSize(); editpos.x *= (float)mBlendMapSize; editpos.y = (1.0f - editpos.y) * (float)mBlendMapSize; if(!_getEditRect(editpos, brushrect, maprect, mBlendMapSize)) return; int mLayer = 0; mLayer = handle->_getLayerID(mTextureDiffuse, mTextureNormal, mEditDirection); if(mLayer < 1) return; handle->_notifyModification(mLayer, maprect); int mLayerMax = terrain->getLayerCount(); Ogre::TerrainLayerBlendMap *mBlendMaps[128]; float *mBlendDatas[128]; Ogre::TerrainLayerBlendMap *mCurrentBlendMap = terrain->getLayerBlendMap(mLayer); float *mCurrentBlendData = mCurrentBlendMap->getBlendPointer(); for(int l = mLayer;l < mLayerMax;l++) { mBlendMaps[l] = terrain->getLayerBlendMap(l); mBlendDatas[l] = mBlendMaps[l]->getBlendPointer(); } float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize; float brushPos; int mapPos; int right = brushrect.right; brushrect.right = BRUSH_DATA_SIZE - brushrect.left; brushrect.left = BRUSH_DATA_SIZE - right; float factor = mBrushIntensity * timePassed * 0.2f; if(!mEditDirection) { int u; float sum; for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * mBlendMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); sum = 0.0f; for(u = mLayer + 1;u < mLayerMax;u++) sum += mBlendDatas[u][mapPos]; float val = mCurrentBlendData[mapPos] + (mBrushData[(int)brushPos] * factor); sum += val; if(sum > 1.0f) { float normfactor = 1.0f / (float)sum; mCurrentBlendData[mapPos] = val * normfactor; for(u = mLayer + 1;u < mLayerMax;u++) mBlendDatas[u][mapPos] *= normfactor; } else mCurrentBlendData[mapPos] = val; ++mapPos; } } for(u = mLayer;u < mLayerMax;u++) { mBlendMaps[u]->dirtyRect(maprect); mBlendMaps[u]->update(); } } else { for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * mBlendMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); float val = mCurrentBlendData[mapPos] - (mBrushData[(int)brushPos] * factor); if(val < 0.0f) val = 0.0f; mCurrentBlendData[mapPos] = val; ++mapPos; } } mCurrentBlendMap->dirtyRect(maprect); mCurrentBlendMap->update(); } }
CoiHandle terrain_get_layer_blend_map(CoiHandle terrain_handle, int layer_index) { Ogre::Terrain* terrain = reinterpret_cast<Ogre::Terrain*>(terrain_handle); return terrain->getLayerBlendMap(layer_index); }
//----------------------------------------------------------------------------------------- bool CTerrainGroupEditor::update(float timePassed) { if(mEditActive && mDecalFrustum->getVisible()) { mEditDirection = CViewportEditor::mViewKeyboard[CViewportEditor::mSpecial.SPK_REVERSE_UPDATE]; Ogre::Vector3 cursorpos = mDecalNode->getPosition(); Ogre::Terrain *terrain; Ogre::Vector3 editpos; Ogre::TerrainGroup::TerrainList terrainList; Ogre::Real halfBrushSizeWorldSpace = (Ogre::Real)(mWorldSize->get() * mBrushSize) / (Ogre::Real)(mMapSize->get()) / 2.0f; Ogre::Sphere sphere(cursorpos, halfBrushSizeWorldSpace); mHandle->sphereIntersects(sphere, &terrainList); mModificationRect.merge(Ogre::Rect(cursorpos.x - halfBrushSizeWorldSpace, cursorpos.z - halfBrushSizeWorldSpace, cursorpos.x + halfBrushSizeWorldSpace, cursorpos.z + halfBrushSizeWorldSpace)); bool groupUpdateNeeded = false; float avg_total = 0.0f; float sample_count_total = 0; if(mEditMode == EM_SMOOTH) { for (Ogre::TerrainGroup::TerrainList::iterator ti = terrainList.begin(); ti != terrainList.end(); ++ti) { terrain = *ti; terrain->getTerrainPosition(cursorpos, &editpos); CTerrainPageEditor *terED = 0; for(NameObjectPairList::iterator it = mChildren.begin(); it != mChildren.end();it++) { if(it->second->getHandle() == (void*)terrain) { terED = static_cast<CTerrainPageEditor*>(it->second); break; } } float avg = 0.0f; int sample_count = 0; _calculatesmoothingfactor(terED, editpos, avg, sample_count); avg_total += avg; sample_count_total += sample_count; } } for (Ogre::TerrainGroup::TerrainList::iterator ti = terrainList.begin(); ti != terrainList.end(); ++ti) { terrain = *ti; terrain->getTerrainPosition(cursorpos, &editpos); CTerrainPageEditor *terED = 0; for(NameObjectPairList::iterator it = mChildren.begin(); it != mChildren.end();it++) { if(it->second->getHandle() == (void*)terrain) { terED = static_cast<CTerrainPageEditor*>(it->second); break; } } if(mEditMode == EM_DEFORM) { _deform(terED, editpos, timePassed); groupUpdateNeeded |= true; } else if(mEditMode == EM_SMOOTH) { if(sample_count_total) { _smooth(terED, editpos, avg_total / (float)sample_count_total, timePassed); groupUpdateNeeded |= true; } } else if(mEditMode == EM_SPLAT) _splat(terED, editpos, timePassed); else if(mEditMode == EM_PAINT) _paint(terED, editpos, timePassed); else if(mEditMode == EM_SPLATGRASS) _splatGrass(terED, editpos, timePassed); } if(groupUpdateNeeded) mHandle->update(); mOgitorsRoot->SetSceneModified(true); } if(mPGHandle) mPGHandle->update(); return false; }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::_paint(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed) { Ogre::Rect brushrect, maprect; int ColourMapSize = mColourMapTextureSize->get(); editpos.x *= (float)ColourMapSize; editpos.y = (1.0f - editpos.y) * (float)ColourMapSize; if(!_getEditRect(editpos, brushrect, maprect, ColourMapSize)) return; handle->_notifyModification(0, maprect); Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle()); float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize; float brushPos; int mapPos; int buffersize = terrain->getGlobalColourMap()->getBuffer()->getSizeInBytes(); int spacing = buffersize / (ColourMapSize * ColourMapSize); unsigned char *data = (unsigned char *)terrain->getGlobalColourMap()->getBuffer()->lock(0, buffersize, Ogre::HardwareBuffer::HBL_NORMAL); Ogre::PixelFormat pf = terrain->getGlobalColourMap()->getBuffer()->getFormat(); Ogre::ColourValue colVal; int right = brushrect.right; brushrect.right = BRUSH_DATA_SIZE - brushrect.left; brushrect.left = BRUSH_DATA_SIZE - right; float factor = std::min(mBrushIntensity * timePassed * 0.2f, 1.0f); float bfactor; if(!mEditDirection) { for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * ColourMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (ColourMapSize * ColourMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); bfactor = mBrushData[(int)brushPos] * factor; Ogre::PixelUtil::unpackColour(&colVal, pf, (void*)&data[mapPos * spacing]); colVal.r = colVal.r + ((mColour.r - colVal.r) * bfactor); colVal.g = colVal.g + ((mColour.g - colVal.g) * bfactor); colVal.b = colVal.b + ((mColour.b - colVal.b) * bfactor); Ogre::PixelUtil::packColour(colVal, pf, (void*)&data[mapPos * spacing]); ++mapPos; } } } else { for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * ColourMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (ColourMapSize * ColourMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); bfactor = mBrushData[(int)brushPos] * factor; Ogre::PixelUtil::unpackColour(&colVal, pf, (void*)&data[mapPos * spacing]); colVal.r = colVal.r + ((1.0f - colVal.r) * bfactor); colVal.g = colVal.g + ((1.0f - colVal.g) * bfactor); colVal.b = colVal.b + ((1.0f - colVal.b) * bfactor); Ogre::PixelUtil::packColour(colVal, pf, (void*)&data[mapPos * spacing]); ++mapPos; } } } terrain->getGlobalColourMap()->getBuffer()->unlock(); }
//----------------------------------------------------------------------------------------- void CTerrainGroupEditor::_splat(CTerrainPageEditor *handle, Ogre::Vector3 &editpos, float timePassed) { Ogre::Rect brushrect, maprect; Ogre::Terrain *terrain = static_cast<Ogre::Terrain*>(handle->getHandle()); int mBlendMapSize = terrain->getLayerBlendMapSize(); editpos.x *= (float)mBlendMapSize; editpos.y = (1.0f - editpos.y) * (float)mBlendMapSize; if(!_getEditRect(editpos, brushrect, maprect, mBlendMapSize)) return; int mLayer = 0; mLayer = handle->_getLayerID(mTextureDiffuse, mTextureNormal, mEditDirection); if(mLayer == -1) { Ogre::String msg = handle->getName() + " already has the maximum number of supported texture layers."; mSystem->DisplayMessageDialog(OTR(msg), DLGTYPE_OK); return; } else if(mLayer == 0) { Ogre::TerrainLayerBlendMap *mBlendMaps[128]; float *mBlendDatas[128]; int mLayerMax = terrain->getLayerCount(); for(int l = 1;l < mLayerMax;l++) { mBlendMaps[l] = terrain->getLayerBlendMap(l); mBlendDatas[l] = mBlendMaps[l]->getBlendPointer(); } float maxVal; int u; int num; for(u = mLayerMax-1;u > 0;u--) { mLayer = u; maxVal = 0.0f; for(int j = maprect.top;j < maprect.bottom;j++) { int mapPos = (j * mBlendMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { maxVal += mBlendDatas[u][mapPos]; } } num = (maprect.top*mBlendMapSize); num = (num+maprect.right)-(num+maprect.left); if (maxVal > num) break; } if (mLayer == 0) return; mEditDirection = true; } handle->_notifyModification(mLayer, maprect); int mLayerMax = terrain->getLayerCount(); Ogre::TerrainLayerBlendMap *mBlendMaps[128]; float *mBlendDatas[128]; Ogre::TerrainLayerBlendMap *mCurrentBlendMap = terrain->getLayerBlendMap(mLayer); float *mCurrentBlendData = mCurrentBlendMap->getBlendPointer(); for(int l = mLayer;l < mLayerMax;l++) { mBlendMaps[l] = terrain->getLayerBlendMap(l); mBlendDatas[l] = mBlendMaps[l]->getBlendPointer(); } float mRatio = (float)BRUSH_DATA_SIZE / (float)mBrushSize; float brushPos; int mapPos; int right = brushrect.right; brushrect.right = BRUSH_DATA_SIZE - brushrect.left; brushrect.left = BRUSH_DATA_SIZE - right; float factor = mBrushIntensity * timePassed * 0.2f; if(!mEditDirection) { int u; float sum; for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * mBlendMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); sum = 0.0f; for(u = mLayer + 1;u < mLayerMax;u++) sum += mBlendDatas[u][mapPos]; float val = mCurrentBlendData[mapPos] + (mBrushData[(int)brushPos] * factor); sum += val; if(sum > 1.0f) { float normfactor = 1.0f / (float)sum; mCurrentBlendData[mapPos] = val * normfactor; for(u = mLayer + 1;u < mLayerMax;u++) mBlendDatas[u][mapPos] *= normfactor; } else mCurrentBlendData[mapPos] = val; ++mapPos; } } for(u = mLayer;u < mLayerMax;u++) { mBlendMaps[u]->dirtyRect(maprect); mBlendMaps[u]->update(); } } else { for(int j = maprect.top;j < maprect.bottom;j++) { brushPos = (brushrect.top + (int)((j - maprect.top) * mRatio)) * BRUSH_DATA_SIZE; brushPos += brushrect.right; mapPos = (j * mBlendMapSize) + maprect.left; for(int i = maprect.left;i < maprect.right;i++) { brushPos -= mRatio; assert(mapPos < (mBlendMapSize * mBlendMapSize) && mapPos >= 0); assert((int)brushPos < (BRUSH_DATA_SIZE * BRUSH_DATA_SIZE) && (int)brushPos >= 0); float val = mCurrentBlendData[mapPos] - (mBrushData[(int)brushPos] * factor); if(val < 0.0f) val = 0.0f; mCurrentBlendData[mapPos] = val; ++mapPos; } } mCurrentBlendMap->dirtyRect(maprect); mCurrentBlendMap->update(); } }
float terrain_get_height_at_terrain_position(CoiHandle terrain_handle, float x, float y) { Ogre::Terrain* terrain = reinterpret_cast<Ogre::Terrain*>(terrain_handle); return terrain->getHeightAtTerrainPosition(x, y); }
int _tmain(int argc, _TCHAR* argv[]) { // ------------------------- Check for command line argument ------------------------------------------- if (! argv[1]) { printf("\n"); printf("Missing argument.\nExample: \"Converter.exe job1.cfg\""); return 0; } // ------------------------- Basic Ogre Engine initialization ------------------------------------------- Ogre::Root* root = new Ogre::Root; Ogre::RenderSystem* rendersys = root->getRenderSystemByName("Direct3D9 Rendering Subsystem"); rendersys->setConfigOption("Full Screen", "No"); rendersys->setConfigOption("Video Mode", "800 x 600 @ 32-bit colour"); root->setRenderSystem(rendersys); Ogre::ResourceGroupManager::getSingleton().addResourceLocation("resource", "FileSystem", "General"); Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); root->initialise(false); Ogre::RenderWindow* window = root->createRenderWindow("RAW2OGT", 800, 600, false); Ogre::SceneManager* scenemgr = root->createSceneManager(Ogre::SceneType::ST_GENERIC); Ogre::Camera* camera = scenemgr->createCamera("camera"); Ogre::Viewport* viewport = window->addViewport(camera); /*Ogre::Vector3 lightdir(0, -0.3, 0.75); lightdir.normalise(); Ogre::Light* l = scenemgr->createLight("tstLight"); l->setType(Ogre::Light::LT_DIRECTIONAL); l->setDirection(lightdir); l->setDiffuseColour(Ogre::ColourValue(1.0, 1.0, 1.0)); l->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));*/ scenemgr->setAmbientLight(Ogre::ColourValue(0.7, 0.7, 0.7)); // --------------------------------- Start convert ---------------------------------------------------- // Load job config Ogre::ConfigFile* terrainconfig = OGRE_NEW Ogre::ConfigFile(); terrainconfig->loadDirect(argv[1]); // Load info from [general] block Ogre::String heightmapfile = terrainconfig->getSetting("heightmap", "general"); Ogre::Real heightmapscale = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapscale", "general")); Ogre::Real heightmapoffset = Ogre::StringConverter::parseReal(terrainconfig->getSetting("heightmapoffset", "general")); Ogre::uint16 terrainsize = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("terrainsize", "general")); Ogre::Real worldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", "general")); Ogre::uint16 layercount = Ogre::StringConverter::parseUnsignedInt(terrainconfig->getSetting("layercount", "general")); // initialise stream to heightmapfile Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().openResource(heightmapfile, "General"); size_t size = stream.get()->size(); // verify size if(size != terrainsize * terrainsize * 4) OGRE_EXCEPT( Ogre::Exception::ERR_INTERNAL_ERROR, "Size of stream does not match terrainsize!", "TerrainPage" ); // load to buffer float* buffer = OGRE_ALLOC_T(float, size, Ogre::MEMCATEGORY_GENERAL); stream->read(buffer, size); // apply scale and offset for(int i=0;i<terrainsize*terrainsize;i++) { buffer[i] = (buffer[i] + heightmapoffset) * heightmapscale; } // Terrain initialization Ogre::TerrainGlobalOptions* terrainglobals = OGRE_NEW Ogre::TerrainGlobalOptions(); terrainglobals->setMaxPixelError(1); //terrainglobals->setCompositeMapDistance(30000); //terrainglobals->setLightMapDirection(lightdir); //terrainglobals->setCompositeMapAmbient(scenemgr->getAmbientLight()); //terrainglobals->setCompositeMapDiffuse(l->getDiffuseColour()); Ogre::TerrainMaterialGeneratorA::SM2Profile* pMatProfile = static_cast<Ogre::TerrainMaterialGeneratorA::SM2Profile*>(terrainglobals->getDefaultMaterialGenerator()->getActiveProfile()); pMatProfile->setLightmapEnabled(false); pMatProfile->setCompositeMapEnabled(false); Ogre::TerrainGroup* terraingroup = OGRE_NEW Ogre::TerrainGroup(scenemgr, Ogre::Terrain::ALIGN_X_Z, terrainsize, worldsize); terraingroup->setFilenameConvention(Ogre::String("terrain"), Ogre::String("ogt")); terraingroup->setOrigin(Ogre::Vector3::ZERO); Ogre::Terrain* terrain = OGRE_NEW Ogre::Terrain(scenemgr); // terrainsettings Ogre::Terrain::ImportData& imp = terraingroup->getDefaultImportSettings(); imp.terrainSize = terrainsize; imp.worldSize = worldsize; imp.minBatchSize = 33; imp.maxBatchSize = 65; // use float RAW heightmap as input imp.inputFloat = buffer; // process texture layers imp.layerList.resize(layercount); Ogre::StringVector blendmaps(layercount); for(int i=0;i<layercount;i++) { // load layer info Ogre::String sectionStr = Ogre::StringConverter::toString(i); Ogre::Real layerworldsize = Ogre::StringConverter::parseReal(terrainconfig->getSetting("worldsize", sectionStr)); if (i==0) { // no blendmap at layer 0 (baselayer) Ogre::String specular = terrainconfig->getSetting("specular", sectionStr); Ogre::String normal = terrainconfig->getSetting("normal", sectionStr); // add layer imp.layerList[i].textureNames.push_back(specular); imp.layerList[i].textureNames.push_back(normal); imp.layerList[i].worldSize = layerworldsize; } else { Ogre::String specular = terrainconfig->getSetting("specular", sectionStr); Ogre::String normal = terrainconfig->getSetting("normal", sectionStr); Ogre::String blend = terrainconfig->getSetting("blend", sectionStr); // add layer imp.layerList[i].textureNames.push_back(specular); imp.layerList[i].textureNames.push_back(normal); imp.layerList[i].worldSize = layerworldsize; blendmaps[i] = blend; } } // load the terrain terrain->prepare(imp); terrain->load(); // load those blendmaps into the layers for(int j = 1;j < terrain->getLayerCount();j++) { Ogre::TerrainLayerBlendMap *blendmap = terrain->getLayerBlendMap(j); Ogre::Image img; img.load(blendmaps[j],"General"); int blendmapsize = terrain->getLayerBlendMapSize(); if(img.getWidth() != blendmapsize) img.resize(blendmapsize, blendmapsize); float *ptr = blendmap->getBlendPointer(); Ogre::uint8 *data = static_cast<Ogre::uint8*>(img.getPixelBox().data); for(int bp = 0;bp < blendmapsize * blendmapsize;bp++) ptr[bp] = static_cast<float>(data[bp]) / 255.0f; blendmap->dirty(); blendmap->update(); } // create filename for writing int pos = heightmapfile.find_last_of('.'); if (pos < 0) heightmapfile = heightmapfile + ".ogt"; else heightmapfile = heightmapfile.substr(0, pos) + ".ogt"; // save as Ogre .OGT terrain->save(heightmapfile); Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LogMessageLevel::LML_NORMAL, heightmapfile + " successfully written."); // debug viewing (exit with CTRL+C) camera->setPosition(-terrainsize, 7000, -terrainsize); camera->lookAt(terrainsize/2,0,terrainsize/2); root->startRendering(); return 0; }
const std::string ManipulatorTerrain::GetLayerNormalMap( int nLayer ) const { Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); assert(nLayer >=0 && nLayer<(int)pTerrain->getLayerCount()); return pTerrain->getLayerTextureName(nLayer, 1); }
float ManipulatorTerrain::GetLayerTexWorldSize( int nLayer ) { Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); assert(nLayer >=0 && nLayer<(int)pTerrain->getLayerCount()); return pTerrain->getLayerWorldSize(nLayer); }
float MyTerrain::GetImageXFromWorldX( float x ) { Ogre::Terrain* terrain = m_pTerrainGroup->getTerrain(0,0); return x*m_EdgeImage.width()/(float)terrain->getWorldSize(); }
void ManipulatorTerrain::SetLayerTexWorldSize(int nLayer, float fSize) { Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); assert(nLayer >=0 && nLayer<(int)pTerrain->getLayerCount()); pTerrain->setLayerWorldSize(nLayer, fSize); }
void ManipulatorTerrain::OnEdit( float dt ) { assert(m_curEditMode != eTerrainEditMode_None); //第0层不能编辑BlendMap,应该从第1层开始 if(m_curEditMode == eTerrainEditMode_Splat && m_curEditLayer == 0) return; Ogre::Terrain* pTerrain = ManipulatorSystem.GetScene()->GetTerrain(); const Vector3 brushPos = m_brush[m_curBrushIndex]->GetPosition(); Vector3 tsPos; pTerrain->getTerrainPosition(brushPos, &tsPos); float brushSizeW, brushSizeH; m_brush[m_curBrushIndex]->GetDimension(brushSizeW, brushSizeH); float worldSize = GetWorldSize(); brushSizeW /= worldSize; brushSizeH /= worldSize; int multiplier; Ogre::TerrainLayerBlendMap* layer = nullptr; if(m_curEditMode == eTerrainEditMode_Deform) { multiplier = pTerrain->getSize() - 1; } else { multiplier = pTerrain->getLayerBlendMapSize(); layer = pTerrain->getLayerBlendMap(m_curEditLayer); } long startx = (long)((tsPos.x - brushSizeW / 2) * multiplier); long starty = (long)((tsPos.y - brushSizeH / 2) * multiplier); long endx = (long)((tsPos.x + brushSizeW / 2) * multiplier); long endy= (long)((tsPos.y + brushSizeH / 2) * multiplier); startx = max(startx, 0L); starty = max(starty, 0L); endx = min(endx, (long)multiplier); endy = min(endy, (long)multiplier); for (long y = starty; y <= endy; ++y) { for (long x = startx; x <= endx; ++x) { float tsXdist = (x / multiplier) - tsPos.x; float tsYdist = (y / multiplier) - tsPos.y; if(m_curEditMode == eTerrainEditMode_Deform) { float* pData = pTerrain->getHeightData(); pData[y*GetMapSize()+x] += 100.0f * dt; } else { float* pData = layer->getBlendPointer(); size_t imgY = multiplier - y; float newValue = pData[imgY*multiplier+x] + dt; newValue = Ogre::Math::Clamp(newValue, 0.0f, 1.0f); pData[imgY*multiplier+x] = newValue; } } } if(m_curEditMode == eTerrainEditMode_Deform) { Ogre::Rect rect(startx, starty, endx, endy); pTerrain->dirtyRect(rect); pTerrain->update(); } else { size_t imgStartY = multiplier - starty; size_t imgEndY = multiplier - endy; Ogre::Rect rect(startx, min(imgStartY,imgEndY), endx, max(imgStartY,imgEndY)); layer->dirtyRect(rect); layer->update(); } }
void TerrainManager::terrainInit(Ogre::String file, OgreManager* o) { _OgreManager = o; initialiseResources(); createLight(); setGlobalOptions(); _TerrainGroup = OGRE_NEW Ogre::TerrainGroup(_OgreManager->getSceneManager(), Ogre::Terrain::ALIGN_X_Z, 513, 12000.0f); _TerrainGroup->setFilenameConvention(Ogre::String("GameTerrain"), Ogre::String("dat")); _TerrainGroup->setOrigin(Ogre::Vector3::ZERO); setDefaultImportSettings(); bool lTerrainsImported = false; for (long x = 0; x <= 0; ++x) { for (long y = 0; y <= 0; ++y) { //Define terrain function Ogre::String filename = _TerrainGroup->generateFilename(x, y); if (Ogre::ResourceGroupManager::getSingleton().resourceExists(_TerrainGroup->getResourceGroup(), filename)) { _TerrainGroup->defineTerrain(x, y); } else { Ogre::Image img; //Get terrain image Ogre::String tempFile = Ogre::StringConverter::toString(x * 10 + y); tempFile.append(".bmp"); img.load("terrain.bmp", Ogre::String("TerrainResources")); if (x % 2 != 0) img.flipAroundY(); if (y % 2 != 0) img.flipAroundX(); //Get terrain image end _TerrainGroup->defineTerrain(x, y, &img); lTerrainsImported = true; } //Define terrain function end } } _TerrainGroup->loadAllTerrains(true); if (lTerrainsImported) { Ogre::TerrainGroup::TerrainIterator ti = _TerrainGroup->getTerrainIterator(); while(ti.hasMoreElements()) { Ogre::Terrain* t = ti.getNext()->instance; //Init blend maps function start Ogre::TerrainLayerBlendMap* blendMap0 = t->getLayerBlendMap(1); Ogre::TerrainLayerBlendMap* blendMap1 = t->getLayerBlendMap(2); Ogre::Real minHeight0 = -10; Ogre::Real fadeDist0 = 0;//40; Ogre::Real minHeight1 = -10; Ogre::Real fadeDist1 = 0;//15; float* pBlend0 = blendMap0->getBlendPointer(); float* pBlend1 = blendMap1->getBlendPointer(); for (Ogre::uint16 y = 0; y < t->getLayerBlendMapSize(); ++y) { for (Ogre::uint16 x = 0; x < t->getLayerBlendMapSize(); ++x) { Ogre::Real tx, ty; blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty); Ogre::Real height = t->getHeightAtTerrainPosition(tx, ty); Ogre::Real val = (height - minHeight0) / fadeDist0; val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1); *pBlend0++ = val; val = (height - minHeight1) / fadeDist1; val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1); *pBlend1++ = val; } } blendMap0->dirty(); blendMap1->dirty(); blendMap0->update(); blendMap1->update(); //Init blend maps end } } _TerrainGroup->freeTemporaryResources(); _OgreManager->getSceneManager()->setSkyBox(true, "Examples/EarlyMorningSkyBox", 5000, true, Ogre::Quaternion::IDENTITY, "GameResources"); }
int terrain_get_layer_blend_map_size(CoiHandle terrain_handle) { Ogre::Terrain* terrain = reinterpret_cast<Ogre::Terrain*>(terrain_handle); return terrain->getLayerBlendMapSize(); }
float MyTerrain::GetImageYFromWorldY( float y ) { Ogre::Terrain* terrain = m_pTerrainGroup->getTerrain(0,0); return y*m_EdgeImage.height()/(float)terrain->getWorldSize(); }