LWJGL Forum

Programming => JOML => Topic started by: Kai on January 01, 2016, 13:34:59

Title: [UPDATE] New billboard matrix methods
Post by: Kai on January 01, 2016, 13:34:59
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 (https://github.com/JOML-CI/JOML/commit/6c58ff079ab1fe1b0d34897628e93e50f46b5151).

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 (https://msdn.microsoft.com/en-us/library/bb195598.aspx) and CreateConstrainedBillboard (https://msdn.microsoft.com/en-us/library/bb195602.aspx) 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 (https://github.com/JOML-CI/joml-lwjgl3-demos/blob/master/src/org/joml/lwjgl/BillboardDemo.java) 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! :)
Title: Re: [UPDATE] New billboard matrix methods
Post by: Kai on January 01, 2016, 14:07:56
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 (http://javadoc.lwjgl.org/org/lwjgl/opengl/GL11.html#glMultMatrixf(java.nio.ByteBuffer)) to multiply that model matrix against the active modelview matrix when using the fixed-function pipeline.