Java-Gaming.org Hi !
 Featured games (91) games approved by the League of Dukes Games in Showcase (756) Games in Android Showcase (229) games submitted by our members Games in WIP (842) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Creating a 3D Camera  (Read 14780 times) 0 Members and 1 Guest are viewing this topic.
Agro
 « Posted 2012-11-27 00:07:12 »

Explaining the Math of a 3D camera

===================================

In this guide, I will explain how to go about creating a modern 3D camera with Java and OpenGL(using the LWJGL library). In order to do that, I
will also explain a little bit of trigonometry and how the functions work, instead of just giving you code to use.

The trigonometric functions we will be using in this guide is sin(sine) and cos(cosine). There are other functions like tan(tanget), cot(cotanget), sec(secant), and csc(cosecant), but we won't be needing them to write a basic camera.

The functions sin and cos can help us find angles in a right triangle, calculate polar - cartesian coordinates, and more. The phrase  "SOH CAH TOA" will help you remember what sin and cos do.

Sin(a) = Opposite / Hypotenuse

We will only focus on the first two. What this is saying is that the sine of an angle is the opposite side over the hypotenuse(the side opposite the RIGHT angle). The opposite is the side opposite the angle. It might be confusing but let's focus on what we're going to use it for.

You might have seen that sin and cos are used to convert polar coordinates into cartesian coordinates. Polar coordinates are defined by a length and an angle. Do you see how it works when you think of it as a triangle? Think of it as going from 0 to the x coordinate as the adjacent and the 0 to the y coordinate as the opposite side. Then the length of the line will be the hypotenuse. An example of converting a polar coordinate to a cartesian coordinate is like this:

Polar coordinate (45 degrees, 1.414 length)
X = cos(45) * 1.414; = 1
Y = cos(45) * 1.414; = 1

As you can see, the polar coordinate yields the cartesian coordinate (1, 1).

What I think the sin and cos functions do(I've never really received a general definition) is that they convert an angle measure to a  normalized directional vector. Let's apply this to how we would use it in a 3D camera.

Creating a 3D Camera
===========================
In a 3D camera, there are 2 components I can think of right away. Those are the pitch and yaw values and the position of the camera.

The pitch of a camera is the vertical orientation of the camera. The yaw of a camera is the horizontal orientation of the camera. You might've heard about roll, and that is the "Z-axis" orientation of the camera. The pitch rotates on the x axis, and the yaw rotates on the y-axis.
Basically in general, the pitch and yaw is how much you have rotated in a horizontal and vertical direction.

To incorporate pitch and yaw into a 3D game, you have to do something like this:
 1 `glRotatef(-pitch, -yaw, 0);`

To receive pitch and yaw values, you have to keep the mouse in the center of the screen all the time. Whenever you detect there is a change, the amount of change in X will be added to yaw, and the amount of change in Y will be added to pitch. Once the yaw exceeds 359 degrees, reset
it to 0. Also make sure that you lock the pitch values so it can't be less than -90 or greater than 90.

The next component is the position. This is described as a 3-dimensional coordinate being (x, y, z).

To incorporate position into a 3D game, do this
 1 `glTranslatef(-pos.x, -pos.y, -pos.z);`

So what we need to solve is:
- How do we represent movement in a camera?

If you have developed a 2D game before(which I'm sure you have), you can easily move the player in the x and y axis depending on what key you press. But since a 3rd dimension is being added, there is more to maintain. If your yaw is say, 90 degrees, and you press the forward button, you would originally be moving positively in the Z direction. That's wrong. Since you're yaw is 90, you should be moving in the positive X direction. The trigonometric functions sin and cos will help us solve this problem.

Relative to your current direction, forward is 0 degrees, backwards is 180 degrees, left is -90 or +270 degrees, right is +90 or -270 degrees.
If we incorporate this with our knowledge of sin and cos, we can figure out the correct direction to move in.

That being said, here is the function:

 1  2  3  4 `void moveCamera(float direction) { // direction is in degrees   pos.x += Math.sin(Math.toRadians(yaw + direction)) * SPEED;   pos.z += Math.cos(Math.toRadians(yaw + direction)) * SPEED;}`

As you can see, X is using the sin function, and Z is using the cos function. But why is this? I said earlier that cos is for X and sin is for Y, right? Well, you see, since we're in the 3rd dimension now, Y is the UPWARD direction. If we think of XZ as a normal coordinating system as of XY (in a 2D plane), then it works.

Want some examples of this being used?

If yaw = 90 and move left:
sin(90 - 90) = sin(0) = 0
cos(90 - 90) = cos(0) = 1

It checks off.

If yaw = 180 and move backwards:
sin(180 + 180) = sin(360) = sin(0) = 0;
cos(180 + 180) = cos(260) = cos(0) = 1;

Same thing.

If yaw = 270 and move backwards:
sin(270 + 180) = sin(450) = 1
cos(270 + 180) = cos(450) = 0

This tutorial was mostly intended for explaining the math behind a camera, and not how to implement. Should I explain how to implement cameras with LWJGL?

And any tips, comments, or suggestions on how to make this guide better? Thanks for reading.

sproingie

JGO Kernel

Medals: 202

 « Reply #1 - Posted 2012-11-27 02:09:30 »

OpenGL works with degrees, but the trig functions on Math use radians.

You also introduced a shift of axes to Y=up, which may be true for several engines such as idTech and Unreal, but it's not the intuition that applies to the camera out of the box (and what most tutorials will assume) which is the camera looking down Z

Agro
 « Reply #2 - Posted 2012-11-27 02:11:56 »

Fixed.

Its easier to visualize the upward direction being Y, well, because Y has always meant up and down to me. ^_^ Z has always meant "depth" to me, so it all makes sense.

gmaker

Junior Devvie

Projects: 8

 « Reply #3 - Posted 2013-03-07 17:19:02 »

Polar coordinate (45 degrees, 1.414 length)
X = cos(45) * 1.414; = 1
Y = cos(45) * 1.414; = 1

is it typo?

mb
Y = sin(45) * 1.414; =~1;
quew8

JGO Knight

Medals: 53

 « Reply #4 - Posted 2013-03-07 18:59:47 »

sin(45) = cos(45) = sqrt(2) / 2
Agro
 « Reply #5 - Posted 2013-03-07 23:53:25 »

Yeah, I think I should've said sqrt(2) sorry.

relminator
 « Reply #6 - Posted 2013-03-08 14:32:37 »

This might interest you a bit. Speaking of polar coords, why not use the 3d version of the polar coordinate system (spherical)?

Very, very old article I wrote:

http://www.phatcode.net/articles.php?id=216

 1  2  3 `camLookAT.x = SIN(Phi) * COS(Theta) camLookAT.z = SIN(Phi) * SIN(Theta)camLookAT.y = COS(Phi)`

Pages: [1]
 ignore  |  Print

 DesertCoockie (54 views) 2018-05-13 18:23:11 nelsongames (86 views) 2018-04-24 18:15:36 nelsongames (76 views) 2018-04-24 18:14:32 ivj94 (761 views) 2018-03-24 14:47:39 ivj94 (93 views) 2018-03-24 14:46:31 ivj94 (645 views) 2018-03-24 14:43:53 Solater (106 views) 2018-03-17 05:04:08 nelsongames (187 views) 2018-03-05 17:56:34 Gornova (428 views) 2018-03-02 22:15:33 buddyBro (1088 views) 2018-02-28 16:59:18
 Java Gaming Resourcesby philfrei2017-12-05 19:38:37Java Gaming Resourcesby philfrei2017-12-05 19:37:39Java Gaming Resourcesby philfrei2017-12-05 19:36:10Java Gaming Resourcesby philfrei2017-12-05 19:33:10List of Learning Resourcesby elect2017-03-13 14:05:44List of Learning Resourcesby elect2017-03-13 14:04:45SF/X Librariesby philfrei2017-03-02 08:45:19SF/X Librariesby philfrei2017-03-02 08:44:05
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org