//----------------------------------------------------------------------------------------- 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 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(); } }