[UPDATE] New billboard matrix methods

Started by Kai, January 01, 2016, 13:34:59

Previous topic - Next topic

Kai

I think I'll start the first topic here with some update/bulletin entry.
From now on every new information about changes in JOML will start with a "[UPDATE]" in the subject.

JOML is now finally on-par with XNA's math library with this commit.

The only thing that was missing was a way to create a spherical and cylindrical billboard matrix.
There were some design decisions that needed to be made for this:
1. Should the method assume to operate on an already established view/camera matrix?
2. Should it be post-multiplying or create/set the matrix?

I decided to use the same semantics as does the XNA CreateBillboard and CreateConstrainedBillboard Matrix methods, by having that method create a completely independent model transformation matrix that can later be concatenated/multiplied to a view transformation matrix.

See the BillboardDemo for an example.

Additionally, the Matrix4 classes got a little utility origin() method to determine the camera position from a view/camera transformation matrix. (hint: this is not simply the last column of the matrix).

Oh and by the way: Happy new year! :)

Kai

How to use it
In order to create a cylindrical billboard model matrix for an object located at objPos (in world-coordinates) that should look at a camera at camPos (also in world-coordinates), use the following code:

Vector3f objPos = ...;
Vector3f camPos = ...;
Vector3f up = new Vector3f(0, 1, 0); // <- cylinder axis
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.billboardCylindrical(objPos, camPos, up);


If you don't know the camera position because all you may have is a view/camera transformation matrix, you can use Matrix4f.origin() like so:
Matrix4f camMatrix = ...;
Vector3f objPos = ...;
Vector3f camPos = new Vector3f();
camMatrix.origin(camPos); // <- compute camera position from matrix
Vector3f up = new Vector3f(0, 1, 0);
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.billboardCylindrical(objPos, camPos, up);


This will create a model transformation that will position an object at its specified objPos and rotate it accordingly to let its local +Z axis point to camPos. You can then upload that matrix as a "model" matrix to your shader, or use GL11.glMultMatrixf to multiply that model matrix against the active modelview matrix when using the fixed-function pipeline.