I would like to rotate view matrix (I supposed to think this represents camera position).
I already rotate view matrix about Y-axis by using Matrix4f#rotateY successfully.
However, about rotateX this requires the target position at (0,0,0) center of the world, I would like to rotate the view matrix around a specified position.
I tried to rotate the matrix like following:
targetCenter = Vector3f(x, y, z)
viewMatrix
.translate(targetCenter)
.rotateX(rotation)
.translate(targetCenter.mul(-1.0f))
However, this make the rendered model twice. Is this the correct method to rotate view matrix around specified axis ?
EDIT
fun Matrix4f.orbitBy(modelCenter: Vector3f, angleY: Float, angleX: Float, focalLength: Float) {
// Setup both camera's view matrices
val modelCenterCp = Vector3f(modelCenter)
val recenter = Matrix4f().translate(modelCenterCp.mul(-1.0f)) //not needed if world origin
val rotation = Matrix4f()
.rotateY(angleY)
.rotateX(angleX)
val moveBack = Matrix4f().translate(modelCenter) //not needed if world origin
val transfer = moveBack.mul(rotation).mul(recenter) //order from right to left
val eye = Vector3f(0f, modelCenter.y, -focalLength).mulProject(transfer)
val up = Vector3f(0f, 1f, 0f)
this.setLookAt(eye, modelCenter, up)
}
It works in your example because I suppose your target equals the world origin. If you want to rotate around the world origin, you don't need the translation part. If it's around a point it will become mandatory.
What I like to use when computing the view Matrix is to keep 3 values inside my camera:
If you want to orbit around your target point you need to apply your rotation on your eye and upVector, once done you can recompute the viewMatrix using a mat4 lookAt(eye, center, up)
void orbitBy(float yaw, vec3 rotationCenter) {
mat4 recenter = translate(mat4(1.0), -rotationCenter); //not needed if world origin
mat4 rotation = rotateY(mat4(1.0), yaw); //can be replaced by glm::eulerAngleZXY(yaw, pitch, roll) ...
mat4 moveBack = translate(mat4(1.0, rotationCenter)); //not needed if world origin
mat4 transfo = moveBack * rotation * recenter; //order from right to left
m_eye = transfo * m_eye;
m_up = transfo * m_up;
m_viewMatrix = lookAt(m_eye, m_center, m_up);
}
I prefer this approach cause it gives you simpler values which are very helpfull for debugging