I'm developing a 3D game in Java using LWJGL and JOML. In order to simplify player and NPC coding, I'm representing their orientation as two scalar quantities: "direction" and "angle" (maybe not the best names). "Direction" is the compass direction that the object is facing, and "angle" is the angle of the object relative to a horizontal plane. So for example if a player has a direction of 180 and an angle of 45, it will be looking south at a point halfway between the horizon and the zenith.

First question: what is this kind of rotation called officially?

I've already written code to handle calculations on points/positions represented in this manner, but I don't know how to include the rotation in a transformation matrix for OpenGL. I have the following code to produce a transformation matrix for an object:

Matrix4f world_matrix = new Matrix4f().identity().translate((float) position.x, (float) position.z, (float) -position.y).rotateY((float) Math.toRadians(-direction));

(same code, more readable)

Matrix4f world_matrix = new Matrix4f()
    .translate((float) position.x, (float) position.z, (float) -position.y)
    .rotateY((float) Math.toRadians(-direction));

where position is the location of the object and direction is the aforedescribed "direction" of the object.

Second question: how do I include angle in world_matrix?


1 Answer 1


What you're using are called Euler angles. Euler angles can tell the direction of a vector (in your case the direction that an object is facing) with 2 angles, one around the Y axis (yaw) and 1 around the X axis (pitch).

A common misconception is that Euler angles consist of angles around the X, Y and Z axes, but what those are really called are Tait-Bryan angles.

You can include your "angle" in the world matrix by rotating around the X axis after the rotation around the Y axis (using the rotateX method at the end of your transformation chain). Note that the transformation methods in JOML act after any existing transformations already applied to the matrix, so rotateX will rotate the object about its local X axis (to set the object's rotation relative to the global coordinate space use one of the "setRotation" methods).

  • \$\begingroup\$ I've done that for my camera angle but it doesn't work for objects (as I originally expected it wouldn't) because the angle rotation isn't about the global X axis but about the local (object-relative) X axis. .rotationX() rotates the object about the global X axis. \$\endgroup\$ Commented Aug 16, 2016 at 15:14
  • \$\begingroup\$ I don't understand why Matrix4f().identity().rotateX((float) Math.toRadians(-angle)).rotateY((float) Math.toRadians(direction)).translate((float) -position.x, (float) -position.z, (float) position.y) works for the camera matrix but Matrix4f().identity().translate((float) position.x, (float) position.z, (float) -position.y).rotateX((float) Math.toRadians(angle)).rotateY((float) Math.toRadians(-direction)) doesn't work for an object's transformation matrix (the object ends up "sideways" as direction moves away from 0). \$\endgroup\$ Commented Aug 16, 2016 at 15:22
  • \$\begingroup\$ Never mind I've got it now - I put .rotateX() after .rotateY() and now it works. I thought the rotations were independent of each other (i.e. that .rotateX() means "set the rotation about the X (global) axis") but they're not (i.e. .rotateX() actually means "rotate the object about the (local) X axis, taking into account any existing rotations"). \$\endgroup\$ Commented Aug 16, 2016 at 15:24
  • \$\begingroup\$ I will once my edit has been accepted (as it is it isn't worthy of accepting, because it's too confusing to answer the question by itself). \$\endgroup\$ Commented Aug 16, 2016 at 16:36
  • \$\begingroup\$ @MichealJohnson I already accepted ages ago \$\endgroup\$
    – Bálint
    Commented Aug 16, 2016 at 16:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .