linalg look_at left-handedness issues
Context
Odin: dev-2024-03-nightly:4c35633e0
OS: Windows 11 Home Basic (version: 23H2), build 22631.3296
CPU: 13th Gen Intel(R) Core(TM) i9-13900HX
RAM: 32507 MiB
Backend: LLVM 17.0.1
The problem
In core/math/linalg lib there are many functions that allow a flip_z_axis variable (default true). These works fine (i think) in a right handed coordinate system, but the flip_z_axis is kinda a lie.
Let us have a look at one of them:
@(require_results)
matrix4_look_at_f32 :: proc "contextless" (eye, centre, up: Vector3f32, flip_z_axis : bool) -> (m: Matrix4f32) {
f := normalize(centre - eye)
s := normalize(cross(f, up))
u := cross(s, f)
fe := dot(f, eye)
return {
+s.x, +s.y, +s.z, -dot(s, eye),
+u.x, +u.y, +u.z, -dot(u, eye),
-f.x, -f.y, -f.z, +fe if flip_z_axis else -fe,
0, 0, 0, 1,
}
}
Let us have a look at why the matrix4_look_at_f32 is not correct.
One would expect that in a left handed coordinate system where x positive is right, y positive is up and z positive is forward (into the screen) that the matrix : look_at_mat := linalg.matrix4_look_at_f32({0,0,0}, {0,0,1}, {0,1,0}, false); would inded not flip any axis.
The output from the operation is shown below:
look_at_mat : matrix[
-1, 0, 0, 0,
0, 1, 0, 0,
0, 0, -1, 0,
0, 0, 0, 1,
]
It is quite clear to see that the axis was flipped!
and as a matter of fact, the matrix with flip_z_axis = true looks the exact same.
One might note that the x-axis is also flipped making this a 180 degree rotation and not a flip of the handedness.
But here is the weird thing. This will keep a right handed coordinate system right handed and a left handed coordinate system left handed.
So the problem might not be that it is inherently incorrect, but it does define the axis the following way:
For the right handed coordinate system the coordinates are x-right, y-up, z-back (out of screen).
But for the left handed coordinate system the coordinate are x-left, y-up, z-back. Why would it flip x-axis and not the z?
It seems weird and I have not found any documentation on what the left-handed vs right-handed coordinates are supossed to be.
To me this feels like a design flaw. It seems that flip_z_axis implies that it will be the z-axis that are flipped not the x-axis.
From the operation look_at_mat := linalg.matrix4_look_at_f32({0,0,0}, {0,0,1}, {0,1,0}, false); I would expect the matrix to return the identity matrix.
Just like look_at_mat := linalg.matrix4_look_at_f32({0,0,0}, {0,0,-1}, {0,1,0}, true); return the identity matrix for the right handed coordinate system.
There are many functions in the linalg library with the same problem.
Please don't use stupid titles.