示例#1
0
bool  TerrainLattice::Copy_Rect_to_HeightField( TTerrain* pHeightField, float x, float y, float fRadius, bool bNormalize )
{
	Terrain *pTerrain = GetTerrainAtPoint(x, y);
	if(pTerrain==NULL || pTerrain->IsEmpty())
		return false;
	float fVertexSpacing = pTerrain->GetVertexSpacing();
	
	int nCount = Math::Round(fRadius/fVertexSpacing)*2+1;
	float fMinX = x-nCount/2*fVertexSpacing;
	float fMinY = y-nCount/2*fVertexSpacing;

	pHeightField->CreatePlane(nCount, 0,fVertexSpacing);
	for(int i=0;i<nCount;i++)
	{
		for(int j=0;j<nCount;j++)
		{
			float fVertexX = fMinX + i*fVertexSpacing;
			float fVertexY = fMinY + j*fVertexSpacing;
			float fElev = GetVertexElevation(fVertexX, fVertexY);
			pHeightField->SetHeight(i,j, fElev);
		}
	}
	if(bNormalize)
		pHeightField->Normalize();
	return true;
}
示例#2
0
bool  TerrainLattice::Apply_HeightField_to_Rect( TTerrain* pHeightField, float x, float y, bool bRecalculateGeometry, bool bRecoverHeightData)
{
	Terrain *pTerrain = GetTerrainAtPoint(x, y);
	if(pTerrain==NULL || pTerrain->IsEmpty())
		return false;
	float fVertexSpacing = pTerrain->GetVertexSpacing();

	int nCount = pHeightField->GetGridSize();
	float fMinX = x-nCount/2*fVertexSpacing;
	float fMinY = y-nCount/2*fVertexSpacing;

	if(bRecoverHeightData)
		pHeightField->Recover();

	for(int i=0;i<nCount;i++)
	{
		for(int j=0;j<nCount;j++)
		{
			float fVertexX = fMinX + i*fVertexSpacing;
			float fVertexY = fMinY + j*fVertexSpacing;
			SetVertexElevation(fVertexX, fVertexY, pHeightField->GetHeight(i,j), false);
		}
	}
	if(bRecalculateGeometry == true)
	{
		/** make the region slightly larger. the exact region radius is (nCount-1)*fVertexSpacing/2 */
		RecalculateTerrainGeometry(x,y,nCount*fVertexSpacing/2);
	}
	return true;
}
示例#3
0
void TerrainLattice::MergeHeightField( float x, float y, const char* filename, int mergeOperation/*=0*/, float weight1/*=1.0*/, float weight2/*=1.0*/, int nSmoothPixels/*=7*/ )
{
	// snap to terrain grid.
	if(SnapPointToVertexGrid(x,y) == false)
		return;

	CTerrainFilters terrafilter;
	TTerrain* pHeightField = terrafilter.GetTerrainData();

	Terrain *pTerrain = GetTerrainAtPoint(x, y);
	if(pTerrain==NULL || pTerrain->IsEmpty())
		return;
	float fVertexSpacing = pTerrain->GetVertexSpacing();

	if(pHeightField->CreatePlane(filename, fVertexSpacing))
	{
		// Set the height to the lowest terrain height in the inner radius
		terrafilter.SetConstEdgeHeight(0, nSmoothPixels);

		CTerrainFilters terrafilter2;
		TTerrain* pHeightFieldCurrent = terrafilter2.GetTerrainData();
		if(Copy_Rect_to_HeightField(pHeightFieldCurrent, x,y, (pHeightField->GetGridSize()-1)*fVertexSpacing/2,false) == false)
			return;
		terrafilter2.Merge( pHeightFieldCurrent, pHeightField, weight1, weight2, (CTerrainFilters::MergeOperation)mergeOperation);

		if(Apply_HeightField_to_Rect(pHeightFieldCurrent, x,y,true,true) == false)
			return;
	}
}
示例#4
0
void TerrainLattice::SetVertexElevation(float x, float y, float newElevation, bool recalculate_geometry)
{
/* some vertex on border needs to be duplicated. This macro set the vertex on the given terrain tile.
* it is just to make the code easy to understand
*/
#define SETELEVATION(indexX, indexY) \
pTerrain = GetTerrain((indexX), (indexY));\
if(pTerrain && (!pTerrain->IsEmpty())){\
	int nIndex = pTerrain->GetVertexW(x,y);\
	pTerrain->SetVertexElevation(nIndex, newElevation,recalculate_geometry);\
	pTerrain->SetModified(true, MODIFIED_HEIGHTMAP);\
}

	Terrain *pTerrain = NULL;
	if(x<0 || y<0)
		return;
	int indexX = (int)(x / m_TerrainWidth);
	int indexY = (int)(y / m_TerrainHeight);
	
	SETELEVATION(indexX, indexY);
	
	float dX = x-indexX*m_TerrainWidth;
	float dY = y-indexY*m_TerrainHeight;
	float fRadius = pTerrain->GetVertexSpacing()/2;
	if(dX<fRadius)
	{
		SETELEVATION(indexX-1, indexY);
		if(dY<fRadius)
		{
			SETELEVATION(indexX-1, indexY-1);
		}
		else if(dY>m_TerrainHeight-fRadius)
		{
			SETELEVATION(indexX-1, indexY+1);
		}
	}
	else if(dX>m_TerrainWidth-fRadius)
	{
		SETELEVATION(indexX+1, indexY);
		if(dY<fRadius)
		{
			SETELEVATION(indexX+1, indexY-1);
		}
		else if(dY>m_TerrainHeight-fRadius)
		{
			SETELEVATION(indexX+1, indexY+1);
		}
	}
	if(dY<fRadius)
	{
		SETELEVATION(indexX, indexY-1);
	}
	else if(dY>m_TerrainHeight-fRadius)
	{
		SETELEVATION(indexX, indexY+1);
	}
}
示例#5
0
bool TerrainLattice::SnapPointToVertexGrid(float& x, float& y)
{
	Terrain *pTerrain = GetTerrainAtPoint(x, y);
	if(pTerrain==NULL || pTerrain->IsEmpty())
		return false;
	float fVertexSpacing = pTerrain->GetVertexSpacing();
	x = (Math::Round(x / fVertexSpacing))*fVertexSpacing;
	y = (Math::Round(y / fVertexSpacing))*fVertexSpacing;
	return true;
}
示例#6
0
void TerrainLattice::SetVertexInfo(float x,float y,uint32 data,uint32 bitMask,uint32 bitOffset)
{
#define SETDATA(idxX,idxY)\
	pTerrain = GetTerrain((idxX),(idxY));\
	if(pTerrain && (!pTerrain->IsEmpty())){\
		int idx = pTerrain->GetVertexW(x,y);\
		pTerrain->SetVertexInfo(idx,data,bitMask,bitOffset);\
	}

	Terrain* pTerrain = NULL;
	if(x<0 || y<0)
		return;

	int idxX = (int)(x / m_TerrainWidth);
	int idxY = (int)(y / m_TerrainHeight);
	SETDATA(idxX,idxY);

	float dx = x - idxX * m_TerrainWidth;
	float dy = y - idxY * m_TerrainHeight;
	float radius = pTerrain->GetVertexSpacing() / 2;
	if(dx < radius)
	{
		SETDATA(idxX - 1,idxY);
		if(dy < radius)
		{
			SETDATA(idxX-1,idxY-1);
		}
		else if(dy > m_TerrainHeight - radius)
		{
			SETDATA(idxX-1,idxY+1);
		}
	}
	else if(dx > m_TerrainWidth - radius)
	{
		SETDATA(idxX+1, idxY);
		if(dy<radius)
		{
			SETDATA(idxX+1, idxY-1);
		}
		else if(dy>m_TerrainHeight-radius)
		{
			SETDATA(idxX+1, idxY+1);
		}
	}

	if(dy<radius)
	{
		SETDATA(idxX, idxY-1);
	}
	else if(dy>m_TerrainHeight-radius)
	{
		SETDATA(idxX, idxY+1);
	}
}
示例#7
0
void TerrainLattice::SetTerrainInfo(float x,float y,float radius,uint32 data,uint32 bitMask,uint32 bitOffset)
{
	if(SnapPointToVertexGrid(x,y) == false)
		return;

	Terrain* pTerrain = GetTerrainAtPoint(x,y);
	if(pTerrain == NULL || pTerrain->IsEmpty())
		return;

	float vertexSpacing = pTerrain->GetVertexSpacing();
	float minX = x - radius;
	float minY = y - radius;

	int count = (int)(radius * 2.f / vertexSpacing);
	if(count < 1)
		count = 1;
	for(int i=0;i<count;i++)
	{
		for(int j=0;j<count;j++)
		{
			float curX = minX + i * vertexSpacing;
			float curY = minY + j* vertexSpacing;
			SetVertexInfo(curX,curY,data,bitMask,bitOffset);
		}
	}

	Terrain* affectedTerrainTiles[4];
	affectedTerrainTiles[0] = GetTerrainAtPoint(x+radius, y+radius);
	affectedTerrainTiles[1] = GetTerrainAtPoint(x+radius, y-radius);
	affectedTerrainTiles[2] = GetTerrainAtPoint(x-radius, y+radius);
	affectedTerrainTiles[3] = GetTerrainAtPoint(x-radius, y-radius);

	for(int i=0;i<4; i++)
	{
		Terrain * pTerrain = affectedTerrainTiles[i];
		bool bDraw = true;
		for(int k=i-1;k>=0; --k)
		{
			if(affectedTerrainTiles[k] == pTerrain)
			{
				bDraw = false;
				break;
			}
		}
	
		if(bDraw && pTerrain != NULL && (!pTerrain->IsEmpty()))
		{
			pTerrain->RefreshTerrainInfo();
		}
	
	}
}