Game Development Community

Terrains - non-repeating render & collision

by Ken Finney · in Torque Game Engine · 05/27/2002 (9:27 pm) · 2 replies

Now we can have the kinds of terrains many of us need/want: arbitrarily large, with no repeating or tiling.

First, go here to get the latest copy of Bryan's most excellent Terrain Manager code:

www.garagegames.com/index.php?sec=mg&mod=forums&page=result.thread&qt=4474


This works as advertised. Next step is to turn off the tiling 'feature'.


Open terrManager.cc which is part of Bryan's Terrain Manager.

In the function TerrainManager::renderObject

find this block of code:
for ( S32 x = xStart; x < xEnd; x++ )
	{
		S32 xi = wrap(x,m_nNumTerrBlocksWide);
		for ( S32 y = yStart; y < yEnd; y++ )
		{
			S32 yi = wrap(y,m_nNumTerrBlocksHigh);

			// (xi,yi) contains the NxM block index.
			// Convert this to a block array index, and render the terrain.
			glPushMatrix();
			TerrainRender::renderBlock( this, pBlock[blockIdx(xi,yi)], Point3F(x*blockSize,y*blockSize,0), state);
			glPopMatrix();
		}
	}

and change it to this:
[b]	for ( S32 xi = xStart; xi < xEnd ; xi++ )
	{
                if (xi < 0)  continue;
                if (xi >= m_nNumTerrBlocksWide) break;
		for ( S32 yi = yStart; yi < yEnd ; yi++ )
		{
                        if (yi < 0)  continue; 
                        if ( yi >= m_nNumTerrBlocksHigh) break;
			glPushMatrix();
			TerrainRender::renderBlock( this, pBlock[blockIdx(xi,yi)], Point3F(xi*blockSize,yi*blockSize,0), state);
			glPopMatrix();
		}
	}
[/b]

That takes care of the repeated rendering.

Next, in the function TerrainManager::renderObject

find this block of code:

for ( S32 x = xStart; x != xEnd; x++ )
	{
		S32 xi = wrap(x,m_nNumTerrBlocksWide);

		for ( S32 y = yStart; y != yEnd; y++ )
		{
			Box3F tmpBox = osBox;
			S32 yi = wrap(y,m_nNumTerrBlocksHigh);

			// Box does not contain any part of terrain
			if ( tmpBox.min.x >= (x+1)*blockSize ||
				 tmpBox.min.y >= (y+1)*blockSize ||
				 tmpBox.max.x <= x*blockSize ||
				 tmpBox.max.y <= y*blockSize )
			{
				continue;
			}

			// Clip box to current terrain..
			if ( tmpBox.min.x < x*blockSize ) tmpBox.min.x = x*blockSize;
			if ( tmpBox.min.y < y*blockSize ) tmpBox.min.y = y*blockSize;
			if ( tmpBox.max.x > (x+1)*blockSize ) tmpBox.max.x = (x+1)*blockSize;
			if ( tmpBox.max.y > (y+1)*blockSize ) tmpBox.max.y = (y+1)*blockSize;
			pBlock[blockIdx(xi,yi)]->buildConvex(tmpBox,convex);
		}
	}

and replace it with this:

[b]
	for ( S32 xi = xStart; xi != xEnd; xi++ )
	{
                if (xi < 0)  continue;
                if (xi >= m_nNumTerrBlocksWide) break;
		for ( S32 yi = yStart; yi != yEnd; yi++ )
		{
                        if (yi < 0)  continue; 
                        if ( yi >= m_nNumTerrBlocksHigh) break;
			Box3F tmpBox = osBox;

			// Box does not contain any part of terrain
			if ( tmpBox.min.x >= (xi+1)*blockSize ||
				 tmpBox.min.y >= (yi+1)*blockSize ||
				 tmpBox.max.x <= xi*blockSize ||
				 tmpBox.max.y <= yi*blockSize )
			{
				continue;
			}
			// Clip box to current terrain..
			if ( tmpBox.min.x < xi*blockSize ) tmpBox.min.x = xi*blockSize;
			if ( tmpBox.min.y < yi*blockSize ) tmpBox.min.y = yi*blockSize;
			if ( tmpBox.max.x > (xi+1)*blockSize ) tmpBox.max.x = (xi+1)*blockSize;
			if ( tmpBox.max.y > (yi+1)*blockSize ) tmpBox.max.y = (yi+1)*blockSize;
			pBlock[blockIdx(xi,yi)]->buildConvex(tmpBox,convex);
		}
	}
[/b]


- now the collision repeating is gone and there you have it.

This was tested and works with a 6x6 matrix for the terrain blocks. I've tested it extensively, but not yet exhaustively.

www.tubettiworld.com/team/pedric/norepeat.jpg

#1
05/29/2002 (4:40 am)
Ken,

Great work! Nice screenshot too. I'm glad the TerrainManager fits your needs.

Looks like I need to get back to work and finish the save/load and CRC code. :)

--Bryan
#2
05/29/2002 (4:55 am)
Thanks Bryan .

BTW - I've tested the Terrain Manager with the May 26 HEAD and it works well - just be sure that the mission file paths are correct (especially if you use Bryan's included Stronghold sample mission).