Search code examples
javac++matrixrotationlwjgl

LWJGL: Strange Matrix rotation effect using "partial" axis


I'm currently following the OpenGL tutorials over at https://learnopengl.com/ except I'm doing it in Java instead of C++. It's going quite well but I've stumbled upon something that may be caused by a difference in implementation, unless I'm doing something wrong.

I'm at the part where a cube has just been rendered and is rotating. The tutorial gives the following code:

model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));```

To elaborate on this, model is the model matrix. The GLM library is used to rotate this matrix, using glfwGetTime() which returns the time in seconds since initialization. The part that I'm curious about is the vec3(0.5f, 1.0f, 0.0f). Here they specify which Euler angles/axes to rotate around, and by the looks of it, specifying 0.5f for the X axis rotates it half the amount on X compared to Y here. The resulting cube looks like this:

https://i.imgur.com/caK1BTS.mp4

Back to Java, I have set up a similar thing. I run the following on the model matrix:

Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.5f, 1.0f, 0.0f),  model, model);

The resulting cube rotates like this, oddly enough:

https://i.imgur.com/0ZqpgEA.mp4

If I change things up by separating which axe is affected per rotation, the cube looks normal like in this video:

https://i.imgur.com/u2zV2Zo.mp4

Code:

Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(50), new Vector3f(0.0f, 1.0f, 0.0f),  model, model);
Matrix4f.rotate(timeSinceStart * (float) Math.toRadians(25), new Vector3f(1.0f, 0.0f, 0.0f),  model, model);

The difference here is that instead of doing "half" an axis, I instead do half the degrees on a full axis.

My question then is: Is it wrong of me to attempt to rotate around an axis that is not set to 1.0f? Is the GLM implementation of the 4x4 matrix rotate function different from the LWJGL-Utils' Matrix4f class?

PS: I'm using LWJGL 2 and Java 8u141. I'd be happy to provide more code about my setup if requested, but the entire process for rendering a cube is extensive. I've done the tutorial 2-3 times from scratch with the same result, so I think there's something going on here.


Solution

  • According to this source in GLM GitHub repository GLM does rotation axis normalization before constructing transformation matrix. LWJGL-Utils Matrix4f class doesn't do this. So probably you should just normalize rotation axis (0.5f, 1.0f, 0.0f) by yourself.

    Also, I'm not shure that you're right when calling rotation axis as 'Euler angles'. Euler angles may define rotation about first axis and then about derived second axis and so on. They basically define rotation as combination of three rotations about two or three base axes. Here you have one rotation axis and rotation angle.

    See: