void ManipulatorTerrain::SetBrushPosition( const Ogre::Vector3& pos ) { //检测防止画刷范围超出地形边界 Ogre::Vector3 clampPos(pos); float brushDim1, brushDim2; m_brush[m_curBrushIndex]->GetDimension(brushDim1, brushDim2); float worldSize = GetWorldSize(); if (m_curBrushIndex == 0) //circle { if(clampPos.x - brushDim2 < -worldSize/2) clampPos.x = brushDim2 - worldSize/2; if(clampPos.x + brushDim2 > worldSize/2) clampPos.x = worldSize/2 - brushDim2; if(clampPos.z - brushDim2 < -worldSize/2) clampPos.z = brushDim2 - worldSize/2; if(clampPos.z + brushDim2 > worldSize/2) clampPos.z = worldSize/2 - brushDim2; } else //square { if(clampPos.x - brushDim1/2 < -worldSize/2) clampPos.x = brushDim1/2 - worldSize/2; if(clampPos.x + brushDim1/2 > worldSize/2) clampPos.x = worldSize/2 - brushDim1/2; if(clampPos.z - brushDim2/2 < -worldSize/2) clampPos.z = brushDim2/2 - worldSize/2; if(clampPos.z + brushDim2/2 > worldSize/2) clampPos.z = worldSize/2 - brushDim2/2; } m_brush[m_curBrushIndex]->SetPosition(clampPos); }
void Layer::GetBounds( double* bounds ) { double* origin = GetWorldOrigin(); double* size = GetWorldSize(); for ( int i = 0; i < 3; i++ ) { bounds[i*2] = origin[i]; bounds[i*2+1] = origin[i] + size[i]; } }
void ManipulatorTerrain::Serialize( rapidxml::xml_document<>* doc, rapidxml::xml_node<>* XMLNode ) { String strWorldSize = Ogre::StringConverter::toString(GetWorldSize()); String strTerrainSize = Ogre::StringConverter::toString(GetMapSize()); float pixelError = ManipulatorSystem.GetScene()->GetTerrainOption()->getMaxPixelError(); String strPixelError = Ogre::StringConverter::toString(pixelError); XMLNode->append_attribute(doc->allocate_attribute("worldSize", doc->allocate_string(strWorldSize.c_str()))); XMLNode->append_attribute(doc->allocate_attribute("mapSize", doc->allocate_string(strTerrainSize.c_str()))); XMLNode->append_attribute(doc->allocate_attribute("tuningMaxPixelError", doc->allocate_string(strPixelError.c_str()))); //保存地形数据 std::wstring fullPath(ManipulatorSystem.GenerateSceneFullPath()); fullPath += L"terrain.dat"; Ogre::DataStreamPtr stream = Ogre::Root::getSingleton().createFileStream(Utility::UnicodeToEngine(fullPath), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true); Ogre::DataStreamPtr compressStream(new Ogre::DeflateStream(Utility::UnicodeToEngine(fullPath), stream)); Ogre::StreamSerialiser ser(compressStream); ManipulatorSystem.GetScene()->GetTerrain()->save(ser); }
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(); } }