Game Development Community

Spherical Terrain in T3D

by Jack Stone · in Torque 3D Professional · 11/05/2014 (4:30 pm) · 29 replies

Hello,

As I mentioned here:
http://www.garagegames.com/community/forums/viewthread/140239/1#comment-862259

I am working on implementing spherical terrain in T3D. I have have found some equations here:

http://mathproofs.blogspot.ie/2005/07/mapping-cube-to-sphere.html

That work for generating the Z-component of the terrain. However, I am now stuck.

I need to modify the X and Y components of T3D's Terrain in order to generate the quad cube. Here is what I am doing:

Here is where I generate the terrain. The "Height" equation is correct. The length and width equations are not.
for ( S32 y = 0; y < blockSize; y++ )
{
	for ( S32 x = 0; x < blockSize; x++ )
	{

		F32 x1 = x+1;
		F32 y1 = y+1;

		x1 /= 256;
		y1 /= 256;

		height =  sqrt((F32)1 - ((x1*x1)/2) - ((y1*y1)/2) + (((x1*x1)*(y1*y1))/3) );


		F32 z1 = height;

		widthY =	sqrt((F32)1 - ((z1*z1)/2) - ((x1*x1)/2) + (((z1*z1)*(x1*x1))/3) );//x*2;
		lengthX =	sqrt((F32)1 - ((y1*y1)/2) - ((z1*z1)/2) + (((y1*y1)*(z1*z1))/3) );//x*2;

		lengthX *= 256;

		widthY *= 256;;

		height *= 256;

		Con::printf("setterraindata: %d %d %f %d" , x , y ,height, floatToFixed( height ));

		file->setWidthY( x, y, floatToFixed( widthY ) );
		file->setLengthX( x, y, floatToFixed( lengthX ) );

		file->setHeight( x, y, floatToFixed( height ) );


		count++;

	}
}

terrain->updateGrid( Point2I::Zero, Point2I( blockSize, blockSize ) );
terrain->updateGridMaterials( Point2I::Zero, Point2I( blockSize, blockSize ) );
terrain->registerObject( terrainName );

SimGroup *missionGroup;
if( Sim::findObject( "MissionGroup", missionGroup ) ){
	missionGroup->addObject( terrain );
}

In terrFile.h, I have copied and modified the set/get height functions:

inline void TerrainFile::setWidthY( U32 x, U32 y, U16 width )
{
   x %= mSize;
   y %= mSize;
   mWidthMap[ x + ( y * mSize ) ] = width;
}
inline void TerrainFile::setLengthX( U32 x, U32 y, U16 length )
{
   x %= mSize;
   y %= mSize;
   mLengthMap[ x + ( y * mSize ) ] = length;
}
inline void TerrainFile::setHeight( U32 x, U32 y, U16 height )
{
   x %= mSize;
   y %= mSize;
   mHeightMap[ x + ( y * mSize ) ] = height;
}

And finally, in terCell.cpp, the rendering code:

for ( U32 y = 0; y < smVBStride; y++ )
{
	for ( U32 x = 0; x < smVBStride; x++ )
	{

		// We clamp here to keep the geometry from reading across
		// one side of the height map to the other causing walls
		// around the edges of the terrain.
		//   terpoint.x = mClamp( mPoint.x + x * stepSize, 0, blockSize - 1 );
		//    terpoint.y = mClamp( mPoint.y + y * stepSize, 0, blockSize - 1 );
		gridPt.x = mClamp( mPoint.x + x * stepSize, 0, blockSize - 1 );
		gridPt.y = mClamp( mPoint.y + y * stepSize, 0, blockSize - 1 );

		// Setup this point.
		point.x = (F32)gridPt.x * squareSize;
		point.y = (F32)gridPt.y * squareSize;

		lengthX = fixedToFloat( file->getLengthX( gridPt.x, gridPt.y ) );
		widthY = fixedToFloat( file->getWidthY( gridPt.x, gridPt.y ) );
		height = fixedToFloat( file->getHeight( gridPt.x, gridPt.y ) );

		Point3F terdata = file->getterdata(count);

		vert->point.x = lengthX;// point.x;//terdata.x;//point.x*2;
		vert->point.y = widthY;//point.y;//terdata.y;//point.y;
		vert->point.z = height;//50.0755;//terdata.z;//height;

		count++;

		Con::printf("updatevertexbuffer: %f %f %f" ,widthY, lengthX,height);
		// Get the normal.
		mTerrain->getSmoothNormal( point, &normal, true, false );
		vert->normal = normal;

		// Get the tangent z.
		vert->tangentZ = fixedToFloat( file->getHeight( gridPt.x + 1, gridPt.y ) ) - height;

		// Test the empty state for this vert.
		if ( file->isEmptyAt( gridPt.x, gridPt.y ) )
		{
			mHasEmpty = true;
			mEmptyVertexList.push_back( vbcounter );
		}

		vbcounter++;
		++vert;
	}
}

"LengthX" and "WidthY" are being read correctly, and seem to have the correct values, but the terrain looks like this:

http://phoenixgamedevelopment.com/blog/wp-content/uploads/2014/11/PhoenixGameDevelopment130-Nov.-05-20.10-1024x793.jpg

It looks symmetrical, but clearly distorted.

I think the main issue I am having is getting the X,Y,and Z cube coordinates for the input to the speherical mapping function. The X and Y come from iterating through the terrain height map, but what is Z?


Page«First 1 2 Next»
#21
11/30/2014 (8:12 am)
I have made significant progress with this, I have the quad sphere drawn, and I can apply noise to it to simulate terrain.

However, I have now arrived at what I feel will be the most difficult part of this project, which is trying to match up the seams of the six different planes of the sphere.

Does anyone have any advice on this?

Right now I am selecting a group of pixels at the borders between the six planes and trying to interpolate between them, but it is not working.

#22
12/01/2014 (6:34 am)
I am glad to hear about your progress Jack would love to see a photo of the screen, to better represent the object.
  And regarding your question, I would try to make synchronous simply pointing one of the dominant and the other simply repeats its position in space, this can be achieved by specifying a reference to one coordinate to two vertices, but the best course would spawn only one mesh for the planet instead of 6 separate planes.
#23
12/01/2014 (8:48 am)
Hello,

Thank you very much, I have posted quite a lot of images on my site here:


http://phoenixgamedevelopment.com/blog/?s=P-152


If I am following your advice correctly, I think I am working on that solution at the moment. I will post updates on my progress.

I am actually generating the mesh as one object, but I am generating the planes in six steps, if that makes sense?
#24
12/04/2014 (9:02 am)
Jack forgive me for that long without an answer, I now have a little crowded stack of tasks, all trying to gain access, but I am unable to respond quickly in different places.
And now to business ...
  I spent two days ago is already coming to your site (by the way the site ironed perfectly. I like the dark background;)) But that day I did not have time to answer you as I drowned in the robot in another field of activity. But I still had time to see there your screen shots, where seams from the six planes hang around, and then I realized that you were fed to apply noise to each of the planes separately each serving, and using a modification of the height of the vertices in it only one axis. But I'm afraid it will not give you the desired effect, van must be multiplied by the desired height all axis vector at the same time, please re-read what I described earlier, I just want to emphasize that it is important not to forget to do ...
1) change the height and edited after creation, you need only multiply (ALL) axis desired to change the vertex (ie multiply the vector vertices to the desired height) (but not in any case, not a single axis)
2) First you need to create a sphere without noise,
3) all changes and modifications of vertices "planet" should be exclusively on this local center (origin) of the coordinates of the planet (but not global, world!)
4) I would recommend to abandon the creation of six planes and spawn vertices using the method in a clockwise spiral, creating a cube initially without joints, starting from the north (in the center of the "upper" plane of the cube) pole to the south pole (in the center of the "lower "plane of the cube) for this use cycles" for "embedded in each other, with an indication of the size of the" diameter "as a parameter in the amount of the desired counter vertices along each edge of the cube, the upper plane begins to build the center ++ 1 step every two turns in a clockwise spiral direction when the specified size is reached chapel "diameter" occurs more nested loops "for" in him falling down in a spiral around the walls of the cube turns each full turn on the size --1 below the former, while the number of turns it reaches the "diameter", then the inverse operation as it used to build the upper plane, and the cube will be closed in the opposite pole.
After generating the cube, apply to it the methods that I have described in predvedushih posts to make a smooth sphere from the cube, and then multiplying by the height, specify the desired noise.
#25
12/04/2014 (10:17 am)
Olexiy, Thank you very much! You have been very helpful! I actually just noticed your post, but you are exactly right, I was wrong to try to apply the noise on each plane, I'm not sure what I was thinking there.

I now have the noise working, and I have started on the procedural texturing. Collision next, that should be fun :P

I have some new pics here:


http://phoenixgamedevelopment.com/blog/?p=1142


Thanks again!
#26
12/04/2014 (12:43 pm)
Oh, I looked at your screen shots, and your new planet, I like it, it is much better than the old way, really looking forward to more news from you, I am glad that I was somehow helpful to you, good luck!
#27
12/04/2014 (4:41 pm)
The planet is looking good, Your screenshots are getting closer and closer to a great looking spherical terrain!
#28
12/04/2014 (7:15 pm)
Nice work! That's looking fantastic :).
#29
12/05/2014 (8:28 pm)
Thank you, yeah I am very pleased with it :)

The collision system is going to be tricky though!
Page«First 1 2 Next»