aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--demos/webgl/CubicVR.js11660
-rw-r--r--demos/webgl/CubicVR_Core.fs281
-rw-r--r--demos/webgl/CubicVR_Core.vs127
-rw-r--r--demos/webgl/bullet_1_1_q1.ccsimple.js4404
-rw-r--r--demos/webgl/bullet_glue.js44
-rw-r--r--demos/webgl/demo.html196
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();
+ }
+ else if (type === "load_collada") {
+ WorkerConnection.listener = new CubicVR_ColladaLoadWorker();
+ }
+ else if (type === "octree") {
+ WorkerConnection.listener = new CubicVR_OctreeWorker();
+ } //if
+ }
+ else if (message === "function") {
+ var data = e.data.data;
+ var options = e.data.options;
+ var parts = data.split('(');