Jump to content
  • Advertisement
Sign in to follow this  

Opengl - Camera rotation on terrain problem

This topic is 2341 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

I need to find how to adjust the camera's X rotation to immitate a person across slopes on a terrain, if that makes any sense. The cameras X rotation is set to default <0,0,0> (looking straight ahead) until i figure how to solve the problem.
I have a few a few images to help you understand my problem.
My problem: I need my camera to look upwards/downwards as it walks across hills and valleys on the terrain.

Given information:
- Terrains normal
- Cameras x,z position relative to the terrain
- Cameras height
Unknown information:
- Cameras X rotation


Share this post

Link to post
Share on other sites
If you're camera is heading forward in Z, do a cross product with the terrain normal and (1,0,0) and that'll give you a direction vector that points in the direction the camera (is/should be) looking at. I'm not sure if you actually wanted the angle of rotation or just that direction vector. But to get the angle of rotation you can do some dot products with it against axis to get the rotation amount....

tilt = acos( clamp(-1.0, lookDir.dotProduct( (1,0,0) ) , 1.0) )
pan = acos( clamp(-1.0, lookDir.dotProduct( (0,1,0) ) , 1.0) )
roll = acos( clamp(-1.0, lookDir.dotProduct( (0,0,1) ) , 1.0) )

The clamp may seem unneccesary, but when performing an acos on a dot product result, it is always necessary, beware the QNANs

Share this post

Link to post
Share on other sites
That all makes perfect sense, however, i'v came across a couple problem while trying to implement it.

Also, i am trying to find just the tilt angle, not the direction vector.

a = Terrain normal;
b = Standard unit vector <1,0,0>;
c = a.cross(b); //look direction vector
d = c.dot(b);
e = acos(d)*(180/3.14); //radians to angle for Opengl purposes

My problem is, my x-component in variable 'c'(look direction vector) ALWAYS remains 0. So when i attempt to calculate variable 'd' by dot'ing it with my <1,0,0> axis vector, i ALWAYS result in variable 'd' being zero. Why? because doing the dot product formula of <0,?,?> with <1,0,0> will always result in zero. Subsequently finding variable 'e' by acos(d), where 'd' is always zero, results in 90 degrees forever as a tilt rotation.


Share this post

Link to post
Share on other sites

You want c to be equal to the 'a' vector but normalised

So you want the 'c' variable to be the normalized terrain normal, so the final tilt would be ->
tilt = acos(c.dot(<1,0,0>))*(180/3.14);

If so, that cannot be correct because on a flat surface where the terrain normal would point up <0,1,0>, the formula would be ->
tilt = acos(<0,1,0>.dot(<1,0,0>))*(180/3.14);
tilt = 90 degrees

Which is perpendicular to <1,0,0> and back where we started.

Share this post

Link to post
Share on other sites
The terms pan, tilt & roll are dependent upon the coordinate system, sine you've gone through and worked the math out this should be easy to explain i guess.

the acos of the dot will give you the angle a vecfor is from an arbitary axis, and in this case we're not using the third axis the dot product of your resultant cross vector against whatever vector is the 'forward' axis should give you the tilt.

If I was working this out for 3d I would have the following information and perform the following calculations.

Required information:
normal of the terrain at current position.
Side axis of the camera, the left vector rotated around the up vector by the pan of the camera,

normal.cross(side) = new Forward

I'm on my phone so sorry about the typos but from that you should be able to figure out the tilt with atan2

Sorry about the last answer, short story it was wrong, long story i forgot a few required cross products in the algorithm; that way is actually a really round about way of doing it and i've forgotten the complete algorithm anyway

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!