//-----------------------------------------------------------------------------------------
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;
}
示例#2
0
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();
	}
}