diff options
-rw-r--r-- | demos/webgl/CubicVR.js | 11660 | ||||
-rw-r--r-- | demos/webgl/CubicVR_Core.fs | 281 | ||||
-rw-r--r-- | demos/webgl/CubicVR_Core.vs | 127 | ||||
-rw-r--r-- | demos/webgl/bullet_1_1_q1.ccsimple.js | 4404 | ||||
-rw-r--r-- | demos/webgl/bullet_glue.js | 44 | ||||
-rw-r--r-- | demos/webgl/demo.html | 196 |
6 files changed, 16712 insertions, 0 deletions
diff --git a/demos/webgl/CubicVR.js b/demos/webgl/CubicVR.js new file mode 100644 index 00000000..897fc887 --- /dev/null +++ b/demos/webgl/CubicVR.js @@ -0,0 +1,11660 @@ +/* + Javascript port of CubicVR 3D engine for WebGL + by Charles J. Cliffe + http://www.cubicvr.org/ + + May be used under the terms of LGPL v3.0 or greater. +*/ + +/*globals alert: false */ + +/** Global Constants **/ +var M_PI = 3.1415926535897932384626433832795028841968; +var M_TWO_PI = 2.0 * M_PI; +var M_HALF_PI = M_PI / 2.0; + +var SCRIPT_LOCATION = ""; + +try { + Array.forEach(document.querySelectorAll("script"), function (a) { + var pos = a.src.lastIndexOf('/CubicVR.js'); + if (pos > -1) { + SCRIPT_LOCATION = a.src.substr(0, pos) + "/"; + } //if + }); +} +catch(e) { + // likely that 'document' is not defined (doesn't really matter) +} //try + +(function(undef) { + + var CubicVR = this.CubicVR = {}; + + var GLCore = {}; + var Materials = []; + var Material_ref = []; + var Textures = []; + var Textures_obj = []; + var Texture_ref = []; + var Images = []; + var ShaderPool = []; + var MeshPool = []; + + var CoreShader_vs = null; + var CoreShader_fs = null; + + var log; + try { + log = (console !== undefined && console.log) ? + function(msg) { console.log("CubicVR Log: " + msg); } : + function() {}; + } + catch(e) { + log = function() {}; + } //try + + var enums = { + // Math + math: {}, + + frustum: { + plane: { + LEFT: 0, + RIGHT: 1, + TOP: 2, + BOTTOM: 3, + NEAR: 4, + FAR: 5 + } + }, + + octree: { + TOP_NW: 0, + TOP_NE: 1, + TOP_SE: 2, + TOP_SW: 3, + BOTTOM_NW: 4, + BOTTOM_NE: 5, + BOTTOM_SE: 6, + BOTTOM_SW: 7 + }, + + + // Light Types + light: { + type: { + NULL: 0, + POINT: 1, + DIRECTIONAL: 2, + SPOT: 3, + AREA: 4, + MAX: 5 + }, + method: { + GLOBAL: 0, + STATIC: 1, + DYNAMIC: 2 + } + }, + + // Texture Types + texture: { + map: { + COLOR: 0, + ENVSPHERE: 1, + NORMAL: 2, + BUMP: 3, + REFLECT: 4, + SPECULAR: 5, + AMBIENT: 6, + ALPHA: 7, + MAX: 8 + }, + filter: { + LINEAR: 0, + LINEAR_MIP: 1, + NEAREST: 2, + NEAREST_MIP: 3 + } + }, + + uv: { + /* UV Axis enums */ + axis: { + X: 0, + Y: 1, + Z: 2 + }, + + /* UV Projection enums */ + projection: { + UV: 0, + PLANAR: 1, + CYLINDRICAL: 2, + SPHERICAL: 3, + CUBIC: 4, + SKY: 5 + } + }, + + // Shader Map Inputs (binary hash index) + shader: { + map: { + COLOR: 1, + SPECULAR: 2, + NORMAL: 4, + BUMP: 8, + REFLECT: 16, + ENVSPHERE: 32, + AMBIENT: 64, + ALPHA: 128 + }, + + /* Uniform types */ + uniform: { + MATRIX: 0, + VECTOR: 1, + FLOAT: 2, + ARRAY_VERTEX: 3, + ARRAY_UV: 4, + ARRAY_FLOAT: 5, + INT: 6 + } + + }, + + motion: { + POS: 0, + ROT: 1, + SCL: 2, + FOV: 3, + LENS: 4, + NEARCLIP: 5, + FARCLIP: 6, + INTENSITY: 7, + X: 0, + Y: 1, + Z: 2, + V: 3 + }, + + envelope: { + shape: { + TCB: 0, + HERM: 1, + BEZI: 2, + LINE: 3, + STEP: 4, + BEZ2: 5 + }, + behavior: { + RESET: 0, + CONSTANT: 1, + REPEAT: 2, + OSCILLATE: 3, + OFFSET: 4, + LINEAR: 5 + } + }, + + /* Post Processing */ + post: { + output: { + REPLACE: 0, + BLEND: 1, + ADD: 2, + ALPHACUT: 3 + } + } + }; + + var cubicvr_identity = [1.0, 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0, 0.0, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0]; + + /* Base functions */ + var vec2 = { + equal: function(a, b) { + var epsilon = 0.00000001; + + if ((a === undef) && (b === undef)) { + return true; + } + if ((a === undef) || (b === undef)) { + return false; + } + + return (Math.abs(a[0] - b[0]) < epsilon && Math.abs(a[1] - b[1]) < epsilon); + } + }; + + var vec3 = { + length: function(pt) { + return Math.sqrt(pt[0] * pt[0] + pt[1] * pt[1] + pt[2] * pt[2]); + }, + normalize: function(pt) { + var d = Math.sqrt((pt[0] * pt[0]) + (pt[1] * pt[1]) + (pt[2] * pt[2])); + if (d === 0) { + return [0, 0, 0]; + } + return [pt[0] / d, pt[1] / d, pt[2] / d]; + }, + dot: function(v1, v2) { + return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]; + }, + angle: function(v1, v2) { + var a = Math.acos((v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) / (Math.sqrt(v1[0] * v1[0] + v1[1] * v1[1] + v1[2] * v1[2]) * Math.sqrt(v2[0] * v2[0] + v2[1] * v2[1] + v2[2] * v2[2]))); + + return a; + }, + cross: function(vectA, vectB) { + return [ + vectA[1] * vectB[2] - vectB[1] * vectA[2], vectA[2] * vectB[0] - vectB[2] * vectA[0], vectA[0] * vectB[1] - vectB[0] * vectA[1]]; + }, + multiply: function(vectA, constB) { + return [vectA[0] * constB, vectA[1] * constB, vectA[2] * constB]; + }, + add: function(vectA, vectB) { + return [vectA[0] + vectB[0], vectA[1] + vectB[1], vectA[2] + vectB[2]]; + }, + subtract: function(vectA, vectB) { + return [vectA[0] - vectB[0], vectA[1] - vectB[1], vectA[2] - vectB[2]]; + }, + equal: function(a, b) { + var epsilon = 0.0000001; + + if ((a === undef) && (b === undef)) { + return true; + } + if ((a === undef) || (b === undef)) { + return false; + } + + return (Math.abs(a[0] - b[0]) < epsilon && Math.abs(a[1] - b[1]) < epsilon && Math.abs(a[2] - b[2]) < epsilon); + }, + moveViewRelative: function(position, target, xdelta, zdelta, alt_source) { + var ang = Math.atan2(zdelta, xdelta); + var cam_ang = Math.atan2(target[2] - position[2], target[0] - position[0]); + var mag = Math.sqrt(xdelta * xdelta + zdelta * zdelta); + + var move_ang = cam_ang + ang + M_HALF_PI; + + if (typeof(alt_source) === 'object') { + return [alt_source[0] + mag * Math.cos(move_ang), alt_source[1], alt_source[2] + mag * Math.sin(move_ang)]; + } + + return [position[0] + mag * Math.cos(move_ang), position[1], position[2] + mag * Math.sin(move_ang)]; + }, + trackTarget: function(position, target, trackingSpeed, safeDistance) { + var camv = vec3.subtract(target, position); + var dist = camv; + var fdist = vec3.length(dist); + var motionv = camv; + + motionv = vec3.normalize(motionv); + motionv = vec3.multiply(motionv, trackingSpeed * (1.0 / (1.0 / (fdist - safeDistance)))); + + var ret_pos; + + if (fdist > safeDistance) { + ret_pos = vec3.add(position, motionv); + } else if (fdist < safeDistance) { + motionv = camv; + motionv = vec3.normalize(motionv); + motionv = vec3.multiply(motionv, trackingSpeed * (1.0 / (1.0 / (Math.abs(fdist - safeDistance))))); + ret_pos = vec3.subtract(position, motionv); + } else { + ret_pos = [position[0], position[1] + motionv[2], position[2]]; + } + + return ret_pos; + }, + get_closest_to: function(ptA, ptB, ptTest) { + var S, T, U; + + S = vec3.subtract(ptB, ptA); + T = vec3.subtract(ptTest, ptA); + U = vec3.add(vec3.multiply(S, vec3.dot(S, T) / vec3.dot(S, S)), ptA); + + return U; + } + }; + + var triangle = { + normal: function(pt1, pt2, pt3) { + + var v10 = pt1[0] - pt2[0]; + var v11 = pt1[1] - pt2[1]; + var v12 = pt1[2] - pt2[2]; + var v20 = pt2[0] - pt3[0]; + var v21 = pt2[1] - pt3[1]; + var v22 = pt2[2] - pt3[2]; + + return [v11 * v22 - v12 * v21, v12 * v20 - v10 * v22, v10 * v21 - v11 * v20]; + } + }; + + + var mat3 = { + transpose_inline: function(mat) { + var a01 = mat[1], a02 = mat[2], a12 = mat[5]; + + mat[1] = mat[3]; + mat[2] = mat[6]; + mat[3] = a01; + mat[5] = mat[7]; + mat[6] = a02; + mat[7] = a12; + } + } + + var mat4 = { + lookat: function(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz) { + var forward = [], side = [], up = []; + var m = []; + + forward[0] = centerx - eyex; + forward[1] = centery - eyey; + forward[2] = centerz - eyez; + + up[0] = upx; + up[1] = upy; + up[2] = upz; + + forward = vec3.normalize(forward); + + /* Side = forward x up */ + var side = vec3.cross(forward, up); + side = vec3.normalize(side); + + /* Recompute up as: up = side x forward */ + up = vec3.cross(side, forward); + + var m = [ side[0], up[0], -forward[0], 0, side[1], up[1], -forward[1], 0, side[2], up[2], -forward[2], 0, 0, 0, 0, 1]; + + var t = new Transform(m); + t.translate([-eyex,-eyey,-eyez]); + + return t.getResult(); + }, + multiply: function (m1, m2) { + var mOut = []; + + mOut[0] = m2[0] * m1[0] + m2[4] * m1[1] + m2[8] * m1[2] + m2[12] * m1[3]; + mOut[1] = m2[1] * m1[0] + m2[5] * m1[1] + m2[9] * m1[2] + m2[13] * m1[3]; + mOut[2] = m2[2] * m1[0] + m2[6] * m1[1] + m2[10] * m1[2] + m2[14] * m1[3]; + mOut[3] = m2[3] * m1[0] + m2[7] * m1[1] + m2[11] * m1[2] + m2[15] * m1[3]; + mOut[4] = m2[0] * m1[4] + m2[4] * m1[5] + m2[8] * m1[6] + m2[12] * m1[7]; + mOut[5] = m2[1] * m1[4] + m2[5] * m1[5] + m2[9] * m1[6] + m2[13] * m1[7]; + mOut[6] = m2[2] * m1[4] + m2[6] * m1[5] + m2[10] * m1[6] + m2[14] * m1[7]; + mOut[7] = m2[3] * m1[4] + m2[7] * m1[5] + m2[11] * m1[6] + m2[15] * m1[7]; + mOut[8] = m2[0] * m1[8] + m2[4] * m1[9] + m2[8] * m1[10] + m2[12] * m1[11]; + mOut[9] = m2[1] * m1[8] + m2[5] * m1[9] + m2[9] * m1[10] + m2[13] * m1[11]; + mOut[10] = m2[2] * m1[8] + m2[6] * m1[9] + m2[10] * m1[10] + m2[14] * m1[11]; + mOut[11] = m2[3] * m1[8] + m2[7] * m1[9] + m2[11] * m1[10] + m2[15] * m1[11]; + mOut[12] = m2[0] * m1[12] + m2[4] * m1[13] + m2[8] * m1[14] + m2[12] * m1[15]; + mOut[13] = m2[1] * m1[12] + m2[5] * m1[13] + m2[9] * m1[14] + m2[13] * m1[15]; + mOut[14] = m2[2] * m1[12] + m2[6] * m1[13] + m2[10] * m1[14] + m2[14] * m1[15]; + mOut[15] = m2[3] * m1[12] + m2[7] * m1[13] + m2[11] * m1[14] + m2[15] * m1[15]; + + return mOut; + }, + vec4_multiply: function (m1, m2) { + var mOut = []; + + mOut[0] = m2[0] * m1[0] + m2[4] * m1[1] + m2[8] * m1[2] + m2[12] * m1[3]; + mOut[1] = m2[1] * m1[0] + m2[5] * m1[1] + m2[9] * m1[2] + m2[13] * m1[3]; + mOut[2] = m2[2] * m1[0] + m2[6] * m1[1] + m2[10] * m1[2] + m2[14] * m1[3]; + mOut[3] = m2[3] * m1[0] + m2[7] * m1[1] + m2[11] * m1[2] + m2[15] * m1[3]; + + return mOut; + }, + vec3_multiply: function (m1, m2) { + var mOut = []; + + mOut[0] = m2[0] * m1[0] + m2[4] * m1[1] + m2[8] * m1[2] + m2[12]; + mOut[1] = m2[1] * m1[0] + m2[5] * m1[1] + m2[9] * m1[2] + m2[13]; + mOut[2] = m2[2] * m1[0] + m2[6] * m1[1] + m2[10] * m1[2] + m2[14]; + + return mOut; + }, + perspective: function (fovy, aspect, near, far) { + var yFac = Math.tan(fovy * M_PI / 360.0); + var xFac = yFac * aspect; + + return [ + 1.0 / xFac, 0, 0, 0, 0, 1.0 / yFac, 0, 0, 0, 0, -(far + near) / (far - near), -1, 0, 0, -(2.0 * far * near) / (far - near), 0]; + }, + determinant: function (m) { + + var a0 = m[0] * m[5] - m[1] * m[4]; + var a1 = m[0] * m[6] - m[2] * m[4]; + var a2 = m[0] * m[7] - m[3] * m[4]; + var a3 = m[1] * m[6] - m[2] * m[5]; + var a4 = m[1] * m[7] - m[3] * m[5]; + var a5 = m[2] * m[7] - m[3] * m[6]; + var b0 = m[8] * m[13] - m[9] * m[12]; + var b1 = m[8] * m[14] - m[10] * m[12]; + var b2 = m[8] * m[15] - m[11] * m[12]; + var b3 = m[9] * m[14] - m[10] * m[13]; + var b4 = m[9] * m[15] - m[11] * m[13]; + var b5 = m[10] * m[15] - m[11] * m[14]; + + var det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0; + + return det; + }, + coFactor: function (m, n, out) { + // .. todo.. + }, + + transpose: function (m) { + return [m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11], m[15]]; + }, + + inverse_mat3: function(mat) { + var dest = []; + + var a00 = mat[0], a01 = mat[1], a02 = mat[2], + a10 = mat[4], a11 = mat[5], a12 = mat[6], + a20 = mat[8], a21 = mat[9], a22 = mat[10]; + + var b01 = a22*a11-a12*a21, + b11 = -a22*a10+a12*a20, + b21 = a21*a10-a11*a20; + + var d = a00*b01 + a01*b11 + a02*b21; + if (!d) { return null; } + var id = 1/d; + + dest[0] = b01*id; + dest[1] = (-a22*a01 + a02*a21)*id; + dest[2] = (a12*a01 - a02*a11)*id; + dest[3] = b11*id; + dest[4] = (a22*a00 - a02*a20)*id; + dest[5] = (-a12*a00 + a02*a10)*id; + dest[6] = b21*id; + dest[7] = (-a21*a00 + a01*a20)*id; + dest[8] = (a11*a00 - a01*a10)*id; + + return dest; + }, + + // not sure which is faster yet.. + + inverse$1: function (m) { + var tmp = []; + var src = []; + var dst = []; + + // Transpose matrix + for (var i = 0; i < 4; i++) { + src[i + 0] = m[i*4 + 0]; + src[i + 4] = m[i*4 + 1]; + src[i + 8] = m[i*4 + 2]; + src[i + 12] = m[i*4 + 3]; + } + + // Calculate pairs for first 8 elements (cofactors) + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + + // Calculate first 8 elements (cofactors) + dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; + dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; + dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; + dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; + dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; + dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; + dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; + dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; + dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; + dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; + dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; + dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; + dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; + dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; + dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; + dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + + // Calculate pairs for second 8 elements (cofactors) + tmp[0] = src[2]*src[7]; + tmp[1] = src[3]*src[6]; + tmp[2] = src[1]*src[7]; + tmp[3] = src[3]*src[5]; + tmp[4] = src[1]*src[6]; + tmp[5] = src[2]*src[5]; + tmp[6] = src[0]*src[7]; + tmp[7] = src[3]*src[4]; + tmp[8] = src[0]*src[6]; + tmp[9] = src[2]*src[4]; + tmp[10] = src[0]*src[5]; + tmp[11] = src[1]*src[4]; + + // Calculate second 8 elements (cofactors) + dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]; + dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]; + dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]; + dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]; + dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10]* src[15]; + dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11]* src[15]; + dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11]* src[14]; + dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10]* src[14]; + dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]; + dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]; + dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]; + dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]; + dst[14] = tmp[6] * src[9] + tmp[11]* src[11] + tmp[3] * src[8]; + dst[14] -= tmp[10]* src[11 ] + tmp[2] * src[8] + tmp[7] * src[9]; + dst[15] = tmp[10]* src[10] + tmp[4] * src[8] + tmp[9] * src[9]; + dst[15] -= tmp[8] * src[9] + tmp[11]* src[10] + tmp[5] * src[8]; + + // Calculate determinant + var det = src[0]*dst[0] + src[1]*dst[1] + src[2]*dst[2] + src[3]*dst[3]; + + var ret = []; + + // Calculate matrix inverse + det = 1.0 / det; + for (var i = 0; i < 16; i++) { + ret[i] = dst[i] * det; + } + + return ret; + }, + + inverse$2: function (m) { + var inv = []; + + inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15] + + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10]; + inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15] + - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10]; + inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15] + + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9]; + inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14] + - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9]; + inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15] + - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10]; + inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15] + + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10]; + inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15] + - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9]; + inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14] + + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9]; + inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15] + + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6]; + inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15] + - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6]; + inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15] + + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5]; + inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14] + - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5]; + inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11] + - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6]; + inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11] + + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6]; + inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11] + - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5]; + inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10] + + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5]; + + det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12]; + + if (det == 0) return null; + + inverse_det = 1.0 / det; + + inv[0] *= inverse_det; + inv[1] *= inverse_det; + inv[2] *= inverse_det; + inv[3] *= inverse_det; + inv[4] *= inverse_det; + inv[5] *= inverse_det; + inv[6] *= inverse_det; + inv[7] *= inverse_det; + inv[8] *= inverse_det; + inv[9] *= inverse_det; + inv[10] *= inverse_det; + inv[11] *= inverse_det; + inv[12] *= inverse_det; + inv[13] *= inverse_det; + inv[14] *= inverse_det; + inv[15] *= inverse_det; + + return inv; + }, + + inverse: function (m) { + var a0 = m[0] * m[5] - m[1] * m[4]; + var a1 = m[0] * m[6] - m[2] * m[4]; + var a2 = m[0] * m[7] - m[3] * m[4]; + var a3 = m[1] * m[6] - m[2] * m[5]; + var a4 = m[1] * m[7] - m[3] * m[5]; + var a5 = m[2] * m[7] - m[3] * m[6]; + var b0 = m[8] * m[13] - m[9] * m[12]; + var b1 = m[8] * m[14] - m[10] * m[12]; + var b2 = m[8] * m[15] - m[11] * m[12]; + var b3 = m[9] * m[14] - m[10] * m[13]; + var b4 = m[9] * m[15] - m[11] * m[13]; + var b5 = m[10] * m[15] - m[11] * m[14]; + + var determinant = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0; + + if (determinant != 0) { + var m_inv = []; + m_inv[0] = 0 + m[5] * b5 - m[6] * b4 + m[7] * b3; + m_inv[4] = 0 - m[4] * b5 + m[6] * b2 - m[7] * b1; + m_inv[8] = 0 + m[4] * b4 - m[5] * b2 + m[7] * b0; + m_inv[12] = 0 - m[4] * b3 + m[5] * b1 - m[6] * b0; + m_inv[1] = 0 - m[1] * b5 + m[2] * b4 - m[3] * b3; + m_inv[5] = 0 + m[0] * b5 - m[2] * b2 + m[3] * b1; + m_inv[9] = 0 - m[0] * b4 + m[1] * b2 - m[3] * b0; + m_inv[13] = 0 + m[0] * b3 - m[1] * b1 + m[2] * b0; + m_inv[2] = 0 + m[13] * a5 - m[14] * a4 + m[15] * a3; + m_inv[6] = 0 - m[12] * a5 + m[14] * a2 - m[15] * a1; + m_inv[10] = 0 + m[12] * a4 - m[13] * a2 + m[15] * a0; + m_inv[14] = 0 - m[12] * a3 + m[13] * a1 - m[14] * a0; + m_inv[3] = 0 - m[9] * a5 + m[10] * a4 - m[11] * a3; + m_inv[7] = 0 + m[8] * a5 - m[10] * a2 + m[11] * a1; + m_inv[11] = 0 - m[8] * a4 + m[9] * a2 - m[11] * a0; + m_inv[15] = 0 + m[8] * a3 - m[9] * a1 + m[10] * a0; + + var inverse_det = 1.0 / determinant; + + m_inv[0] *= inverse_det; + m_inv[1] *= inverse_det; + m_inv[2] *= inverse_det; + m_inv[3] *= inverse_det; + m_inv[4] *= inverse_det; + m_inv[5] *= inverse_det; + m_inv[6] *= inverse_det; + m_inv[7] *= inverse_det; + m_inv[8] *= inverse_det; + m_inv[9] *= inverse_det; + m_inv[10] *= inverse_det; + m_inv[11] *= inverse_det; + m_inv[12] *= inverse_det; + m_inv[13] *= inverse_det; + m_inv[14] *= inverse_det; + m_inv[15] *= inverse_det; + + return m_inv; + } + + return null; + } + }; + + + var util = { + getScriptContents: function(id) { + var shaderScript = document.getElementById(id); + + var str = ""; + var srcUrl = ""; + + if (!shaderScript) { + srcUrl = id; + } else { + if (shaderScript.src !== "" || shaderScript.attributes['srcUrl'] !== undef) { + srcUrl = (shaderScript.src !== '') ? shaderScript.src : (shaderScript.attributes['srcUrl'].value); + } + } + + if (srcUrl.length !== 0) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('GET', srcUrl, false); + xmlHttp.send(null); + + if (xmlHttp.status === 200 || xmlHttp.status === 0) { + str = xmlHttp.responseText; + } + } else { + var k = shaderScript.firstChild; + while (k) { + if (k.nodeType === 3) { + str += k.textContent; + } + k = k.nextSibling; + } + } + + return str; + }, + getURL: function(srcUrl) { + try { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('GET', srcUrl, false); + xmlHttp.send(null); + + if (xmlHttp.status === 200 || xmlHttp.status === 0) { + if (xmlHttp.responseText.length) { + return xmlHttp.responseText; + } else if (xmlHttp.responseXML) { + return xmlHttp.responseXML; + } + } + } + catch(e) { + alert(srcUrl + " failed to load."); + } + + + return null; + }, + getXML: function(srcUrl) { + try { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open('GET', srcUrl, false); + xmlHttp.overrideMimeType("application/xml"); + xmlHttp.send(null); + + if (xmlHttp.status === 200 || xmlHttp.status === 0) { + return xmlHttp.responseXML; + } + } + catch(e) { + try { + alert(srcUrl + " failed to load."); + } + catch (ex) { + throw(e); + } + } + + + return null; + }, + repackArray: function(data, stride, count) { + if (data.length !== parseInt(stride, 10) * parseInt(count, 10)) { + log("array repack error, data size !== stride*count: data.length=" + + data.length + " stride=" + stride + " count=" + count); + } + + var returnData = []; + + var c = 0; + for (var i = 0, iMax = data.length; i < iMax; i++) { + var ims = i % stride; + + if (ims === 0) { + returnData[c] = []; + } + + returnData[c][ims] = data[i]; + + if (ims === stride - 1) { + c++; + } + } + + return returnData; + }, + collectTextNode: function(tn) { + if (!tn) { + return ""; + } + + var s = ""; + var textNodeChildren = tn.childNodes; + for (var i = 0, tnl = textNodeChildren.length; i < tnl; i++) { + s += textNodeChildren[i].nodeValue; + } + return s; + }, + floatDelimArray: function(float_str, delim) { +// if (!float_str) return []; + var fa = float_str.split(delim ? delim : ","); + for (var i = 0, imax = fa.length; i < imax; i++) { + fa[i] = parseFloat(fa[i]); + } + if (fa[fa.length - 1] !== fa[fa.length - 1]) { + fa.pop(); + } + return fa; + }, + intDelimArray: function(float_str, delim) { +// if (!float_str) return []; + var fa = float_str.split(delim ? delim : ","); + for (var i = 0, imax = fa.length; i < imax; i++) { + fa[i] = parseInt(fa[i], 10); + } + if (fa[fa.length - 1] !== fa[fa.length - 1]) { + fa.pop(); + } + return fa; + }, + textDelimArray: function(text_str, delim) { +// if (!text_str) return ""; + var fa = text_str.split(delim ? delim : ","); + for (var i = 0, imax = fa.length; i < imax; i++) { + fa[i] = fa[i]; + } + return fa; + } + }; + + + var MAX_LIGHTS=6; + + + /* Core Init, single context only at the moment */ + GLCore.init = function(gl_in, vs_in, fs_in) { + var gl; + + if (gl_in.getContext!==undef&&gl_in.width!==undef&&gl_in.height!==undef) + { + try { + gl = gl_in.getContext("experimental-webgl"); + gl.viewport(0, 0, gl_in.width, gl_in.height); + + // set these default, can always be easily over-ridden + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.clearDepth(1.0); + gl.enable(gl.DEPTH_TEST); + gl.depthFunc(gl.LEQUAL); + } catch (e) {} + + if (!gl) { +// alert("Could not initialise WebGL, sorry :-("); + return null; + } + } + else + { + gl = gl_in; + } + + + GLCore.gl = gl; + GLCore.CoreShader_vs = util.getScriptContents(vs_in); + GLCore.CoreShader_fs = util.getScriptContents(fs_in); + GLCore.depth_alpha = false; + GLCore.default_filter = enums.texture.filter.LINEAR_MIP; + GLCore.mainloop = null; + + gl.enable(gl.CULL_FACE); + gl.cullFace(gl.BACK); + gl.frontFace(gl.CCW); + + + for (var i = enums.light.type.NULL; i < enums.light.type.MAX; i++) { + ShaderPool[i] = []; + } + + var dummyTex = new CubicVR.Texture(); + var lightTest = new CubicVR.Material(); + + for (var i = 0; i < enums.texture.map.MAX; i++) { + if (i===enums.texture.map.BUMP) continue; // fix for crashy fglrx driver, todo: check it against newer revisions. + lightTest.setTexture(dummyTex,i); + } + lightTest.opacity = 0.5; + + var lc = 1; + + try { + while (1) { + lightTest.use(enums.light.type.POINT,lc); + if (lc === 8) { + MAX_LIGHTS=lc; + break; + } + lc++; + } + } catch (e) { + MAX_LIGHTS=lc; + // console.log(e); + } + + log("Calibrated maximum lights per pass to: "+lc); + + + for (var i = enums.light.type.NULL; i < enums.light.type.MAX; i++) { + ShaderPool[i] = []; + } + + + return gl; + }; + + GLCore.setDepthAlpha = function(da, near, far) { + GLCore.depth_alpha = da; + GLCore.depth_alpha_near = near; + GLCore.depth_alpha_far = far; + }; + + GLCore.setDefaultFilter = function(filterType) { + GLCore.default_filter = filterType; + }; + + + + + var cubicvr_compileShader = function(gl, str, type) { + var shader; + + if (type === "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (type === "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; + } + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + log(gl.getShaderInfoLog(shader)); + return null; + } + + return shader; + }; + + var cubicvr_getShader = function(gl, id) { + var shaderScript = document.getElementById(id); + + if (!shaderScript) { + return null; + } + + var str = ""; + var k = shaderScript.firstChild; + while (k) { + if (k.nodeType === 3) { + str += k.textContent; + } + k = k.nextSibling; + } + + var shader; + + if (shaderScript.type === "x-shader/x-fragment") { + shader = gl.createShader(gl.FRAGMENT_SHADER); + } else if (shaderScript.type === "x-shader/x-vertex") { + shader = gl.createShader(gl.VERTEX_SHADER); + } else { + return null; + } + + gl.shaderSource(shader, str); + gl.compileShader(shader); + + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + log(gl.getShaderInfoLog(shader)); +// return null; + } + + return shader; + }; + + /***************************************************************************** + * Workers + *****************************************************************************/ + + function CubicVR_Worker(settings) { + this.worker = new Worker(SCRIPT_LOCATION + "CubicVR.js"); + this.message = settings.message; + this.error = settings.error; + this.type = settings.type; + var that = this; + this.worker.onmessage = function(e) { + if (that.message) { + that.message(e.data); + } //if + }; + this.worker.onerror = function(e) { + if (that.error) { + that.error(e); + } else { + log("Error: " + e.message + ": " + e.lineno); + } //if + }; //onerror + this.fn = function(fn, options) { + that.worker.postMessage({ + message: "function", + data: fn, + options: options, + }); + }; + this.start = function(options) { + that.worker.postMessage({ + message: "start", + data: that.type, + options: options + }); + }; + this.init = function(data) { + that.send({message:'init', data:data}); + }; + this.stop = function() { + that.worker.postMessage({ + message: "stop", + data: null + }); + }; + this.send = function(message) { + that.worker.postMessage({ + message: "data", + data: message + }); + }; + }; //CubicVR_Worker::Constructor + + function CubicVR_TestWorker() { + var that = this; + this.onmessage = function(message) { + if (message.test) { + setTimeout(function(){postMessage(message.test);}, 1000); + } + else { + setTimeout(function(){throw new Error(message);}, 1000); + } //if + }; //onmessage + }; //CubicVR_TestWorker + + function CubicVR_ColladaLoadWorker() { + var that = this; + this.onmessage = function(message) { + }; //onmessage + }; //CubicVR_ColladaLoadWorker + + function CubicVR_WorkerConnection() { + this.listener = null; + } //CubicVR_WorkerConnection + var WorkerConnection = new CubicVR_WorkerConnection(); + + if (1) { + self.addEventListener('message', function(e) { + var message = e.data.message; + var type = e.data.data; + if (message === "start") { + if (type === "test") { + WorkerConnection.listener = new CubicVR_TestWorker(); + |