Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linalg look_at left-handedness issues #3392

Open
xzores opened this issue Apr 7, 2024 · 1 comment
Open

linalg look_at left-handedness issues #3392

xzores opened this issue Apr 7, 2024 · 1 comment

Comments

@xzores
Copy link

xzores commented Apr 7, 2024

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.

@gingerBill gingerBill changed the title I am 90% sure linalg is broken linalg look_at left-handedness issues Apr 7, 2024
@gingerBill
Copy link
Member

Please don't use stupid titles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants