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