Skip to main content
GameDev.net gamedev.net
🔒 Locked

Getting a "tank" to be at the appropriate angle on a heightmap

Started by Maverick Programmer Mar 8, 2009 at 7:29 PM 13 replies 2k views
Original Post
Maverick Programmer
Maverick Programmer
Due to my incompetence with 3D math ( I am top notch with 2D math if I say so myself. And I do. ^^ ) and my dumb human brain, I am having a hard time trying to get my "tank" to be at the appropriate angle on a hill. I'm using heightmaps. My idea is to find the normal in the last position vector to the new one. Once I find the normal, I find the angles to change to and I rotate. I got nothing. Sometimes it seems like it works but it'll have seizures or it'll just spazz out in 3D space. I'm using C++ if it helps anyone. It would be great to stop suffering about this. ... Dumb tanks.
Holy crap, you can read!
Zakwayda
Zakwayda
Quote:
Original post by PCN
Due to my incompetence with 3D math ( I am top notch with 2D math if I say so myself. And I do. ^^ ) and my dumb human brain, I am having a hard time trying to get my "tank" to be at the appropriate angle on a hill. I'm using heightmaps.

My idea is to find the normal in the last position vector to the new one. Once I find the normal, I find the angles to change to and I rotate.

I got nothing. Sometimes it seems like it works but it'll have seizures or it'll just spazz out in 3D space.

I'm using C++ if it helps anyone. It would be great to stop suffering about this.
... Dumb tanks.
If you search the archives for phrases such as 'align vehicle to terrain', you'll find some previous threads on the topic (there have been quite a few).

Meanwhile, how are you representing the tank's orientation? A matrix? A quaternion? Euler angles?
Maverick Programmer
Maverick Programmer
Just euler angles. Trying to keep it simple. I've been looking. I've found topics but nothing that aids me. Perhaps those specific key terms will help.
Holy crap, you can read!
Zakwayda
Zakwayda
Quote:
Original post by PCN
Just euler angles. Trying to keep it simple. I've been looking. I've found topics but nothing that aids me. Perhaps those specific key terms will help.
IMO, Euler angles are probably about the worst representation to use when trying to solve this particular problem. I'd recommend using matrices or quaternions instead.

A fairly standard solution is to apply incremental corrective rotations to align the vehicle's 'up' vector with the normal vector of the terrain beneath it. The main drawback of this method is that it essentially treats the vehicle as a point, which means that parts of the vehicle may clip into the terrain mesh, depending on its orientation. Doing it the 'right way' though is non-trivial, and would probably be most easily accomplished by using a third-party physics engine.
Maverick Programmer
Maverick Programmer
It's actually supposed to be a crappy "get to the point" demo for someone. The main focus isn't the tank at an angle at this point but I wanted to add this feature. I'll keep that in mind though! Thanks for the help so far.
Holy crap, you can read!
jdindia
jdindia
This is linear algebra land. It really helps to be good at this kind of thing if you want to do 3d games - as you've discovered. =) IHMO, one general tip is, you should almost never need to calculate angles. If you're trying to, you're probably doing something inefficiently.

I'll assume you're familiar with vector notation. You said you were able to calculate the normal at the point, so you have a 2d point (P), an angle (a) representing the orientation of the tank in the flat 2d plane, the height at point p (h) and you want to know how to orient everything. This is really a basis problem, as you want a local coordinate system and the mapping to the global coordinate system.

What you want to do is calculate the vectors corresponding to the local directions of the tank. First is the normal, that's given and we'll call that up. Next is going to be forward, which will be determined by the angle a. Once you have those two, the third direction, to the right of the tank, is just the cross product between the forward vector and the normal vector. I'll get to calculating the forward vector itself in a minute, but I hope it's clear that once you have the forward, up, and right vectors and you know the position (p.x,p.y,h), you have everything. You can generate a transformation matrix that takes you from world space to object space and back.

Now to the forward vector. In order to calculate the normal, you basically had to generate a local coordinate system at the point p on the terrain. This involves a bit of calculus on surfaces; your surface is R(x,y)=(x,y,h(x,y)) and your local coordinate frame is then Rx, Ry and (Rx cross Ry) = normal. Normalize those and then you can calculate the forward vector as cos(a)*Rx^ + sin(a)*Ry^. One way of looking at the tank's coordinate system is to look at the local terrain coordinate system and then rotate by angle a along the normal axis - as I've done. Also, you have a discrete heightmap, so you'll have to do some interpolating to get useful partial derivatives, which you'll want to do anyway to maintain continuity when your tank moves from one cell to another.

I hope that made sense. I imagine my notation threw you off in a few places, so feel free to ask for more explanation where it's not clear.

[jyk is a ninja! You two had a whole conversation while I was typing that. >_<]
Maverick Programmer
Maverick Programmer
I know how to get the other directions. So that made sense. I think you lost me at the first sentence of "local terrain coordinate system" deeper into the last section.
Holy crap, you can read!
jdindia
jdindia
I feel like my solution is kind of mathematical overkill. =P Heh. This is what happens when you study math for too long. Realistically, you'd use a physics simulation like Jyk said, or some corrective hack. Anyway.

By local coordinate system, I mean, imagine standing at that point on the terrain. You point your hand in the air, and that's up to YOU, but not necessarily to the world. You point your hand to the right and that's right for you, but not necessarily right to the world. Since the world is usually roughly flat, there's not much difference, but you're asking for the difference in your question. =)

As for R(x,y)=(x,y,h(x,y)), that's your heightmap surface in 3 dimensions. Given an x,y pair, we get the z by plugging in the height function h(x,y) and we have a point on the surface. Rx and Ry are the local forward and right vectors to someone standing on the surface and they're calculated by taking the partial derivatives (Rx = (1,0,hx(x,y) ~= aprrox. (1,0,(h(x+dx,y)-h(x,y))/dx)). I confess if you're not too familiar with calculus, this won't make much sense. Local coordinate systems fall in the domain of differential geometry, which you don't see any of until third semester calculus.
Bob Janova
Bob Janova
If you just construct a quaternion (or rotation matrix) based on the axis (terrain normal×world Z axis), and then rotate the object's local coordinate system by it, will that not do the job?
jdindia
jdindia
I'm not sure your rotation will give you the same result as what I've proposed, but it wouldn't be much of a difference. =)

The real question though is, what's the normal? I mean, if you use the surface normal of the triangle the tank is sitting on, then you have discontinuities at the transition with neighboring triangles. If you try to get rid of those with multi-sampling or interpolation, then how is that any different than multisampling the partial derivatives or passing a curve through the heightmap vertices and calculating the partial derivatives from there. It's really many ways of talking about the same thing. Speaking of local coordinates and partial derivatives is the more general language.
Bob Janova
Bob Janova
Yeah I think so too ... I think the general solution is overkill though. Either you can just use the triangle over which the centre of the tank is sitting (and yes, you get artifacts at the edges, I don't know if the OP will be bothered by those), or you can get the preferred heights of the four wheels and calculate a plane and normal from that.
Maverick Programmer
Maverick Programmer
I have the normal no doubt, but I can't seem to find the angle from the normal to the front vector. Once I find that, I can angle the tank according to the terrain.

Maybe I am using the correct terminology? Gah.

I have been reading up on vector math to aid me. Hopefully can find a decent book on the matter as well. My only is question is this: if vector math is more appropriate to use in graphics and what-not, then why the heck do we learn trig and crap in high school?
Holy crap, you can read!
jdindia
jdindia
Quote:
Original post by PCN
My only is question is this: if vector math is more appropriate to use in graphics and what-not, then why the heck do we learn trig and crap in high school?


From my experience, most people don't really use math at all. Even people you'd think would need reasonable math skills, like engineers or high school math teachers usually know very little.

That means that math education isn't primarily driven by practical needs, unlike say business or engineering. The math curriculum is roughly a product of history; there have been a few reform attempts ("New Math" of the 60s? or 50s, I forget) but they've been controversial. Remember, math has the unique feature that people at the top of the field have completely different interests/concerns than the students trying to learn math so they can go do something else. Math education is therefore a very, very challenging topic.

Anyway, I think Bob has the right idea. I'd take 3 points on the tank body, rotate them in the flat 2d plane, and then use your heightmap to offset them. It's not correct, but it's not bad as long as the terrain is relatively flat.
Codeka
Codeka
Quote:
Original post by PCN
why the heck do we learn trig and crap in high school?
Not so we can all becomes graphics programmers, that's for sure [wink] (actually, one of the first things I learnt at university was linear algebra - it was a first year course)

But as for why we learn math in high school, it's not so much so that it will be immediately relevent to every day life, but mostly it's about logical thinking and problem solving. The actual problems don't matter so much. Keith Devlin says it better than I could.
Maverick Programmer
Maverick Programmer
Thanks guys. I think I got it. And thanks for the articles too!
Holy crap, you can read!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.