You are doing something in your functions which is very unsafe. You are using
if(!dest) { dest = mat; }
This is very bad because users won’t expect that input matrix to be changed inside the function. For example:
var m1 = mat4.create(...);
var m2 = mat4.create(...);
var m3 = mat4.multiply(m1, m2);
var m4 = mat4.multiply(m1, m3); // will not work as expected since m1 is changed
Users will expect m1 to still have the value it had before the previous line, however m1 and m3 now point to the same object. This should not be the default behavior, and no parameters other than dest should be modified inside the function.
If the user wanted to explicitly use m1 to store the final value he could simply have done:
mat4.multiply(m1, m2, m1);
This way it’s much clearer what he meant to do. It also makes the objects themselves behave as if they were immutable in some sense, since they are never modified inside the functions unless explicitly told to. No functionality or performance is lost, and it should make for a much safer coding practice. The solution is simple, instead of setting “dest = mat;” (or equivalent) it should set it to “mat4.create();” (or equivalent)
The affected functions include (but may not be limited to): vec3.negate(), vec3.normalize(), vec3.cross(), vec3.direction(), mat4.inverse(), mat4.multiply(), mat4.multiplyVec3(), mat4.multiplyVec4(), mat4.rotate(), mat4.rotateX(), mat4.rotateY(), mat4.rotateZ(), quat4.normalize(), quat4.multiply(), quat4.multiplyVec3().