UNPKG

toloframework

Version:

Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.

366 lines (324 loc) 11.8 kB
"use strict"; module.exports = { m4: { identity: identity4, matrix: mat4, vector: vec4, projection: projection4, translation: translation4, rotationX: rotationX4, rotationY: rotationY4, rotationZ: rotationZ4, scaling: scaling4, copy: copy, normalize: normalize, cameraPolar: cameraPolar4, perspective: perspective4, mul: mul }, m3: { identity: identity3, matrix: mat3, projection: projection3, translation: translation3, rotation: rotation3, scaling: scaling3 } }; function copy( arr ) { return new Float32Array( arr ); } function normalize( arr ) { var n = copy( arr ); var len = 0, v, k; for ( k = 0; k < n.length; k++ ) { v = n[ k ]; len += v * v; } if ( len > 0 ) { var coeff = 1 / Math.sqrt( len ); for ( k = 0; k < n.length; k++ ) { n[ k ] *= coeff; } } return n; } function cameraPolar4( targetX, targetY, targetZ, dis, lat, lng, result ) { result = result || new Float32Array( 16 ); var cosLat = Math.cos( lat ); var sinLat = Math.sin( lat ); var cosLng = - Math.cos( lng + Math.PI * .5 ); var sinLng = - Math.sin( lng + Math.PI * .5 ); // Vecteur Z de la caméra. var Zx = cosLng * cosLat; var Zy = sinLng * cosLat; var Zz = sinLat; // V2/2 // Le vecteur X se déduit par un produit vectoriel de (0,0,1) avec Z. var Xx = -Zy; var Xy = Zx; var Xz = 0; // Comme (0,0,1) n'est pas orthogonal à Z, il faut normaliser X. var len = Math.sqrt( Xx * Xx + Xy * Xy + Xz * Xz ); Xx /= len; Xy /= len; Xz /= len; // Y peut alors se déduire par le produit vectoriel de Z par X. // Et il n'y aura pas besoin de le normaliser. var Yx = Zy * Xz - Zz * Xy; var Yy = Xx * Zz - Xz * Zx; var Yz = Zx * Xy - Zy * Xx; // Translation. var Tx = -( Zx * dis + targetX ); var Ty = -( Zy * dis + targetY ); var Tz = -( Zz * dis + targetZ ); // Le résultat est la multiplication de la projection avec la translation. result[ 0 ] = Xx; result[ 4 ] = Xy; result[ 8 ] = Xz; result[ 12 ] = Tx * Xx + Ty * Xy + Tz * Xz; result[ 1 ] = Yx; result[ 5 ] = Yy; result[ 9 ] = Yz; result[ 13 ] = Tx * Yx + Ty * Yy + Tz * Yz; result[ 2 ] = Zx; result[ 6 ] = Zy; result[ 10 ] = Zz; result[ 14 ] = Tx * Zx + Ty * Zy + Tz * Zz; result[ 3 ] = 0; result[ 7 ] = 0; result[ 11 ] = 0; result[ 15 ] = 1; return result; } /** * Define the `frustum`. * @param {number} fieldAngle - View angle in radians. Maximum is PI. * @param {number} aspect - (width / height) of the canvas. * @param {number} near - Clip every Z lower than `near`. * @param {number} far - Clip every Z greater than `far`. */ function perspective4( fieldAngle, aspect, near, far, result ) { result = result || new Float32Array( 16 ); var f = Math.tan( Math.PI * 0.5 - 0.5 * fieldAngle ); var rangeInv = 1.0 / ( near - far ); result[ 0 ] = f / aspect; result[ 1 ] = 0; result[ 2 ] = 0; result[ 3 ] = 0; result[ 4 ] = 0; result[ 5 ] = f; result[ 6 ] = 0; result[ 7 ] = 0; result[ 8 ] = 0; result[ 9 ] = 0; result[ 10 ] = ( near + far ) * rangeInv; result[ 11 ] = -1; result[ 12 ] = 0; result[ 13 ] = 0; result[ 14 ] = near * far * rangeInv * 2; result[ 15 ] = 0; return result; } function identity3() { return mat3( 1, 0, 0, 0, 1, 0, 0, 0, 1 ); } function identity4() { return mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); } function inverse4( m, dst ) { dst = dst || mat4( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); var m00 = m[ 0 ]; var m01 = m[ 1 ]; var m02 = m[ 2 ]; var m03 = m[ 3 ]; var m10 = m[ 4 ]; var m12 = m[ 5 ]; var m11 = m[ 6 ]; var m13 = m[ 7 ]; var m20 = m[ 8 ]; var m21 = m[ 9 ]; var m22 = m[ 10 ]; var m23 = m[ 11 ]; var m30 = m[ 12 ]; var m31 = m[ 13 ]; var m32 = m[ 14 ]; var m33 = m[ 15 ]; var tmp_0 = m22 * m33; var tmp_1 = m32 * m23; var tmp_2 = m12 * m33; var tmp_3 = m32 * m13; var tmp_4 = m12 * m23; var tmp_5 = m22 * m13; var tmp_6 = m02 * m33; var tmp_7 = m32 * m03; var tmp_8 = m02 * m23; var tmp_9 = m22 * m03; var tmp_10 = m02 * m13; var tmp_11 = m12 * m03; var tmp_12 = m20 * m31; var tmp_13 = m30 * m21; var tmp_14 = m10 * m31; var tmp_15 = m30 * m11; var tmp_16 = m10 * m21; var tmp_17 = m20 * m11; var tmp_18 = m00 * m31; var tmp_19 = m30 * m01; var tmp_20 = m00 * m21; var tmp_21 = m20 * m01; var tmp_22 = m00 * m11; var tmp_23 = m10 * m01; var t0 = ( tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31 ) - ( tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31 ); var t1 = ( tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31 ) - ( tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31 ); var t2 = ( tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31 ) - ( tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31 ); var t3 = ( tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21 ) - ( tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21 ); var d = 1.0 / ( m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3 ); dst[ 0 ] = d * t0; dst[ 1 ] = d * t1; dst[ 2 ] = d * t2; dst[ 3 ] = d * t3; dst[ 4 ] = d * ( ( tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30 ) - ( tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30 ) ); dst[ 5 ] = d * ( ( tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30 ) - ( tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30 ) ); dst[ 6 ] = d * ( ( tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30 ) - ( tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30 ) ); dst[ 7 ] = d * ( ( tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20 ) - ( tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20 ) ); dst[ 8 ] = d * ( ( tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33 ) - ( tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33 ) ); dst[ 9 ] = d * ( ( tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33 ) - ( tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33 ) ); dst[ 10 ] = d * ( ( tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33 ) - ( tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33 ) ); dst[ 11 ] = d * ( ( tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23 ) - ( tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23 ) ); dst[ 12 ] = d * ( ( tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12 ) - ( tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22 ) ); dst[ 13 ] = d * ( ( tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22 ) - ( tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02 ) ); dst[ 14 ] = d * ( ( tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02 ) - ( tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12 ) ); dst[ 15 ] = d * ( ( tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12 ) - ( tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02 ) ); return dst; } function projection3( width, height ) { return mat3( 2 / width, 0, 0, 0, -2 / height, 0, 0, 0, 1 ); } function projection4( width, height, depth ) { return mat4( 2 / width, 0, 0, 0, 0, -2 / height, 0, 0, 0, 0, 2 / depth, 0, 0, 0, 0, 1 ); } function translation3( tx, ty ) { return mat3( 1, 0, 0, 0, 1, 0, tx, ty, 1 ); } function translation4( tx, ty, tz ) { return mat4( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1 ); } function rotation3( rad ) { var c = Math.cos( rad ); var s = Math.sin( rad ); return mat3( c, -s, 0, s, c, 0, 0, 0, 1 ); } function rotationX4( rad ) { var c = Math.cos( rad ); var s = Math.sin( rad ); return mat4( 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1 ); } function rotationY4( rad ) { var c = Math.cos( rad ); var s = Math.sin( rad ); return mat4( c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1 ); } function rotationZ4( rad ) { var c = Math.cos( rad ); var s = Math.sin( rad ); return mat4( c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); } function scaling3( sx, sy ) { return mat3( sx, 0, 0, 0, sy, 0, 0, 0, 1 ); } function scaling4( sx, sy, sz ) { return mat4( sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1 ); } function mat2( v00, v10, v01, v11 ) { return Float32Array( [ v00, v10, v01, v11 ] ); } function mat3( v00, v10, v20, v01, v11, v21, v02, v12, v22 ) { return new Float32Array( [ v00, v10, v20, v01, v11, v21, v02, v12, v22 ] ); } function mat4( v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, v33 ) { return new Float32Array( [ v00, v10, v20, v30, v01, v11, v21, v31, v02, v12, v22, v32, v03, v13, v23, v33 ] ); } function vec2( a, b ) { return new Float32Array( [ a, b ] ); } function vec3( a, b, c ) { return new Float32Array( [ a, b, c ] ); } function vec4( a, b, c, d ) { return new Float32Array( [ a, b, c, d ] ); } var MUL = { m4m4: function ( a, b, result ) { result = result || new Float32Array( 4 ); result[ 0 ] = a[ 0 ] * b[ 0 ] + a[ 2 ] * b[ 1 ]; result[ 1 ] = a[ 1 ] * b[ 0 ] + a[ 3 ] * b[ 1 ]; result[ 2 ] = a[ 0 ] * b[ 2 ] + a[ 2 ] * b[ 3 ]; result[ 3 ] = a[ 1 ] * b[ 2 ] + a[ 3 ] * b[ 3 ]; return result; }, m9m9: function ( a, b, result ) { result = result || new Float32Array( 9 ); result[ 0 ] = a[ 0 ] * b[ 0 ] + a[ 3 ] * b[ 1 ] + a[ 6 ] * b[ 2 ]; result[ 1 ] = a[ 1 ] * b[ 0 ] + a[ 4 ] * b[ 1 ] + a[ 7 ] * b[ 2 ]; result[ 2 ] = a[ 2 ] * b[ 0 ] + a[ 5 ] * b[ 1 ] + a[ 8 ] * b[ 2 ]; result[ 3 ] = a[ 0 ] * b[ 3 ] + a[ 3 ] * b[ 4 ] + a[ 6 ] * b[ 5 ]; result[ 4 ] = a[ 1 ] * b[ 3 ] + a[ 4 ] * b[ 4 ] + a[ 7 ] * b[ 5 ]; result[ 5 ] = a[ 2 ] * b[ 3 ] + a[ 5 ] * b[ 4 ] + a[ 8 ] * b[ 5 ]; result[ 6 ] = a[ 0 ] * b[ 6 ] + a[ 3 ] * b[ 7 ] + a[ 6 ] * b[ 8 ]; result[ 7 ] = a[ 1 ] * b[ 6 ] + a[ 4 ] * b[ 7 ] + a[ 7 ] * b[ 8 ]; result[ 8 ] = a[ 2 ] * b[ 6 ] + a[ 5 ] * b[ 7 ] + a[ 8 ] * b[ 8 ]; return result; }, m16m16: function ( a, b, result ) { result = result || new Float32Array( 16 ); result[ 0 ] = a[ 0 ] * b[ 0 ] + a[ 4 ] * b[ 1 ] + a[ 8 ] * b[ 2 ] + a[ 12 ] * b[ 3 ]; result[ 1 ] = a[ 1 ] * b[ 0 ] + a[ 5 ] * b[ 1 ] + a[ 9 ] * b[ 2 ] + a[ 13 ] * b[ 3 ]; result[ 2 ] = a[ 2 ] * b[ 0 ] + a[ 6 ] * b[ 1 ] + a[ 10 ] * b[ 2 ] + a[ 14 ] * b[ 3 ]; result[ 3 ] = a[ 3 ] * b[ 0 ] + a[ 7 ] * b[ 1 ] + a[ 11 ] * b[ 2 ] + a[ 15 ] * b[ 3 ]; result[ 4 ] = a[ 0 ] * b[ 4 ] + a[ 4 ] * b[ 5 ] + a[ 8 ] * b[ 6 ] + a[ 12 ] * b[ 7 ]; result[ 5 ] = a[ 1 ] * b[ 4 ] + a[ 5 ] * b[ 5 ] + a[ 9 ] * b[ 6 ] + a[ 13 ] * b[ 7 ]; result[ 6 ] = a[ 2 ] * b[ 4 ] + a[ 6 ] * b[ 5 ] + a[ 10 ] * b[ 6 ] + a[ 14 ] * b[ 7 ]; result[ 7 ] = a[ 3 ] * b[ 4 ] + a[ 7 ] * b[ 5 ] + a[ 11 ] * b[ 6 ] + a[ 15 ] * b[ 7 ]; result[ 8 ] = a[ 0 ] * b[ 8 ] + a[ 4 ] * b[ 9 ] + a[ 8 ] * b[ 10 ] + a[ 12 ] * b[ 11 ]; result[ 9 ] = a[ 1 ] * b[ 8 ] + a[ 5 ] * b[ 9 ] + a[ 9 ] * b[ 10 ] + a[ 13 ] * b[ 11 ]; result[ 10 ] = a[ 2 ] * b[ 8 ] + a[ 6 ] * b[ 9 ] + a[ 10 ] * b[ 10 ] + a[ 14 ] * b[ 11 ]; result[ 11 ] = a[ 3 ] * b[ 8 ] + a[ 7 ] * b[ 9 ] + a[ 11 ] * b[ 10 ] + a[ 15 ] * b[ 11 ]; result[ 12 ] = a[ 0 ] * b[ 12 ] + a[ 4 ] * b[ 13 ] + a[ 8 ] * b[ 14 ] + a[ 12 ] * b[ 15 ]; result[ 13 ] = a[ 1 ] * b[ 12 ] + a[ 5 ] * b[ 13 ] + a[ 9 ] * b[ 14 ] + a[ 13 ] * b[ 15 ]; result[ 14 ] = a[ 2 ] * b[ 12 ] + a[ 6 ] * b[ 13 ] + a[ 10 ] * b[ 14 ] + a[ 14 ] * b[ 15 ]; result[ 15 ] = a[ 3 ] * b[ 12 ] + a[ 7 ] * b[ 13 ] + a[ 11 ] * b[ 14 ] + a[ 15 ] * b[ 15 ]; return result; }, m16m4: function ( a, b, result ) { result = result || new Float32Array( 4 ); result[ 0 ] = a[ 0 ] * b[ 0 ] + a[ 4 ] * b[ 1 ] + a[ 8 ] * b[ 2 ] + a[ 12 ] * b[ 3 ]; result[ 1 ] = a[ 1 ] * b[ 0 ] + a[ 5 ] * b[ 1 ] + a[ 9 ] * b[ 2 ] + a[ 13 ] * b[ 3 ]; result[ 2 ] = a[ 2 ] * b[ 0 ] + a[ 6 ] * b[ 1 ] + a[ 10 ] * b[ 2 ] + a[ 14 ] * b[ 3 ]; result[ 3 ] = a[ 3 ] * b[ 0 ] + a[ 7 ] * b[ 1 ] + a[ 11 ] * b[ 2 ] + a[ 15 ] * b[ 3 ]; return result; } }; function mul( a, b, result ) { var f = MUL[ 'm' + a.length + 'm' + b.length ]; if ( typeof f !== 'function' ) { throw Error( "[webgl.math.mul] I don't know how to multiply 'M" + a.length + "' with 'M" + b.length + "'!" ); } return f( a, b, result ); }