# Placing Objects on Slopes( eg hills ) -- Now Solved

This topic is 4975 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Ok, my problem is this. I have a terrain generation program that produces a scene from a heightmap. I have a tank which i can drive around. What I want to do is make it so that the tank tilts when it goes up the hills. Racing games do this all the time obviously so it shouldnt be too hard. How do I go about making my tank tilt to match the slope of the terrain? I am using DirectX 9 and thought there might be a matrix function to help, but there doesnt appear to be. Any help would be appreciated. Thanks, Pete [Edited by - pete_2004 on June 6, 2005 8:23:53 PM]

##### Share on other sites
Typically you can do some "ground clamping" or "terrain following" by shooting 3-4 rays down in a triangle or quad pattern underneath the tank and based on their collisions some simple logic to the tank to allow it to follow the contour of the terrain. If you want it to move realistically it can get quite a bit more complex I believe.

##### Share on other sites
Here's a theory. What if you define 6 to 8 points on the bottom of the tank, give them weight ratios and such, orientate them every frame to match the tank state, then let them fall where they may?

So you let the points free-fall with gravity but check for terrain collision. Then you average their orientation (basically, you just flatten the points on the plane that most closely matches their current orientation). Use that state to rotate and position the tank, and also to reset the points into valid positions. You'll have to tweak gravity influences. If gravity is allowed to contuously increase as a point is in the air, the tank could literally be ripped in half if it kept one end off the ground for a long period of time.

Like I said, it's just a theory. I have yet to test anything.

##### Share on other sites
Jiia, you've basically just invented verlet physics ;) I would probably go for ray casting, if the terrain is quite 'smooth.' However, if it really is rough, and physics solution may be best.

##### Share on other sites
Yay! I got it working. I did the shooting 4 rays idea of yours DrEvil. Heres what I did:

////////////////////////////////make tank tilt with terrain////////////////////////////////get the terrain poly normalD3DXVECTOR3 polyNormal = GetPolyNormalAt( tankTransform.pos.x, tankTransform.pos.z );//point in front of and behind tanks x axisD3DXVECTOR3 p0 = tankTransform.pos - (tankTransform.viewDir*1.5f);D3DXVECTOR3 p1 = tankTransform.pos + (tankTransform.viewDir*1.5f);		//points on either side of tanks z axisD3DXVECTOR3 p2 = tankTransform.pos - (tankTransform.right*1.5f);D3DXVECTOR3 p3 = tankTransform.pos + (tankTransform.right*1.5f);				//calculate z axis tilt//get p2 and p3 projected onto the terrainD3DXVECTOR3 e1( p2.x, GetTerrainHeightAt( p2.x, p2.z ), p2.z );D3DXVECTOR3 e2( p3.x, GetTerrainHeightAt( p3.x, p3.z ), p3.z );//calculate the dot between ground vector( e1,e2 ) and tank vector//( p2, p3 ) this will get us the cosine angle difference around the tanks//z axis to the terrainD3DXVECTOR3 s1 = p3 - p2;D3DXVec3Normalize( &s1, &s1 );D3DXVECTOR3 s2 = e2 - e1;D3DXVec3Normalize( &s2, &s2 );float zDot = D3DXVec3Dot( &s1, &s2 );		//convert the zDot from its cosine value into an actual anglefloat angle = acos( zDot );//make sure the angle is negative if necessary//the way we are calculating the angle means it will always be positive//( because the ground slope vector is projected directly from the tank right vector//  the two vectors always travel in the same direction )float result = D3DXVec3Dot( &polyNormal, &tankTransform.right );if( result >= 0 ) angle *=-1;//tilt the tank left or righttankTilt.TiltLeftRight( angle );		//now we will tilt the tanks x axis		//get p0 and p1 projected onto the terrainD3DXVECTOR3 e3( p0.x, GetTerrainHeightAt( p0.x, p0.z ), p0.z );D3DXVECTOR3 e4( p1.x, GetTerrainHeightAt( p1.x, p1.z ), p1.z );//calculate the dot between forward ground vector( e3,e4 ) and tank forward vector//( p0, p1 ) this will get us the cosine angle difference around the tanks//x axis to the terrainD3DXVECTOR3 s3 = p1 - p0;D3DXVec3Normalize( &s3, &s3 );D3DXVECTOR3 s4 = e4 - e3;D3DXVec3Normalize( &s4, &s4 );float xDot = D3DXVec3Dot( &s3, &s4 );		//convert the xDot from its cosine value into an actual anglefloat xAngle = acos( xDot );		//make sure the xAngle is negative if necessary//by finding which way we are tiltingfloat xResult = D3DXVec3Dot( &polyNormal,&tankTransform.viewDir );if( xResult >= 0 ) xAngle *=-1;tankTilt.TiltFrontBack( xAngle );

Thanks for the help guys. Its a bit bumpy but ill work on that.
Pete

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 9
• 10
• 11
• 13
• 9
• ### Forum Statistics

• Total Topics
634094
• Total Posts
3015467
×