This one is easy.

**How it works the long way**Once you've built the camera matrix, you can transform the default orientation vectors for

`at=(0, 0, -1)` and

`up=(0, 1, 0)` with the inverse of that matrix to obtain the real 'at' and 'up' vectors for OpenAL, like so:

`Matrix4f cam = ...; // <- some camera transformation`

Matrix4f invCam = new Matrix4f(cam).invert(); // <- inverse of camera

Vector3f at = new Vector3f(0, 0, -1);

invCam.transformDirection(at);

Vector3f up = new Vector3f(0, 1, 0);

invCam.transformDirection(up);

After this,

`at` and

`up` contain the transformed vectors for OpenAL.

The method

`Matrix4f.transformDirection()` takes care that only the rotational part of the camera transformation is used when transforming a

*direction* vector as opposed to a

*position*.

**Why do we need to invert the camera matrix?**The reason for that is that the uninverted camera matrix transforms from some "world" coordinate system into eye/view/camera space.

In the latter space the direction along which the camera is looking is always

`(0, 0, -1)` and up is always

`(0, 1, 0)`.

But we need the opposite transformation to get from that view/eye/camera-space vectors to the "world" vectors for that particular camera transformation. And the opposite transformation in matrix-speak is the matrix inverse.

**The shortcut for this in JOML**Now that you know how it works in theory, let's do it more efficiently.

Because obtaining the world-space vectors from a (camera) transformation matrix for the base axes is such a frequent task, JOML provides a faster shortcut method for this that does not require to calculate the matrix inverse and does not require to perform a full matrix/vector multiplication:

`Matrix4f cam = ...; // <- some camera transformation`

Vector3f at = new Vector3f();

cam.positiveZ(at).negate();

Vector3f up = new Vector3f();

cam.positiveY(up);

This is equivalent to the above code.