JOML

Started by Kai, May 31, 2015, 14:08:57

Previous topic - Next topic

Kai

JOML has now a nice auto-generated GitHub Pages site with links to its generated JavaDocs. :)
Also, JOML's current 1.3.2-SNAPSHOT head is now pretty complete and contains full JavaDocs documentation for each method and every parameter/return value, passing JDK 1.8 doclint.

Kai

As of now, all snapshots and releases of JOML will be deployed to Sonatype.org.
The current version 1.3.3-SNAPSHOT is now there and can be used with the coordinates org.joml:joml

Since snapshot releases are not synchronized with Maven Central, you have to add a reference to the repository
https://oss.sonatype.org/content/repositories/snapshots
in your pom.xml, like so:
<repositories>
		<repository>
			<id>Sonatype Snapshots Repository</id>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
			<url>https://oss.sonatype.org/content/repositories/snapshots</url>
		</repository>
	</repositories>


However, major releases of JOML (the next being 1.4.0) will be staged and synchronized with Maven Central, so you would not need the above repository declaration.

As part of the process, JOML now also has a domain joml.org, which header-redirects to http://joml-ci.github.io/JOML/ until we have a web presence.

SHC

Instead of the header redirecting, set the domain to your GitHub pages by adding a CNAME record.

https://help.github.com/articles/adding-a-cname-file-to-your-repository/

BrickFarmer

Quote from: Kai on July 01, 2015, 18:57:38
However, major releases of JOML (the next being 1.4.0) will be staged and synchronized with Maven Central

Great news, and thanks :)

I have finally been able to port my Oculus VR code over to JOML, and the strange matrix issues I was previously having are now gone :)
Oculus Rift CV1, MBP 2016 - 2.9 i7 - Radeon Pro 460  OSX 10.12.4,  Win7 - i5 4670K - GTX1070.
Oculus Rift VR Experiments: https://github.com/WhiteHexagon

Kai

Glad to hear that.
Also the latest 1.3.4 snapshot (already deployed to sonatype) contains the implementation of an incredibly nifty way to compute the camera frustum planes (in class GeometryUtils). This insanely clever algorithm is also waaay faster and more accurate than what libGDX is currently doing (i.e. they go the way about unprojecting each of the 8 frustum corner points back from NDC, which requires a matrix inversion, and then building the planes from 3 of the corner points, each).
These can be used for frustum culling on the CPU, which is especially useful to keep the FPS high in very demanding scenes on the Rift. :)

EDIT:
The Matrix4 classes now also have fast and convenient is*InsideFrustum() methods for point, sphere and axis-aligned box tests.
Those are now on the edge towards render engine math utility functions, but JOML wants to provide math for OpenGL rendering calculations and I think this frustum check functions fit into this definition quite nicely.

These functions make use of the aforementioned method to compute the frustum planes (which is now also a part of the Matrix4 classes), and can be used for frustum culling in someone's voxel game, for example, like so:

Matrix4f m = new Matrix4f();
m.perspective(45.0f, (float)width/height, 0.01f, 100.0f)
 .lookAt(0.0f, 0.0f, 10.0f,
         0.0f, 0.0f, 0.0f,
         0.0f, 1.0f, 0.0f);
// ...
Vector3f boxMin = new Vector3f(1.0f, 0.0f, 0.0f);
Vector3f boxMax = new Vector3f(2.0f, 1.0f, 1.0f);
boolean inside = m.isAabInsideFrustum(boxMin, boxMax);
// or
boolean inside = m.isAabInsideFrustum(1.0f, 0.0f, 0.0f, 
                                      2.0f, 1.0f, 1.0f);


The method directly operates on that view-projection or modelview-projection matrix which is used to transform the scene into clipping space. Therefore, JOML does not require a dedicated "Camera" class with various other parameters but can use the underlying transformation matrix directly.

(On my crappy i3-2120 the isAabInsideFrustum() can perform around 40 million AAB-frustum-intersection tests per second on a generic matrix, without any caching of frustum planes or anything else.)

EDIT2:

There is now also a Matrix4.frustumRayDir() which efficiently computes the direction of a ray starting from the origin and going through the near frustum plane, with interpolation parameters (x, y) to compute rays over the whole view frustum. This is especially useful for computing the eye rays for software raycasting/raytracing.

(it performs at about 30 million ray direction computations per second)

spasi

Fantastic progress Kai. Haven't used JOML yet so can't give more feedback, but I'm following the commits and love that you're keeping it simple and super useful.

Kai

Thank you Spasi!

Due to most of JOML's users wanting to use radians instead of degrees for angle parameters, starting with JOML's current 1.3.5-SNAPSHOT radians are now being used everywhere instead of degrees.
This also includes Matrix4.perspective, which now differs from the GLU API, so you gonna have to make:
new Matrix4f().perspective((float)Math.toRadians(60.0f), 1.0f, 0.01f, 100.0f);

if you want a 60 degrees vertical field of view angle.

See this issue for further info.

Kai

Hello everyone,

finally, JOML also has a working and reliable method to compute the eight frustum corner points of any arbitrary projection or combined modelview-projection matrix in Matrix4.frustumCorner.
I was searching for a working way to do this for some time and finally found the 3-planes intersection technique to be the most performant.
It is also far more performant than the usual "transform NDC by the inverse of the matrix" way, which is taken by libGDX, among others.

The method generally is useful if you want to display a mesh representing a camera's view frustum in your scene / model editor, etc.

To obtain all 8 corners of an arbitrary view-projection matrix, first the near plane corners in counter-clockwise order, then the far plane corners in clockwise order, use:
Matrix4f m = new Matrix4f()
  .perspective((float) Math.toRadians(90), 1.0f, 0.1f, 100.0f)
  .lookAt(0, 3, 10,
          0, 0,  0, 
          0, 1,  0);
Vector3f[] allCorners = new Vector3f[8];
for (int i = 0; i < 8; i++) {
    m.frustumCorner(i, allCorners[i] = new Vector3f());
}


Matrix4 also defines convenient constants for the first parameter of frustumCorner(), to know which corner is which.
One example of such a constant is 'CORNER_PXNYNZ'.
The naming convention here follows after what sign the respective corner co-ordinate would have for the identity matrix/transformation (i.e. the default OpenGL clip space coordinate system).
'PX' means "positive X", and 'NY' means "negative Y".
So with the given constant, we would get the corner at (1, -1, -1) with the identity matrix.
This coincidentally is also the right-bottom-near corner in a standard OpenGL/GLU perspective projection matrix.

(The method performs at around 50 million corners per second on my i7-3820QM and can, like all the rest of JOML, be fully multithreaded, so potentially scales very well.)

EDIT:

There are now additional Matrix4 methods to get several properties of a perspective transformation, which are:
- perspectiveOrigin() - computes the origin/eye location of an arbitrary perspective transformation (either combined modelview-projection or just projection)
- perspectiveFov() - computes the vertical field-of-view angle of an arbitrary perspective transformation (either combined modelview-projection or just projection)

Kai

Since JOML grows and grows, in order to be equally useful to a wide range of people with slightly differing requirements, as a result the boundary between what is essential/necessary and what is nice to have/convenient/utility is becoming blurrier.
To keep JOML still simple, there will now be a `org.joml:joml-mini` artifact in a new 'mini' git branch.
The goal with this is to keep JOML as simple and intelligible for newcomers as possible and sufficient for the 95% percent of 3D OpenGL applications.
It currently only contains 6 classes and its jar distribution only weighs about 38% (49KB) of the original full-feature `org.joml:joml`.
All non-essential but still useful additional stuff will go in the 'master' branch in the future.

The properties of joml-mini:
- only single-precision floating-point classes
- only 3D and 4D vectors
- no AxisAngle4f (use Quaternionf for rotations)
- no 'utility' classes and methods that are not really necessary
- classes are still named identical to the 'master' branch

What _is_ "necessary" is of course always debatable, but I think joml-mini contains all essential stuff right now.

Kai

First Maven Central deployed release 1.4.0 of joml and joml-mini are out now!
The coordinates are org.joml:joml:1.4.0 and org.joml:joml-mini:1.4.0.

Kai

I am currently preparing another "spin-off" (or variant) of the original JOML, that is called "joml-2d", which will be specifically geared towards 2D applications.
Since 2D applications/games seem so common around Java game developers, I am stripping the 3D classes of JOML off all things that do not apply to 2D, and add other things that do.
Currently, the "2d" branch of JOML's git repository contains only 2 classes: Matrix3f and Vector2f.
The 2D Matrix3f class resembles a bit the 3D Matrix4f class, with one dimension stripped. So the fourth column of Matrix4f becomes the third column in Matrix3f to represent a translation.
With 2D it is also only possible to rotate about the Z axis, so there is no rotateX, rotateY and rotateZ methods anymore, just rotate(). Also quaternions apply no more in 2D.

The general idea is then that with 2D applications you would only build 3x3 transformation matrices, which you also only upload as mat3 uniforms and apply only (x, y, 1.0) vector multiplications on them in your shaders.
The reduced number of arithmetic operations in the 3x3 matrix multiplication and such will also reduce the runtime of JOML-2d.

Altogether, the "ecosystem" of JOML would now be composed of three libraries:
- joml (contains everything for 3D applications, from the fundamentals to useful utility functions)
- joml-mini (contains only the things that 99% of the OpenGL applications would ever need)
- joml-2d (contains only things related to 2D, joml-2d is a spin-off of joml-mini)