Jump to content
  • Advertisement
Sign in to follow this  

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

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

If you intended to correct an error in the post then please contact us.

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 this post

Link to post
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 this post

Link to post
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 this post

Link to post
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 this post

Link to post
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 normal
D3DXVECTOR3 polyNormal = GetPolyNormalAt( tankTransform.pos.x, tankTransform.pos.z );

//point in front of and behind tanks x axis
D3DXVECTOR3 p0 = tankTransform.pos - (tankTransform.viewDir*1.5f);
D3DXVECTOR3 p1 = tankTransform.pos + (tankTransform.viewDir*1.5f);

//points on either side of tanks z axis
D3DXVECTOR3 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 terrain
D3DXVECTOR3 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 terrain
D3DXVECTOR3 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 angle
float 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 right
tankTilt.TiltLeftRight( angle );

//now we will tilt the tanks x axis

//get p0 and p1 projected onto the terrain
D3DXVECTOR3 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 terrain
D3DXVECTOR3 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 angle
float xAngle = acos( xDot );

//make sure the xAngle is negative if necessary
//by finding which way we are tilting
float 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.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!