JOML 1.8.0 Release

Somewhat in tandem with the LWJGL 3.0.0 release there is now the next JOML version 1.8.0 of joml-master and joml-mini. Both can be used from Maven Central.
Here are the changes compared to the last version 1.7.1.

much obliged!

Though not technically connected to the JOML 1.8.0 release – I just did not want to open a new thread for it – over the last weeks I collected some recurring “anti-patterns” and suboptimal usages of JOML from various projects making us of it as well as LWJGL and JGO forum posts and begun to write them down with best-practices to avoid them:

Preview of what’s to come in the next release:

Much of the next 1.8.1 release of JOML will be about performance improvements for commonly recurring usage patterns.
Most users (in projects, tutorials, online-books, videos) seen so far use JOML in the following way:


Matrix4f m = new Matrix4f().translate(...).rotate(...).scale(...);

This is common for building a model transformation. Even though the above can be optimized with the existing special-case method:


Matrix4f m = new Matrix4f().translationRotateScale(..., ..., ....);

most users probably won’t use the special-case methods, yet expect peak performance.
Therefore, JOML 1.8.1 will focus on optimizing these usage patterns with the issue https://github.com/JOML-CI/JOML/issues/83.
The current implementation of Matrix4f gives a performance increase of around 11% for the above use-case when using rotate() with axis-angle.
When using rotate() with a quaternion it’s even around 37% performance increase.

Nice Kai, but I suggest using a shorter name. My matrix class is called Mat3 Mat4 and my vectors Vec3 Vec4. LongNamesArentDifficult.class

you know nothing, Jon Snow ^^

Real code…


abstract public class _E_PD_Use_Ref_Color_Mult<E extends _Param_Ref_Use_Obj_Col_Mult>
									extends __E_PD_Use_Ref<Param_Ref_Color_Mult<E>, E, int[]>{

_E_PD - Short name XD[spoiler]
hm… _E_PD_UR_Color_Mult
[/spoiler]

That’s really complex for no reason lol.

you know nothing, Jon Snow =)

http://s33.postimg.org/4gzofwdp7/qqq.jpg

and this only template ,it will grow

I feel sorry for the compiler and jvm.

Feel sorry for whoever has to maintain that code. It may run fine, until it doesn’t, and then it doesn’t.

Haha. Thanks for the lol.

Its true, even from small refactoring

  • eclipse jvm crash compilation build - on any file change (with 0 error shown – build error),
    So need clear project Build Data =), weak eclipse ^^

Bad advices from enterprise developer…
“How to be good enterprise developer and become irreplaceable part of company:
-write code, that no one except you can"t support XD”

(can’t find youtube video about this :frowning: )

p.s y, need move classes together by usage in img above - it save little space and organize folders ^^
It’s all in big refactoring - i can’t run code someting like half month :wink:
(so all i doing now, can’t even work at all (1000 - 2000 errors in project its ok) XD)

up:
pp.s I have no idea how people support big projects - its ongoing nightmare…

Latest release 1.8.1 is out and can be used from Maven Central. See the change log
It contains the performance improvements talked about earlier in this thread. This is for users who used the generic Matrix4 methods, such as mul() and invert() in situations where certain properties of the matrix are known so that rather the much faster specialized methods could have been used instead. The new release will now route to these methods automatically.

The next release version 1.8.2 of JOML will make memory copies of Matrix4f on common JVMs, such as OpenJDK and HotSpot, even faster.
This includes typical usecases such as transferring a Matrix4f into a NIO buffer for submission to OpenGL via an OpenGL binding library, copying a Matrix4f into another Matrix4f or setting it to identity().
See commits:

This is a small maintenance release mainly improving Matrix4f <-> NIO Buffer copying. See the release notes for full info.

        final void copy(Matrix4f src, Matrix4f dest) {
            UNSAFE.putLong(dest, m00FieldOffset,    UNSAFE.getLongVolatile(src, m00FieldOffset));
            UNSAFE.putLong(dest, m00FieldOffset+8,  UNSAFE.getLongVolatile(src, m00FieldOffset+8));
            UNSAFE.putLong(dest, m00FieldOffset+16, UNSAFE.getLongVolatile(src, m00FieldOffset+16));
            UNSAFE.putLong(dest, m00FieldOffset+24, UNSAFE.getLongVolatile(src, m00FieldOffset+24));
            UNSAFE.putLong(dest, m00FieldOffset+32, UNSAFE.getLongVolatile(src, m00FieldOffset+32));
            UNSAFE.putLong(dest, m00FieldOffset+40, UNSAFE.getLongVolatile(src, m00FieldOffset+40));
            UNSAFE.putLong(dest, m00FieldOffset+48, UNSAFE.getLongVolatile(src, m00FieldOffset+48));
            UNSAFE.putLong(dest, m00FieldOffset+56, UNSAFE.getLongVolatile(src, m00FieldOffset+56));
        }

Why volatile?

True. Volatile was not really needed, only “ordered” writes. The current code that shipped with 1.8.2 for this method is:


final void copy(Matrix4f src, Matrix4f dest) {
    for (int i = 0; i < 8; i++) {
        UNSAFE.putOrderedLong(dest, Matrix4f_m00 + (i << 3), UNSAFE.getLong(src, Matrix4f_m00 + (i << 3)));
    }
}

When not using “ordered”, the JIT seemed to “optimize”/rewrite memory write accesses across subsequent reads of the same fields (maybe because the JIT did not know anymore that it actually was that field being written to).

Since the last notification, three new versions of JOML have been released, the latest of which is 1.8.5 (now in Maven Central).

Most notable changes:

See the release change logs for more information:

To note. The linked paper and that thread on polynomial approximations are examples of exactly how to not attack a problem. If anyone want to create approximations…start here: http://sollya.gforge.inria.fr/ either the software itself or walk the papers. There’s also the papers by robin green which cover the basics quickly.

Example: “It takes a long time to create these approximations”. It should take less than a second. The approximation is 15th degree (pretty high) and the range reduction is unsound.

Err… Isn’t that just a simple Taylor expansion of sin(x) around x=0? You can calculate almost optimal coefficients for that very easily. I wrote a tiny program that calculates them, then refines them by testing extremely tiny random variations of to try to refine the final results, compared to Math.sin(). Took me a solid 20 min to code up:

Current error: 9.706913049840798E-14
    1E0
    -1.6666655242443085E-1
    8.333154022693634E-3
    -1.9835088460240513E-4
    2.7543485430214787E-6
    -2.503251117502714E-8
    1.6041354355955662E-10
    -6.5907815229721E-13

Error was the total squared error of 100 evenly distributed sin() samples between 0 and PI/2.


private static double sinApprox(float[] constants, float x){
	float x2 = x * x;
	float tx = x * x2;
	float sin = x * constants[0];
	for(int i = 1; i < constants.length; i++){
		sin += tx * constants[i];
		tx *= x2;
	}
	return sin;
}