# LWJGL Forum

## Programming => OpenGL => Topic started by: JemBot on July 06, 2005, 02:15:27

Title: Algorithm for camera translation in 3D
Post by: JemBot on July 06, 2005, 02:15:27
Hi there.

I'm trying to calculate the camera or 'player' position in 3D space.

I can calculate it in 2D (ie a single plane) using sin(heading * pi/180) and cos(heading * pi/180), as is well documented on the net.

But I want to have free movement in 3D. I.e. I want to include a heading on the X plane as well as the Y plane.

At first I thought I could use a Y-plane heading to calculate X & Z camera positions, and an X-plane heading to calculate the Y camera position. This *almost* worked, but falls over when my headings are non-zero on all 3 axes.

Someone at work suggested I use glLookAt, but I don't think this answers my problem, as the first three parameters (location of eye point) are exactly the numbers I'm trying to calculate.

Any help is tremendously appreciated!

Thanks
JemBot
Title: Algorithm for camera translation in 3D
Post by: Funkapotamus on July 06, 2005, 19:32:33
Take a look at the code I posted here: http://lwjgl.org/forum/viewtopic.php?t=1182

You don't need to worry about calculating everything.  Just give the camera a position in space, a random direction to point it in, and set it's up vector to (0, 1, 0) as that's typically "up" in most 3d worlds.

If you want the camera to point in a specific direction or look at a particular thing when it loads- just set the target vector to that entity's position.  You don't have to deal with angles at all using this approach.
Title: hmmmmmmm....
Post by: Fool Running on July 06, 2005, 19:34:53
Are you trying to position your camera in relationship to a specific point? If you want the camera to just be at a point in space, then gluLookAt() is what you want.
Title: Algorithm for camera translation in 3D
Post by: JemBot on July 06, 2005, 23:23:54
Thanks guys.

It's the input to glLookAt that I need to determine - location of the eye. My camera has speed and a vector. Each time I need to recalculate its position along the vector.

I think I've nutted my problem, but I haven't had a chance to code it yet. I was calculating a new point on the Y plane, then shifting on the Y axis by the correct amount. This means I was effectively mapping a new point on the edge of a cylinder, not a sphere.

My new approach will be:
Use X plane to determine position on Y axis
Determine radius of the crosscentre at this point (this is the bit I was missing)
Determine X & Z positions on the crosscentre using the Y plane.

It makes sense in my head. I'll put some code here when I create it. I realise I should probably reuse other people's solutions, but this has become a bit of a challenge for me now.

Funkapotamus, thanks for the link to your snippet. I'll peruse that too when I can break from work.

Cheers
JemBot
Title: Algorithm for camera translation in 3D
Post by: JemBot on July 07, 2005, 03:43:26
Funk, how do you determine the target? If I had a target I could use your approach. But all I have is a vector. Determining a target along a vector is exactly the problem I'm trying to solve.
Title: Algorithm for camera translation in 3D
Post by: JemBot on July 07, 2005, 06:25:02
I think this is what I've been trying to figure out...

Code: [Select]
`        double y = Math.sin(headingPlaneX * PI_OVER_180);        double modifier = Math.cos(headingPlaneX * PI_OVER_180);        double x = modifier * Math.sin(headingPlaneY * PI_OVER_180);        double z = modifier * Math.cos(headingPlaneY * PI_OVER_180);                // target is a double[], length = 3, and is used to store the camera's position at the next iteration        target  += x;        target  += y;        target  += z;`

Effectively giving me 1 unit of movement in any direction I happen to be facing (as recorded by the two angles, headingPlaneY and headingPlaneX).

Does this make sense to people?
Does it finally explain what I was trying to do? (Calcuate the 'target' parameter for the glLookAt function)
Is there a better way to do this?
Is it broken in any way?

Cheers
Jem
Title: hmmmmm...
Post by: Fool Running on July 07, 2005, 15:40:20
The best way is to rotate a point arount the orgin and then translate it to the location that you want

Code: [Select]
`    /**     * Rotates the specified Vector3f around the x-axis by the specified angle     * @param  point The Vector3f to rotate     * @param  angle The angle (in degrees) to rotate the Vector3f     */    private static void pitch(final Vector3f point, final float angle){        final float yTemp = point.y * getCosValue(angle) + point.z * getSinValue(angle);        point.z = point.z * getCosValue(angle) - point.y * getSinValue(angle);        point.y = yTemp;    }`
and
Code: [Select]
`    /**     * Rotates the specified Vector3f around the y-axis by the specified angle     * @param  point The Vector3f to rotate     * @param  angle The angle (in degrees) to rotate the Vector3f     */    private static void yaw(final Vector3f point, final float angle){        final float xTemp = point.x * getCosValue(angle) - point.z * getSinValue(angle);        point.z = point.x * getSinValue(angle) + point.z * getCosValue(angle);        point.x = xTemp;    }`
so you would call it like this:
Code: [Select]
`Vector3f point = new Vector3f(1.0f, 0.0f, 0.0f);pitch(point, headingPlaneX);yaw(point, headingPlaneY);target += point.x;target += point.y;target += point.z;`
(I think that will work)  :roll:
Title: Algorithm for camera translation in 3D
Post by: Funkapotamus on July 07, 2005, 17:38:26
Just randomly give it a target.  It doesn't matter really.  Try (0, 1, 0) for the target.  Close your eyes and spin around so fast you land on the floor, then get up and open your eyes- there's your target.

Once your world content gets underway you can do more things such as spawning the camera while looking at a particular wall.

To be crafty, if you don't know what coordinates your object is you want to look at-, give your camera a random target, then run the game.  Manually move the camera to look at the spot you desire.  Then have it spit out the current target vector (System.out or something)- use this as your target vector the next time you run your game.

So basically:

Camera.setOrigin(new Vector3df(0, 0, 0), new Vector3df(0, 1, 0), new Vector3df(0, 1, 0));

Then look at the spot you want, record the xyz of the target vector and use that as the value you init setOrigin() with.