From 683607d7bf4015f1b04ec4864589b3c8cdc932fc Mon Sep 17 00:00:00 2001 From: Theunis Johannes Botha Date: Sat, 1 Oct 2016 01:10:02 +0200 Subject: [PATCH 01/15] cross origin mipmaps --- game-lib.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/game-lib.js b/game-lib.js index 0b6569f..e7ffdbd 100644 --- a/game-lib.js +++ b/game-lib.js @@ -1917,6 +1917,8 @@ GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMate if (imagePath) { + this.textureLoader.crossOrigin = ''; + this.textureLoader.load( imagePath, function(texture) { @@ -2367,7 +2369,7 @@ GameLib.D3.prototype.loadSceneFromApi = function(sceneName, onLoaded) { var xhr = new XMLHttpRequest(); xhr.open( 'GET', - this.apiUrl + '/scene/pong%20latest' + this.apiUrl + '/scene/' + sceneName ); xhr.onreadystatechange = function(xhr, gameLibD3) { From 70b2957343ec5e8a38db0fa3a823d59e5e27500d Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Tue, 4 Oct 2016 19:37:13 +0200 Subject: [PATCH 02/15] store clipping planes as arrays --- game-lib.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game-lib.js b/game-lib.js index e7ffdbd..2069b65 100644 --- a/game-lib.js +++ b/game-lib.js @@ -685,7 +685,7 @@ GameLib.D3.Material = function( this.alphaTest = alphaTest; if (typeof clippingPlanes == 'undefined') { - clippingPlanes = null; + clippingPlanes = []; } this.clippingPlanes = clippingPlanes; From e39ffd7383077f1a9efc933ef76875ea87ae7b79 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Fri, 7 Oct 2016 10:51:37 +0200 Subject: [PATCH 03/15] game lib controls --- game-lib-controls.js | 227 +++++++++++++++++++++++++++++++++++++++++++ game-lib.js | 11 +++ 2 files changed, 238 insertions(+) create mode 100644 game-lib-controls.js diff --git a/game-lib-controls.js b/game-lib-controls.js new file mode 100644 index 0000000..c6a477c --- /dev/null +++ b/game-lib-controls.js @@ -0,0 +1,227 @@ +function Controls() {} + +Controls.FlyControls = function( + camera, + THREE, + canvas +) { + this.flySpeed = 25; + + this.canvas = canvas; + + this.THREE = THREE; + + this.yaw = 0; + this.pitch = 0; + this.canRotate = false; + + this.moveForward = false; + this.moveBackward = false; + this.moveLeft = false; + this.moveRight = false; + this.moveUp = false; + this.moveDown = false; + + // Lock cursor + this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; + this.element = document.body; + + if (this.havePointerLock) { + this.element.requestPointerLock = this.element.requestPointerLock || this.element.mozRequestPointerLock || this.element.webkitRequestPointerLock; + document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; + } + + this.mouseUpCallback = this.onMouseUp.bind(this); + this.mouseDownCallback = this.onMouseDown.bind(this); + this.mouseMoveCallback = this.onMouseMove.bind(this); + this.keyDownCallback = this.onKeyDown.bind(this); + this.keyUpCallback = this.onKeyUp.bind(this); + //this.mouseClickCallback = this.onMouseClick.bind(this); + + this.camera = camera; + + // Add listeners + this.canvas.addEventListener('keydown', this.keyDownCallback, false); + this.canvas.addEventListener('keyup', this.keyUpCallback, false); + this.canvas.addEventListener('mousedown', this.mouseDownCallback, false); + this.canvas.addEventListener('mouseup', this.mouseUpCallback, false); +}; + +Controls.FlyControls.prototype.onMouseClick = function(event) { + if (this.havePointerLock) { + if (event.button == 0) { + this.canRotate = true; + this.element.requestPointerLock(); + } else if(event.button == 2) { + this.canRotate = false; + document.exitPointerLock(); + } + } +}; + +Controls.FlyControls.prototype.onMouseDown = function(event) { + if (event.button == 0) { + this.canRotate = true; + this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); + } +}; + +Controls.FlyControls.prototype.onMouseUp = function(event) { + if (event.button == 0) { + this.canRotate = false; + this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); + } +}; + + +Controls.FlyControls.prototype.getForward = function() { + var direction = new this.THREE.Vector3(0, 0, 1); + var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); + rotation.set(this.pitch, this.yaw, 0, "YXZ"); + var forward = direction.applyEuler(rotation).normalize(); + return forward; +}; + +Controls.FlyControls.prototype.applyRotation = function(deltaTime) { + this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ"); +}; + +Controls.FlyControls.prototype.applyTranslation = function(deltaTime) { + var direction = new this.THREE.Vector3(0, 0, -1); + var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); + rotation.set(this.pitch, this.yaw, 0, "YXZ"); + + direction = direction.applyEuler(rotation); + + if(this.moveForward) { + + var newPos = direction.normalize(); + this.camera.position.x += newPos.x * (deltaTime * this.flySpeed); + this.camera.position.y += newPos.y * (deltaTime * this.flySpeed); + this.camera.position.z += newPos.z * (deltaTime * this.flySpeed); + + } else if(this.moveBackward) { + + var newPos = direction.normalize(); + this.camera.position.x -= newPos.x * (deltaTime * this.flySpeed); + this.camera.position.y -= newPos.y * (deltaTime * this.flySpeed); + this.camera.position.z -= newPos.z * (deltaTime * this.flySpeed); + } + + if(this.moveLeft) { + + var forward = direction.normalize(); + var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); + var newPos = right; + this.camera.position.x -= newPos.x * (deltaTime * this.flySpeed); + this.camera.position.y -= newPos.y * (deltaTime * this.flySpeed); + this.camera.position.z -= newPos.z * (deltaTime * this.flySpeed); + + } else if(this.moveRight) { + + var forward = direction.normalize(); + var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); + var newPos = right; + this.camera.position.x += newPos.x * (deltaTime * this.flySpeed); + this.camera.position.y += newPos.y * (deltaTime * this.flySpeed); + this.camera.position.z += newPos.z * (deltaTime * this.flySpeed); + } + + // Absolute Y-Axis + if(this.moveUp) { + + this.camera.position.y += (deltaTime * this.flySpeed); + + } else if(this.moveDown) { + + this.camera.position.y -= (deltaTime * this.flySpeed); + + } +}; + +Controls.FlyControls.prototype.update = function(deltaTime) { + +}; + +Controls.FlyControls.prototype.onMouseMove = function ( event ) { + + if (this.canRotate) { + var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; + var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; + + this.yaw -= movementX * 0.002; + this.pitch -= movementY * 0.002; + } + + // Save mouseCoords + + // sys.mouseCoords.set( ( event.clientX / window.innerWidth ) * 2 - 1, + // -( event.clientY / window.innerHeight ) * 2 + 1 ); + +}; + +Controls.FlyControls.prototype.onKeyDown = function ( event ) { + switch ( event.keyCode ) { + + case 87: // w + this.moveForward = true; + break; + + case 65: // a + this.moveLeft = true; + break; + + case 83: // s + this.moveBackward = true; + break; + + case 68: // d + this.moveRight = true; + break; + + case 32: // space + this.moveUp = true; + break; + + case 16: + this.moveDown = true; + break; + } +}; + +Controls.FlyControls.prototype.onKeyUp = function ( event ) { + switch ( event.keyCode ) { + + case 38: // up + case 87: // w + this.moveForward = false; + break; + + case 37: // left + case 65: // a + this.moveLeft = false; + break; + + case 40: // down + case 83: // s + this.moveBackward = false; + break; + + case 39: // right + case 68: // d + this.moveRight = false; + break; + + case 32: // space + this.moveUp = false; + break; + + case 16: + this.moveDown = false; + break; + } +}; + +if (typeof module !== 'undefined') { + module.exports = Controls; +} \ No newline at end of file diff --git a/game-lib.js b/game-lib.js index 2069b65..05487ed 100644 --- a/game-lib.js +++ b/game-lib.js @@ -2,6 +2,10 @@ if (typeof require != 'undefined') { var Maths3D = require('./game-lib-maths.js'); } +if (typeof require != 'undefined') { + var Controls = require('./game-lib-controls.js'); +} + function GameLib() {} /** @@ -34,6 +38,13 @@ if (typeof require == 'undefined' && console.warn("You need a proper Maths3D library in order to use this library"); } +if (typeof require == 'undefined' && + typeof Controls == 'undefined') { + console.warn("You need a proper Control library in order to use this library"); +} + +GameLib.D3.Controls = Controls; + GameLib.D3.Vector2 = Maths3D.Vector2; GameLib.D3.Vector3 = Maths3D.Vector3; GameLib.D3.Vector4 = Maths3D.Vector4; From be9718aaeecd8278940b036733f14a6dee41e3f0 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Fri, 7 Oct 2016 16:06:50 +0200 Subject: [PATCH 04/15] starting to work with physics --- game-lib-controls.js | 21 +---- game-lib.js | 217 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 188 insertions(+), 50 deletions(-) diff --git a/game-lib-controls.js b/game-lib-controls.js index c6a477c..2245a7a 100644 --- a/game-lib-controls.js +++ b/game-lib-controls.js @@ -73,16 +73,7 @@ Controls.FlyControls.prototype.onMouseUp = function(event) { } }; - -Controls.FlyControls.prototype.getForward = function() { - var direction = new this.THREE.Vector3(0, 0, 1); - var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); - rotation.set(this.pitch, this.yaw, 0, "YXZ"); - var forward = direction.applyEuler(rotation).normalize(); - return forward; -}; - -Controls.FlyControls.prototype.applyRotation = function(deltaTime) { +Controls.FlyControls.prototype.applyRotation = function() { this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ"); }; @@ -140,11 +131,11 @@ Controls.FlyControls.prototype.applyTranslation = function(deltaTime) { }; Controls.FlyControls.prototype.update = function(deltaTime) { - + this.applyRotation(); + this.applyTranslation(deltaTime); }; Controls.FlyControls.prototype.onMouseMove = function ( event ) { - if (this.canRotate) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; @@ -152,12 +143,6 @@ Controls.FlyControls.prototype.onMouseMove = function ( event ) { this.yaw -= movementX * 0.002; this.pitch -= movementY * 0.002; } - - // Save mouseCoords - - // sys.mouseCoords.set( ( event.clientX / window.innerWidth ) * 2 - 1, - // -( event.clientY / window.innerHeight ) * 2 + 1 ); - }; Controls.FlyControls.prototype.onKeyDown = function ( event ) { diff --git a/game-lib.js b/game-lib.js index 85aa924..3bac60a 100644 --- a/game-lib.js +++ b/game-lib.js @@ -1121,73 +1121,166 @@ GameLib.D3.Bone = function( this.rawData = null;//rawData; }; -GameLib.D3.Physics = function() {}; - /** - * Physics Engine Superset + * Physics Superset * @param id * @param name * @param engineType - * @param engine + * @param CANNON + * @param Ammo + * @param Goblin + * @param worlds GameLib.D3.Physics.World[] * @constructor */ -GameLib.D3.Physics.Engine = function( +GameLib.D3.Physics = function( id, name, engineType, - engine + CANNON, + Ammo, + Goblin ) { + this.id = id; this.name = name; this.engineType = engineType; - this.engine = engine; + + this.CANNON = CANNON; + + this.Ammo = Ammo; + + this.Goblin = Goblin; + + this.worlds = []; + + this.customWorlds = []; }; /** * Physics Engine Types * @type {number} */ -GameLib.D3.Physics.Engine.TYPE_CANNON = 0x1; -GameLib.D3.Physics.Engine.TYPE_AMMO = 0x2; -GameLib.D3.Physics.Engine.TYPE_GOBLIN = 0x3; +GameLib.D3.Physics.TYPE_CANNON = 0x1; +GameLib.D3.Physics.TYPE_AMMO = 0x2; +GameLib.D3.Physics.TYPE_GOBLIN = 0x3; + +/** + * Broadphase Types + * @type {number} + */ +GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE = 0x1; +GameLib.D3.Physics.BROADPHASE_TYPE_GRID = 0x2; +GameLib.D3.Physics.BROADPHASE_TYPE_SAP = 0x3; + +/** + * Solver Types + * @type {number} + */ +GameLib.D3.Physics.SPLIT_SOLVER = 0x1; +GameLib.D3.Physics.GS_SOLVER = 0x2; + +/** + * Physics Solver Superset + * @param id + * @param name + * @param solverType + * @param iterations + * @param tolerance + * @constructor + */ +GameLib.D3.Physics.Solver = function( + id, + name, + solverType, + iterations, + tolerance +) { + this.id = id; + this.name = name; + this.solverType = solverType; + this.iterations = iterations; + this.tolerance = tolerance; +}; + +/** + * Physics Broadphase Superset + * @param id + * @param name + * @param broadphaseType + * @constructor + */ +GameLib.D3.Physics.Broadphase = function( + id, + name, + broadphaseType +) { + this.id = id; + this.name = name; + this.broadphaseType = broadphaseType; +}; /** * Physics World Superset * @param id * @param name + * @param physics * @param gravity - * @param rigidBodies GameLib.D3.Physics.RigidBody[] - * @param engine GameLib.D3.Physics.Engine + * @param broadphase + * @param solver + * @param rigidBodies * @constructor */ GameLib.D3.Physics.World = function( id, name, - engineType, - gravity + physics, + gravity, + broadphase, + solver, + rigidBodies ) { this.id = id; this.name = name; - this.engineType = engineType; + this.physics = physics; + + //this.worldType = GameLib.D3.Physics.World.TYPE_CANNON_WORLD; if (typeof gravity == 'undefined') { - gravity = new THREE.Vector3(0, -9.81, 0); + gravity = new GameLib.D3.Vector3(0, -9.81, 0); } this.gravity = gravity; - this.worldObject = null; - - if(this.engineType === GameLib.D3.Physics.Engine.TYPE_CANNON) { - this.worldObject = new CANNON.World(); - this.worldObject.gravity.set(this.gravity.x, this.gravity.y, this.gravity.z); - this.worldObject.broadphase = new CANNON.NaiveBroadphase(); - //this.worldObject.broadphase = new CANNON.SAPBroadphase(); - this.worldObject.solver.iterations = 10; + if (typeof broadphase == 'undefined') { + broadphase = new GameLib.D3.Physics.Broadphase( + null, + 'broadPhaseNaive', + GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE + ); } + this.broadphase = broadphase; + + if (typeof solver == 'undefined') { + solver = new GameLib.D3.Physics.Solver( + null, + 'GCSolver', + GameLib.D3.Physics.GS_SOLVER + ); + } + this.solver = solver; + + if (typeof rigidBodies == 'undefined') { + rigidBodies = []; + } + this.rigidBodies = rigidBodies; + + physics.worlds.push(this); + physics.customWorlds.push(this.getCustomWorld(this)); }; +//GameLib.D3.Physics.World.TYPE_CANNON_WORLD = 0x1; + /** * Physics Rigid Body Superset * @param id @@ -1471,7 +1564,8 @@ GameLib.D3.Scene = function( rotation, scale, parentSceneId, - lights + lights, + physics ) { this.id = id; this.path = path; @@ -1510,6 +1604,11 @@ GameLib.D3.Scene = function( lights = []; } this.lights = lights; + + if (typeof physics == 'undefined') { + physics = []; + } + this.physics = physics; }; /** @@ -1936,7 +2035,7 @@ GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMate if (imagePath) { - this.textureLoader.crossOrigin = ''; + this.textureLoader.crossOrigin = ''; this.textureLoader.load( imagePath, @@ -2661,9 +2760,65 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals }); }; -// --------------- -// Physics -// --------------- +/** --------------- + * Physics + * --------------- */ +/** + * Creates a Custom World object from a GameLib.D3.Physics.World + */ +GameLib.D3.Physics.World.prototype.getCustomWorld = function() { + + var engineType = this.physics.engineType; + + if (engineType != GameLib.D3.Physics.TYPE_CANNON) { + console.warn('Unsupported engine type: ' + engineType); + throw new Error('Unsupported engine type: ' + engineType); + } + + var customWorld = new this.physics.CANNON.World(); + + var cannonBroadphase = null; + + if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE) { + cannonBroadphase = new this.physics.CANNON.NaiveBroadphase(); + } else if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_GRID) { + cannonBroadphase = new this.physics.CANNON.GridBroadphase(); + } else if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_SAP) { + cannonBroadphase = new this.physics.CANNON.SAPBroardphase(); + } else { + console.warn('Unsupported broadphase type: ' + this.broadphase.broadphaseType); + throw new Error('Unsupported broadphase type: ' + this.broadphase.broadphaseType); + } + + customWorld.broadphase = cannonBroadphase; + + var cannonSolver = null; + + if (this.solver.solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + cannonSolver = new this.physics.CANNON.SplitSolver(); + } else if (this.solver.solverType == GameLib.D3.Physics.GS_SOLVER) { + cannonSolver = new this.physics.CANNON.GSSolver(); + cannonSolver.iterations = this.solver.iterations; + } + + customWorld.solver = cannonSolver; + + customWorld.gravity.x = this.gravity.x; + customWorld.gravity.y = this.gravity.y; + customWorld.gravity.z = this.gravity.z; + + for (var b = 0; b < this.rigidBodies.length; b++) { + + var customBody = this.createCustomBody(this.rigidBodies[b]); + + //customWorld.AddRigidBody(); + } + + customWorld.name = this.name; + + return customWorld; +}; + GameLib.D3.Physics.Shape.prototype.Update = function( physicsWorld @@ -2725,9 +2880,7 @@ GameLib.D3.Physics.World.prototype.AddWheel = function( } }; -GameLib.D3.Physics.Vehicle.prototype.GetWheelInfo = function( - -) { +GameLib.D3.Physics.Vehicle.prototype.GetWheelInfo = function() { return this.vehicleObject.wheelBodies; }; From 91094883f06e672f8ba0c54aaa2b675d68c560ea Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Mon, 10 Oct 2016 15:01:50 +0200 Subject: [PATCH 05/15] better loading and displaying of scenes, start work with physics data --- game-lib-controls.js | 77 ++++++++++++++++++++++++++------------------ game-lib.js | 65 +++++++++++++++++++++++++++++++++---- 2 files changed, 104 insertions(+), 38 deletions(-) diff --git a/game-lib-controls.js b/game-lib-controls.js index 2245a7a..2580743 100644 --- a/game-lib-controls.js +++ b/game-lib-controls.js @@ -5,7 +5,7 @@ Controls.FlyControls = function( THREE, canvas ) { - this.flySpeed = 25; + this.flySpeed = 100; this.canvas = canvas; @@ -22,7 +22,21 @@ Controls.FlyControls = function( this.moveUp = false; this.moveDown = false; - // Lock cursor + this.mouseUpCallback = this.onMouseUp.bind(this); + this.mouseDownCallback = this.onMouseDown.bind(this); + this.mouseMoveCallback = this.onMouseMove.bind(this); + this.mouseWheelCallback = this.onMouseWheel.bind(this); + this.keyDownCallback = this.onKeyDown.bind(this); + this.keyUpCallback = this.onKeyUp.bind(this); + + this.camera = camera; + + this.canvas.addEventListener('keydown', this.keyDownCallback, false); + this.canvas.addEventListener('keyup', this.keyUpCallback, false); + this.canvas.addEventListener('mousedown', this.mouseDownCallback, false); + this.canvas.addEventListener('mouseup', this.mouseUpCallback, false); + this.canvas.addEventListener('mousewheel', this.mouseWheelCallback, false); + this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; this.element = document.body; @@ -31,43 +45,42 @@ Controls.FlyControls = function( document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; } - this.mouseUpCallback = this.onMouseUp.bind(this); - this.mouseDownCallback = this.onMouseDown.bind(this); - this.mouseMoveCallback = this.onMouseMove.bind(this); - this.keyDownCallback = this.onKeyDown.bind(this); - this.keyUpCallback = this.onKeyUp.bind(this); - //this.mouseClickCallback = this.onMouseClick.bind(this); - - this.camera = camera; - - // Add listeners - this.canvas.addEventListener('keydown', this.keyDownCallback, false); - this.canvas.addEventListener('keyup', this.keyUpCallback, false); - this.canvas.addEventListener('mousedown', this.mouseDownCallback, false); - this.canvas.addEventListener('mouseup', this.mouseUpCallback, false); }; -Controls.FlyControls.prototype.onMouseClick = function(event) { - if (this.havePointerLock) { - if (event.button == 0) { - this.canRotate = true; - this.element.requestPointerLock(); - } else if(event.button == 2) { - this.canRotate = false; - document.exitPointerLock(); - } - } +Controls.FlyControls.prototype.onMouseWheel = function(event) { + this.moveForward = true; + this.applyTranslation(event.wheelDelta * 0.001); + event.preventDefault(); + this.moveForward = false; }; Controls.FlyControls.prototype.onMouseDown = function(event) { - if (event.button == 0) { + + // if (event.button == 0) { + // this.canRotate = true; + // this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); + // if (this.havePointerLock) { + // this.element.requestPointerLock(); + // } + // } + + if (event.button == 1) { this.canRotate = true; this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); } }; Controls.FlyControls.prototype.onMouseUp = function(event) { - if (event.button == 0) { + + // if (event.button == 0) { + // this.canRotate = false; + // this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); + // if (this.havePointerLock) { + // document.exitPointerLock(); + // } + // } + + if (event.button == 1) { this.canRotate = false; this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); } @@ -164,11 +177,11 @@ Controls.FlyControls.prototype.onKeyDown = function ( event ) { this.moveRight = true; break; - case 32: // space + case 104: // keypad up arrow this.moveUp = true; break; - case 16: + case 98: // keypad down arrow this.moveDown = true; break; } @@ -197,11 +210,11 @@ Controls.FlyControls.prototype.onKeyUp = function ( event ) { this.moveRight = false; break; - case 32: // space + case 104: // keypad up arrow this.moveUp = false; break; - case 16: + case 98: // keypad down arrow this.moveDown = false; break; } diff --git a/game-lib.js b/game-lib.js index 3bac60a..7e8f6c9 100644 --- a/game-lib.js +++ b/game-lib.js @@ -2475,7 +2475,7 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial) { * @param sceneName * @param onLoaded callback */ -GameLib.D3.prototype.loadSceneFromApi = function(sceneName, onLoaded) { +GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { /** * First check if this is a client or server side request */ @@ -2487,14 +2487,31 @@ GameLib.D3.prototype.loadSceneFromApi = function(sceneName, onLoaded) { var xhr = new XMLHttpRequest(); xhr.open( 'GET', - this.apiUrl + '/scene/' + sceneName + this.apiUrl + '/scene/' + scene.name ); xhr.onreadystatechange = function(xhr, gameLibD3) { return function() { if (xhr.readyState == 4) { var response = JSON.parse(xhr.responseText); - gameLibD3.loadScene(response.scene[0], onLoaded, false); + + var scene = response.scene[0]; + + var scene3d = new GameLib.D3.Scene( + scene._id || scene.id, + scene.path, + scene.name, + scene.meshes, + scene.quaternion, + scene.position, + scene.rotation, + scene.scale, + scene.parentSceneId, + scene.lights, + scene.physics + ); + + gameLibD3.loadScene(scene3d, onLoaded, false); } } }(xhr, this); @@ -2662,7 +2679,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals function(gl3d, mesh, geometry) { return function(materials) { - console.log("loaded all materials maps (" + materials.length + ")"); + console.log("loaded material : " + materials[0].name); /** * We don't support MultiMaterial atm - it doesn't work with raycasting @@ -2753,9 +2770,45 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals } } - onLoaded(threeMeshes, threeLights); + var threeScene = new this.THREE.Scene(); + + threeScene.name = gameLibScene.name; + + threeScene.position.x = gameLibScene.position.x; + threeScene.position.y = gameLibScene.position.y; + threeScene.position.z = gameLibScene.position.z; + + threeScene.rotation.x = gameLibScene.rotation.x; + threeScene.rotation.y = gameLibScene.rotation.y; + threeScene.rotation.z = gameLibScene.rotation.z; + + threeScene.scale.x = gameLibScene.scale.x; + threeScene.scale.y = gameLibScene.scale.y; + threeScene.scale.z = gameLibScene.scale.z; + + threeScene.quaternion.x = gameLibScene.quaternion.x; + threeScene.quaternion.y = gameLibScene.quaternion.y; + threeScene.quaternion.z = gameLibScene.quaternion.z; + threeScene.quaternion.w = gameLibScene.quaternion.w; + + for (var m = 0; m < threeMeshes.length; m++) { + threeScene.add(threeMeshes[m]); + } + + for (var l = 0; l < threeLights.length; l++) { + threeScene.add(threeLights[l]); + } + + onLoaded( + gameLibScene, + { + scene: threeScene, + lights: threeLights, + meshes: threeMeshes + } + ); } - }).catch(function(error){ + }.bind(this)).catch(function(error){ console.log(error); }); }; From e8d6b56f429e088c25191ba0505268cd1cd117ec Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Tue, 11 Oct 2016 19:57:12 +0200 Subject: [PATCH 06/15] physics worlds - hello --- game-lib.js | 274 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 205 insertions(+), 69 deletions(-) diff --git a/game-lib.js b/game-lib.js index 7e8f6c9..258a7eb 100644 --- a/game-lib.js +++ b/game-lib.js @@ -23,14 +23,17 @@ GameLib.D3 = function( Q, THREE, apiUrl, - editorUrl + editorUrl, + CANNON ){ this.config = config; this.Q = Q; this.THREE = THREE; + this.CANNON = CANNON; this.textureLoader = new this.THREE.TextureLoader(); this.apiUrl = apiUrl || this.config.api16.url; this.editorUrl = editorUrl || this.config.editor.url; + this.path = null; }; if (typeof require == 'undefined' && @@ -78,7 +81,6 @@ GameLib.D3.Color = Maths3D.Color; */ GameLib.D3.Texture = function( id, - path, name, image, wrapS, @@ -100,7 +102,6 @@ GameLib.D3.Texture = function( encoding ) { this.id = id; - this.path = path; this.name = name; this.image = image; @@ -416,7 +417,6 @@ GameLib.D3.Light = function( */ GameLib.D3.Material = function( id, - path, name, materialType, opacity, @@ -475,7 +475,6 @@ GameLib.D3.Material = function( envMapIntensity ) { this.id = id; - this.path = path; this.name = name; if (typeof materialType == 'undefined') { materialType = GameLib.D3.Material.TYPE_MESH_STANDARD; @@ -1138,7 +1137,9 @@ GameLib.D3.Physics = function( engineType, CANNON, Ammo, - Goblin + Goblin, + worlds, + customWorlds ) { this.id = id; @@ -1196,6 +1197,15 @@ GameLib.D3.Physics.Solver = function( tolerance ) { this.id = id; + if (typeof name == 'undefined') { + if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + name = 'split solver'; + } else if (solverType == GameLib.D3.Physics.GS_SOLVER) { + name = 'gs solver'; + } else { + name = 'unknown solver'; + } + } this.name = name; this.solverType = solverType; this.iterations = iterations; @@ -1215,7 +1225,17 @@ GameLib.D3.Physics.Broadphase = function( broadphaseType ) { this.id = id; + + if (typeof name == 'undefined') { + name = 'broadphase-' + broadphaseType; + } this.name = name; + + if (typeof broadphaseType == 'undefined') { + console.warn('undefined broadphase type'); + throw new Error('undefined broadphase type'); + } + this.broadphaseType = broadphaseType; }; @@ -1243,10 +1263,6 @@ GameLib.D3.Physics.World = function( this.name = name; - this.physics = physics; - - //this.worldType = GameLib.D3.Physics.World.TYPE_CANNON_WORLD; - if (typeof gravity == 'undefined') { gravity = new GameLib.D3.Vector3(0, -9.81, 0); } @@ -1275,8 +1291,16 @@ GameLib.D3.Physics.World = function( } this.rigidBodies = rigidBodies; - physics.worlds.push(this); - physics.customWorlds.push(this.getCustomWorld(this)); + /** + * We only set the physics property if we pass it in the constructor, + * because we don't always want the physics object (ex. when we store this world to the API - we also don't then + * want to store the custom worlds - we want to generate them after loading from API) + */ + if (physics) { + this.physics = physics; + this.physics.worlds.push(this); + this.physics.customWorlds.push(this.getCustomWorld(this)); + } }; //GameLib.D3.Physics.World.TYPE_CANNON_WORLD = 0x1; @@ -1483,8 +1507,6 @@ GameLib.D3.Vertex = function( * @param id * @param textureLink * @param filename - * @param uploadPath - * @param apiPath * @param size * @param contentType * @constructor @@ -1493,8 +1515,6 @@ GameLib.D3.Image = function( id, textureLink, filename, - uploadPath, - apiPath, size, contentType ) { @@ -1504,16 +1524,6 @@ GameLib.D3.Image = function( this.textureLink = textureLink; - if (typeof uploadPath == 'undefined') { - uploadPath = null; - } - this.uploadPath = uploadPath; - - if (typeof apiPath == 'undefined') { - apiPath = null; - } - this.apiPath = apiPath; - if (typeof size == 'undefined') { size = 0; } @@ -1641,30 +1651,6 @@ GameLib.D3.TriangleFace.prototype.clone = function(){ ); }; -/** - * Associates bones with their child bones, based on parent bone references - */ -GameLib.D3.prototype.createChildBoneIds = function() { - for (var bi = 0; bi < this.bones.length; bi++) { - var childBoneIds = []; - - for (var sbi = 0; sbi < this.bones.length; sbi++) { - - if (this.bones[sbi] == this.bones[bi]) { - continue; - } - - if (this.bones[sbi].parentBoneId !== null && - this.bones[sbi].parentBoneId == this.bones[bi].boneId) - { - childBoneIds.push(this.bones[sbi].boneId); - } - } - - this.bones[bi].childBoneIds = childBoneIds; - } -}; - /** * This is a work-around function to fix polys which don't triangulate because * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around @@ -1673,7 +1659,7 @@ GameLib.D3.prototype.createChildBoneIds = function() { * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY * @return [] */ -GameLib.D3.prototype.fixPolyZPlane = function(verticesFlat, grain) { +GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) { if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) { console.log("The vertices are not in the right length : " + verticesFlat.length); @@ -1734,7 +1720,7 @@ GameLib.D3.prototype.fixPolyZPlane = function(verticesFlat, grain) { * @param orientationEdge GameLib.D3.Vector2 * @returns {Array} */ -GameLib.D3.prototype.fixWindingOrder = function(faces, orientationEdge) { +GameLib.D3.fixWindingOrder = function(faces, orientationEdge) { /** * Checks if a TriangleFace belonging to a TriangleEdge has already been processed @@ -2019,18 +2005,11 @@ GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMate var imagePath = null; - if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.apiPath && gameLibTexture.image.filename) { - /** - * Load the image from API here if apiPath is defined - */ - imagePath = this.apiUrl + gameLibTexture.image.uploadPath + '/' + gameLibTexture.image.filename; - } - - if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.uploadPath && gameLibTexture.image.filename) { + if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { /** * Else, load from upload source */ - imagePath = this.editorUrl + gameLibTexture.image.uploadPath + '/' + gameLibTexture.image.filename; + imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; } if (imagePath) { @@ -2476,6 +2455,7 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial) { * @param onLoaded callback */ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { + /** * First check if this is a client or server side request */ @@ -2487,28 +2467,182 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { var xhr = new XMLHttpRequest(); xhr.open( 'GET', - this.apiUrl + '/scene/' + scene.name + this.apiUrl + '/scene/load' + scene.path + '/' + scene.name ); xhr.onreadystatechange = function(xhr, gameLibD3) { return function() { if (xhr.readyState == 4) { + var response = JSON.parse(xhr.responseText); + if (!response.scene || response.scene.length == 0) { + return onLoaded(null, null, new Error('Could not load scene')); + } + var scene = response.scene[0]; + var physics3ds = []; + + if (scene.physics && scene.physics.length > 0) { + + for (var p = 0; p < scene.physics.length; p++) { + + var physics = scene.physics[p]; + + var physics3d = new GameLib.D3.Physics( + physics.id, + physics.name, + physics.engineType, + gameLibD3.CANNON, + null, + null + ); + + var worlds3d = []; + + for (var w = 0; w < physics.worlds.length; w++) { + + var world = physics.worlds[w]; + + var broadphase = world.broadphase; + + var broadphase3d = new GameLib.D3.Physics.Broadphase( + broadphase.id, + broadphase.name, + broadphase.broadphaseType + ); + + var solver = world.solver; + + var solver3d = new GameLib.D3.Physics.Solver( + solver.id, + solver.name, + solver.solverType, + solver.iterations, + solver.tolerance + ); + + var bodies = world.rigidBodies; + + var bodies3d = []; + + for (var b = 0; b < bodies.length; b++) { + + var body = bodies[b]; + + //TODO: add all body properties here + var body3d = new GameLib.D3.Physics.RigidBody( + body.id, + body.name + ); + + bodies3d.push(body3d); + } + + var world3d = new GameLib.D3.Physics.World( + null, + world.name, + physics3d, + new GameLib.D3.Vector3( + world.gravity.x, + world.gravity.y, + world.gravity.z + ), + broadphase3d, + solver3d, + bodies3d + ); + + worlds3d.push(world3d); + } + + physics3ds.push(physics3d); + } + } + + var lights3d = []; + + for (var l = 0; l < scene.lights.length; l++) { + + var light = scene.lights[l]; + + var light3d = new GameLib.D3.Light( + light.id, + light.lightType, + light.name, + new GameLib.D3.Color( + light.color.r, + light.color.g, + light.color.b, + light.color.a + ), + light.intensity, + new GameLib.D3.Vector3( + light.position.x, + light.position.y, + light.position.z + ), + new GameLib.D3.Vector3( + light.targetPosition.x, + light.targetPosition.y, + light.targetPosition.z + ), + new GameLib.D3.Vector4( + light.quaternion.x, + light.quaternion.y, + light.quaternion.z, + light.quaternion.w + ), + new GameLib.D3.Vector3( + light.rotation.x, + light.rotation.y, + light.rotation.z + ), + new GameLib.D3.Vector3( + light.scale.x, + light.scale.y, + light.scale.z + ), + light.distance, + light.decay, + light.power, + light.angle, + light.penumbra + ); + + lights3d.push(light3d); + }; + var scene3d = new GameLib.D3.Scene( scene._id || scene.id, scene.path, scene.name, scene.meshes, - scene.quaternion, - scene.position, - scene.rotation, - scene.scale, + new GameLib.D3.Vector4( + scene.quaternion.x, + scene.quaternion.y, + scene.quaternion.z, + scene.quaternion.w + ), + new GameLib.D3.Vector3( + scene.position.x, + scene.position.y, + scene.position.z + ), + new GameLib.D3.Vector3( + scene.rotation.x, + scene.rotation.y, + scene.rotation.z + ), + new GameLib.D3.Vector3( + scene.scale.x, + scene.scale.y, + scene.scale.z + ), scene.parentSceneId, - scene.lights, - scene.physics + lights3d, + physics3ds ); gameLibD3.loadScene(scene3d, onLoaded, false); @@ -2529,6 +2663,8 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals console.log("loading scene " + gameLibScene.name); + this.path = gameLibScene.path; + var meshQ = []; for (var m = 0; m < gameLibScene.meshes.length; m++) { @@ -3369,5 +3505,5 @@ GameLib.D3.Game.prototype.LinkPair = function ( }; if (typeof module != 'undefined') { - module.exports = GameLib.D3; + module.exports = GameLib; } \ No newline at end of file From 0b414dc4a53c11e3b0560434c5e5a49924facaf2 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Wed, 12 Oct 2016 12:48:06 +0200 Subject: [PATCH 07/15] remove uploadpath --- game-lib.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/game-lib.js b/game-lib.js index 258a7eb..e9d4d09 100644 --- a/game-lib.js +++ b/game-lib.js @@ -2215,8 +2215,7 @@ GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMate if ( blenderTexture && blenderTexture.image && - blenderTexture.image.filename && - blenderTexture.image.uploadPath + blenderTexture.image.filename ) { var threeMap = null; From d002814c40252c0d34c79ed10fc157bea42be56f Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Fri, 14 Oct 2016 12:32:53 +0200 Subject: [PATCH 08/15] gulp build - now start to fix --- game-lib-maths.js | 704 ---- game-lib.js | 3712 ----------------- game.js | 24 - gulpfile.js | 26 + package.json | 13 + src/game-lib-a.js | 7 + src/game-lib-bone-weight.js | 13 + src/game-lib-bone.js | 65 + src/game-lib-broadphase.js | 34 + src/game-lib-color.js | 18 + src/game-lib-engine.js | 60 + .../game-lib-fly-controls.js | 35 +- src/game-lib-game.js | 106 + src/game-lib-heightmap.js | 95 + src/game-lib-image.js | 45 + src/game-lib-light.js | 92 + src/game-lib-material.js | 679 +++ src/game-lib-matrix-3.js | 37 + src/game-lib-matrix-4.js | 173 + src/game-lib-mesh.js | 539 +++ src/game-lib-physics.js | 32 + src/game-lib-poly-vertex.js | 36 + src/game-lib-raycast-vehicle.js | 10 + src/game-lib-rigid-body-vehicle.js | 9 + src/game-lib-rigid-body.js | 92 + src/game-lib-scene.js | 571 +++ src/game-lib-shape.js | 37 + src/game-lib-skeleton.js | 69 + src/game-lib-sky-box.js | 65 + src/game-lib-solver.js | 38 + src/game-lib-texture.js | 370 ++ src/game-lib-triangle-edge.js | 13 + src/game-lib-triangle-face.js | 125 + src/game-lib-vector-2.js | 27 + src/game-lib-vector-3.js | 134 + src/game-lib-vector-4-points.js | 224 + src/game-lib-vector-4.js | 99 + src/game-lib-vertex.js | 13 + src/game-lib-world.js | 448 ++ src/game-lib-z.js | 3 + src/index.js | 94 + 41 files changed, 4529 insertions(+), 4457 deletions(-) delete mode 100644 game-lib-maths.js delete mode 100644 game-lib.js delete mode 100644 game.js create mode 100644 gulpfile.js create mode 100644 package.json create mode 100644 src/game-lib-a.js create mode 100644 src/game-lib-bone-weight.js create mode 100644 src/game-lib-bone.js create mode 100644 src/game-lib-broadphase.js create mode 100644 src/game-lib-color.js create mode 100644 src/game-lib-engine.js rename game-lib-controls.js => src/game-lib-fly-controls.js (89%) create mode 100644 src/game-lib-game.js create mode 100644 src/game-lib-heightmap.js create mode 100644 src/game-lib-image.js create mode 100644 src/game-lib-light.js create mode 100644 src/game-lib-material.js create mode 100644 src/game-lib-matrix-3.js create mode 100644 src/game-lib-matrix-4.js create mode 100644 src/game-lib-mesh.js create mode 100644 src/game-lib-physics.js create mode 100644 src/game-lib-poly-vertex.js create mode 100644 src/game-lib-raycast-vehicle.js create mode 100644 src/game-lib-rigid-body-vehicle.js create mode 100644 src/game-lib-rigid-body.js create mode 100644 src/game-lib-scene.js create mode 100644 src/game-lib-shape.js create mode 100644 src/game-lib-skeleton.js create mode 100644 src/game-lib-sky-box.js create mode 100644 src/game-lib-solver.js create mode 100644 src/game-lib-texture.js create mode 100644 src/game-lib-triangle-edge.js create mode 100644 src/game-lib-triangle-face.js create mode 100644 src/game-lib-vector-2.js create mode 100644 src/game-lib-vector-3.js create mode 100644 src/game-lib-vector-4-points.js create mode 100644 src/game-lib-vector-4.js create mode 100644 src/game-lib-vertex.js create mode 100644 src/game-lib-world.js create mode 100644 src/game-lib-z.js create mode 100644 src/index.js diff --git a/game-lib-maths.js b/game-lib-maths.js deleted file mode 100644 index a36988a..0000000 --- a/game-lib-maths.js +++ /dev/null @@ -1,704 +0,0 @@ -function Maths3D() {} - -Maths3D.Vector2 = function(x, y) { - - this.x = 0; - this.y = 0; - - if (x) { - this.x = x; - } - - if (y) { - this.y = y; - } -}; - -Maths3D.Vector3 = function(x, y, z) { - - this.x = 0; - this.y = 0; - this.z = 0; - - if (x) { - this.x = x; - } - - if (y) { - this.y = y; - } - - if (z) { - this.z = z; - } -}; - -Maths3D.Vector4 = function(x, y, z, w) { - - this.x = 0; - this.y = 0; - this.z = 0; - this.w = 0; - - if (x) { - this.x = x; - } - - if (y) { - this.y = y; - } - - if (z) { - this.z = z; - } - - if (w) { - this.w = w; - } -}; - -Maths3D.Matrix3 = function( - row0, - row1, - row2 -) { - this.identity(); - - if (row0) { - this.rows[0] = row0; - } - - if (row1) { - this.rows[1] = row1; - } - - if (row2) { - this.rows[2] = row2; - } -}; - -Maths3D.Matrix4 = function( - row0, - row1, - row2, - row3 -) { - - this.identity(); - - if (row0) { - this.rows[0] = row0; - } - - if (row1) { - this.rows[1] = row1; - } - - if (row2) { - this.rows[2] = row2; - } - - if (row3) { - this.rows[3] = row3; - } -}; - -Maths3D.Color = function(r, g, b, a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; -}; - -Maths3D.Vector2.prototype.copy = function() { - return new Maths3D.Vector2( - this.x, - this.y - ); -}; - -Maths3D.Vector2.prototype.equals = function(v) { - return !!(((this.x == v.x) && - (this.y == v.y)) || - ((this.y == v.x) && - (this.x == v.y))); -}; - - -Maths3D.Matrix4.prototype.rotationMatrixX = function (radians) { - this.identity(); - this.rows[1] = new Maths3D.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0); - this.rows[2] = new Maths3D.Vector4(0, Math.sin(radians), Math.cos(radians), 0); - return this; -}; - -Maths3D.Matrix4.prototype.rotationMatrixY = function (radians) { - this.identity(); - this.rows[0] = new Maths3D.Vector4( - Math.cos(radians), - 0, - Math.sin(radians), - 0 - ); - this.rows[2] = new Maths3D.Vector4( - -1 * Math.sin(radians), - 0, - Math.cos(radians), - 0 - ); - return this; -}; - -Maths3D.Matrix4.prototype.rotationMatrixZ = function (radians) { - this.identity(); - this.rows[0] = new Maths3D.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0); - this.rows[1] = new Maths3D.Vector4(Math.sin(radians), Math.cos(radians), 0, 0); - return this; -}; - -Maths3D.Matrix4.prototype.rotateX = function (radians, point) { - this.identity(); - this.rotationMatrixX(radians); - return this.multiply(point); -}; - -Maths3D.Matrix4.prototype.rotateY = function (radians, point) { - this.identity(); - this.rotationMatrixY(radians); - return this.multiply(point); -}; - -Maths3D.Matrix4.prototype.rotateZ = function (radians, point) { - this.identity(); - this.rotationMatrixZ(radians); - return this.multiply(point); -}; - -Maths3D.Matrix4.prototype.multiply = function (mvp) { - if (mvp instanceof Maths3D.Vector4) { - return new Maths3D.Vector4( - this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w, - this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w, - this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w, - this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w - ); - } else if (mvp instanceof Maths3D.Vector3) { - return new Maths3D.Vector3( - this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z, - this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z, - this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z - ); - } -}; - -Maths3D.Vector4.Points = function () { - this.vectors = []; -}; - -Maths3D.Vector4.Points.prototype.add = function (vector) { - - if (vector instanceof Maths3D.Vector3) { - vector = new Maths3D.Vector4( - vector.x, - vector.y, - vector.z, - 1 - ) - } - - if (!vector instanceof Maths3D.Vector4) { - console.warn("Vector needs to be of type Vector4"); - throw new Error("Vector needs to be of type Vector4"); - } - - this.vectors.push(vector); - - return this; -}; - -Maths3D.Vector4.Points.prototype.copy = function () { - - var vectors = []; - - for (var i = 0; i < this.vectors.length; i++) { - vectors.push(this.vectors[i].copy()); - } - - return vectors; -}; - -Maths3D.Vector4.Points.prototype.maximizeXDistance = function (grain) { - -// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); - - var multiplier = 0; - - var rotationMatrixY = new Maths3D.Matrix4().rotationMatrixY(grain); - - var totalRadians = 0; - - var backupVectors = this.copy(); - - var maxXDistance = 0; - - for (var i = 0; i < Math.PI * 2; i += grain) { - - multiplier++; - - for (var j = 0; j < this.vectors.length; j++) { - this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); - } - - var distances = this.distances(); - - if (distances.x > maxXDistance) { - - maxXDistance = distances.x; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxXDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new Maths3D.Matrix4().rotationMatrixY(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - -Maths3D.Vector4.Points.prototype.maximizeYDistance = function (grain) { - -// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); - - var multiplier = 0; - - var rotationMatrixX = new Maths3D.Matrix4().rotationMatrixX(grain); - - var totalRadians = 0; - - var backupVectors = this.copy(); - - var maxYDistance = 0; - - for (var i = 0; i < Math.PI * 2; i += grain) { - - multiplier++; - - for (var j = 0; j < this.vectors.length; j++) { - this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); - } - - var distances = this.distances(); - - if (distances.y > maxYDistance) { - maxYDistance = distances.y; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxYDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new Maths3D.Matrix4().rotationMatrixX(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - - -Maths3D.Vector4.Points.prototype.lookAt = function (at, up) { - - var polyCenter = this.average(); - - console.log("poly center : " + JSON.stringify(polyCenter)); - - var lookAtMatrix = new Maths3D.Matrix4().lookAt(polyCenter, at, up); - - lookAtMatrix.rows[0] = new Maths3D.Vector4(1, 0, 0, 0); - lookAtMatrix.rows[1] = new Maths3D.Vector4(0, 0, 1, 0); - lookAtMatrix.rows[2] = new Maths3D.Vector4(0, 1, 0, 0); - - console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); - - for (var i = 0; i < this.vectors.length; i++) { - console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); - this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); - console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); - } -}; - -Maths3D.Vector4.Points.prototype.distances = function () { - - var minX = this.vectors[0].x; - var minY = this.vectors[0].y; - var minZ = this.vectors[0].z; - - var maxX = this.vectors[0].x; - var maxY = this.vectors[0].y; - var maxZ = this.vectors[0].z; - - for (var i = 0; i < this.vectors.length; i++) { - if (this.vectors[i].x < minX) { - minX = this.vectors[i].x; - } - if (this.vectors[i].y < minY) { - minY = this.vectors[i].y; - } - if (this.vectors[i].z < minZ) { - minZ = this.vectors[i].z; - } - - if (this.vectors[i].x > maxX) { - maxX = this.vectors[i].x; - } - if (this.vectors[i].y > maxY) { - maxY = this.vectors[i].y; - } - if (this.vectors[i].z > maxZ) { - maxZ = this.vectors[i].z; - } - } - - return new Maths3D.Vector3( - Math.abs(maxX - minX), - Math.abs(maxY - minY), - Math.abs(maxY - minZ) - ) -}; - -Maths3D.Vector4.Points.prototype.average = function () { - var averageX = 0; - var averageY = 0; - var averageZ = 0; - - for (var i = 0; i < this.vectors.length; i++) { - averageX += this.vectors[i].x; - averageY += this.vectors[i].y; - averageZ += this.vectors[i].z; - } - - return new Maths3D.Vector3( - averageX / this.vectors.length, - averageY / this.vectors.length, - averageZ / this.vectors.length - ); -}; - -Maths3D.Vector4.Points.prototype.negative = function () { - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].x *= -1; - this.vectors[i].y *= -1; - this.vectors[i].z *= -1; - } - - return this; -}; - - -Maths3D.Vector4.Points.prototype.toOrigin = function () { - - var distanceFromOrigin = this.average().negative(); - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].translate(distanceFromOrigin); - } -}; - -Maths3D.Vector3.clockwise = function (u, v, w, viewPoint) { - - var normal = Maths3D.Vector3.normal(u, v, w); - - var uv = u.copy(); - - var winding = normal.dot(uv.subtract(viewPoint)); - - return (winding > 0); -}; - -Maths3D.Vector3.normal = function (u, v, w) { - var vv = v.copy(); - var wv = w.copy(); - return vv.subtract(u).cross(wv.subtract(u)); -}; - -Maths3D.Vector3.prototype.lookAt = function (at, up) { - - var lookAtMatrix = Maths3D.Matrix4.lookAt(this, at, up); - - this.multiply(lookAtMatrix); -}; - -Maths3D.Vector3.prototype.translate = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - return this; -}; - -Maths3D.Vector4.prototype.translate = function (v) { - this.x += v.x; - this.y += v.y; - this.z += v.z; - return this; -}; - -Maths3D.Vector3.prototype.squared = function () { - return this.x * this.x + this.y * this.y + this.z * this.z; -}; - -Maths3D.Vector3.prototype.copy = function () { - return new Maths3D.Vector3( - this.x, - this.y, - this.z - ); -}; - -Maths3D.Vector4.prototype.copy = function () { - return new Maths3D.Vector4( - this.x, - this.y, - this.z, - this.w - ); -}; - -Maths3D.Vector3.prototype.multiply = function (s) { - if (s instanceof Maths3D.Vector3) { - this.x *= s.x; - this.y *= s.y; - this.z *= s.z; - } else if (s instanceof Maths3D.Matrix4) { - var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z; - var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z; - var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z; - this.x = x; - this.y = y; - this.z = z; - } else { - console.log("functionality not implemented - please do this"); - throw new Error("not implemented"); - } - return this; -}; - -Maths3D.Vector4.prototype.multiply = function (s) { - if (s instanceof Maths3D.Vector3) { - this.x *= s.x; - this.y *= s.y; - this.z *= s.z; - } else if (s instanceof Maths3D.Matrix4) { - var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w; - var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w; - var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w; - var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w; - this.x = x; - this.y = y; - this.z = z; - this.w = w; - } else { - console.log("functionality not implemented - please do this"); - throw new Error("not implemented"); - } -}; - -Maths3D.Vector3.prototype.dot = function (v) { - return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); -}; - -Maths3D.Vector3.prototype.normalize = function () { - - var EPSILON = 0.000001; - - var v2 = this.squared(); - - if (v2 < EPSILON) { - return this; //do nothing for zero vector - } - - var invLength = 1 / Math.sqrt(v2); - - this.x *= invLength; - this.y *= invLength; - this.z *= invLength; - - return this; -}; - -Maths3D.Vector4.prototype.normalize = function () { - - // note - leave w untouched - var EPSILON = 0.000001; - - var v2 = this.x * this.x + this.y * this.y + this.z * this.z; - - if (v2 < EPSILON) { - return this; //do nothing for zero vector - } - - var invLength = 1 / Math.sqrt(v2); - - this.x *= invLength; - this.y *= invLength; - this.z *= invLength; - - return this; -}; - -Maths3D.Matrix3.prototype.identity = function () { - this.rows = [ - new Maths3D.Vector4(1, 0, 0), - new Maths3D.Vector4(0, 1, 0), - new Maths3D.Vector4(0, 0, 1) - ]; -}; - -Maths3D.Matrix4.prototype.identity = function () { - this.rows = [ - new Maths3D.Vector4(1, 0, 0, 0), - new Maths3D.Vector4(0, 1, 0, 0), - new Maths3D.Vector4(0, 0, 1, 0), - new Maths3D.Vector4(0, 0, 0, 1) - ]; -}; - -Maths3D.Matrix4.prototype.lookAt = function (position, target, up) { - - var pv = new Maths3D.Vector3(position.x, position.y, position.z); - - var z = pv.subtract(target).normalize(); - - if (z.squared() === 0) { - z.z = 1; - } - - var x = up.cross(z).normalize(); - - if (x.squared() === 0) { - z.x += 0.0001; - x = up.cross(z).normalize(); - } - - var y = z.cross(x); - - this.rows[0].x = x.x; - this.rows[0].y = x.y; - this.rows[0].z = x.z; - - this.rows[1].x = y.x; - this.rows[1].y = y.y; - this.rows[1].z = y.z; - - this.rows[2].x = z.x; - this.rows[2].y = z.y; - this.rows[2].z = z.z; - - return this; - - // te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; - // te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; - // te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; - - - // var matrix4 = new Matrix4(); - // - // matrix4.rows[0] = side.negative(); - // matrix4.rows[1] = _up; - // matrix4.rows[2] = forward; - - // - // matrix4.setColumn(0, side.negative()); - // matrix4.setColumn(1, _up); - // matrix4.setColumn(2, forward); - - //return matrix4; - - // return new Matrix4( - // new Vector4( - // side.x, - // side.y, - // side.z, - // side.negative().dot(position) - // ), - // new Vector4( - // _up.x, - // _up.y, - // _up.z, - // _up.negative().dot(position) - // ), - // new Vector4( - // forward.negative().x, - // forward.negative().y, - // forward.negative().z, - // forward.dot(position) - // ) - // ) -}; - -Maths3D.Vector3.prototype.negative = function () { - this.x *= -1; - this.y *= -1; - this.z *= -1; - return this; -}; - -Maths3D.Vector3.prototype.magnitude = function () { - return this.x + this.y + this.z; -}; - -Maths3D.Vector4.prototype.subtract = function (v) { - - if (v instanceof Maths3D.Vector3) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - } - - if (v instanceof Maths3D.Vector4) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - this.w -= v.w; - } - - return this; -}; - -Maths3D.Vector3.prototype.subtract = function (v) { - - if (v instanceof Maths3D.Vector3) { - this.x -= v.x; - this.y -= v.y; - this.z -= v.z; - } - - if (v instanceof Maths3D.Vector4) { - console.warn("trying to subtract vector of bigger length (4 vs 3))"); - } - - return this; -}; - -Maths3D.Vector3.prototype.cross = function (v) { - return new Maths3D.Vector3( - this.y * v.z - this.z * v.y, - this.z * v.x - this.x * v.z, - this.x * v.y - this.y * v.x - ); -}; - -if (typeof module !== 'undefined') { - module.exports = Maths3D; -} \ No newline at end of file diff --git a/game-lib.js b/game-lib.js deleted file mode 100644 index a32540e..0000000 --- a/game-lib.js +++ /dev/null @@ -1,3712 +0,0 @@ -if (typeof require != 'undefined') { - var Maths3D = require('./game-lib-maths.js'); -} - -if (typeof require != 'undefined') { - var Controls = require('./game-lib-controls.js'); -} - -function GameLib() {} - -/** - * GameLib.D3 connects our GameLib.D3 assets to a graphics library like THREE.js, but could technically be any graphics - * lib - * @param config - * @param Q Q - * @param THREE THREE.js - * @param apiUrl - * @param editorUrl - * @constructor - */ -GameLib.D3 = function( - config, - Q, - THREE, - apiUrl, - editorUrl, - CANNON, - path -){ - this.config = config; - this.Q = Q; - this.THREE = THREE; - this.CANNON = CANNON; - this.textureLoader = new this.THREE.TextureLoader(); - this.apiUrl = apiUrl || this.config.api16.url; - this.editorUrl = editorUrl || this.config.editor.url; - this.path = path; -}; - -if (typeof require == 'undefined' && - typeof Maths3D == 'undefined') { - console.warn("You need a proper Maths3D library in order to use this library"); -} - -if (typeof require == 'undefined' && - typeof Controls == 'undefined') { - console.warn("You need a proper Control library in order to use this library"); -} - -GameLib.D3.Controls = Controls; - -GameLib.D3.Vector2 = Maths3D.Vector2; -GameLib.D3.Vector3 = Maths3D.Vector3; -GameLib.D3.Vector4 = Maths3D.Vector4; -GameLib.D3.Matrix4 = Maths3D.Matrix4; -GameLib.D3.Color = Maths3D.Color; - -/** - * Texture Superset - * @param id - * @param path - * @param name - * @param image - * @param wrapS - * @param wrapT - * @param repeat - * @param data - * @param format - * @param mapping - * @param magFilter - * @param minFilter - * @param textureType - * @param anisotropy - * @param offset - * @param generateMipmaps - * @param flipY - * @param mipmaps - * @param unpackAlignment - * @param premultiplyAlpha - * @param encoding - * @constructor - */ -GameLib.D3.Texture = function( - id, - name, - image, - wrapS, - wrapT, - repeat, - data, - format, - mapping, - magFilter, - minFilter, - textureType, - anisotropy, - offset, - generateMipmaps, - flipY, - mipmaps, - unpackAlignment, - premultiplyAlpha, - encoding -) { - this.id = id; - this.name = name; - this.image = image; - - if (typeof wrapS == 'undefined') { - wrapS = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; - } - this.wrapS = wrapS; - - if (typeof wrapT == 'undefined') { - wrapT = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; - } - this.wrapT = wrapT; - - if (typeof repeat == 'undefined') { - repeat = new GameLib.D3.Vector2(1, 1); - } - this.repeat = repeat; - - if (typeof data == 'undefined') { - data = null; - } - this.data = data; - - if (typeof format == 'undefined') { - format = GameLib.D3.Texture.TYPE_RGBA_FORMAT; - } - this.format = format; - - if (typeof mapping == 'undefined') { - mapping = GameLib.D3.Texture.TYPE_UV_MAPPING; - } - this.mapping = mapping; - - if (typeof magFilter == 'undefined') { - magFilter = GameLib.D3.Texture.TYPE_LINEAR_FILTER; - } - this.magFilter = magFilter; - - if (typeof minFilter == 'undefined') { - minFilter = GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER; - } - this.minFilter = minFilter; - - if (typeof textureType == 'undefined') { - textureType = GameLib.D3.Texture.TYPE_UNSIGNED_BYTE; - } - this.textureType = textureType; - - if (typeof anisotropy == 'undefined') { - anisotropy = 1; - } - this.anisotropy = anisotropy; - - if (typeof offset == 'undefined') { - offset = new GameLib.D3.Vector2(0, 0); - } - this.offset = offset; - - if (typeof generateMipmaps == 'undefined') { - generateMipmaps = true; - } - this.generateMipmaps = generateMipmaps; - - if (typeof flipY == 'undefined') { - flipY = true; - } - this.flipY = flipY; - - if (typeof mipmaps == 'undefined') { - mipmaps = []; - } - this.mipmaps = mipmaps; - - if (typeof unpackAlignment == 'undefined') { - unpackAlignment = 4; - } - this.unpackAlignment = unpackAlignment; - - if (typeof premultiplyAlpha == 'undefined') { - premultiplyAlpha = false; - } - this.premultiplyAlpha = premultiplyAlpha; - - if (typeof encoding == 'undefined') { - encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING; - } - this.encoding = encoding; -}; - -/** - * Texture Formats - * @type {number} - */ -GameLib.D3.Texture.TYPE_ALPHA_FORMAT = 1019; -GameLib.D3.Texture.TYPE_RGB_FORMAT = 1020; -GameLib.D3.Texture.TYPE_RGBA_FORMAT = 1021; -GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT = 1022; -GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023; -GameLib.D3.Texture.TYPE_DEPTH_FORMAT = 1026; - -/** - * Mapping modes - * @type {number} - */ -GameLib.D3.Texture.TYPE_UV_MAPPING = 300; -GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301; -GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302; -GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303; -GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304; -GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305; -GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306; -GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307; - -/** - * Wrapping Modes - * @type {number} - */ -GameLib.D3.Texture.TYPE_REPEAT_WRAPPING = 1000; -GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001; -GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002; - -/** - * Mipmap Filters - * @type {number} - */ -GameLib.D3.Texture.TYPE_NEAREST_FILTER = 1003; -GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004; -GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005; -GameLib.D3.Texture.TYPE_LINEAR_FILTER = 1006; -GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007; -GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008; - -/** - * Texture Data Types - * @type {number} - */ -GameLib.D3.Texture.TYPE_UNSIGNED_BYTE = 1009; -GameLib.D3.Texture.TYPE_BYTE = 1010; -GameLib.D3.Texture.TYPE_SHORT = 1011; -GameLib.D3.Texture.TYPE_UNSIGNED_SHORT = 1012; -GameLib.D3.Texture.TYPE_INT = 1013; -GameLib.D3.Texture.TYPE_UNSIGNED_INT = 1014; -GameLib.D3.Texture.TYPE_FLOAT = 1015; -GameLib.D3.Texture.TYPE_HALF_FLOAT = 1025; - -/** - * Encoding Modes - * @type {number} - */ -GameLib.D3.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL. -GameLib.D3.Texture.TYPE_SRGB_ENCODING = 3001; -GameLib.D3.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT -GameLib.D3.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE. -GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING = 3003; -GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004; -GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; -GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. - -/** - * Light Superset - * @param id - * @param lightType - * @param name - * @param color - * @param intensity - * @param position - * @param targetPosition - * @param quaternion - * @param rotation - * @param scale - * @param distance - * @param decay - * @param power - * @param angle - * @param penumbra - * @constructor - */ -GameLib.D3.Light = function( - id, - lightType, - name, - color, - intensity, - position, - targetPosition, - quaternion, - rotation, - scale, - distance, - decay, - power, - angle, - penumbra -) { - this.id = id; - this.lightType = lightType; - this.name = name; - this.color = color; - this.intensity = intensity; - - if (typeof position == 'undefined') { - position = new GameLib.D3.Vector3(0,0,0); - } - this.position = position; - - if (typeof targetPosition == 'undefined') { - targetPosition = new GameLib.D3.Vector3(0,0,0); - } - this.targetPosition = targetPosition; - - if (typeof quaternion == 'undefined'){ - quaternion = new GameLib.D3.Vector4(); - } - this.quaternion = quaternion; - - if (typeof rotation == 'undefined'){ - rotation = new GameLib.D3.Vector3(0,0,0); - } - this.rotation = rotation; - - if (typeof scale == 'undefined'){ - scale = new GameLib.D3.Vector3(1,1,1); - } - this.scale = scale; - - if (typeof distance == 'undefined'){ - distance = 0; - } - this.distance = distance; - - if (typeof decay == 'undefined'){ - decay = 1; - } - this.decay = decay; - - if (typeof power == 'undefined'){ - power = 4 * Math.PI; - } - this.power = power; - - if (typeof angle == 'undefined'){ - angle = Math.PI / 3; - } - this.angle = angle; - - if (typeof penumbra == 'undefined'){ - penumbra = 0; - } - this.penumbra = penumbra; -}; - -/** - * Material Superset - * @param id - * @param path - * @param name - * @param materialType - * @param opacity - * @param side - * @param transparent - * @param maps - * @param specular - * @param lightMapIntensity - * @param aoMapIntensity - * @param color - * @param emissive - * @param emissiveIntensity - * @param combine - * @param shininess - * @param reflectivity - * @param refractionRatio - * @param fog - * @param wireframe - * @param wireframeLineWidth - * @param wireframeLineCap - * @param wireframeLineJoin - * @param vertexColors - * @param skinning - * @param morphTargets - * @param morphNormals - * @param lineWidth - * @param lineCap - * @param lineJoin - * @param dashSize - * @param gapWidth - * @param blending - * @param blendSrc - * @param blendDst - * @param blendEquation - * @param depthTest - * @param depthFunc - * @param depthWrite - * @param polygonOffset - * @param polygonOffsetFactor - * @param polygonOffsetUnits - * @param alphaTest - * @param clippingPlanes - * @param clipShadows - * @param visible - * @param overdraw - * @param shading - * @param bumpScale - * @param normalScale - * @param displacementScale - * @param displacementBias - * @param roughness - * @param metalness - * @param pointSize - * @param pointSizeAttenuation - * @param spriteRotation - * @param envMapIntensity - * @constructor - */ -GameLib.D3.Material = function( - id, - name, - materialType, - opacity, - side, - transparent, - maps, - specular, - lightMapIntensity, - aoMapIntensity, - color, - emissive, - emissiveIntensity, - combine, - shininess, - reflectivity, - refractionRatio, - fog, - wireframe, - wireframeLineWidth, - wireframeLineCap, - wireframeLineJoin, - vertexColors, - skinning, - morphTargets, - morphNormals, - lineWidth, - lineCap, - lineJoin, - dashSize, - gapWidth, - blending, - blendSrc, - blendDst, - blendEquation, - depthTest, - depthFunc, - depthWrite, - polygonOffset, - polygonOffsetFactor, - polygonOffsetUnits, - alphaTest, - clippingPlanes, - clipShadows, - visible, - overdraw, - shading, - bumpScale, - normalScale, - displacementScale, - displacementBias, - roughness, - metalness, - pointSize, - pointSizeAttenuation, - spriteRotation, - envMapIntensity -) { - this.id = id; - this.name = name; - if (typeof materialType == 'undefined') { - materialType = GameLib.D3.Material.TYPE_MESH_STANDARD; - } - this.materialType = materialType; - - if (typeof opacity == 'undefined') { - opacity = 1.0; - } - this.opacity = opacity; - - if (typeof side == 'undefined') { - side = GameLib.D3.Material.TYPE_FRONT_SIDE; - } - this.side = side; - - if (typeof transparent == 'undefined') { - transparent = false; - } - this.transparent = transparent; - - if (typeof maps == 'undefined') { - maps = { - alpha: null, - ao: null, - bump: null, - diffuse: null, - displacement: null, - emissive: null, - environment: null, - light: null, - metalness: null, - normal: null, - roughness: null, - specular: null - }; - } - this.maps = maps; - - if (typeof specular == 'undefined') { - specular = new GameLib.D3.Color(0.06, 0.06, 0.06, 0.06); - } - this.specular = specular; - - if (typeof lightMapIntensity == 'undefined') { - lightMapIntensity = 1; - } - this.lightMapIntensity = lightMapIntensity; - - if (typeof aoMapIntensity == 'undefined') { - aoMapIntensity = 1; - } - this.aoMapIntensity = aoMapIntensity; - - if (typeof color == 'undefined') { - color = new GameLib.D3.Color(1, 1, 1, 1) - } - this.color = color; - - if (typeof emissive == 'undefined') { - emissive = new GameLib.D3.Color(0, 0, 0, 0); - } - this.emissive = emissive; - - if (typeof emissiveIntensity == 'undefined') { - emissiveIntensity = 1; - } - this.emissiveIntensity = emissiveIntensity; - - if (typeof combine == 'undefined') { - combine = GameLib.D3.Material.TYPE_MULTIPLY_OPERATION; - } - this.combine = combine; - - if (typeof shininess == 'undefined') { - shininess = 30; - } - this.shininess = shininess; - - if (typeof reflectivity == 'undefined') { - reflectivity = 1; - } - this.reflectivity = reflectivity; - - if (typeof refractionRatio == 'undefined') { - refractionRatio = 0.98; - } - this.refractionRatio = refractionRatio; - - if (typeof fog == 'undefined') { - fog = true; - } - this.fog = fog; - - if (typeof wireframe == 'undefined') { - wireframe = false; - } - this.wireframe = wireframe; - - if (typeof wireframeLineWidth == 'undefined') { - wireframeLineWidth = 1; - } - this.wireframeLineWidth = wireframeLineWidth; - - if (typeof wireframeLineCap == 'undefined') { - wireframeLineCap = 'round'; - } - this.wireframeLineCap = wireframeLineCap; - - if (typeof wireframeLineJoin == 'undefined') { - wireframeLineJoin = 'round'; - } - this.wireframeLineJoin = wireframeLineJoin; - - if (typeof vertexColors == 'undefined') { - vertexColors = GameLib.D3.Material.TYPE_NO_COLORS; - } - this.vertexColors = vertexColors; - - if (typeof skinning == 'undefined') { - skinning = false; - } - this.skinning = skinning; - - if (typeof morphTargets == 'undefined') { - morphTargets = false; - } - this.morphTargets = morphTargets; - - if (typeof morphNormals == 'undefined') { - morphNormals = false; - } - this.morphNormals = morphNormals; - - if (typeof overdraw == 'undefined') { - overdraw = 0; - } - this.overdraw = overdraw; - - if (typeof lineWidth == 'undefined') { - lineWidth = 1; - } - this.lineWidth = lineWidth; - - if (typeof lineCap == 'undefined') { - lineCap = 'round'; - } - this.lineCap = lineCap; - - if (typeof lineJoin == 'undefined') { - lineJoin = 'round'; - } - this.lineJoin = lineJoin; - - if (typeof dashSize == 'undefined') { - dashSize = 3; - } - this.dashSize = dashSize; - - if (typeof gapWidth == 'undefined') { - gapWidth = 1; - } - this.gapWidth = gapWidth; - - if (typeof blending == 'undefined') { - blending = GameLib.D3.Material.TYPE_NORMAL_BLENDING; - } - this.blending = blending; - - if (typeof blendSrc == 'undefined') { - blendSrc = GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR; - } - this.blendSrc = blendSrc; - - if (typeof blendDst == 'undefined') { - blendDst = GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR; - } - this.blendDst = blendDst; - - if (typeof blendEquation == 'undefined') { - blendEquation = GameLib.D3.Material.TYPE_ADD_EQUATION; - } - this.blendEquation = blendEquation; - - if (typeof depthTest == 'undefined') { - depthTest = true; - } - this.depthTest = depthTest; - - if (typeof depthFunc == 'undefined') { - depthFunc = GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH; - } - this.depthFunc = depthFunc; - - if (typeof depthWrite == 'undefined') { - depthWrite = true; - } - this.depthWrite = depthWrite; - - if (typeof polygonOffset == 'undefined') { - polygonOffset = false; - } - this.polygonOffset = polygonOffset; - - if (typeof polygonOffsetFactor == 'undefined') { - polygonOffsetFactor = 1; - } - this.polygonOffsetFactor = polygonOffsetFactor; - - if (typeof polygonOffsetUnits == 'undefined') { - polygonOffsetUnits = 1; - } - this.polygonOffsetUnits = polygonOffsetUnits; - - if (typeof alphaTest == 'undefined') { - alphaTest = 0; - } - this.alphaTest = alphaTest; - - if (typeof clippingPlanes == 'undefined') { - clippingPlanes = []; - } - this.clippingPlanes = clippingPlanes; - - if (typeof clipShadows == 'undefined') { - clipShadows = false; - } - this.clipShadows = clipShadows; - - if (typeof visible == 'undefined') { - visible = true; - } - this.visible = visible; - - if (typeof shading == 'undefined') { - shading = GameLib.D3.Material.TYPE_FLAT_SHADING; - } - this.shading = shading; - - if (typeof bumpScale == 'undefined') { - bumpScale = 1; - } - this.bumpScale = bumpScale; - - if (typeof normalScale == 'undefined') { - normalScale = 1; - } - this.normalScale = normalScale; - - if (typeof displacementScale == 'undefined') { - displacementScale = 1; - } - this.displacementScale = displacementScale; - - if (typeof displacementBias == 'undefined') { - displacementBias = 0; - } - this.displacementBias = displacementBias; - - if (typeof roughness == 'undefined') { - roughness = 0.5; - } - this.roughness = roughness; - - if (typeof metalness == 'undefined') { - metalness = 0.5; - } - this.metalness = metalness; - - if (typeof pointSize == 'undefined') { - pointSize = 1; - } - this.pointSize = pointSize; - - if (typeof pointSizeAttenuation == 'undefined') { - pointSizeAttenuation = true; - } - this.pointSizeAttenuation = pointSizeAttenuation; - - if (typeof spriteRotation == 'undefined') { - spriteRotation = 0; - } - this.spriteRotation = spriteRotation; - - if (typeof envMapIntensity == 'undefined') { - envMapIntensity = 1.0; - } - this.envMapIntensity = envMapIntensity; - -}; - -/** - * Combine Method - * @type {number} - */ -GameLib.D3.Material.TYPE_MULTIPLY_OPERATION = 0; -GameLib.D3.Material.TYPE_MIX_OPERATION = 1; -GameLib.D3.Material.TYPE_ADD_OPERATION = 2; - -/** - * Vertex Color Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_NO_COLORS = 0; -GameLib.D3.Material.TYPE_FACE_COLORS = 1; -GameLib.D3.Material.TYPE_VERTEX_COLORS = 2; - -/** - * Blending Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_NORMAL_BLENDING = 1; -GameLib.D3.Material.TYPE_ADDITIVE_BLENDING = 2; -GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING = 3; -GameLib.D3.Material.TYPE_MULTIPLY_BLENDING = 4; -GameLib.D3.Material.TYPE_CUSTOM_BLENDING = 5; - -/** - * Blend Source and Destination - * @type {number} - */ -GameLib.D3.Material.TYPE_ZERO_FACTOR = 200; -GameLib.D3.Material.TYPE_ONE_FACTOR = 201; -GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR = 202; -GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR = 203; -GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR = 204; -GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR = 205; -GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR = 206; -GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR = 207; -GameLib.D3.Material.TYPE_DST_COLOR_FACTOR = 208; -GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR = 209; -GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR = 210; - -/** - * Blend Operation - * @type {number} - */ -GameLib.D3.Material.TYPE_ADD_EQUATION = 100; -GameLib.D3.Material.TYPE_SUBTRACT_EQUATION = 101; -GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION = 102; -GameLib.D3.Material.TYPE_MIN_EQUATION = 103; -GameLib.D3.Material.TYPE_MAX_EQUATION = 104; - -/** - * Depth Function - * @type {number} - */ -GameLib.D3.Material.TYPE_NEVER_DEPTH = 0; -GameLib.D3.Material.TYPE_ALWAYS_DEPTH = 1; -GameLib.D3.Material.TYPE_LESS_DEPTH = 2; -GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH = 3; -GameLib.D3.Material.TYPE_EQUAL_DEPTH = 4; -GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH = 5; -GameLib.D3.Material.TYPE_GREATER_DEPTH = 6; -GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH = 7; - -/** - * Culling Mode - * @type {number} - */ -GameLib.D3.Material.TYPE_FRONT_SIDE = 0; -GameLib.D3.Material.TYPE_BACK_SIDE = 1; -GameLib.D3.Material.TYPE_DOUBLE_SIDE = 2; - -/** - * Shading Type - * @type {number} - */ -GameLib.D3.Material.TYPE_FLAT_SHADING = 1; -GameLib.D3.Material.TYPE_SMOOTH_SHADING = 2; - -/** - * Material Type - * @type {string} - */ -GameLib.D3.Material.TYPE_LINE_BASIC = "LineBasicMaterial"; -GameLib.D3.Material.TYPE_LINE_DASHED = "LineDashedMaterial"; -GameLib.D3.Material.TYPE_MESH_BASIC = "MeshBasicMaterial"; -GameLib.D3.Material.TYPE_MESH_DEPTH = "MeshDepthMaterial"; -GameLib.D3.Material.TYPE_MESH_LAMBERT = "MeshLambertMaterial"; -GameLib.D3.Material.TYPE_MESH_NORMAL = "MeshNormalMaterial"; -GameLib.D3.Material.TYPE_MESH_PHONG = "MeshPhongMaterial"; -GameLib.D3.Material.TYPE_MESH_STANDARD = "MeshStandardMaterial"; -GameLib.D3.Material.TYPE_POINTS = "PointsMaterial"; -GameLib.D3.Material.TYPE_SPRITE = "SpriteMaterial"; -GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial"; - -/** - * Skeleton Superset - * @param id - * @param bones GameLib.D3.Bone - * @param boneInverses - * @param useVertexTexture - * @param boneTextureWidth - * @param boneTextureHeight - * @param boneMatrices - * @param boneTexture - * @constructor - */ -GameLib.D3.Skeleton = function( - id, - bones, - boneInverses, - useVertexTexture, - boneTextureWidth, - boneTextureHeight, - boneMatrices, - boneTexture -) { - this.id = id; - - this.bones = bones; - - /** - * An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones. - * @type GameLib.D3.Matrix4[] - */ - if (typeof boneInverses == 'undefined') { - boneInverses = []; - } - this.boneInverses = boneInverses; - - /** - * Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices - * @type {boolean} - */ - if (typeof useVertexTexture == 'undefined') { - useVertexTexture = false; - } - this.useVertexTexture = useVertexTexture; - - if (this.useVertexTexture == true) { - console.warn('support for vertex texture bones is not supported yet - something could break somewhere'); - } - - if (typeof boneTextureWidth == 'undefined') { - boneTextureWidth = 0; - } - this.boneTextureWidth = boneTextureWidth; - - if (typeof boneTextureHeight == 'undefined') { - boneTextureHeight = 0; - } - this.boneTextureHeight = boneTextureHeight; - - if (typeof boneMatrices == 'undefined') { - boneMatrices = []; - } - this.boneMatrices = boneMatrices; - - if (typeof boneTexture == 'undefined') { - boneTexture = []; - } - this.boneTexture = boneTexture; -}; - -/** - * Mesh Superset - * @param id - * @param path - * @param name - * @param meshType - * @param vertices - * @param faces - * @param skeleton - * @param faceVertexUvs - * @param skinIndices - * @param skinWeights - * @param materials - * @param position - * @param quaternion - * @param rotation - * @param scale - * @param up - * @param physics - * @param parentMeshId - * @param parentSceneId - * @param rawData - * @constructor - */ -GameLib.D3.Mesh = function( - id, - path, - name, - meshType, - vertices, - faces, - skeleton, - faceVertexUvs, - skinIndices, - skinWeights, - materials, - position, - quaternion, - rotation, - scale, - up, - physics, - parentMeshId, - parentSceneId, - rawData -) { - this.id = id; - this.path = path; - this.name = name; - this.meshType = meshType; - this.vertices = vertices; - this.faces = faces; - - if (typeof skeleton == 'undefined') { - skeleton = null; - } - this.skeleton = skeleton; - - if (typeof faceVertexUvs == 'undefined') { - faceVertexUvs = []; - } - this.faceVertexUvs = faceVertexUvs; - - if (typeof skinIndices == 'undefined') { - skinIndices = []; - } - this.skinIndices = skinIndices; - - if (typeof skinWeights == 'undefined') { - skinWeights = []; - } - this.skinWeights = skinWeights; - - if (typeof materials == 'undefined') { - materials = []; - } - this.materials = materials; - - if (typeof position == 'undefined') { - position = new GameLib.D3.Vector3(0,0,0); - } - this.position = position; - - if (typeof quaternion == 'undefined') { - new GameLib.D3.Vector4(); - } - this.quaternion = quaternion; - - if (typeof rotation == 'undefined') { - rotation = new GameLib.D3.Vector3(0,0,0); - } - this.rotation = rotation; - - if (typeof scale == 'undefined') { - scale = new GameLib.D3.Vector3(1,1,1); - } - this.scale = scale; - - if (typeof up == 'undefined') { - up = new GameLib.D3.Vector3(0,1,0); - } - this.up = up; - - this.physics = physics; - - this.parentMeshId = parentMeshId; - - this.parentSceneId = parentSceneId; - - this.rawData = null;// rawData; -}; - -/** - * Mesh Type - * @type {number} - */ -GameLib.D3.Mesh.TYPE_NORMAL = 0; -GameLib.D3.Mesh.TYPE_SKINNED = 1; - -/** - * Bone Superset - * @param id - * @param name string - * @param boneId - * @param childBoneIds - * @param parentBoneId - * @param quaternion - * @param position - * @param rotation - * @param scale GameLib.D3.Vector3 - * @param up - * @param rawData - * @constructor - */ -GameLib.D3.Bone = function( - id, - boneId, - name, - childBoneIds, - parentBoneId, - quaternion, - position, - rotation, - scale, - up, - rawData -) { - this.id = id; - this.name = name; - this.boneId = boneId; - - if (typeof childBoneIds == 'undefined') { - childBoneIds = []; - } - this.childBoneIds = childBoneIds; - - if (typeof parentBoneId == 'undefined') { - parentBoneId = null; - } - this.parentBoneId = parentBoneId; - - if (typeof quaternion == 'undefined') { - quaternion = new GameLib.D3.Vector4(); - } - this.quaternion = quaternion; - - if (typeof position == 'undefined') { - position = new GameLib.D3.Vector3(0,0,0); - } - this.position = position; - - if (typeof rotation == 'undefined') { - rotation = new GameLib.D3.Vector3(0,0,0); - } - this.rotation = rotation; - - if (typeof scale == 'undefined') { - scale = new GameLib.D3.Vector3(1,1,1); - } - this.scale = scale; - - if (typeof up == 'undefined') { - up = new GameLib.D3.Vector3(0,1,0); - } - this.up = up; - - this.rawData = null;//rawData; -}; - -/** - * Physics Superset - * @param id - * @param name - * @param engineType - * @param CANNON - * @param Ammo - * @param Goblin - * @param worlds GameLib.D3.Physics.World[] - * @constructor - */ -GameLib.D3.Physics = function( - id, - name, - engineType, - CANNON, - Ammo, - Goblin, - worlds, - customWorlds -) { - - this.id = id; - this.name = name; - this.engineType = engineType; - - this.CANNON = CANNON; - - this.Ammo = Ammo; - - this.Goblin = Goblin; - - this.worlds = []; - - this.customWorlds = []; -}; - -/** - * Physics Engine Types - * @type {number} - */ -GameLib.D3.Physics.TYPE_CANNON = 0x1; -GameLib.D3.Physics.TYPE_AMMO = 0x2; -GameLib.D3.Physics.TYPE_GOBLIN = 0x3; - -/** - * Broadphase Types - * @type {number} - */ -GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE = 0x1; -GameLib.D3.Physics.BROADPHASE_TYPE_GRID = 0x2; -GameLib.D3.Physics.BROADPHASE_TYPE_SAP = 0x3; - -/** - * Solver Types - * @type {number} - */ -GameLib.D3.Physics.SPLIT_SOLVER = 0x1; -GameLib.D3.Physics.GS_SOLVER = 0x2; - -/** - * Physics Solver Superset - * @param id - * @param name - * @param solverType - * @param iterations - * @param tolerance - * @constructor - */ -GameLib.D3.Physics.Solver = function( - id, - name, - solverType, - iterations, - tolerance -) { - this.id = id; - if (typeof name == 'undefined') { - if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) { - name = 'split solver'; - } else if (solverType == GameLib.D3.Physics.GS_SOLVER) { - name = 'gs solver'; - } else { - name = 'unknown solver'; - } - } - this.name = name; - this.solverType = solverType; - this.iterations = iterations; - this.tolerance = tolerance; -}; - -/** - * Physics Broadphase Superset - * @param id - * @param name - * @param broadphaseType - * @constructor - */ -GameLib.D3.Physics.Broadphase = function( - id, - name, - broadphaseType -) { - this.id = id; - - if (typeof name == 'undefined') { - name = 'broadphase-' + broadphaseType; - } - this.name = name; - - if (typeof broadphaseType == 'undefined') { - console.warn('undefined broadphase type'); - throw new Error('undefined broadphase type'); - } - - this.broadphaseType = broadphaseType; -}; - -/** - * Physics World Superset - * @param id - * @param name - * @param physics - * @param gravity - * @param broadphase - * @param solver - * @param rigidBodies - * @constructor - */ -GameLib.D3.Physics.World = function( - id, - name, - physics, - gravity, - broadphase, - solver, - rigidBodies -) { - this.id = id; - - this.name = name; - - if (typeof gravity == 'undefined') { - gravity = new GameLib.D3.Vector3(0, -9.81, 0); - } - this.gravity = gravity; - - if (typeof broadphase == 'undefined') { - broadphase = new GameLib.D3.Physics.Broadphase( - null, - 'broadPhaseNaive', - GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE - ); - } - this.broadphase = broadphase; - - if (typeof solver == 'undefined') { - solver = new GameLib.D3.Physics.Solver( - null, - 'GSSolver', - GameLib.D3.Physics.GS_SOLVER - ); - } - this.solver = solver; - - if (typeof rigidBodies == 'undefined') { - rigidBodies = []; - } - this.rigidBodies = rigidBodies; - - /** - * We only set the physics property if we pass it in the constructor, - * because we don't always want the physics object (ex. when we store this world to the API - we also don't then - * want to store the custom worlds - we want to generate them after loading from API) - */ - if (physics) { - this.physics = physics; - this.physics.worlds.push(this); - this.physics.customWorlds.push(this.getCustomWorld(this)); - } -}; - -/** - * Physics Rigid Body Superset - * @param id - * @param name - * @constructor - */ -GameLib.D3.Physics.RigidBody = function( - id, - name -) { - this.bodyObject = null; -}; - -/** - * Physics Rigid Body Vehicle Superset - * TODO: body + wheels[] - * @constructor - */ -GameLib.D3.Physics.RigidVehicle = function( -) { - this.vehicleObject = null; -}; - -/** - * Physics Raycast Vehicle Superset - * TODO: body + wheels[] - * @constructor - */ -GameLib.D3.Physics.RaycastVehicle = function( -) { - this.vehicleObject = null; -}; - -/** - * Physics Shape Superset - * @constructor - */ -GameLib.D3.Physics.Shape = function( - shapeObject, // Physics engine specific - shapeType -) { - this.shapeObject = shapeObject; - this.shapeType = shapeType; - this.scale = new GameLib.D3.Vector3(1, 1, 1); -}; - -GameLib.D3.Physics.Shape.TYPE_SPHERE = 1; -GameLib.D3.Physics.Shape.TYPE_BOX = 2; -GameLib.D3.Physics.Shape.TYPE_TRIMESH = 3; -GameLib.D3.Physics.Shape.TYPE_CYLINDER = 4; - -/** - * Physics Convex Hull Shape Superset - * @param id - * @param name - * @constructor - */ -GameLib.D3.Physics.Shape.ConvexHull = function( - id, - name -) { - this.id = id; - this.name = name; -}; - -/** - * Physics Triangle Mesh Shape Superset - * @param id - * @param name - * @constructor - */ -GameLib.D3.Physics.Shape.TriangleMesh = function( - id, - name -) { - this.id = id; - this.name = name; -}; - -/** - * TriangleFace - * @param v0 - * @param v1 - * @param v2 - * @param materialIndex - * @param v0uv - * @param v1uv - * @param v2uv - * @param color - * @param vertexColors - * @param vertexNormals - * @param normal - * @constructor - */ -GameLib.D3.TriangleFace = function( - v0, - v1, - v2, - materialIndex, - v0uv, - v1uv, - v2uv, - color, - vertexColors, - vertexNormals, - normal -) { - this.v0 = v0; - this.v1 = v1; - this.v2 = v2; - this.materialIndex = materialIndex; - this.v0uv = v0uv; - this.v1uv = v1uv; - this.v2uv = v2uv; - if (!color) { - color = new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff); - } - this.color = color; - - if (!vertexColors) { - vertexColors = [ - new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), - new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), - new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff) - ]; - } - this.vertexColors = vertexColors; - - if (!vertexNormals) { - vertexNormals = [ - new GameLib.D3.Vector3(), - new GameLib.D3.Vector3(), - new GameLib.D3.Vector3() - ] - } - this.vertexNormals = vertexNormals; - - if (!normal) { - normal = new GameLib.D3.Vector3(0); - } - - this.normal = normal; -}; - -/** - * TriangleEdge - * @param triangle - * @param edge - * @constructor - */ -GameLib.D3.TriangleEdge = function( - triangle, - edge -) { - this.triangle = triangle; - this.edge = edge; -}; - -/** - * Contains a Poly vertex data structure - * @param localIndex - * @param mvertIndex - * @param uv GameLib.D3.Vector2 - * @param materialIndex - * @param edgeIndex - * @constructor - */ -GameLib.D3.PolyVertex = function( - localIndex, - mvertIndex, - uv, - materialIndex, - edgeIndex -) { - this.localIndex = localIndex; - this.mvertIndex = mvertIndex; - this.uv = uv; - this.materialIndex = materialIndex; - this.edgeIndex = edgeIndex; -}; - -/** - * BoneWeight object - associates a vertex to a bone with some weight - * @param boneIndex int - * @param weight float - * @constructor - */ -GameLib.D3.BoneWeight = function( - boneIndex, - weight -) { - this.boneIndex = boneIndex; - this.weight = weight; -}; - -/** - * The normal gets assigned when the face calculates its normal - * @param position - * @param boneWeights GameLib.D3.BoneWeight[] - * @constructor - */ -GameLib.D3.Vertex = function( - position, - boneWeights -) { - this.position = position; - this.boneWeights = boneWeights; -}; - -/** - * Image - * @param id - * @param textureLink - * @param filename - * @param size - * @param contentType - * @constructor - */ -GameLib.D3.Image = function( - id, - textureLink, - filename, - size, - contentType -) { - this.id = id; - - this.filename = filename; - - this.textureLink = textureLink; - - if (typeof size == 'undefined') { - size = 0; - } - this.size = size; - - if (typeof contentType == 'undefined') { - - contentType = 'application/octet-stream'; - - if (this.filename.match(/(png)$/i)) { - contentType = 'image/png'; - } - - if (this.filename.match(/(jpg|jpeg)$/i)) { - contentType = 'image/jpeg'; - } - - if (this.filename.match(/(gif)$/i)) { - contentType = 'image/gif'; - } - } - this.contentType = contentType; - - -}; - -/** - * Scenes are objects putting meshes into 'world space' - * @param id - * @param path String - * @param name String - * @param meshes GameLib.D3.Mesh[] - * @param quaternion - * @param position - * @param rotation - * @param scale - * @param parentSceneId - * @param lights - * @constructor - */ -GameLib.D3.Scene = function( - id, - path, - name, - meshes, - quaternion, - position, - rotation, - scale, - parentSceneId, - lights, - physics -) { - this.id = id; - this.path = path; - this.name = name; - if (this.name.trim() == "") { - this.name = 'unnamed'; - } - this.meshes = meshes; - - if (typeof quaternion == 'undefined') { - quaternion = new GameLib.D3.Vector4(); - } - this.quaternion = quaternion; - - if (typeof position == 'undefined') { - position = new GameLib.D3.Vector3(0,0,0); - } - this.position = position; - - if (typeof rotation == 'undefined') { - rotation = new GameLib.D3.Vector3(0,0,0); - } - this.rotation = rotation; - - if (typeof scale == 'undefined') { - scale = new GameLib.D3.Vector3(1,1,1); - } - this.scale = scale; - - if (typeof parentSceneId == 'undefined') { - parentSceneId = null; - } - this.parentSceneId = parentSceneId; - - if (typeof lights == 'undefined') { - lights = []; - } - this.lights = lights; - - if (typeof physics == 'undefined') { - physics = []; - } - this.physics = physics; -}; - -/** - * Clone a PolyVertex - * @returns {GameLib.D3.PolyVertex} - */ -GameLib.D3.PolyVertex.prototype.clone = function() { - return new GameLib.D3.PolyVertex( - this.localIndex, - this.mvertIndex, - this.uv.copy(), - this.materialIndex, - this.edgeIndex - ) -}; - -/** - * Clone a TriangleFace - * @returns {GameLib.D3.TriangleFace} - */ -GameLib.D3.TriangleFace.prototype.clone = function(){ - return new GameLib.D3.TriangleFace( - this.v0, - this.v1, - this.v2, - this.materialIndex, - this.v0uv.copy(), - this.v1uv.copy(), - this.v2uv.copy() - ); -}; - -/** - * This is a work-around function to fix polys which don't triangulate because - * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around - * Z then Y axis - * @param verticesFlat [] - * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY - * @return [] - */ -GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) { - - if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) { - console.log("The vertices are not in the right length : " + verticesFlat.length); - } - - var vertices = []; - - var points = new GameLib.D3.Vector4.Points(); - - for (var i = 0; i < verticesFlat.length; i += 3) { - points.add(new GameLib.D3.Vector3( - verticesFlat[i], - verticesFlat[i + 1], - verticesFlat[i + 2] - )); - } - - points.toOrigin(); - - points.maximizeXDistance(grain); - - points.maximizeYDistance(grain); - - for (i = 0; i < points.vectors.length; i++) { - vertices.push( - [ - points.vectors[i].x, - points.vectors[i].y - ] - ); - } - - return vertices; -}; - -/** - * This function resets the winding order for triangles in faces, given an initial triangle and orientation edge - * used pseudocode from - * http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh - * We need to use a graph traversal algorithm, - * lets assume we have method that returns neighbor of triangle on given edge - * - * neighbor_on_egde( next_tria, edge ) - * - * to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it - * processed = set of processed triangles; initial empty - * - * while to_process is not empty: - * next_tria, orientation_edge = to_process.pop() - * add next_tria in processed - * if next_tria is not opposite oriented than orientation_edge: - * change next_tria (ABC) orientation (B<->C) - * for each edge (AB) in next_tria: - * neighbor_tria = neighbor_on_egde( next_tria, edge ) - * if neighbor_tria exists and neighbor_tria not in processed: - * to_process add (neighbor_tria, edge opposite oriented (BA)) - * @param faces GameLib.D3.TriangleFace[] - * @param orientationEdge GameLib.D3.Vector2 - * @returns {Array} - */ -GameLib.D3.fixWindingOrder = function(faces, orientationEdge) { - - /** - * Checks if a TriangleFace belonging to a TriangleEdge has already been processed - * @param processed TriangleEdge[] - * @param triangle TriangleFace - * @returns {boolean} - */ - function inProcessed(processed, triangle) { - - for (var i = 0; i < processed.length; i++) { - if (processed[i].triangle.equals(triangle)) { - return true; - } - } - - return false; - } - - /** - * Returns a neighbouring triangle on a specific edge - preserving the edge orientation - * @param edge GameLib.D3.Vector2 - * @param faces GameLib.D3.TriangleFace[] - * @param currentTriangle - * @returns {*} - */ - function neighbourOnEdge(edge, faces, currentTriangle) { - - for (var i = 0; i < faces.length; i++) { - if ( - (faces[i].v0 == edge.x && faces[i].v1 == edge.y) || - (faces[i].v1 == edge.x && faces[i].v2 == edge.y) || - (faces[i].v2 == edge.x && faces[i].v0 == edge.y) || - (faces[i].v0 == edge.y && faces[i].v1 == edge.x) || - (faces[i].v1 == edge.y && faces[i].v2 == edge.x) || - (faces[i].v2 == edge.y && faces[i].v0 == edge.x) - ) { - - var triangle = new GameLib.D3.TriangleFace( - faces[i].v0, - faces[i].v1, - faces[i].v2, - faces[i].materialIndex, - faces[i].v0uv, - faces[i].v1uv, - faces[i].v2uv - ); - - if (triangle.equals(currentTriangle)) { - continue; - } - - return new GameLib.D3.TriangleEdge( - triangle, - edge - ); - } - } - - return null; - } - - var toProcess = [ - new GameLib.D3.TriangleEdge( - new GameLib.D3.TriangleFace( - faces[0].v0, - faces[0].v1, - faces[0].v2, - faces[0].materialIndex, - faces[0].v0uv, - faces[0].v1uv, - faces[0].v2uv - ), - orientationEdge - ) - ]; - - var processed = []; - - while (toProcess.length > 0) { - - var triangleEdge = toProcess.pop(); - - /** - * If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed - * to have the same winding order) - */ - if ( - (triangleEdge.triangle.v0 == triangleEdge.edge.x && - triangleEdge.triangle.v1 == triangleEdge.edge.y) || - (triangleEdge.triangle.v1 == triangleEdge.edge.x && - triangleEdge.triangle.v2 == triangleEdge.edge.y) || - (triangleEdge.triangle.v2 == triangleEdge.edge.x && - triangleEdge.triangle.v0 == triangleEdge.edge.y) - ) { - var backupV = triangleEdge.triangle.v1; - triangleEdge.triangle.v1 = triangleEdge.triangle.v2; - triangleEdge.triangle.v2 = backupV; - - var backupUV = triangleEdge.triangle.v1uv; - triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv; - triangleEdge.triangle.v2uv = backupUV; - } - - processed.push(triangleEdge); - - var edges = [ - new GameLib.D3.Vector2( - triangleEdge.triangle.v0, - triangleEdge.triangle.v1 - ), - new GameLib.D3.Vector2( - triangleEdge.triangle.v1, - triangleEdge.triangle.v2 - ), - new GameLib.D3.Vector2( - triangleEdge.triangle.v2, - triangleEdge.triangle.v0 - ) - ]; - - for (var j = 0; j < edges.length; j++) { - var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle); - if (neighbour && !inProcessed(processed, neighbour.triangle)) { - toProcess.push(neighbour); - } - } - } - - /** - * In processed - we will have some duplicates - only add the unique ones - * @type {Array} - */ - var triangles = []; - for (var i = 0; i < processed.length; i++) { - var found = false; - for (var k = 0; k < triangles.length; k++) { - if (triangles[k].equals(processed[i].triangle)){ - found = true; - break; - } - } - if (!found) { - triangles.push(processed[i].triangle); - } - } - - return triangles; -}; - -/** - * Returns true if two triangles are equal (their vertex indices match in some order) - * @param triangle - * @returns {boolean} - */ -GameLib.D3.TriangleFace.prototype.equals = function(triangle) { - return !!( - ( - (this.v0 == triangle.v0) && - (this.v1 == triangle.v1) && - (this.v2 == triangle.v2) - ) - || - ( - (this.v0 == triangle.v0) && - (this.v1 == triangle.v2) && - (this.v2 == triangle.v1) - ) - || - ( - (this.v0 == triangle.v1) && - (this.v1 == triangle.v0) && - (this.v2 == triangle.v2) - ) - || - ( - (this.v0 == triangle.v1) && - (this.v1 == triangle.v2) && - (this.v2 == triangle.v0) - ) - || - ( - (this.v0 == triangle.v2) && - (this.v1 == triangle.v0) && - (this.v2 == triangle.v1) - ) - || - ( - (this.v0 == triangle.v2) && - (this.v1 == triangle.v1) && - (this.v2 == triangle.v0) - )); -}; - -GameLib.D3.prototype.invertWindingOrder = function(triangles) { - - for (var i = 0; i < triangles.length; i++) { - var v1 = triangles[i].v1; - triangles[i].v1 = triangles[i].v2; - triangles[i].v2 = v1; - - var backupUV = triangles[i].triangle.v1uv; - triangles[i].triangle.v1uv = triangles[i].triangle.v2uv; - triangles[i].triangle.v2uv = backupUV; - } - - return triangles; -}; - -/** - * This function resets a the winding order of a mesh from a reference point V (the average center of the mesh) - */ -GameLib.D3.prototype.resetWindingOrder = function(faces, vertices) { - - var vertexList = new GameLib.D3.Vector3.Points(); - - for (var v = 0; v < vertices.length; v++) { - vertexList.add(new GameLib.D3.Vector3( - vertices[v].position.x, - vertices[v].position.y, - vertices[v].position.z - )); - } - - var V = vertexList.average(); - - var triangles = []; - - for (var s = 0; s < faces.length; s += 3) { - - var v0 = faces[s]; - var v1 = faces[s+1]; - var v2 = faces[s+2]; - - triangles.push( - { - v0 : v0, - v1 : v1, - v2 : v2, - edges : [ - {v0: v0, v1: v1}, - {v0: v1, v1: v2}, - {v0: v2, v1: v0} - ], - winding : 0, - edgeIndex : -1, - processed : false - } - ); - } - - for (var i = 0; i < triangles.length; i++) { - if ( - GameLib.D3.Vector3.clockwise( - vertices[triangles[i].v0].position, - vertices[triangles[i].v1].position, - vertices[triangles[i].v2].position, - V - ) - ) { - console.log('clockwise'); - var bv1 = triangles[i].v1; - triangles[i].v1 = triangles[i].v2; - triangles[i].v2 = bv1; - } else { - console.log('not clockwise'); - } - } - - return triangles; -}; - -/** - * Defers loading of an image and resolves once image is loaded - * @param gameLibTexture - * @param threeMaterial - * @param threeMaterialMapType - * @returns {Promise} - */ -GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) { - - var q = this.Q.defer(); - - var imagePath = null; - - if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { - /** - * Else, load from upload source - */ - imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; - } - - if (imagePath) { - - this.textureLoader.crossOrigin = ''; - - this.textureLoader.load( - imagePath, - function(texture) { - /** - * onLoad - */ - threeMaterial[threeMaterialMapType] = texture; - threeMaterial[threeMaterialMapType].name = gameLibTexture.name; - threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy; - threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding; - threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY; - /** - * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes - */ - threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; - threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter; - threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter; - threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping; - threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps; - threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2( - gameLibTexture.offset.x, - gameLibTexture.offset.y - ); - threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; - threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType; - threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS; - threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT; - threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; - threeMaterial.needsUpdate = true; - q.resolve(true); - }, - function(xhr) { - /** - * onProgress - */ - if (this.editor) { - this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success'); - } - }, - function(error) { - /** - * onError - */ - console.log("an error occurred while trying to load the image : " + imagePath); - q.resolve(null); - } - ); - - } else { - q.resolve(null); - } - - return q.promise; -}; - -/** - * Creates a THREE Mesh from GameLib.D3.Mesh - * @param gameLibMesh - * @param threeGeometry - * @param threeMaterial - * @returns {*} - */ -GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) { - - var threeMesh = null; - - if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) { - threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial); - } - - if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) { - - var bones = gameLibMesh.skeleton.bones; - - var skinIndices = gameLibMesh.skinIndices; - - var skinWeights = gameLibMesh.skinWeights; - - var threeBones = []; - - for (var bi = 0; bi < bones.length; bi++) { - - var bone = new this.THREE.Bone(); - - bone.name = bones[bi].name; - - bone.position.x = bones[bi].position.x; - bone.position.y = bones[bi].position.y; - bone.position.z = bones[bi].position.z; - - bone.rotation.x = bones[bi].rotation.x; - bone.rotation.y = bones[bi].rotation.y; - bone.rotation.z = bones[bi].rotation.z; - - bone.quaternion.x = bones[bi].quaternion.x; - bone.quaternion.y = bones[bi].quaternion.y; - bone.quaternion.z = bones[bi].quaternion.z; - bone.quaternion.w = bones[bi].quaternion.w; - - bone.scale.x = bones[bi].scale.x; - bone.scale.y = bones[bi].scale.y; - bone.scale.z = bones[bi].scale.z; - - bone.up.x = bones[bi].up.x; - bone.up.y = bones[bi].up.y; - bone.up.z = bones[bi].up.z; - - threeBones.push(bone); - } - - /** - * Setup the bone relationships - */ - for (var br = 0; br < bones.length; br++) { - for (var cbi = 0; cbi < bones[br].childBoneIds.length; cbi++) { - threeBones[br].add(threeBones[bones[br].childBoneIds[cbi]]); - } - } - - /** - * Setup bones (indexes) - */ - for (var si = 0; si < skinIndices.length; si++) { - threeGeometry.skinIndices.push( - new this.THREE.Vector4( - skinIndices[si].x, - skinIndices[si].y, - skinIndices[si].z, - skinIndices[si].w - ) - ); - } - - /** - * Setup bones (weights) - */ - for (var sw = 0; sw < skinWeights.length; sw++) { - threeGeometry.skinWeights.push( - new this.THREE.Vector4( - skinWeights[sw].x, - skinWeights[sw].y, - skinWeights[sw].z, - skinWeights[sw].w - ) - ); - } - - threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial); - - var skeleton = new this.THREE.Skeleton(threeBones); - - skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture; - - for (var i = 0; i < bones.length; i++) { - if (bones[i].parentBoneId === null) { - threeMesh.add(threeBones[i]); - break; - } - } - - threeMesh.bind(skeleton); - - threeMesh.pose(); - - threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh); - threeMesh.skeleton.skeletonHelper.material.linewidth = 5; - } - - if (threeMesh == null) { - console.log('cannot handle meshes of type ' + gameLibMesh.meshType + ' yet.'); - } - - gameLibMesh.threeMeshId = threeMesh.id; - - return threeMesh; -}; - -/** - * Returns an array of image loading Promises - * @param blenderMaterial - * @param blenderMaps - * @param threeMaterial - * @returns Q[] - */ -GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) { - - var textureMaps = []; - - for (var ti = 0; ti < blenderMaps.length; ti++) { - - var map = blenderMaps[ti]; - - if (blenderMaterial.maps.hasOwnProperty(map)) { - - var blenderTexture = blenderMaterial.maps[map]; - - if ( - blenderTexture && - blenderTexture.image && - blenderTexture.image.filename - ) { - - var threeMap = null; - - if (map == 'alpha') { - threeMap = 'alhpaMap'; - } - - if (map == 'ao') { - threeMap = 'aoMap'; - } - - if (map == 'bump') { - threeMap = 'bumpMap'; - } - - if (map == 'displacement') { - threeMap = 'displacementMap'; - } - - if (map == 'emissive') { - threeMap = 'emissiveMap'; - } - - if (map == 'environment') { - threeMap = 'envMap'; - } - - if (map == 'light') { - threeMap = 'lightMap'; - } - - if (map == 'specular') { - threeMap = 'specularMap'; - } - - if (map == 'diffuse') { - threeMap = 'map'; - } - - if (map == 'roughness') { - threeMap = 'roughnessMap'; - } - - if (map == 'metalness') { - threeMap = 'metalnessMap'; - } - - if (threeMap == null) { - console.warn("unsupported map type : " + map); - } - - textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap)); - } - } - } - - return textureMaps; -}; - -/** - * Creates a this.THREE.Material from a GameLib.D3.Material - * @param blenderMaterial GameLib.D3.Material - */ -GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial) { - - var defer = this.Q.defer(); - - var threeMaterial = null; - - var blenderMaps = []; - - if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { - - threeMaterial = new this.THREE.MeshStandardMaterial({ - name: blenderMaterial.name, - opacity: blenderMaterial.opacity, - transparent: blenderMaterial.transparent, - blending: blenderMaterial.blending, - blendSrc: blenderMaterial.blendSrc, - blendDst: blenderMaterial.blendDst, - blendEquation: blenderMaterial.blendEquation, - depthTest: blenderMaterial.depthTest, - depthFunc: blenderMaterial.depthFunc, - depthWrite: blenderMaterial.depthWrite, - polygonOffset: blenderMaterial.polygonOffset, - polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, - polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, - alphaTest: blenderMaterial.alphaTest, - clippingPlanes: blenderMaterial.clippingPlanes, - clipShadows: blenderMaterial.clipShadows, - overdraw: blenderMaterial.overdraw, - visible: blenderMaterial.visible, - side: blenderMaterial.side, - color: new this.THREE.Color( - blenderMaterial.color.r, - blenderMaterial.color.g, - blenderMaterial.color.b - ), - roughness: blenderMaterial.roughness, - metalness: blenderMaterial.metalness, - lightMapIntensity: blenderMaterial.lightMapIntensity, - aoMapIntensity: blenderMaterial.aoMapIntensity, - emissive: new this.THREE.Color( - blenderMaterial.emissive.r, - blenderMaterial.emissive.g, - blenderMaterial.emissive.b - ), - emissiveIntensity: blenderMaterial.emissiveIntensity, - bumpScale: blenderMaterial.bumpScale, - normalScale: blenderMaterial.normalScale, - displacementScale: blenderMaterial.displacementScale, - refractionRatio: blenderMaterial.refractionRatio, - fog: blenderMaterial.fog, - shading: blenderMaterial.shading, - wireframe: blenderMaterial.wireframe, - wireframeLinewidth: blenderMaterial.wireframeLineWidth, - wireframeLinecap: blenderMaterial.wireframeLineCap, - wireframeLinejoin: blenderMaterial.wireframeLineJoin, - vertexColors: blenderMaterial.vertexColors, - skinning: blenderMaterial.skinning, - morphTargets: blenderMaterial.morphTargets, - morphNormals: blenderMaterial.morphNormals - }); - - blenderMaps.push( - 'diffuse', - 'light', - 'ao', - 'emissive', - 'bump', - 'normal', - 'displacement', - 'roughness', - 'metalness', - 'alpha', - 'environment' - ); - } else if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { - - threeMaterial = new this.THREE.MeshPhongMaterial({ - name: blenderMaterial.name, - opacity: blenderMaterial.opacity, - transparent: blenderMaterial.transparent, - blending: blenderMaterial.blending, - blendSrc: blenderMaterial.blendSrc, - blendDst: blenderMaterial.blendDst, - blendEquation: blenderMaterial.blendEquation, - depthTest: blenderMaterial.depthTest, - depthFunc: blenderMaterial.depthFunc, - depthWrite: blenderMaterial.depthWrite, - polygonOffset: blenderMaterial.polygonOffset, - polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, - polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, - alphaTest: blenderMaterial.alphaTest, - clippingPlanes: blenderMaterial.clippingPlanes, - clipShadows: blenderMaterial.clipShadows, - overdraw: blenderMaterial.overdraw, - visible: blenderMaterial.visible, - side: blenderMaterial.side, - color: new this.THREE.Color( - blenderMaterial.color.r, - blenderMaterial.color.g, - blenderMaterial.color.b - ), - specular: new this.THREE.Color( - blenderMaterial.specular.r, - blenderMaterial.specular.g, - blenderMaterial.specular.b - ), - shininess: blenderMaterial.shininess, - lightMapIntensity: blenderMaterial.lightMapIntensity, - aoMapIntensity: blenderMaterial.aoMapIntensity, - emissive: new this.THREE.Color( - blenderMaterial.emissive.r, - blenderMaterial.emissive.g, - blenderMaterial.emissive.b - ), - emissiveIntensity: blenderMaterial.emissiveIntensity, - bumpScale: blenderMaterial.bumpScale, - normalScale: blenderMaterial.normalScale, - displacementScale: blenderMaterial.displacementScale, - combine: blenderMaterial.combine, - refractionRatio: blenderMaterial.refractionRatio, - fog: blenderMaterial.fog, - shading: blenderMaterial.shading, - wireframe: blenderMaterial.wireframe, - wireframeLinewidth: blenderMaterial.wireframeLineWidth, - wireframeLinecap: blenderMaterial.wireframeLineCap, - wireframeLinejoin: blenderMaterial.wireframeLineJoin, - vertexColors: blenderMaterial.vertexColors, - skinning: blenderMaterial.skinning, - morphTargets: blenderMaterial.morphTargets, - morphNormals: blenderMaterial.morphNormals - }); - - blenderMaps.push( - 'diffuse', - 'light', - 'ao', - 'emissive', - 'bump', - 'normal', - 'displacement', - 'specular', - 'alpha', - 'environment' - ); - - } else { - console.log("material type is not implemented yet: " + blenderMaterial.materialType + " - material indexes could be screwed up"); - } - - if (blenderMaps.length > 0) { - var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial); - Q.all(textureMaps).then( - function(){ - defer.resolve(threeMaterial); - } - ).catch( - function(error){ - console.log(error); - defer.reject(error); - } - ) - } else { - defer.resolve(threeMaterial); - } - - return defer.promise; -}; - -/** - * Loads a scene directly from the API - * @param sceneName - * @param onLoaded callback - */ -GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { - - /** - * First check if this is a client or server side request - */ - if (typeof XMLHttpRequest == 'undefined') { - console.warn('implement server side loading from API here'); - return onLoaded(null, new Error('not implemented')); - } - - var xhr = new XMLHttpRequest(); - xhr.open( - 'GET', - this.apiUrl + '/scene/load' + scene.path + '/' + scene.name - ); - - xhr.onreadystatechange = function(xhr, gameLibD3) { - return function() { - if (xhr.readyState == 4) { - - var response = JSON.parse(xhr.responseText); - - if (!response.scene || response.scene.length == 0) { - return onLoaded(null, null, new Error('Could not load scene')); - } - - var scene = response.scene[0]; - - var physics3ds = []; - - if (scene.physics && scene.physics.length > 0) { - - for (var p = 0; p < scene.physics.length; p++) { - - var physics = scene.physics[p]; - - var physics3d = new GameLib.D3.Physics( - physics.id, - physics.name, - physics.engineType, - gameLibD3.CANNON, - null, - null - ); - - var worlds3d = []; - - for (var w = 0; w < physics.worlds.length; w++) { - - var world = physics.worlds[w]; - - var broadphase = world.broadphase; - - var broadphase3d = new GameLib.D3.Physics.Broadphase( - broadphase.id, - broadphase.name, - broadphase.broadphaseType - ); - - var solver = world.solver; - - var solver3d = new GameLib.D3.Physics.Solver( - solver.id, - solver.name, - solver.solverType, - solver.iterations, - solver.tolerance - ); - - var bodies = world.rigidBodies; - - var bodies3d = []; - - for (var b = 0; b < bodies.length; b++) { - - var body = bodies[b]; - - //TODO: add all body properties here - var body3d = new GameLib.D3.Physics.RigidBody( - body.id, - body.name - ); - - bodies3d.push(body3d); - } - - var world3d = new GameLib.D3.Physics.World( - null, - world.name, - physics3d, - new GameLib.D3.Vector3( - world.gravity.x, - world.gravity.y, - world.gravity.z - ), - broadphase3d, - solver3d, - bodies3d - ); - - worlds3d.push(world3d); - } - - physics3ds.push(physics3d); - } - } - - var lights3d = []; - - for (var l = 0; l < scene.lights.length; l++) { - - var light = scene.lights[l]; - - var light3d = new GameLib.D3.Light( - light.id, - light.lightType, - light.name, - new GameLib.D3.Color( - light.color.r, - light.color.g, - light.color.b, - light.color.a - ), - light.intensity, - new GameLib.D3.Vector3( - light.position.x, - light.position.y, - light.position.z - ), - new GameLib.D3.Vector3( - light.targetPosition.x, - light.targetPosition.y, - light.targetPosition.z - ), - new GameLib.D3.Vector4( - light.quaternion.x, - light.quaternion.y, - light.quaternion.z, - light.quaternion.w - ), - new GameLib.D3.Vector3( - light.rotation.x, - light.rotation.y, - light.rotation.z - ), - new GameLib.D3.Vector3( - light.scale.x, - light.scale.y, - light.scale.z - ), - light.distance, - light.decay, - light.power, - light.angle, - light.penumbra - ); - - lights3d.push(light3d); - }; - - var scene3d = new GameLib.D3.Scene( - scene._id || scene.id, - scene.path, - scene.name, - scene.meshes, - new GameLib.D3.Vector4( - scene.quaternion.x, - scene.quaternion.y, - scene.quaternion.z, - scene.quaternion.w - ), - new GameLib.D3.Vector3( - scene.position.x, - scene.position.y, - scene.position.z - ), - new GameLib.D3.Vector3( - scene.rotation.x, - scene.rotation.y, - scene.rotation.z - ), - new GameLib.D3.Vector3( - scene.scale.x, - scene.scale.y, - scene.scale.z - ), - scene.parentSceneId, - lights3d, - physics3ds - ); - - gameLibD3.loadScene(scene3d, onLoaded, false); - } - } - }(xhr, this); - - xhr.send(); -}; - -/** - * Loads a GameLib.D3.Scene object into a ThreeJS Scene object - * @param gameLibScene GameLib.D3.Scene - * @param onLoaded callback when all meshes have loaded - * @param computeNormals set to true to compute new face and vertex normals during load - */ -GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) { - - console.log("loading scene " + gameLibScene.name); - - this.path = gameLibScene.path; - - var meshQ = []; - - for (var m = 0; m < gameLibScene.meshes.length; m++) { - - var mesh = gameLibScene.meshes[m]; - - console.log("loading mesh " + mesh.name); - - var geometry = new this.THREE.Geometry(); - - var vertices = mesh.vertices; - - var faces = mesh.faces; - - var faceVertexUvs = mesh.faceVertexUvs; - - var materials = mesh.materials; - - /** - * Setup vertices - */ - for (var v = 0; v < vertices.length; v++) { - geometry.vertices.push( - new this.THREE.Vector3( - vertices[v].position.x, - vertices[v].position.y, - vertices[v].position.z - ) - ) - } - - /** - * Setup faces - */ - for (var f = 0; f < faces.length; f++) { - - var face = new this.THREE.Face3( - faces[f].v0, - faces[f].v1, - faces[f].v2, - new this.THREE.Vector3( - faces[f].normal.x, - faces[f].normal.y, - faces[f].normal.z - ), - new this.THREE.Color( - faces[f].color.r, - faces[f].color.g, - faces[f].color.b - ), - faces[f].materialIndex - ); - - face.vertexColors = [ - new this.THREE.Color( - faces[f].vertexColors[0].r, - faces[f].vertexColors[0].g, - faces[f].vertexColors[0].b - ), - new this.THREE.Color( - faces[f].vertexColors[1].r, - faces[f].vertexColors[1].g, - faces[f].vertexColors[1].b - ), - new this.THREE.Color( - faces[f].vertexColors[2].r, - faces[f].vertexColors[2].g, - faces[f].vertexColors[2].b - ) - ]; - - face.normal = new this.THREE.Vector3( - faces[f].normal.x, - faces[f].normal.y, - faces[f].normal.z - ); - - face.vertexNormals = [ - new this.THREE.Vector3( - faces[f].vertexNormals[0].x, - faces[f].vertexNormals[0].y, - faces[f].vertexNormals[0].z - ), - new this.THREE.Vector3( - faces[f].vertexNormals[1].x, - faces[f].vertexNormals[1].y, - faces[f].vertexNormals[1].z - ), - new this.THREE.Vector3( - faces[f].vertexNormals[2].x, - faces[f].vertexNormals[2].y, - faces[f].vertexNormals[2].z - ) - ]; - - geometry.faces.push(face); - } - - geometry.faceVertexUvs = []; - - /** - * Setup face UVs - */ - for (var fm = 0; fm < faceVertexUvs.length; fm++) { - - var faceMaterialVertexUvs = faceVertexUvs[fm]; - - geometry.faceVertexUvs[fm] = []; - - for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) { - geometry.faceVertexUvs[fm][fuv] = []; - geometry.faceVertexUvs[fm][fuv].push( - new this.THREE.Vector2( - faceMaterialVertexUvs[fuv][0].x, - faceMaterialVertexUvs[fuv][0].y - ), - new this.THREE.Vector2( - faceMaterialVertexUvs[fuv][1].x, - faceMaterialVertexUvs[fuv][1].y - ), - new this.THREE.Vector2( - faceMaterialVertexUvs[fuv][2].x, - faceMaterialVertexUvs[fuv][2].y - ) - ); - } - } - - /** - * Re-calculate normals (if we have to) - * @type {Array} - */ - if (computeNormals) { - geometry.computeFaceNormals(); - geometry.computeVertexNormals(); - } - - var threeMaterialLoaders = []; - - /** - * Setup materials - */ - for (var mi = 0; mi < materials.length; mi++) { - threeMaterialLoaders.push(this.createThreeMaterial(materials[mi])); - } - - var result = this.Q.all(threeMaterialLoaders).then( - function(gl3d, mesh, geometry) { - return function(materials) { - - console.log("loaded material : " + materials[0].name); - - /** - * We don't support MultiMaterial atm - it doesn't work with raycasting - */ - var material = materials[0]; - - var threeMesh = gl3d.createThreeMesh(mesh, geometry, material); - threeMesh.name = mesh.name; - - threeMesh.position.x = mesh.position.x; - threeMesh.position.y = mesh.position.y; - threeMesh.position.z = mesh.position.z; - - threeMesh.rotation.x = mesh.rotation.x; - threeMesh.rotation.y = mesh.rotation.y; - threeMesh.rotation.z = mesh.rotation.z; - - threeMesh.scale.x = mesh.scale.x; - threeMesh.scale.y = mesh.scale.y; - threeMesh.scale.z = mesh.scale.z; - - threeMesh.quaternion.x = mesh.quaternion.x; - threeMesh.quaternion.y = mesh.quaternion.y; - threeMesh.quaternion.z = mesh.quaternion.z; - threeMesh.quaternion.w = mesh.quaternion.w; - - return threeMesh; - }; - }(this, mesh, geometry) - ).catch(function(error){ - console.log(error); - }); - - meshQ.push(result); - } - - this.Q.all(meshQ).then(function(threeMeshes){ - console.log("all meshes have loaded"); - if (typeof onLoaded != 'undefined') { - - var threeLights = []; - - for (var sli = 0; sli < gameLibScene.lights.length; sli++) { - - var blenderLight = gameLibScene.lights[sli]; - - var light = null; - - if (blenderLight.lightType == 'AmbientLight') { - light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity); - } - - if (blenderLight.lightType == 'DirectionalLight') { - light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity); - } - - if (blenderLight.lightType == 'PointLight') { - light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.decay = blenderLight.decay; - } - - if (blenderLight.lightType == 'SpotLight') { - light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.angle = blenderLight.angle; - light.penumbra = blenderLight.penumbra; - light.decay = blenderLight.decay; - } - - light.position.x = blenderLight.position.x; - light.position.y = blenderLight.position.y; - light.position.z = blenderLight.position.z; - - light.rotation.x = blenderLight.rotation.x; - light.rotation.y = blenderLight.rotation.y; - light.rotation.z = blenderLight.rotation.z; - - // light.scale.x = blenderLight.scale.x; - // light.scale.y = blenderLight.scale.y; - // light.scale.z = blenderLight.scale.z; - - if (light == null) { - console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported'); - } else { - light.name = blenderLight.name; - threeLights.push(light); - } - } - - var threeScene = new this.THREE.Scene(); - - threeScene.name = gameLibScene.name; - - threeScene.position.x = gameLibScene.position.x; - threeScene.position.y = gameLibScene.position.y; - threeScene.position.z = gameLibScene.position.z; - - threeScene.rotation.x = gameLibScene.rotation.x; - threeScene.rotation.y = gameLibScene.rotation.y; - threeScene.rotation.z = gameLibScene.rotation.z; - - threeScene.scale.x = gameLibScene.scale.x; - threeScene.scale.y = gameLibScene.scale.y; - threeScene.scale.z = gameLibScene.scale.z; - - threeScene.quaternion.x = gameLibScene.quaternion.x; - threeScene.quaternion.y = gameLibScene.quaternion.y; - threeScene.quaternion.z = gameLibScene.quaternion.z; - threeScene.quaternion.w = gameLibScene.quaternion.w; - - for (var m = 0; m < threeMeshes.length; m++) { - threeScene.add(threeMeshes[m]); - } - - for (var l = 0; l < threeLights.length; l++) { - threeScene.add(threeLights[l]); - } - - onLoaded( - gameLibScene, - { - scene: threeScene, - lights: threeLights, - meshes: threeMeshes - } - ); - } - }.bind(this)).catch(function(error){ - console.log(error); - }); -}; - -/** --------------- - * Physics - * --------------- */ -/** - * Creates a Custom World object from a GameLib.D3.Physics.World - */ -GameLib.D3.Physics.World.prototype.getCustomWorld = function() { - - var engineType = this.physics.engineType; - - if (engineType != GameLib.D3.Physics.TYPE_CANNON) { - console.warn('Unsupported engine type: ' + engineType); - throw new Error('Unsupported engine type: ' + engineType); - } - - var customWorld = new this.physics.CANNON.World(); - - var cannonBroadphase = null; - - if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE) { - cannonBroadphase = new this.physics.CANNON.NaiveBroadphase(); - } else if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_GRID) { - cannonBroadphase = new this.physics.CANNON.GridBroadphase(); - } else if (this.broadphase.broadphaseType == GameLib.D3.Physics.BROADPHASE_TYPE_SAP) { - cannonBroadphase = new this.physics.CANNON.SAPBroardphase(); - } else { - console.warn('Unsupported broadphase type: ' + this.broadphase.broadphaseType); - throw new Error('Unsupported broadphase type: ' + this.broadphase.broadphaseType); - } - - customWorld.broadphase = cannonBroadphase; - - var cannonSolver = null; - - if (this.solver.solverType == GameLib.D3.Physics.SPLIT_SOLVER) { - cannonSolver = new this.physics.CANNON.SplitSolver(); - } else if (this.solver.solverType == GameLib.D3.Physics.GS_SOLVER) { - cannonSolver = new this.physics.CANNON.GSSolver(); - cannonSolver.iterations = this.solver.iterations; - } - - customWorld.solver = cannonSolver; - - customWorld.gravity.x = this.gravity.x; - customWorld.gravity.y = this.gravity.y; - customWorld.gravity.z = this.gravity.z; - - for (var b = 0; b < this.rigidBodies.length; b++) { - - var customBody = this.createCustomBody(this.rigidBodies[b]); - - //customWorld.AddRigidBody(); - } - - customWorld.name = this.name; - - return customWorld; -}; - - -GameLib.D3.Physics.Shape.prototype.Update = function( - physicsWorld -) { - if(physicsWorld.engineType === GameLib.D3.Physics.Engine.TYPE_CANNON) { - if(this.shapeType === GameLib.D3.Physics.Shape.TYPE_TRIMESH) { - this.shapeObject.setScale(new CANNON.Vec3(this.scale.x, this.scale.y, this.scale.z)); - this.shapeObject.scale.x = this.scale.x; - this.shapeObject.scale.y = this.scale.y; - this.shapeObject.scale.z = this.scale.z; - this.shapeObject.updateAABB(); - this.shapeObject.updateNormals(); - this.shapeObject.updateEdges(); - this.shapeObject.updateBoundingSphereRadius(); - this.shapeObject.updateTree(); - } - } -}; - -GameLib.D3.Physics.World.prototype.AddShape = function( - shape, // d3.physics.shape - rigidBody, - offset, // vec3 - orientation //quaternion -) { - shape.shape = shape; - - if(this.engineType === GameLib.D3.Physics.Engine.TYPE_CANNON) { - - var _offset = null; - var _orientation = null; - - if(offset != null && typeof offset !== 'undefined') { - _offset = new CANNON.Vec3(offset.x, offset.y, offset.z); - } - - if(orientation != null && typeof orientation !== 'undefined') { - _orientation = new CANNON.Quaternion(orientation.x, orientation.y, orientation.z, orientation.w); - } - - rigidBody.bodyObject.addShape(shape.shapeObject, _offset, _orientation); - } -}; - -GameLib.D3.Physics.World.prototype.CreateRigidVehicle = function( - chassisBody // Physics.RigidBody -) { - var rigidVehicle = new GameLib.D3.Physics.RigidVehicle(); - - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - var vehicle = new CANNON.RigidVehicle({ - chassisBody: chassisBody.bodyObject - }); - rigidVehicle.vehicleObject = vehicle; - return rigidVehicle; - } -}; - -GameLib.D3.Physics.World.prototype.CreateRaycastVehicle = function( - chassisBody // Physics.RigidBody -) { - var raycastVehicle = new GameLib.D3.Physics.RaycastVehicle(); - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - var vehicle = new CANNON.RaycastVehicle({ - chassisBody: chassisBody.bodyObject - }); - raycastVehicle.vehicleObject = vehicle; - return raycastVehicle; - } -}; - -GameLib.D3.Physics.World.prototype.AddWheelToRigidVehicle = function( - vehicle, - rigidBody, - position, - axis, - direction -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - vehicle.vehicleObject.addWheel({ - body: rigidBody.bodyObject, - position: new CANNON.Vec3(position.x, position.y, position.z), - axis: new CANNON.Vec3(axis.x, axis.y, axis.z), - direction: new CANNON.Vec3(direction.x, direction.y, direction.z) - }); - } -}; - -GameLib.D3.Physics.World.prototype.AddWheelToRaycastVehicle = function ( - vehicle, // physics.raycastvehicle - options // cannon options -) { - if (this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - vehicle.vehicleObject.addWheel(options); - } else { - console.log("function for engine not implemented"); - } -}; - -GameLib.D3.Physics.RigidVehicle.prototype.GetWheelInfo = function( - -) { - // note: need a way to determine which engine we are currently using - return this.vehicleObject.wheelBodies; -}; - -GameLib.D3.Physics.RaycastVehicle.prototype.GetWheelInfo = function( - -) { - // note: need a way to determine which engine we are currently using - return this.vehicleObject.wheelInfos; -}; - - -GameLib.D3.Physics.World.prototype.CreateRigidBody = function( - mass, - friction, - position, - quaternion, - velocity, - angularVelocity, - linearDamping, - angularDamping, - allowSleep, - sleepSpeedLimit, - sleepTimeLimit, - collisionFilterGroup, - collisionFilterMask, - fixedRotation, - shape -) { - - var rigidBody = new GameLib.D3.Physics.RigidBody(0, "null"); - - position = position || new GameLib.D3.Vector3(); - velocity = velocity || new GameLib.D3.Vector3(); - angularVelocity = angularVelocity || new GameLib.D3.Vector3(); - quaternion = quaternion || new GameLib.D3.Vector4(0, 0, 0, 1); - mass = typeof mass == "undefined" ? 0 : mass; - friction = typeof friction == "undefined" ? 5 : friction; - linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping; - angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping; - allowSleep = typeof allowSleep == "undefined" ? true : allowSleep; - sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit; - sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit; - collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup; - collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask; - fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation; - shape = typeof shape == "undefined" ? null : shape; - - - // Create the bodyObject - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - rigidBody.bodyObject = new CANNON.Body( - { - mass: mass, - friction: friction, - position: new CANNON.Vec3(position.x, position.y, position.z), - velocity: new CANNON.Vec3(velocity.x, velocity.y, velocity.z), - quaternion: new CANNON.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w), - angularVelocity: new CANNON.Vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z), - linearDamping: linearDamping, - angularDamping: angularDamping, - allowSleep: allowSleep, - sleepSpeedLimit: sleepSpeedLimit, - sleepTimeLimit: sleepTimeLimit, - collisionFilterGroup: collisionFilterGroup, - collisionFilterMask: collisionFilterMask, - fixedRotation: fixedRotation, - shape: shape - } - ); - - return rigidBody; - } -}; - -GameLib.D3.Physics.World.prototype.CreateTriMeshShape = function( - vertices, // flat list of floats - indices // float list of floats -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - return new GameLib.D3.Physics.Shape(new CANNON.Trimesh(vertices, indices), GameLib.D3.Physics.Shape.TYPE_TRIMESH); - } -}; - -GameLib.D3.Physics.World.prototype.CreateSphereShape = function ( - radius -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - return new GameLib.D3.Physics.Shape(new CANNON.Sphere(radius), GameLib.D3.Physics.Shape.TYPE_SPHERE); - } -}; - -GameLib.D3.Physics.World.prototype.CreateBoxShape = function( - halfExtensions // vec3 -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - return new GameLib.D3.Physics.Shape(new CANNON.Box(new CANNON.Vec3(halfExtensions.x, halfExtensions.y, halfExtensions.z)), GameLib.D3.Physics.Shape.TYPE_BOX); - } -}; - -GameLib.D3.Physics.World.prototype.CreateCylinderShape = function( - radiusTop, - radiusBottom, - height, - numSegments -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - return new GameLib.D3.Physics.Shape(new CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments), GameLib.D3.Physics.Shape.TYPE_CYLINDER); - } -}; - -GameLib.D3.Physics.World.prototype.AddRigidBody = function( - rigidBody // Physics.RigidBody -) { - if(this.engineType === GameLib.D3.Physics.Engine.TYPE_CANNON) { - this.worldObject.addBody(rigidBody.bodyObject); - } -}; - -GameLib.D3.Physics.World.prototype.AddVehicle = function( - vehicle // note: physics.vehicle -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - vehicle.vehicleObject.addToWorld(this.worldObject); - } -}; - -GameLib.D3.Physics.World.prototype.Step = function( - timeStep -) { - if(this.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - - // todo: figure out, why this call to internal step is more stable for trimesh collisions..... - //this.worldObject.internalStep(timeStep); - //return; - - var now = performance.now() / 1000; - - if(!this.lastCallTime){ - // last call time not saved, cant guess elapsed time. Take a simple step. - this.worldObject.step(timeStep); - this.lastCallTime = now; - return; - } - - var timeSinceLastCall = now - this.lastCallTime; - - this.worldObject.step(timeStep, timeSinceLastCall); - - this.lastCallTime = now; - } -}; - -GameLib.D3.Physics.World.prototype.GetIndexedVertices = function( - triangleMeshShape -) { - - if(this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - - return { - vertices : triangleMeshShape.vertices, - indices : triangleMeshShape.indices - }; - - } else { - // todo: implement this for other physics engines. - return null; - } - -}; - -GameLib.D3.Physics.World.prototype.GenerateWireframeViewMesh = function( - triangleMeshShape, - normalLength, - scale, - opacity, - wireframeColor -) { - var geometryTHREE = new THREE.Geometry(); - var wireframeTHREEMesh = new THREE.Mesh - ( - geometryTHREE, - new THREE.MeshBasicMaterial({ - color: wireframeColor ? wireframeColor : 0xfefefe, - wireframe: true, - opacity: opacity ? opacity : 0.5 - }) - ); - - var data = this.GetIndexedVertices(triangleMeshShape); - - for(var i = 0, l = data.vertices.length / 3; i < l; i++) { - geometryTHREE.vertices.push(new THREE.Vector3(data.vertices[i * 3], data.vertices[i * 3 + 1], data.vertices[i * 3 + 2])); - } - - for(var i = 0, l = data.indices.length / 3; i < l; i++) { - var i0 = data.indices[i * 3]; - var i1 = data.indices[i * 3 + 1]; - var i2 = data.indices[i * 3 + 2]; - - geometryTHREE.faces.push(new THREE.Face3(i0, i1, i2)); - - // Create debug view for normals - - // Center point on the mesh itself - var centroid = new THREE.Vector3() - .add(geometryTHREE.vertices[i0]) - .add(geometryTHREE.vertices[i1]) - .add(geometryTHREE.vertices[i2]) - .divideScalar(3); - - var normal = null; - if(this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - var normal = new CANNON.Vec3(); - triangleMeshShape.getNormal(i, normal); - } else { - // todo: calculate the normal for v0, v1 & v2 here. - } - - var arrow = new THREE.ArrowHelper(new THREE.Vector3(normal.x, normal.y, normal.z), centroid, normalLength, new THREE.Color(normal.x, normal.y, normal.z)); - wireframeTHREEMesh.add( arrow ); - } - - wireframeTHREEMesh.scale.x = scale.x; - wireframeTHREEMesh.scale.y = scale.y; - wireframeTHREEMesh.scale.z = scale.z; - - return wireframeTHREEMesh; -}; - -GameLib.D3.Physics.World.prototype.GenerateTriangleCollisionMesh = function( - threeMesh, - mass, // default = 0 - friction, // default = 10 - createCollisionSubMeshes, // boolean. default = false - facesPerSubsection, // int. default = 0 - subsectionsToMerge // int. default = 0 -) { - var processedFaces = 0; - var facesPerSubSection = facesPerSubsection || 0; - var subMeshesToMerge = subsectionsToMerge || 0; - var totalAmtFaces = threeMesh.geometry.faces.length; - var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces; - - var pairs = []; // output - - var vertices = []; - var indicies = []; - - for(var i = 0; i <= totalAmtFaces; i++) { - if(processedFaces == facesToProcess || i == totalAmtFaces) { - - var body = null; - - if(this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_CANNON) { - - var meshShape = new CANNON.Trimesh(vertices, indicies); - meshShape.setScale(new CANNON.Vec3(threeMesh.scale.x, threeMesh.scale.y, threeMesh.scale.z)); - meshShape.updateAABB(); - meshShape.updateNormals(); - meshShape.updateEdges(); - meshShape.updateBoundingSphereRadius(); - meshShape.updateTree(); - - body = new CANNON.Body({ mass: mass ? mass : 0, friction: friction ? friction : 10 }); - body.addShape(meshShape); - - } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_AMMO) { - - } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_GOBLIN) { - - } - - pairs.push({ - threeObject : createCollisionSubMeshes ? null : threeMesh, - physicsObject : body - }); - - vertices = []; - indicies = []; - processedFaces = 0; - - if(i == totalAmtFaces) { - return pairs; - } - } - - var face = threeMesh.geometry.faces[i]; - indicies.push(indicies.length); - indicies.push(indicies.length); - indicies.push(indicies.length); - - var v0 = threeMesh.geometry.vertices[face.a]; - var v1 = threeMesh.geometry.vertices[face.b]; - var v2 = threeMesh.geometry.vertices[face.c]; - - vertices.push(v0.x, v0.y, v0.z); - vertices.push(v1.x, v1.y, v1.z); - vertices.push(v2.x, v2.y, v2.z); - - processedFaces++; - } -}; - -// ----------- -// SkyBox -// ----------- - -GameLib.D3.SkyBox = function ( - -) { - this.id = null; - this.texturesFolder = null; -}; - -GameLib.D3.SkyBox.prototype.Load = function ( - texturesFolder -) { - this.texturesFolder = texturesFolder; - this.textures = []; - this.materials = []; - this.mesh = {}; - this.scene = new THREE.Scene(); - this.textureCube = null; - - var textureLoader = new THREE.TextureLoader(); - - // this textures are used to display the skybox - this.textures.push(textureLoader.load(this.texturesFolder + "px.png")); - this.textures.push(textureLoader.load(this.texturesFolder + "nx.png")); - this.textures.push(textureLoader.load(this.texturesFolder + "py.png")); - this.textures.push(textureLoader.load(this.texturesFolder + "ny.png")); - this.textures.push(textureLoader.load(this.texturesFolder + "pz.png")); - this.textures.push(textureLoader.load(this.texturesFolder + "nz.png")); - - // assign textures to each cube face - for (var i = 0; i < 6; i ++) { - this.materials.push(new THREE.MeshBasicMaterial({ map: this.textures[i] })); - } - - // create cube geometry - this.mesh = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshFaceMaterial(this.materials)); - this.mesh.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1)); - this.scene.add(this.mesh); - - // Load env textureCube - // this is used for reflections on meshes - // mesh.material.envMap = this.textureCube; - this.textureCube = new THREE.CubeTextureLoader().load([ - this.texturesFolder + "px.png", this.texturesFolder + "nx.png", - this.texturesFolder + "py.png", this.texturesFolder + "ny.png", - this.texturesFolder + "pz.png", this.texturesFolder + "nz.png" - ]); -}; - -GameLib.D3.SkyBox.prototype.Render = function ( - threeRenderer, - threeCamera -) { - var cameraPosition = new THREE.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z); - - threeCamera.position.set(0, 0, 0); - - var gl = threeRenderer.context; - - gl.disable(gl.DEPTH_TEST); - - threeRenderer.render(this.scene, threeCamera); - - gl.enable(gl.DEPTH_TEST); - - threeCamera.position.copy(cameraPosition); -}; - - -// --------- -// Game -// --------- -GameLib.D3.Game = function ( - -) { - this.scenes = {}; - this.physicsWorlds = []; - this.sceneToPhysicsWorldsMap = {}; -}; - -GameLib.D3.Game.prototype.AddScene = function( - scene -) { - this.scenes[scene.name] = scene; -}; - -GameLib.D3.Game.prototype.AddPhysicsWorld = function( - physicsWorld -) { - this.physicsWorlds.push(physicsWorld); -}; - -GameLib.D3.Game.prototype.LinkPhysicsWorldToScene = function( - physicsWorld, - scene -) { - this.sceneToPhysicsWorldsMap[scene.name] = this.sceneToPhysicsWorldsMap[scene.name] || []; - this.sceneToPhysicsWorldsMap[scene.name].push(physicsWorld); -}; - -GameLib.D3.Game.prototype.GetPhysicsWorldsForScene = function ( - scene -) { - return this.sceneToPhysicsWorldsMap[scene.name]; -}; - -GameLib.D3.Game.prototype.ProcessPhysics = function ( - timestep -) { - for(var s in this.sceneToPhysicsWorldsMap) { - - var physicsWorldArray = this.sceneToPhysicsWorldsMap[s]; - var scene = this.scenes[s]; - - if(scene && physicsWorldArray) { - - for(var i = 0, l = physicsWorldArray.length; i < l; i++) { - - var physicsWorld = physicsWorldArray[i]; - physicsWorld.Step(timestep); - - for(var p in physicsWorld.linkedPairs) { - var pair = physicsWorld.linkedPairs[p]; - var mesh = pair.threeMesh; - var body = pair.physicsBody; - - if(mesh) { - if(physicsWorld.engineType === GameLib.D3.Physics.Engine.TYPE_CANNON) { - - var quaternion = new THREE.Quaternion(); - quaternion.copy(body.bodyObject.quaternion); - - var quaternionCopy = quaternion.clone(); - - var position = new THREE.Vector3(); - position.copy(body.bodyObject.position); - - if(mesh.permutate) { - - if(mesh.permutate.offset) { - if(mesh.permutate.offset.quaternion) { - var offsetQuaternion = new THREE.Quaternion(); - offsetQuaternion.copy(mesh.permutate.offset.quaternion); - quaternion = quaternion.multiply(offsetQuaternion).normalize(); - } - - if(mesh.permutate.offset.position) { - var offsetPosition = new THREE.Vector3(); - offsetPosition.copy(mesh.permutate.offset.position); - //position = position.add(offsetPosition); - position = position.add(offsetPosition.applyQuaternion(quaternionCopy)); - } - } - } - - mesh.position.copy(position); - mesh.quaternion.copy(quaternion); - } - } - } - } - } - - } -}; - -GameLib.D3.Game.prototype.LinkPair = function ( - threeMesh, - physicsBody, - physicsWorld -) { - physicsWorld.linkedPairs = physicsWorld.linkedPairs || []; - - physicsWorld.linkedPairs.push({ - threeMesh : threeMesh, - physicsBody : physicsBody - }); -}; - - -/* * * * * * * * * * - * Heightmap Tools - * * * * * * * * * */ - -GameLib.D3.HeightmapData = function ( - sizeX, - sizeY, - matrix -) { - this.sizeX = sizeX || 0; - this.sizeY = sizeY || 0; - - // 2D Array with height data - // Column-major - this.matrix = matrix || []; -}; - - -// Note: this currently only works for cannon! -GameLib.D3.GenerateThreeMeshFromHeightField = function ( - heightFieldShape - // Physics type..... -) { - - var geometry = new THREE.Geometry(); - - var v0 = new CANNON.Vec3(); - var v1 = new CANNON.Vec3(); - var v2 = new CANNON.Vec3(); - - var shape = heightFieldShape; - for (var xi = 0; xi < shape.data.length - 1; xi++) { - for (var yi = 0; yi < shape.data[xi].length - 1; yi++) { - for (var k = 0; k < 2; k++) { - shape.getConvexTrianglePillar(xi, yi, k===0); - v0.copy(shape.pillarConvex.vertices[0]); - v1.copy(shape.pillarConvex.vertices[1]); - v2.copy(shape.pillarConvex.vertices[2]); - v0.vadd(shape.pillarOffset, v0); - v1.vadd(shape.pillarOffset, v1); - v2.vadd(shape.pillarOffset, v2); - geometry.vertices.push( - new THREE.Vector3(v0.x, v0.y, v0.z), - new THREE.Vector3(v1.x, v1.y, v1.z), - new THREE.Vector3(v2.x, v2.y, v2.z) - ); - var i = geometry.vertices.length - 3; - geometry.faces.push(new THREE.Face3(i, i+1, i+2)); - } - } - } - geometry.computeBoundingSphere(); - geometry.computeFaceNormals(); - - return new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({ wireframe : false, shading : THREE.SmoothShading })); -}; - -GameLib.D3.GenerateHeightmapDataFromImage = function ( - imagePath, - callback // receives HeightmapData instance as the first argument -) { - var img = new Image(); - - img.onload = function () { - - var canvas = document.createElement('canvas'); - canvas.width = img.width; - canvas.height = img.height; - - var context = canvas.getContext('2d'); - context.drawImage(img, 0, 0); - - var imgd = context.getImageData(0, 0, img.width, img.height); - var pixels = imgd.data; - - var heightList = []; - for (var i = 0, n = pixels.length; i < n; i += (4)) { - heightList.push(pixels[i]); - } - - var matrix = []; - var sizeX = img.width, - sizeY = img.height; - - for (var i = 0; i < sizeX; i++) { - matrix.push([]); - for (var j = 0; j < sizeY; j++) { - var height = (heightList[(sizeX - i) + j * sizeY] / 255) * 15; - matrix[i].push(height); - } - } - - - // todo: delete canvas here - - callback(new GameLib.D3.HeightmapData(sizeX, sizeY, matrix)); - }; - - img.src = imagePath; -}; - -if (typeof module != 'undefined') { - module.exports = GameLib; -} \ No newline at end of file diff --git a/game.js b/game.js deleted file mode 100644 index 0b724be..0000000 --- a/game.js +++ /dev/null @@ -1,24 +0,0 @@ -function Game() {} - -/** - * Games are collections of scenes and physics worlds - * @param id - * @param name - * @param path - * @param scenes THREE.Scene[] - * @param worlds GameLib.D3.Physics.World[] - * @constructor - */ -Game = function( - id, - name, - path, - scenes, - worlds -) { - this.id = id; - this.name = name; - this.path = path; - this.scenes = scenes; - this.worlds = worlds; -}; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..fdb7e86 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,26 @@ +var gulp = require('gulp'); +var concat = require('gulp-concat'); +var sort = require('gulp-sort'); +var minify = require('gulp-minify'); + +gulp.task( + 'build', + function() { + return gulp.src('./src/game-lib-*.js') + .pipe(sort()) + .pipe(concat('game-lib.js')) + .pipe(minify({ + ext:{ + src:'-debug.js', + min:'.js' + } + })) + .pipe(gulp.dest('./build/')); + } +); + +gulp.task( + 'default', + ['build'], + function() {} +); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..9382bf4 --- /dev/null +++ b/package.json @@ -0,0 +1,13 @@ +{ + "name": "gamewheel-game-lib", + "description": "Gamewheel Game Library", + "version": "0.0.1", + "dependencies": { + "gulp": "^3.9.1", + "gulp-concat": "^2.6.0", + "gulp-minify": "0.0.14", + "gulp-sort": "^2.0.0" + }, + "repository": "https://github.com/ToywheelDev/game-lib.git", + "license": "UNLICENSED" +} diff --git a/src/game-lib-a.js b/src/game-lib-a.js new file mode 100644 index 0000000..1a90a34 --- /dev/null +++ b/src/game-lib-a.js @@ -0,0 +1,7 @@ +if (typeof GameLib == 'undefined') { + function GameLib() {} +} + +if (typeof GameLib.D3 == 'undefined') { + GameLib.D3 = function(){}; +} \ No newline at end of file diff --git a/src/game-lib-bone-weight.js b/src/game-lib-bone-weight.js new file mode 100644 index 0000000..954b81f --- /dev/null +++ b/src/game-lib-bone-weight.js @@ -0,0 +1,13 @@ +/** + * BoneWeight object - associates a vertex to a bone with some weight + * @param boneIndex int + * @param weight float + * @constructor + */ +GameLib.D3.BoneWeight = function( + boneIndex, + weight +) { + this.boneIndex = boneIndex; + this.weight = weight; +}; \ No newline at end of file diff --git a/src/game-lib-bone.js b/src/game-lib-bone.js new file mode 100644 index 0000000..0e8585b --- /dev/null +++ b/src/game-lib-bone.js @@ -0,0 +1,65 @@ +/** + * Bone Superset + * @param id + * @param name string + * @param boneId + * @param childBoneIds + * @param parentBoneId + * @param quaternion + * @param position + * @param rotation + * @param scale GameLib.D3.Vector3 + * @param up + * @constructor + */ +GameLib.D3.Bone = function( + id, + boneId, + name, + childBoneIds, + parentBoneId, + quaternion, + position, + rotation, + scale, + up +) { + this.id = id; + this.name = name; + this.boneId = boneId; + + if (typeof childBoneIds == 'undefined') { + childBoneIds = []; + } + this.childBoneIds = childBoneIds; + + if (typeof parentBoneId == 'undefined') { + parentBoneId = null; + } + this.parentBoneId = parentBoneId; + + if (typeof quaternion == 'undefined') { + quaternion = new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof rotation == 'undefined') { + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined') { + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof up == 'undefined') { + up = new GameLib.D3.Vector3(0,1,0); + } + this.up = up; +}; \ No newline at end of file diff --git a/src/game-lib-broadphase.js b/src/game-lib-broadphase.js new file mode 100644 index 0000000..af8aeaf --- /dev/null +++ b/src/game-lib-broadphase.js @@ -0,0 +1,34 @@ +/** + * Physics Broadphase Superset + * @param id + * @param name + * @param broadphaseType + * @constructor + */ +GameLib.D3.Broadphase = function( + id, + name, + broadphaseType +) { + this.id = id; + + if (typeof name == 'undefined') { + name = 'broadphase-' + broadphaseType; + } + this.name = name; + + if (typeof broadphaseType == 'undefined') { + console.warn('undefined broadphase type'); + throw new Error('undefined broadphase type'); + } + + this.broadphaseType = broadphaseType; +}; + +/** + * Broadphase Types + * @type {number} + */ +GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1; +GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2; +GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3; \ No newline at end of file diff --git a/src/game-lib-color.js b/src/game-lib-color.js new file mode 100644 index 0000000..bf8e40e --- /dev/null +++ b/src/game-lib-color.js @@ -0,0 +1,18 @@ +/** + * Color Superset + * @param r + * @param g + * @param b + * @param a + * @constructor + */ +GameLib.D3.Color = function(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; +}; + +if (typeof module !== 'undefined') { + module.exports = GameLib.D3.Color; +} \ No newline at end of file diff --git a/src/game-lib-engine.js b/src/game-lib-engine.js new file mode 100644 index 0000000..241ed20 --- /dev/null +++ b/src/game-lib-engine.js @@ -0,0 +1,60 @@ +/** + * Engine Superset + * @param engineType + * @param instance + * @constructor + */ +GameLib.D3.Engine = function( + engineType, + instance +) { + this.engineType = engineType; + this.instance = instance; +}; + +/** + * True if CANNON physics + * @returns {boolean} + */ +GameLib.D3.Engine.prototype.isCannon = function() { + return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON) +}; + +/** + * Logs a warning and throws an error if not cannon + */ +GameLib.D3.Engine.prototype.isNotCannonThrow = function() { + if (this.engineType != GameLib.D3.Engine.ENGINE_TYPE_CANNON) { + console.warn('Only CANNON supported for this function'); + throw new Error('Only CANNON supported for this function'); + } +}; + + +/** + * True if Ammo physics + * @returns {boolean} + */ +GameLib.D3.Engine.prototype.isAmmo = function() { + return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_AMMO) +}; + +/** + * True if Goblin physics + * @returns {boolean} + */ +GameLib.D3.Engine.prototype.isGoblin = function() { + return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_GOBLIN) +}; + +/** + * Physics GameLib.D3.Engine Types + * @type {number} + */ +GameLib.D3.Engine.ENGINE_TYPE_CANNON = 0x1; +GameLib.D3.Engine.ENGINE_TYPE_AMMO = 0x2; +GameLib.D3.Engine.ENGINE_TYPE_GOBLIN = 0x3; + +if (typeof module !== 'undefined') { + module.exports = GameLib.D3.Engine; +} \ No newline at end of file diff --git a/game-lib-controls.js b/src/game-lib-fly-controls.js similarity index 89% rename from game-lib-controls.js rename to src/game-lib-fly-controls.js index 2580743..36d1c80 100644 --- a/game-lib-controls.js +++ b/src/game-lib-fly-controls.js @@ -1,6 +1,11 @@ -function Controls() {} - -Controls.FlyControls = function( +/** + * Fly Controls + * @param camera + * @param THREE + * @param canvas + * @constructor + */ +GameLib.D3.FlyControls = function( camera, THREE, canvas @@ -47,14 +52,14 @@ Controls.FlyControls = function( }; -Controls.FlyControls.prototype.onMouseWheel = function(event) { +GameLib.D3.FlyControls.prototype.onMouseWheel = function(event) { this.moveForward = true; this.applyTranslation(event.wheelDelta * 0.001); event.preventDefault(); this.moveForward = false; }; -Controls.FlyControls.prototype.onMouseDown = function(event) { +GameLib.D3.FlyControls.prototype.onMouseDown = function(event) { // if (event.button == 0) { // this.canRotate = true; @@ -70,7 +75,7 @@ Controls.FlyControls.prototype.onMouseDown = function(event) { } }; -Controls.FlyControls.prototype.onMouseUp = function(event) { +GameLib.D3.FlyControls.prototype.onMouseUp = function(event) { // if (event.button == 0) { // this.canRotate = false; @@ -86,11 +91,11 @@ Controls.FlyControls.prototype.onMouseUp = function(event) { } }; -Controls.FlyControls.prototype.applyRotation = function() { +GameLib.D3.FlyControls.prototype.applyRotation = function() { this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ"); }; -Controls.FlyControls.prototype.applyTranslation = function(deltaTime) { +GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) { var direction = new this.THREE.Vector3(0, 0, -1); var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); rotation.set(this.pitch, this.yaw, 0, "YXZ"); @@ -143,12 +148,12 @@ Controls.FlyControls.prototype.applyTranslation = function(deltaTime) { } }; -Controls.FlyControls.prototype.update = function(deltaTime) { +GameLib.D3.FlyControls.prototype.update = function(deltaTime) { this.applyRotation(); this.applyTranslation(deltaTime); }; -Controls.FlyControls.prototype.onMouseMove = function ( event ) { +GameLib.D3.FlyControls.prototype.onMouseMove = function ( event ) { if (this.canRotate) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; @@ -158,7 +163,7 @@ Controls.FlyControls.prototype.onMouseMove = function ( event ) { } }; -Controls.FlyControls.prototype.onKeyDown = function ( event ) { +GameLib.D3.FlyControls.prototype.onKeyDown = function ( event ) { switch ( event.keyCode ) { case 87: // w @@ -187,7 +192,7 @@ Controls.FlyControls.prototype.onKeyDown = function ( event ) { } }; -Controls.FlyControls.prototype.onKeyUp = function ( event ) { +GameLib.D3.FlyControls.prototype.onKeyUp = function ( event ) { switch ( event.keyCode ) { case 38: // up @@ -218,8 +223,4 @@ Controls.FlyControls.prototype.onKeyUp = function ( event ) { this.moveDown = false; break; } -}; - -if (typeof module !== 'undefined') { - module.exports = Controls; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/game-lib-game.js b/src/game-lib-game.js new file mode 100644 index 0000000..e40cc81 --- /dev/null +++ b/src/game-lib-game.js @@ -0,0 +1,106 @@ +GameLib.D3.Game = function ( + +) { + this.scenes = {}; + this.physicsWorlds = []; + this.sceneToPhysicsWorldsMap = {}; +}; + +GameLib.D3.Game.prototype.AddScene = function( + scene +) { + this.scenes[scene.name] = scene; +}; + +GameLib.D3.Game.prototype.AddPhysicsWorld = function( + physicsWorld +) { + this.physicsWorlds.push(physicsWorld); +}; + +GameLib.D3.Game.prototype.LinkPhysicsWorldToScene = function( + physicsWorld, + scene +) { + this.sceneToPhysicsWorldsMap[scene.name] = this.sceneToPhysicsWorldsMap[scene.name] || []; + this.sceneToPhysicsWorldsMap[scene.name].push(physicsWorld); +}; + +GameLib.D3.Game.prototype.GetPhysicsWorldsForScene = function ( + scene +) { + return this.sceneToPhysicsWorldsMap[scene.name]; +}; + +GameLib.D3.Game.prototype.ProcessPhysics = function ( + timestep +) { + for(var s in this.sceneToPhysicsWorldsMap) { + + var physicsWorldArray = this.sceneToPhysicsWorldsMap[s]; + var scene = this.scenes[s]; + + if(scene && physicsWorldArray) { + + for(var i = 0, l = physicsWorldArray.length; i < l; i++) { + + var physicsWorld = physicsWorldArray[i]; + physicsWorld.Step(timestep); + + for(var p in physicsWorld.linkedPairs) { + var pair = physicsWorld.linkedPairs[p]; + var mesh = pair.threeMesh; + var body = pair.physicsBody; + + if(mesh) { + if(physicsWorld.engineType === GameLib.D3.Physics.TYPE_CANNON) { + + var quaternion = new THREE.Quaternion(); + quaternion.copy(body.rigidBodyInstance.quaternion); + + var quaternionCopy = quaternion.clone(); + + var position = new THREE.Vector3(); + position.copy(body.rigidBodyInstance.position); + + if(mesh.permutate) { + + if(mesh.permutate.offset) { + if(mesh.permutate.offset.quaternion) { + var offsetQuaternion = new THREE.Quaternion(); + offsetQuaternion.copy(mesh.permutate.offset.quaternion); + quaternion = quaternion.multiply(offsetQuaternion).normalize(); + } + + if(mesh.permutate.offset.position) { + var offsetPosition = new THREE.Vector3(); + offsetPosition.copy(mesh.permutate.offset.position); + //position = position.add(offsetPosition); + position = position.add(offsetPosition.applyQuaternion(quaternionCopy)); + } + } + } + + mesh.position.copy(position); + mesh.quaternion.copy(quaternion); + } + } + } + } + } + + } +}; + +GameLib.D3.Game.prototype.LinkPair = function ( + threeMesh, + physicsBody, + physicsWorld +) { + physicsWorld.linkedPairs = physicsWorld.linkedPairs || []; + + physicsWorld.linkedPairs.push({ + threeMesh : threeMesh, + physicsBody : physicsBody + }); +}; \ No newline at end of file diff --git a/src/game-lib-heightmap.js b/src/game-lib-heightmap.js new file mode 100644 index 0000000..a08ca63 --- /dev/null +++ b/src/game-lib-heightmap.js @@ -0,0 +1,95 @@ +GameLib.D3.HeightmapData = function ( + sizeX, + sizeY, + matrix +) { + this.sizeX = sizeX || 0; + this.sizeY = sizeY || 0; + + // 2D Array with height data + // Column-major + this.matrix = matrix || []; +}; + +// Note: this currently only works for cannon! +GameLib.D3.GenerateThreeMeshFromHeightField = function ( + heightFieldShape + // Physics type..... +) { + + var geometry = new THREE.Geometry(); + + var v0 = new this.physics.CANNON.Vec3(); + var v1 = new this.physics.CANNON.Vec3(); + var v2 = new this.physics.CANNON.Vec3(); + + var shape = heightFieldShape; + for (var xi = 0; xi < shape.data.length - 1; xi++) { + for (var yi = 0; yi < shape.data[xi].length - 1; yi++) { + for (var k = 0; k < 2; k++) { + shape.getConvexTrianglePillar(xi, yi, k===0); + v0.copy(shape.pillarConvex.vertices[0]); + v1.copy(shape.pillarConvex.vertices[1]); + v2.copy(shape.pillarConvex.vertices[2]); + v0.vadd(shape.pillarOffset, v0); + v1.vadd(shape.pillarOffset, v1); + v2.vadd(shape.pillarOffset, v2); + geometry.vertices.push( + new THREE.Vector3(v0.x, v0.y, v0.z), + new THREE.Vector3(v1.x, v1.y, v1.z), + new THREE.Vector3(v2.x, v2.y, v2.z) + ); + var i = geometry.vertices.length - 3; + geometry.faces.push(new THREE.Face3(i, i+1, i+2)); + } + } + } + geometry.computeBoundingSphere(); + geometry.computeFaceNormals(); + + return new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({ wireframe : false, shading : THREE.SmoothShading })); +}; + +GameLib.D3.GenerateHeightmapDataFromImage = function ( + imagePath, + callback // receives HeightmapData instance as the first argument +) { + var img = new Image(); + + img.onload = function () { + + var canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + + var context = canvas.getContext('2d'); + context.drawImage(img, 0, 0); + + var imgd = context.getImageData(0, 0, img.width, img.height); + var pixels = imgd.data; + + var heightList = []; + for (var i = 0, n = pixels.length; i < n; i += (4)) { + heightList.push(pixels[i]); + } + + var matrix = []; + var sizeX = img.width, + sizeY = img.height; + + for (var i = 0; i < sizeX; i++) { + matrix.push([]); + for (var j = 0; j < sizeY; j++) { + var height = (heightList[(sizeX - i) + j * sizeY] / 255) * 15; + matrix[i].push(height); + } + } + + + // todo: delete canvas here + + callback(new GameLib.D3.HeightmapData(sizeX, sizeY, matrix)); + }; + + img.src = imagePath; +}; \ No newline at end of file diff --git a/src/game-lib-image.js b/src/game-lib-image.js new file mode 100644 index 0000000..e9e82d9 --- /dev/null +++ b/src/game-lib-image.js @@ -0,0 +1,45 @@ +/** + * Image + * @param id + * @param textureLink + * @param filename + * @param size + * @param contentType + * @constructor + */ +GameLib.D3.Image = function( + id, + textureLink, + filename, + size, + contentType +) { + this.id = id; + + this.filename = filename; + + this.textureLink = textureLink; + + if (typeof size == 'undefined') { + size = 0; + } + this.size = size; + + if (typeof contentType == 'undefined') { + + contentType = 'application/octet-stream'; + + if (this.filename.match(/(png)$/i)) { + contentType = 'image/png'; + } + + if (this.filename.match(/(jpg|jpeg)$/i)) { + contentType = 'image/jpeg'; + } + + if (this.filename.match(/(gif)$/i)) { + contentType = 'image/gif'; + } + } + this.contentType = contentType; +}; \ No newline at end of file diff --git a/src/game-lib-light.js b/src/game-lib-light.js new file mode 100644 index 0000000..4a66fc3 --- /dev/null +++ b/src/game-lib-light.js @@ -0,0 +1,92 @@ +/** + * Light Superset + * @param id + * @param lightType + * @param name + * @param color + * @param intensity + * @param position + * @param targetPosition + * @param quaternion + * @param rotation + * @param scale + * @param distance + * @param decay + * @param power + * @param angle + * @param penumbra + * @constructor + */ +GameLib.D3.Light = function( + id, + lightType, + name, + color, + intensity, + position, + targetPosition, + quaternion, + rotation, + scale, + distance, + decay, + power, + angle, + penumbra +) { + this.id = id; + this.lightType = lightType; + this.name = name; + this.color = color; + this.intensity = intensity; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof targetPosition == 'undefined') { + targetPosition = new GameLib.D3.Vector3(0,0,0); + } + this.targetPosition = targetPosition; + + if (typeof quaternion == 'undefined'){ + quaternion = new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof rotation == 'undefined'){ + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined'){ + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof distance == 'undefined'){ + distance = 0; + } + this.distance = distance; + + if (typeof decay == 'undefined'){ + decay = 1; + } + this.decay = decay; + + if (typeof power == 'undefined'){ + power = 4 * Math.PI; + } + this.power = power; + + if (typeof angle == 'undefined'){ + angle = Math.PI / 3; + } + this.angle = angle; + + if (typeof penumbra == 'undefined'){ + penumbra = 0; + } + this.penumbra = penumbra; +}; \ No newline at end of file diff --git a/src/game-lib-material.js b/src/game-lib-material.js new file mode 100644 index 0000000..426c7be --- /dev/null +++ b/src/game-lib-material.js @@ -0,0 +1,679 @@ +/** + * Material Superset + * @param id + * @param name + * @param materialType + * @param opacity + * @param side + * @param transparent + * @param maps + * @param specular + * @param lightMapIntensity + * @param aoMapIntensity + * @param color + * @param emissive + * @param emissiveIntensity + * @param combine + * @param shininess + * @param reflectivity + * @param refractionRatio + * @param fog + * @param wireframe + * @param wireframeLineWidth + * @param wireframeLineCap + * @param wireframeLineJoin + * @param vertexColors + * @param skinning + * @param morphTargets + * @param morphNormals + * @param lineWidth + * @param lineCap + * @param lineJoin + * @param dashSize + * @param gapWidth + * @param blending + * @param blendSrc + * @param blendDst + * @param blendEquation + * @param depthTest + * @param depthFunc + * @param depthWrite + * @param polygonOffset + * @param polygonOffsetFactor + * @param polygonOffsetUnits + * @param alphaTest + * @param clippingPlanes + * @param clipShadows + * @param visible + * @param overdraw + * @param shading + * @param bumpScale + * @param normalScale + * @param displacementScale + * @param displacementBias + * @param roughness + * @param metalness + * @param pointSize + * @param pointSizeAttenuation + * @param spriteRotation + * @param envMapIntensity + * @constructor + */ +GameLib.D3.Material = function( + id, + name, + materialType, + opacity, + side, + transparent, + maps, + specular, + lightMapIntensity, + aoMapIntensity, + color, + emissive, + emissiveIntensity, + combine, + shininess, + reflectivity, + refractionRatio, + fog, + wireframe, + wireframeLineWidth, + wireframeLineCap, + wireframeLineJoin, + vertexColors, + skinning, + morphTargets, + morphNormals, + lineWidth, + lineCap, + lineJoin, + dashSize, + gapWidth, + blending, + blendSrc, + blendDst, + blendEquation, + depthTest, + depthFunc, + depthWrite, + polygonOffset, + polygonOffsetFactor, + polygonOffsetUnits, + alphaTest, + clippingPlanes, + clipShadows, + visible, + overdraw, + shading, + bumpScale, + normalScale, + displacementScale, + displacementBias, + roughness, + metalness, + pointSize, + pointSizeAttenuation, + spriteRotation, + envMapIntensity +) { + this.id = id; + this.name = name; + if (typeof materialType == 'undefined') { + materialType = GameLib.D3.Material.TYPE_MESH_STANDARD; + } + this.materialType = materialType; + + if (typeof opacity == 'undefined') { + opacity = 1.0; + } + this.opacity = opacity; + + if (typeof side == 'undefined') { + side = GameLib.D3.Material.TYPE_FRONT_SIDE; + } + this.side = side; + + if (typeof transparent == 'undefined') { + transparent = false; + } + this.transparent = transparent; + + if (typeof maps == 'undefined') { + maps = { + alpha: null, + ao: null, + bump: null, + diffuse: null, + displacement: null, + emissive: null, + environment: null, + light: null, + metalness: null, + normal: null, + roughness: null, + specular: null + }; + } + this.maps = maps; + + if (typeof specular == 'undefined') { + specular = new GameLib.D3.Color(0.06, 0.06, 0.06, 0.06); + } + this.specular = specular; + + if (typeof lightMapIntensity == 'undefined') { + lightMapIntensity = 1; + } + this.lightMapIntensity = lightMapIntensity; + + if (typeof aoMapIntensity == 'undefined') { + aoMapIntensity = 1; + } + this.aoMapIntensity = aoMapIntensity; + + if (typeof color == 'undefined') { + color = new GameLib.D3.Color(1, 1, 1, 1) + } + this.color = color; + + if (typeof emissive == 'undefined') { + emissive = new GameLib.D3.Color(0, 0, 0, 0); + } + this.emissive = emissive; + + if (typeof emissiveIntensity == 'undefined') { + emissiveIntensity = 1; + } + this.emissiveIntensity = emissiveIntensity; + + if (typeof combine == 'undefined') { + combine = GameLib.D3.Material.TYPE_MULTIPLY_OPERATION; + } + this.combine = combine; + + if (typeof shininess == 'undefined') { + shininess = 30; + } + this.shininess = shininess; + + if (typeof reflectivity == 'undefined') { + reflectivity = 1; + } + this.reflectivity = reflectivity; + + if (typeof refractionRatio == 'undefined') { + refractionRatio = 0.98; + } + this.refractionRatio = refractionRatio; + + if (typeof fog == 'undefined') { + fog = true; + } + this.fog = fog; + + if (typeof wireframe == 'undefined') { + wireframe = false; + } + this.wireframe = wireframe; + + if (typeof wireframeLineWidth == 'undefined') { + wireframeLineWidth = 1; + } + this.wireframeLineWidth = wireframeLineWidth; + + if (typeof wireframeLineCap == 'undefined') { + wireframeLineCap = 'round'; + } + this.wireframeLineCap = wireframeLineCap; + + if (typeof wireframeLineJoin == 'undefined') { + wireframeLineJoin = 'round'; + } + this.wireframeLineJoin = wireframeLineJoin; + + if (typeof vertexColors == 'undefined') { + vertexColors = GameLib.D3.Material.TYPE_NO_COLORS; + } + this.vertexColors = vertexColors; + + if (typeof skinning == 'undefined') { + skinning = false; + } + this.skinning = skinning; + + if (typeof morphTargets == 'undefined') { + morphTargets = false; + } + this.morphTargets = morphTargets; + + if (typeof morphNormals == 'undefined') { + morphNormals = false; + } + this.morphNormals = morphNormals; + + if (typeof overdraw == 'undefined') { + overdraw = 0; + } + this.overdraw = overdraw; + + if (typeof lineWidth == 'undefined') { + lineWidth = 1; + } + this.lineWidth = lineWidth; + + if (typeof lineCap == 'undefined') { + lineCap = 'round'; + } + this.lineCap = lineCap; + + if (typeof lineJoin == 'undefined') { + lineJoin = 'round'; + } + this.lineJoin = lineJoin; + + if (typeof dashSize == 'undefined') { + dashSize = 3; + } + this.dashSize = dashSize; + + if (typeof gapWidth == 'undefined') { + gapWidth = 1; + } + this.gapWidth = gapWidth; + + if (typeof blending == 'undefined') { + blending = GameLib.D3.Material.TYPE_NORMAL_BLENDING; + } + this.blending = blending; + + if (typeof blendSrc == 'undefined') { + blendSrc = GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR; + } + this.blendSrc = blendSrc; + + if (typeof blendDst == 'undefined') { + blendDst = GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR; + } + this.blendDst = blendDst; + + if (typeof blendEquation == 'undefined') { + blendEquation = GameLib.D3.Material.TYPE_ADD_EQUATION; + } + this.blendEquation = blendEquation; + + if (typeof depthTest == 'undefined') { + depthTest = true; + } + this.depthTest = depthTest; + + if (typeof depthFunc == 'undefined') { + depthFunc = GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH; + } + this.depthFunc = depthFunc; + + if (typeof depthWrite == 'undefined') { + depthWrite = true; + } + this.depthWrite = depthWrite; + + if (typeof polygonOffset == 'undefined') { + polygonOffset = false; + } + this.polygonOffset = polygonOffset; + + if (typeof polygonOffsetFactor == 'undefined') { + polygonOffsetFactor = 1; + } + this.polygonOffsetFactor = polygonOffsetFactor; + + if (typeof polygonOffsetUnits == 'undefined') { + polygonOffsetUnits = 1; + } + this.polygonOffsetUnits = polygonOffsetUnits; + + if (typeof alphaTest == 'undefined') { + alphaTest = 0; + } + this.alphaTest = alphaTest; + + if (typeof clippingPlanes == 'undefined') { + clippingPlanes = []; + } + this.clippingPlanes = clippingPlanes; + + if (typeof clipShadows == 'undefined') { + clipShadows = false; + } + this.clipShadows = clipShadows; + + if (typeof visible == 'undefined') { + visible = true; + } + this.visible = visible; + + if (typeof shading == 'undefined') { + shading = GameLib.D3.Material.TYPE_FLAT_SHADING; + } + this.shading = shading; + + if (typeof bumpScale == 'undefined') { + bumpScale = 1; + } + this.bumpScale = bumpScale; + + if (typeof normalScale == 'undefined') { + normalScale = 1; + } + this.normalScale = normalScale; + + if (typeof displacementScale == 'undefined') { + displacementScale = 1; + } + this.displacementScale = displacementScale; + + if (typeof displacementBias == 'undefined') { + displacementBias = 0; + } + this.displacementBias = displacementBias; + + if (typeof roughness == 'undefined') { + roughness = 0.5; + } + this.roughness = roughness; + + if (typeof metalness == 'undefined') { + metalness = 0.5; + } + this.metalness = metalness; + + if (typeof pointSize == 'undefined') { + pointSize = 1; + } + this.pointSize = pointSize; + + if (typeof pointSizeAttenuation == 'undefined') { + pointSizeAttenuation = true; + } + this.pointSizeAttenuation = pointSizeAttenuation; + + if (typeof spriteRotation == 'undefined') { + spriteRotation = 0; + } + this.spriteRotation = spriteRotation; + + if (typeof envMapIntensity == 'undefined') { + envMapIntensity = 1.0; + } + this.envMapIntensity = envMapIntensity; + +}; + +/** + * Combine Method + * @type {number} + */ +GameLib.D3.Material.TYPE_MULTIPLY_OPERATION = 0; +GameLib.D3.Material.TYPE_MIX_OPERATION = 1; +GameLib.D3.Material.TYPE_ADD_OPERATION = 2; + +/** + * Vertex Color Mode + * @type {number} + */ +GameLib.D3.Material.TYPE_NO_COLORS = 0; +GameLib.D3.Material.TYPE_FACE_COLORS = 1; +GameLib.D3.Material.TYPE_VERTEX_COLORS = 2; + +/** + * Blending Mode + * @type {number} + */ +GameLib.D3.Material.TYPE_NORMAL_BLENDING = 1; +GameLib.D3.Material.TYPE_ADDITIVE_BLENDING = 2; +GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING = 3; +GameLib.D3.Material.TYPE_MULTIPLY_BLENDING = 4; +GameLib.D3.Material.TYPE_CUSTOM_BLENDING = 5; + +/** + * Blend Source and Destination + * @type {number} + */ +GameLib.D3.Material.TYPE_ZERO_FACTOR = 200; +GameLib.D3.Material.TYPE_ONE_FACTOR = 201; +GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR = 202; +GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR = 203; +GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR = 204; +GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR = 205; +GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR = 206; +GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR = 207; +GameLib.D3.Material.TYPE_DST_COLOR_FACTOR = 208; +GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR = 209; +GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR = 210; + +/** + * Blend Operation + * @type {number} + */ +GameLib.D3.Material.TYPE_ADD_EQUATION = 100; +GameLib.D3.Material.TYPE_SUBTRACT_EQUATION = 101; +GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION = 102; +GameLib.D3.Material.TYPE_MIN_EQUATION = 103; +GameLib.D3.Material.TYPE_MAX_EQUATION = 104; + +/** + * Depth Function + * @type {number} + */ +GameLib.D3.Material.TYPE_NEVER_DEPTH = 0; +GameLib.D3.Material.TYPE_ALWAYS_DEPTH = 1; +GameLib.D3.Material.TYPE_LESS_DEPTH = 2; +GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH = 3; +GameLib.D3.Material.TYPE_EQUAL_DEPTH = 4; +GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH = 5; +GameLib.D3.Material.TYPE_GREATER_DEPTH = 6; +GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH = 7; + +/** + * Culling Mode + * @type {number} + */ +GameLib.D3.Material.TYPE_FRONT_SIDE = 0; +GameLib.D3.Material.TYPE_BACK_SIDE = 1; +GameLib.D3.Material.TYPE_DOUBLE_SIDE = 2; + +/** + * Shading Type + * @type {number} + */ +GameLib.D3.Material.TYPE_FLAT_SHADING = 1; +GameLib.D3.Material.TYPE_SMOOTH_SHADING = 2; + +/** + * Material Type + * @type {string} + */ +GameLib.D3.Material.TYPE_LINE_BASIC = "LineBasicMaterial"; +GameLib.D3.Material.TYPE_LINE_DASHED = "LineDashedMaterial"; +GameLib.D3.Material.TYPE_MESH_BASIC = "MeshBasicMaterial"; +GameLib.D3.Material.TYPE_MESH_DEPTH = "MeshDepthMaterial"; +GameLib.D3.Material.TYPE_MESH_LAMBERT = "MeshLambertMaterial"; +GameLib.D3.Material.TYPE_MESH_NORMAL = "MeshNormalMaterial"; +GameLib.D3.Material.TYPE_MESH_PHONG = "MeshPhongMaterial"; +GameLib.D3.Material.TYPE_MESH_STANDARD = "MeshStandardMaterial"; +GameLib.D3.Material.TYPE_POINTS = "PointsMaterial"; +GameLib.D3.Material.TYPE_SPRITE = "SpriteMaterial"; +GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial"; + +/** + * Creates a this.THREE.Material from a GameLib.D3.Material + * @param blenderMaterial GameLib.D3.Material + */ +GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial) { + + var defer = this.Q.defer(); + + var threeMaterial = null; + + var blenderMaps = []; + + if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { + + threeMaterial = new this.THREE.MeshStandardMaterial({ + name: blenderMaterial.name, + opacity: blenderMaterial.opacity, + transparent: blenderMaterial.transparent, + blending: blenderMaterial.blending, + blendSrc: blenderMaterial.blendSrc, + blendDst: blenderMaterial.blendDst, + blendEquation: blenderMaterial.blendEquation, + depthTest: blenderMaterial.depthTest, + depthFunc: blenderMaterial.depthFunc, + depthWrite: blenderMaterial.depthWrite, + polygonOffset: blenderMaterial.polygonOffset, + polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, + polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, + alphaTest: blenderMaterial.alphaTest, + clippingPlanes: blenderMaterial.clippingPlanes, + clipShadows: blenderMaterial.clipShadows, + overdraw: blenderMaterial.overdraw, + visible: blenderMaterial.visible, + side: blenderMaterial.side, + color: new this.THREE.Color( + blenderMaterial.color.r, + blenderMaterial.color.g, + blenderMaterial.color.b + ), + roughness: blenderMaterial.roughness, + metalness: blenderMaterial.metalness, + lightMapIntensity: blenderMaterial.lightMapIntensity, + aoMapIntensity: blenderMaterial.aoMapIntensity, + emissive: new this.THREE.Color( + blenderMaterial.emissive.r, + blenderMaterial.emissive.g, + blenderMaterial.emissive.b + ), + emissiveIntensity: blenderMaterial.emissiveIntensity, + bumpScale: blenderMaterial.bumpScale, + normalScale: blenderMaterial.normalScale, + displacementScale: blenderMaterial.displacementScale, + refractionRatio: blenderMaterial.refractionRatio, + fog: blenderMaterial.fog, + shading: blenderMaterial.shading, + wireframe: blenderMaterial.wireframe, + wireframeLinewidth: blenderMaterial.wireframeLineWidth, + wireframeLinecap: blenderMaterial.wireframeLineCap, + wireframeLinejoin: blenderMaterial.wireframeLineJoin, + vertexColors: blenderMaterial.vertexColors, + skinning: blenderMaterial.skinning, + morphTargets: blenderMaterial.morphTargets, + morphNormals: blenderMaterial.morphNormals + }); + + blenderMaps.push( + 'diffuse', + 'light', + 'ao', + 'emissive', + 'bump', + 'normal', + 'displacement', + 'roughness', + 'metalness', + 'alpha', + 'environment' + ); + } else if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { + + threeMaterial = new this.THREE.MeshPhongMaterial({ + name: blenderMaterial.name, + opacity: blenderMaterial.opacity, + transparent: blenderMaterial.transparent, + blending: blenderMaterial.blending, + blendSrc: blenderMaterial.blendSrc, + blendDst: blenderMaterial.blendDst, + blendEquation: blenderMaterial.blendEquation, + depthTest: blenderMaterial.depthTest, + depthFunc: blenderMaterial.depthFunc, + depthWrite: blenderMaterial.depthWrite, + polygonOffset: blenderMaterial.polygonOffset, + polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, + polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, + alphaTest: blenderMaterial.alphaTest, + clippingPlanes: blenderMaterial.clippingPlanes, + clipShadows: blenderMaterial.clipShadows, + overdraw: blenderMaterial.overdraw, + visible: blenderMaterial.visible, + side: blenderMaterial.side, + color: new this.THREE.Color( + blenderMaterial.color.r, + blenderMaterial.color.g, + blenderMaterial.color.b + ), + specular: new this.THREE.Color( + blenderMaterial.specular.r, + blenderMaterial.specular.g, + blenderMaterial.specular.b + ), + shininess: blenderMaterial.shininess, + lightMapIntensity: blenderMaterial.lightMapIntensity, + aoMapIntensity: blenderMaterial.aoMapIntensity, + emissive: new this.THREE.Color( + blenderMaterial.emissive.r, + blenderMaterial.emissive.g, + blenderMaterial.emissive.b + ), + emissiveIntensity: blenderMaterial.emissiveIntensity, + bumpScale: blenderMaterial.bumpScale, + normalScale: blenderMaterial.normalScale, + displacementScale: blenderMaterial.displacementScale, + combine: blenderMaterial.combine, + refractionRatio: blenderMaterial.refractionRatio, + fog: blenderMaterial.fog, + shading: blenderMaterial.shading, + wireframe: blenderMaterial.wireframe, + wireframeLinewidth: blenderMaterial.wireframeLineWidth, + wireframeLinecap: blenderMaterial.wireframeLineCap, + wireframeLinejoin: blenderMaterial.wireframeLineJoin, + vertexColors: blenderMaterial.vertexColors, + skinning: blenderMaterial.skinning, + morphTargets: blenderMaterial.morphTargets, + morphNormals: blenderMaterial.morphNormals + }); + + blenderMaps.push( + 'diffuse', + 'light', + 'ao', + 'emissive', + 'bump', + 'normal', + 'displacement', + 'specular', + 'alpha', + 'environment' + ); + + } else { + console.log("material type is not implemented yet: " + blenderMaterial.materialType + " - material indexes could be screwed up"); + } + + if (blenderMaps.length > 0) { + var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial); + Q.all(textureMaps).then( + function(){ + defer.resolve(threeMaterial); + } + ).catch( + function(error){ + console.log(error); + defer.reject(error); + } + ) + } else { + defer.resolve(threeMaterial); + } + + return defer.promise; +}; \ No newline at end of file diff --git a/src/game-lib-matrix-3.js b/src/game-lib-matrix-3.js new file mode 100644 index 0000000..e5a0c7c --- /dev/null +++ b/src/game-lib-matrix-3.js @@ -0,0 +1,37 @@ +/** + * Matrix 3 Maths + * @param row0 GameLib.D3.Vector3 + * @param row1 GameLib.D3.Vector3 + * @param row2 GameLib.D3.Vector3 + * @constructor + */ +GameLib.D3.Matrix3 = function( + row0, + row1, + row2 +) { + this.identity(); + + if (row0) { + this.rows[0] = row0; + } + + if (row1) { + this.rows[1] = row1; + } + + if (row2) { + this.rows[2] = row2; + } +}; + +/** + * Set matrix to identity + */ +GameLib.D3.Matrix3.prototype.identity = function () { + this.rows = [ + new GameLib.D3.Vector4(1, 0, 0), + new GameLib.D3.Vector4(0, 1, 0), + new GameLib.D3.Vector4(0, 0, 1) + ]; +}; \ No newline at end of file diff --git a/src/game-lib-matrix-4.js b/src/game-lib-matrix-4.js new file mode 100644 index 0000000..9b43237 --- /dev/null +++ b/src/game-lib-matrix-4.js @@ -0,0 +1,173 @@ +GameLib.D3.Matrix4 = function( + row0, + row1, + row2, + row3 +) { + + this.identity(); + + if (row0) { + this.rows[0] = row0; + } + + if (row1) { + this.rows[1] = row1; + } + + if (row2) { + this.rows[2] = row2; + } + + if (row3) { + this.rows[3] = row3; + } +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) { + this.identity(); + this.rows[1] = new GameLib.D3.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0); + this.rows[2] = new GameLib.D3.Vector4(0, Math.sin(radians), Math.cos(radians), 0); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixY = function (radians) { + this.identity(); + this.rows[0] = new GameLib.D3.Vector4( + Math.cos(radians), + 0, + Math.sin(radians), + 0 + ); + this.rows[2] = new GameLib.D3.Vector4( + -1 * Math.sin(radians), + 0, + Math.cos(radians), + 0 + ); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixZ = function (radians) { + this.identity(); + this.rows[0] = new GameLib.D3.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0); + this.rows[1] = new GameLib.D3.Vector4(Math.sin(radians), Math.cos(radians), 0, 0); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotateX = function (radians, point) { + this.identity(); + this.rotationMatrixX(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.rotateY = function (radians, point) { + this.identity(); + this.rotationMatrixY(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.rotateZ = function (radians, point) { + this.identity(); + this.rotationMatrixZ(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.multiply = function (mvp) { + if (mvp instanceof GameLib.D3.Vector4) { + return new GameLib.D3.Vector4( + this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w, + this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w, + this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w, + this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w + ); + } else if (mvp instanceof GameLib.D3.Vector3) { + return new GameLib.D3.Vector3( + this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z, + this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z, + this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + ); + } +}; + +GameLib.D3.Matrix4.prototype.identity = function () { + this.rows = [ + new GameLib.D3.Vector4(1, 0, 0, 0), + new GameLib.D3.Vector4(0, 1, 0, 0), + new GameLib.D3.Vector4(0, 0, 1, 0), + new GameLib.D3.Vector4(0, 0, 0, 1) + ]; +}; + +GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) { + + var pv = new GameLib.D3.Vector3(position.x, position.y, position.z); + + var z = pv.subtract(target).normalize(); + + if (z.squared() === 0) { + z.z = 1; + } + + var x = up.cross(z).normalize(); + + if (x.squared() === 0) { + z.x += 0.0001; + x = up.cross(z).normalize(); + } + + var y = z.cross(x); + + this.rows[0].x = x.x; + this.rows[0].y = x.y; + this.rows[0].z = x.z; + + this.rows[1].x = y.x; + this.rows[1].y = y.y; + this.rows[1].z = y.z; + + this.rows[2].x = z.x; + this.rows[2].y = z.y; + this.rows[2].z = z.z; + + return this; + + // te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; + // te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; + // te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; + + + // var matrix4 = new Matrix4(); + // + // matrix4.rows[0] = side.negative(); + // matrix4.rows[1] = _up; + // matrix4.rows[2] = forward; + + // + // matrix4.setColumn(0, side.negative()); + // matrix4.setColumn(1, _up); + // matrix4.setColumn(2, forward); + + //return matrix4; + + // return new Matrix4( + // new Vector4( + // side.x, + // side.y, + // side.z, + // side.negative().dot(position) + // ), + // new Vector4( + // _up.x, + // _up.y, + // _up.z, + // _up.negative().dot(position) + // ), + // new Vector4( + // forward.negative().x, + // forward.negative().y, + // forward.negative().z, + // forward.dot(position) + // ) + // ) +}; diff --git a/src/game-lib-mesh.js b/src/game-lib-mesh.js new file mode 100644 index 0000000..a557188 --- /dev/null +++ b/src/game-lib-mesh.js @@ -0,0 +1,539 @@ +/** + * Mesh Superset + * @param id + * @param path + * @param name + * @param meshType + * @param vertices + * @param faces + * @param skeleton + * @param faceVertexUvs + * @param skinIndices + * @param skinWeights + * @param materials + * @param position + * @param quaternion + * @param rotation + * @param scale + * @param up + * @param physics + * @param parentMeshId + * @param parentSceneId + * @param rawData + * @constructor + */ +GameLib.D3.Mesh = function( + id, + path, + name, + meshType, + vertices, + faces, + skeleton, + faceVertexUvs, + skinIndices, + skinWeights, + materials, + position, + quaternion, + rotation, + scale, + up, + physics, + parentMeshId, + parentSceneId, + rawData +) { + this.id = id; + this.path = path; + this.name = name; + this.meshType = meshType; + this.vertices = vertices; + this.faces = faces; + + if (typeof skeleton == 'undefined') { + skeleton = null; + } + this.skeleton = skeleton; + + if (typeof faceVertexUvs == 'undefined') { + faceVertexUvs = []; + } + this.faceVertexUvs = faceVertexUvs; + + if (typeof skinIndices == 'undefined') { + skinIndices = []; + } + this.skinIndices = skinIndices; + + if (typeof skinWeights == 'undefined') { + skinWeights = []; + } + this.skinWeights = skinWeights; + + if (typeof materials == 'undefined') { + materials = []; + } + this.materials = materials; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof quaternion == 'undefined') { + new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof rotation == 'undefined') { + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined') { + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof up == 'undefined') { + up = new GameLib.D3.Vector3(0,1,0); + } + this.up = up; + + this.physics = physics; + + this.parentMeshId = parentMeshId; + + this.parentSceneId = parentSceneId; + + this.rawData = null;// rawData; +}; + + +/** + * Mesh Type + * @type {number} + */ +GameLib.D3.Mesh.TYPE_NORMAL = 0; +GameLib.D3.Mesh.TYPE_SKINNED = 1; + + +/** + * Creates a THREE Mesh from GameLib.D3.Mesh + * @param gameLibMesh + * @param threeGeometry + * @param threeMaterial + * @returns {*} + */ +GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) { + + var threeMesh = null; + + if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) { + threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial); + } + + if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) { + + var bones = gameLibMesh.skeleton.bones; + + var skinIndices = gameLibMesh.skinIndices; + + var skinWeights = gameLibMesh.skinWeights; + + var threeBones = []; + + for (var bi = 0; bi < bones.length; bi++) { + + var bone = new this.THREE.Bone(); + + bone.name = bones[bi].name; + + bone.position.x = bones[bi].position.x; + bone.position.y = bones[bi].position.y; + bone.position.z = bones[bi].position.z; + + bone.rotation.x = bones[bi].rotation.x; + bone.rotation.y = bones[bi].rotation.y; + bone.rotation.z = bones[bi].rotation.z; + + bone.quaternion.x = bones[bi].quaternion.x; + bone.quaternion.y = bones[bi].quaternion.y; + bone.quaternion.z = bones[bi].quaternion.z; + bone.quaternion.w = bones[bi].quaternion.w; + + bone.scale.x = bones[bi].scale.x; + bone.scale.y = bones[bi].scale.y; + bone.scale.z = bones[bi].scale.z; + + bone.up.x = bones[bi].up.x; + bone.up.y = bones[bi].up.y; + bone.up.z = bones[bi].up.z; + + threeBones.push(bone); + } + + /** + * Setup the bone relationships + */ + for (var br = 0; br < bones.length; br++) { + for (var cbi = 0; cbi < bones[br].childBoneIds.length; cbi++) { + threeBones[br].add(threeBones[bones[br].childBoneIds[cbi]]); + } + } + + /** + * Setup bones (indexes) + */ + for (var si = 0; si < skinIndices.length; si++) { + threeGeometry.skinIndices.push( + new this.THREE.Vector4( + skinIndices[si].x, + skinIndices[si].y, + skinIndices[si].z, + skinIndices[si].w + ) + ); + } + + /** + * Setup bones (weights) + */ + for (var sw = 0; sw < skinWeights.length; sw++) { + threeGeometry.skinWeights.push( + new this.THREE.Vector4( + skinWeights[sw].x, + skinWeights[sw].y, + skinWeights[sw].z, + skinWeights[sw].w + ) + ); + } + + threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial); + + var skeleton = new this.THREE.Skeleton(threeBones); + + skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture; + + for (var i = 0; i < bones.length; i++) { + if (bones[i].parentBoneId === null) { + threeMesh.add(threeBones[i]); + break; + } + } + + threeMesh.bind(skeleton); + + threeMesh.pose(); + + threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh); + threeMesh.skeleton.skeletonHelper.material.linewidth = 5; + } + + if (threeMesh == null) { + console.log('cannot handle meshes of type ' + gameLibMesh.meshType + ' yet.'); + } + + gameLibMesh.threeMeshId = threeMesh.id; + + return threeMesh; +}; + +GameLib.D3.prototype.invertWindingOrder = function(triangles) { + + for (var i = 0; i < triangles.length; i++) { + var v1 = triangles[i].v1; + triangles[i].v1 = triangles[i].v2; + triangles[i].v2 = v1; + + var backupUV = triangles[i].triangle.v1uv; + triangles[i].triangle.v1uv = triangles[i].triangle.v2uv; + triangles[i].triangle.v2uv = backupUV; + } + + return triangles; +}; + +/** + * This function resets a the winding order of a mesh from a reference point V (the average center of the mesh) + */ +GameLib.D3.prototype.resetWindingOrder = function(faces, vertices) { + + var vertexList = new GameLib.D3.Vector3.Points(); + + for (var v = 0; v < vertices.length; v++) { + vertexList.add(new GameLib.D3.Vector3( + vertices[v].position.x, + vertices[v].position.y, + vertices[v].position.z + )); + } + + var V = vertexList.average(); + + var triangles = []; + + for (var s = 0; s < faces.length; s += 3) { + + var v0 = faces[s]; + var v1 = faces[s+1]; + var v2 = faces[s+2]; + + triangles.push( + { + v0 : v0, + v1 : v1, + v2 : v2, + edges : [ + {v0: v0, v1: v1}, + {v0: v1, v1: v2}, + {v0: v2, v1: v0} + ], + winding : 0, + edgeIndex : -1, + processed : false + } + ); + } + + for (var i = 0; i < triangles.length; i++) { + if ( + GameLib.D3.Vector3.clockwise( + vertices[triangles[i].v0].position, + vertices[triangles[i].v1].position, + vertices[triangles[i].v2].position, + V + ) + ) { + console.log('clockwise'); + var bv1 = triangles[i].v1; + triangles[i].v1 = triangles[i].v2; + triangles[i].v2 = bv1; + } else { + console.log('not clockwise'); + } + } + + return triangles; +}; + +/** + * This function resets the winding order for triangles in faces, given an initial triangle and orientation edge + * used pseudocode from + * http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh + * We need to use a graph traversal algorithm, + * lets assume we have method that returns neighbor of triangle on given edge + * + * neighbor_on_egde( next_tria, edge ) + * + * to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it + * processed = set of processed triangles; initial empty + * + * while to_process is not empty: + * next_tria, orientation_edge = to_process.pop() + * add next_tria in processed + * if next_tria is not opposite oriented than orientation_edge: + * change next_tria (ABC) orientation (B<->C) + * for each edge (AB) in next_tria: + * neighbor_tria = neighbor_on_egde( next_tria, edge ) + * if neighbor_tria exists and neighbor_tria not in processed: + * to_process add (neighbor_tria, edge opposite oriented (BA)) + * @param faces GameLib.D3.TriangleFace[] + * @param orientationEdge GameLib.D3.Vector2 + * @returns {Array} + */ +GameLib.D3.fixWindingOrder = function(faces, orientationEdge) { + + /** + * Checks if a TriangleFace belonging to a TriangleEdge has already been processed + * @param processed TriangleEdge[] + * @param triangle TriangleFace + * @returns {boolean} + */ + function inProcessed(processed, triangle) { + + for (var i = 0; i < processed.length; i++) { + if (processed[i].triangle.equals(triangle)) { + return true; + } + } + + return false; + } + + /** + * Returns a neighbouring triangle on a specific edge - preserving the edge orientation + * @param edge GameLib.D3.Vector2 + * @param faces GameLib.D3.TriangleFace[] + * @param currentTriangle + * @returns {*} + */ + function neighbourOnEdge(edge, faces, currentTriangle) { + + for (var i = 0; i < faces.length; i++) { + if ( + (faces[i].v0 == edge.x && faces[i].v1 == edge.y) || + (faces[i].v1 == edge.x && faces[i].v2 == edge.y) || + (faces[i].v2 == edge.x && faces[i].v0 == edge.y) || + (faces[i].v0 == edge.y && faces[i].v1 == edge.x) || + (faces[i].v1 == edge.y && faces[i].v2 == edge.x) || + (faces[i].v2 == edge.y && faces[i].v0 == edge.x) + ) { + + var triangle = new GameLib.D3.TriangleFace( + faces[i].v0, + faces[i].v1, + faces[i].v2, + faces[i].materialIndex, + faces[i].v0uv, + faces[i].v1uv, + faces[i].v2uv + ); + + if (triangle.equals(currentTriangle)) { + continue; + } + + return new GameLib.D3.TriangleEdge( + triangle, + edge + ); + } + } + + return null; + } + + var toProcess = [ + new GameLib.D3.TriangleEdge( + new GameLib.D3.TriangleFace( + faces[0].v0, + faces[0].v1, + faces[0].v2, + faces[0].materialIndex, + faces[0].v0uv, + faces[0].v1uv, + faces[0].v2uv + ), + orientationEdge + ) + ]; + + var processed = []; + + while (toProcess.length > 0) { + + var triangleEdge = toProcess.pop(); + + /** + * If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed + * to have the same winding order) + */ + if ( + (triangleEdge.triangle.v0 == triangleEdge.edge.x && + triangleEdge.triangle.v1 == triangleEdge.edge.y) || + (triangleEdge.triangle.v1 == triangleEdge.edge.x && + triangleEdge.triangle.v2 == triangleEdge.edge.y) || + (triangleEdge.triangle.v2 == triangleEdge.edge.x && + triangleEdge.triangle.v0 == triangleEdge.edge.y) + ) { + var backupV = triangleEdge.triangle.v1; + triangleEdge.triangle.v1 = triangleEdge.triangle.v2; + triangleEdge.triangle.v2 = backupV; + + var backupUV = triangleEdge.triangle.v1uv; + triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv; + triangleEdge.triangle.v2uv = backupUV; + } + + processed.push(triangleEdge); + + var edges = [ + new GameLib.D3.Vector2( + triangleEdge.triangle.v0, + triangleEdge.triangle.v1 + ), + new GameLib.D3.Vector2( + triangleEdge.triangle.v1, + triangleEdge.triangle.v2 + ), + new GameLib.D3.Vector2( + triangleEdge.triangle.v2, + triangleEdge.triangle.v0 + ) + ]; + + for (var j = 0; j < edges.length; j++) { + var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle); + if (neighbour && !inProcessed(processed, neighbour.triangle)) { + toProcess.push(neighbour); + } + } + } + + /** + * In processed - we will have some duplicates - only add the unique ones + * @type {Array} + */ + var triangles = []; + for (var i = 0; i < processed.length; i++) { + var found = false; + for (var k = 0; k < triangles.length; k++) { + if (triangles[k].equals(processed[i].triangle)){ + found = true; + break; + } + } + if (!found) { + triangles.push(processed[i].triangle); + } + } + + return triangles; +}; + +/** + * This is a work-around function to fix polys which don't triangulate because + * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around + * Z then Y axis + * @param verticesFlat [] + * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY + * @return [] + */ +GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) { + + if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) { + console.log("The vertices are not in the right length : " + verticesFlat.length); + } + + var vertices = []; + + var points = new GameLib.D3.Vector4.Points(); + + for (var i = 0; i < verticesFlat.length; i += 3) { + points.add(new GameLib.D3.Vector3( + verticesFlat[i], + verticesFlat[i + 1], + verticesFlat[i + 2] + )); + } + + points.toOrigin(); + + points.maximizeXDistance(grain); + + points.maximizeYDistance(grain); + + for (i = 0; i < points.vectors.length; i++) { + vertices.push( + [ + points.vectors[i].x, + points.vectors[i].y + ] + ); + } + + return vertices; +}; \ No newline at end of file diff --git a/src/game-lib-physics.js b/src/game-lib-physics.js new file mode 100644 index 0000000..3f72cb3 --- /dev/null +++ b/src/game-lib-physics.js @@ -0,0 +1,32 @@ +/** + * Physics SuperSet Namespace Object + * @param id + * @param name + * @param engine GameLib.D3.Engine + * @param worlds + * @returns {{World: World}} + * @constructor + */ +GameLib.D3.Physics = function( + id, + name, + engine, + worlds +) { + this.id = id; + this.name = name; + this.engine = engine; + + if (typeof worlds == 'undefined') { + worlds = []; + } + this.worlds = worlds; +}; + + +/** + * Solver Types + * @type {number} + */ +GameLib.D3.Physics.SPLIT_SOLVER = 0x1; +GameLib.D3.Physics.GS_SOLVER = 0x2; \ No newline at end of file diff --git a/src/game-lib-poly-vertex.js b/src/game-lib-poly-vertex.js new file mode 100644 index 0000000..4ef418b --- /dev/null +++ b/src/game-lib-poly-vertex.js @@ -0,0 +1,36 @@ +/** + * Contains a Poly vertex data structure + * @param localIndex + * @param mvertIndex + * @param uv GameLib.D3.Vector2 + * @param materialIndex + * @param edgeIndex + * @constructor + */ +GameLib.D3.PolyVertex = function( + localIndex, + mvertIndex, + uv, + materialIndex, + edgeIndex +) { + this.localIndex = localIndex; + this.mvertIndex = mvertIndex; + this.uv = uv; + this.materialIndex = materialIndex; + this.edgeIndex = edgeIndex; +}; + +/** + * Clone a PolyVertex + * @returns {GameLib.D3.PolyVertex} + */ +GameLib.D3.PolyVertex.prototype.clone = function() { + return new GameLib.D3.PolyVertex( + this.localIndex, + this.mvertIndex, + this.uv.copy(), + this.materialIndex, + this.edgeIndex + ) +}; \ No newline at end of file diff --git a/src/game-lib-raycast-vehicle.js b/src/game-lib-raycast-vehicle.js new file mode 100644 index 0000000..4b953e2 --- /dev/null +++ b/src/game-lib-raycast-vehicle.js @@ -0,0 +1,10 @@ +/** + * Physics Raycast Vehicle Superset + * TODO: body + wheels[] + * @constructor + */ +GameLib.D3.Physics.RaycastVehicle = function( +) { + this.vehicleObject = null; +}; + diff --git a/src/game-lib-rigid-body-vehicle.js b/src/game-lib-rigid-body-vehicle.js new file mode 100644 index 0000000..410e617 --- /dev/null +++ b/src/game-lib-rigid-body-vehicle.js @@ -0,0 +1,9 @@ +/** + * Physics Rigid Body Vehicle Superset + * TODO: body + wheels[] + * @constructor + */ +GameLib.D3.Physics.RigidVehicle = function( +) { + this.vehicleObject = null; +}; diff --git a/src/game-lib-rigid-body.js b/src/game-lib-rigid-body.js new file mode 100644 index 0000000..b4910df --- /dev/null +++ b/src/game-lib-rigid-body.js @@ -0,0 +1,92 @@ +/** + * RigidBody Superset + * @param mass + * @param friction + * @param position + * @param quaternion + * @param velocity + * @param angularVelocity + * @param linearDamping + * @param angularDamping + * @param allowSleep + * @param sleepSpeedLimit + * @param sleepTimeLimit + * @param collisionFilterGroup + * @param collisionFilterMask + * @param fixedRotation + * @param shape + * @returns {GameLib.D3.Physics.RigidBody} + * @constructor + */ +GameLib.D3.Physics.RigidBody = function( + mass, + friction, + position, + quaternion, + velocity, + angularVelocity, + linearDamping, + angularDamping, + allowSleep, + sleepSpeedLimit, + sleepTimeLimit, + collisionFilterGroup, + collisionFilterMask, + fixedRotation, + shape +) { + + this.position = position || new GameLib.D3.Vector3(); + this.velocity = velocity || new GameLib.D3.Vector3(); + this.angularVelocity = angularVelocity || new GameLib.D3.Vector3(); + this.quaternion = quaternion || new GameLib.D3.Vector4(0, 0, 0, 1); + this.mass = typeof mass == "undefined" ? 0 : mass; + this.friction = typeof friction == "undefined" ? 5 : friction; + this.linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping; + this.angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping; + this.allowSleep = typeof allowSleep == "undefined" ? true : allowSleep; + this.sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit; + this.sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit; + this.collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup; + this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask; + this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation; + this.shape = typeof shape == "undefined" ? null : shape; + + this.rigidBodyInstance = this.createRigidBodyInstance(); +}; + +/** + * + * @returns {*} + */ +GameLib.D3.Physics.World.RigidBody.prototype.createRigidBodyInstance = function() { + + var rigidBody = null; + + // Create the bodyObject + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + rigidBody = new this.physics.CANNON.Body( + { + mass: mass, + friction: friction, + position: new this.physics.CANNON.Vec3(position.x, position.y, position.z), + velocity: new this.physics.CANNON.Vec3(velocity.x, velocity.y, velocity.z), + quaternion: new this.physics.CANNON.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w), + angularVelocity: new this.physics.CANNON.Vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z), + linearDamping: linearDamping, + angularDamping: angularDamping, + allowSleep: allowSleep, + sleepSpeedLimit: sleepSpeedLimit, + sleepTimeLimit: sleepTimeLimit, + collisionFilterGroup: collisionFilterGroup, + collisionFilterMask: collisionFilterMask, + fixedRotation: fixedRotation, + shape: shape + } + ); + + } + + return rigidBody; +}; + diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js new file mode 100644 index 0000000..b036a30 --- /dev/null +++ b/src/game-lib-scene.js @@ -0,0 +1,571 @@ +/** + * Scenes are objects putting meshes into 'world space' + * @param id + * @param path String + * @param name String + * @param meshes GameLib.D3.Mesh[] + * @param quaternion + * @param position + * @param rotation + * @param scale + * @param parentSceneId + * @param lights + * @constructor + */ +GameLib.D3.Scene = function( + id, + path, + name, + meshes, + quaternion, + position, + rotation, + scale, + parentSceneId, + lights, + physics +) { + this.id = id; + this.path = path; + this.name = name; + if (this.name.trim() == "") { + this.name = 'unnamed'; + } + this.meshes = meshes; + + if (typeof quaternion == 'undefined') { + quaternion = new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof rotation == 'undefined') { + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined') { + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof parentSceneId == 'undefined') { + parentSceneId = null; + } + this.parentSceneId = parentSceneId; + + if (typeof lights == 'undefined') { + lights = []; + } + this.lights = lights; + + if (typeof physics == 'undefined') { + physics = []; + } + this.physics = physics; +}; + +/** + * Loads a scene directly from the API + * @param sceneName + * @param onLoaded callback + */ +GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { + + /** + * First check if this is a client or server side request + */ + if (typeof XMLHttpRequest == 'undefined') { + console.warn('implement server side loading from API here'); + return onLoaded(null, new Error('not implemented')); + } + + var xhr = new XMLHttpRequest(); + xhr.open( + 'GET', + this.apiUrl + '/scene/load' + scene.path + '/' + scene.name + ); + + xhr.onreadystatechange = function(xhr, gameLibD3) { + return function() { + if (xhr.readyState == 4) { + + var response = JSON.parse(xhr.responseText); + + if (!response.scene || response.scene.length == 0) { + return onLoaded(null, null, new Error('Could not load scene')); + } + + var scene = response.scene[0]; + + var physics3ds = []; + + if (scene.physics && scene.physics.length > 0) { + + for (var p = 0; p < scene.physics.length; p++) { + + var physics = scene.physics[p]; + + var physics3d = new GameLib.D3.Physics( + physics.id, + physics.name, + physics.engineType, + gameLibD3.CANNON, + null, + null + ); + + var worlds3d = []; + + for (var w = 0; w < physics.worlds.length; w++) { + + var world = physics.worlds[w]; + + var broadphase = world.broadphase; + + var broadphase3d = new GameLib.D3.Physics.Broadphase( + broadphase.id, + broadphase.name, + broadphase.broadphaseType + ); + + var solver = world.solver; + + var solver3d = new GameLib.D3.Physics.Solver( + solver.id, + solver.name, + solver.solverType, + solver.iterations, + solver.tolerance + ); + + var bodies = world.rigidBodies; + + var bodies3d = []; + + for (var b = 0; b < bodies.length; b++) { + + var body = bodies[b]; + + //TODO: add all body properties here + var body3d = new GameLib.D3.Physics.RigidBody( + body.id, + body.name + ); + + bodies3d.push(body3d); + } + + var world3d = new GameLib.D3.Physics.World( + null, + world.name, + physics3d, + new GameLib.D3.Vector3( + world.gravity.x, + world.gravity.y, + world.gravity.z + ), + broadphase3d, + solver3d, + bodies3d + ); + + worlds3d.push(world3d); + } + + physics3ds.push(physics3d); + } + } + + var lights3d = []; + + for (var l = 0; l < scene.lights.length; l++) { + + var light = scene.lights[l]; + + var light3d = new GameLib.D3.Light( + light.id, + light.lightType, + light.name, + new GameLib.D3.Color( + light.color.r, + light.color.g, + light.color.b, + light.color.a + ), + light.intensity, + new GameLib.D3.Vector3( + light.position.x, + light.position.y, + light.position.z + ), + new GameLib.D3.Vector3( + light.targetPosition.x, + light.targetPosition.y, + light.targetPosition.z + ), + new GameLib.D3.Vector4( + light.quaternion.x, + light.quaternion.y, + light.quaternion.z, + light.quaternion.w + ), + new GameLib.D3.Vector3( + light.rotation.x, + light.rotation.y, + light.rotation.z + ), + new GameLib.D3.Vector3( + light.scale.x, + light.scale.y, + light.scale.z + ), + light.distance, + light.decay, + light.power, + light.angle, + light.penumbra + ); + + lights3d.push(light3d); + }; + + var scene3d = new GameLib.D3.Scene( + scene._id || scene.id, + scene.path, + scene.name, + scene.meshes, + new GameLib.D3.Vector4( + scene.quaternion.x, + scene.quaternion.y, + scene.quaternion.z, + scene.quaternion.w + ), + new GameLib.D3.Vector3( + scene.position.x, + scene.position.y, + scene.position.z + ), + new GameLib.D3.Vector3( + scene.rotation.x, + scene.rotation.y, + scene.rotation.z + ), + new GameLib.D3.Vector3( + scene.scale.x, + scene.scale.y, + scene.scale.z + ), + scene.parentSceneId, + lights3d, + physics3ds + ); + + gameLibD3.loadScene(scene3d, onLoaded, false); + } + } + }(xhr, this); + + xhr.send(); +}; + + +/** + * Loads a GameLib.D3.Scene object into a ThreeJS Scene object + * @param gameLibScene GameLib.D3.Scene + * @param onLoaded callback when all meshes have loaded + * @param computeNormals set to true to compute new face and vertex normals during load + */ +GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) { + + console.log("loading scene " + gameLibScene.name); + + this.path = gameLibScene.path; + + var meshQ = []; + + for (var m = 0; m < gameLibScene.meshes.length; m++) { + + var mesh = gameLibScene.meshes[m]; + + console.log("loading mesh " + mesh.name); + + var geometry = new this.THREE.Geometry(); + + var vertices = mesh.vertices; + + var faces = mesh.faces; + + var faceVertexUvs = mesh.faceVertexUvs; + + var materials = mesh.materials; + + /** + * Setup vertices + */ + for (var v = 0; v < vertices.length; v++) { + geometry.vertices.push( + new this.THREE.Vector3( + vertices[v].position.x, + vertices[v].position.y, + vertices[v].position.z + ) + ) + } + + /** + * Setup faces + */ + for (var f = 0; f < faces.length; f++) { + + var face = new this.THREE.Face3( + faces[f].v0, + faces[f].v1, + faces[f].v2, + new this.THREE.Vector3( + faces[f].normal.x, + faces[f].normal.y, + faces[f].normal.z + ), + new this.THREE.Color( + faces[f].color.r, + faces[f].color.g, + faces[f].color.b + ), + faces[f].materialIndex + ); + + face.vertexColors = [ + new this.THREE.Color( + faces[f].vertexColors[0].r, + faces[f].vertexColors[0].g, + faces[f].vertexColors[0].b + ), + new this.THREE.Color( + faces[f].vertexColors[1].r, + faces[f].vertexColors[1].g, + faces[f].vertexColors[1].b + ), + new this.THREE.Color( + faces[f].vertexColors[2].r, + faces[f].vertexColors[2].g, + faces[f].vertexColors[2].b + ) + ]; + + face.normal = new this.THREE.Vector3( + faces[f].normal.x, + faces[f].normal.y, + faces[f].normal.z + ); + + face.vertexNormals = [ + new this.THREE.Vector3( + faces[f].vertexNormals[0].x, + faces[f].vertexNormals[0].y, + faces[f].vertexNormals[0].z + ), + new this.THREE.Vector3( + faces[f].vertexNormals[1].x, + faces[f].vertexNormals[1].y, + faces[f].vertexNormals[1].z + ), + new this.THREE.Vector3( + faces[f].vertexNormals[2].x, + faces[f].vertexNormals[2].y, + faces[f].vertexNormals[2].z + ) + ]; + + geometry.faces.push(face); + } + + geometry.faceVertexUvs = []; + + /** + * Setup face UVs + */ + for (var fm = 0; fm < faceVertexUvs.length; fm++) { + + var faceMaterialVertexUvs = faceVertexUvs[fm]; + + geometry.faceVertexUvs[fm] = []; + + for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) { + geometry.faceVertexUvs[fm][fuv] = []; + geometry.faceVertexUvs[fm][fuv].push( + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][0].x, + faceMaterialVertexUvs[fuv][0].y + ), + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][1].x, + faceMaterialVertexUvs[fuv][1].y + ), + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][2].x, + faceMaterialVertexUvs[fuv][2].y + ) + ); + } + } + + /** + * Re-calculate normals (if we have to) + * @type {Array} + */ + if (computeNormals) { + geometry.computeFaceNormals(); + geometry.computeVertexNormals(); + } + + var threeMaterialLoaders = []; + + /** + * Setup materials + */ + for (var mi = 0; mi < materials.length; mi++) { + threeMaterialLoaders.push(this.createThreeMaterial(materials[mi])); + } + + var result = this.Q.all(threeMaterialLoaders).then( + function(gl3d, mesh, geometry) { + return function(materials) { + + console.log("loaded material : " + materials[0].name); + + /** + * We don't support MultiMaterial atm - it doesn't work with raycasting + */ + var material = materials[0]; + + var threeMesh = gl3d.createThreeMesh(mesh, geometry, material); + threeMesh.name = mesh.name; + + threeMesh.position.x = mesh.position.x; + threeMesh.position.y = mesh.position.y; + threeMesh.position.z = mesh.position.z; + + threeMesh.rotation.x = mesh.rotation.x; + threeMesh.rotation.y = mesh.rotation.y; + threeMesh.rotation.z = mesh.rotation.z; + + threeMesh.scale.x = mesh.scale.x; + threeMesh.scale.y = mesh.scale.y; + threeMesh.scale.z = mesh.scale.z; + + threeMesh.quaternion.x = mesh.quaternion.x; + threeMesh.quaternion.y = mesh.quaternion.y; + threeMesh.quaternion.z = mesh.quaternion.z; + threeMesh.quaternion.w = mesh.quaternion.w; + + return threeMesh; + }; + }(this, mesh, geometry) + ).catch(function(error){ + console.log(error); + }); + + meshQ.push(result); + } + + this.Q.all(meshQ).then(function(threeMeshes){ + console.log("all meshes have loaded"); + if (typeof onLoaded != 'undefined') { + + var threeLights = []; + + for (var sli = 0; sli < gameLibScene.lights.length; sli++) { + + var blenderLight = gameLibScene.lights[sli]; + + var light = null; + + if (blenderLight.lightType == 'AmbientLight') { + light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity); + } + + if (blenderLight.lightType == 'DirectionalLight') { + light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity); + } + + if (blenderLight.lightType == 'PointLight') { + light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity); + light.distance = blenderLight.distance; + light.decay = blenderLight.decay; + } + + if (blenderLight.lightType == 'SpotLight') { + light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity); + light.distance = blenderLight.distance; + light.angle = blenderLight.angle; + light.penumbra = blenderLight.penumbra; + light.decay = blenderLight.decay; + } + + light.position.x = blenderLight.position.x; + light.position.y = blenderLight.position.y; + light.position.z = blenderLight.position.z; + + light.rotation.x = blenderLight.rotation.x; + light.rotation.y = blenderLight.rotation.y; + light.rotation.z = blenderLight.rotation.z; + + // light.scale.x = blenderLight.scale.x; + // light.scale.y = blenderLight.scale.y; + // light.scale.z = blenderLight.scale.z; + + if (light == null) { + console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported'); + } else { + light.name = blenderLight.name; + threeLights.push(light); + } + } + + var threeScene = new this.THREE.Scene(); + + threeScene.name = gameLibScene.name; + + threeScene.position.x = gameLibScene.position.x; + threeScene.position.y = gameLibScene.position.y; + threeScene.position.z = gameLibScene.position.z; + + threeScene.rotation.x = gameLibScene.rotation.x; + threeScene.rotation.y = gameLibScene.rotation.y; + threeScene.rotation.z = gameLibScene.rotation.z; + + threeScene.scale.x = gameLibScene.scale.x; + threeScene.scale.y = gameLibScene.scale.y; + threeScene.scale.z = gameLibScene.scale.z; + + threeScene.quaternion.x = gameLibScene.quaternion.x; + threeScene.quaternion.y = gameLibScene.quaternion.y; + threeScene.quaternion.z = gameLibScene.quaternion.z; + threeScene.quaternion.w = gameLibScene.quaternion.w; + + for (var m = 0; m < threeMeshes.length; m++) { + threeScene.add(threeMeshes[m]); + } + + for (var l = 0; l < threeLights.length; l++) { + threeScene.add(threeLights[l]); + } + + onLoaded( + gameLibScene, + { + scene: threeScene, + lights: threeLights, + meshes: threeMeshes + } + ); + } + }.bind(this)).catch(function(error){ + console.log(error); + }); +}; \ No newline at end of file diff --git a/src/game-lib-shape.js b/src/game-lib-shape.js new file mode 100644 index 0000000..cc572b8 --- /dev/null +++ b/src/game-lib-shape.js @@ -0,0 +1,37 @@ +/** + * Physics Shape Superset + * @constructor + */ +GameLib.D3.Physics.Shape = function( + shapeObject, // Physics engine specific + shapeType +) { + this.shapeObject = shapeObject; + this.shapeType = shapeType; + this.scale = new GameLib.D3.Vector3(1, 1, 1); +}; + +GameLib.D3.Physics.SHAPE_TYPE_SPHERE = 1; +GameLib.D3.Physics.SHAPE_TYPE_BOX = 2; +GameLib.D3.Physics.SHAPE_TYPE_TRIMESH = 3; +GameLib.D3.Physics.SHAPE_TYPE_CYLINDER = 4; + + +GameLib.D3.Physics.Shape.prototype.Update = function() { + if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + if(this.shapeType === GameLib.D3.Physics.SHAPE_TYPE_TRIMESH) { + this.shapeObject.setScale( + new this.physics.CANNON.Vec3( + this.scale.x, + this.scale.y, + this.scale.z + ) + ); + this.shapeObject.updateAABB(); + this.shapeObject.updateNormals(); + this.shapeObject.updateEdges(); + this.shapeObject.updateBoundingSphereRadius(); + this.shapeObject.updateTree(); + } + } +}; diff --git a/src/game-lib-skeleton.js b/src/game-lib-skeleton.js new file mode 100644 index 0000000..d843a5f --- /dev/null +++ b/src/game-lib-skeleton.js @@ -0,0 +1,69 @@ +/** + * Skeleton Superset + * @param id + * @param bones GameLib.D3.Bone + * @param boneInverses + * @param useVertexTexture + * @param boneTextureWidth + * @param boneTextureHeight + * @param boneMatrices + * @param boneTexture + * @constructor + */ +GameLib.D3.Skeleton = function( + id, + bones, + boneInverses, + useVertexTexture, + boneTextureWidth, + boneTextureHeight, + boneMatrices, + boneTexture +) { + this.id = id; + + this.bones = bones; + + /** + * An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones. + * @type GameLib.D3.Matrix4[] + */ + if (typeof boneInverses == 'undefined') { + boneInverses = []; + } + this.boneInverses = boneInverses; + + /** + * Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices + * @type {boolean} + */ + if (typeof useVertexTexture == 'undefined') { + useVertexTexture = false; + } + this.useVertexTexture = useVertexTexture; + + if (this.useVertexTexture == true) { + console.warn('support for vertex texture bones is not supported yet - something could break somewhere'); + } + + if (typeof boneTextureWidth == 'undefined') { + boneTextureWidth = 0; + } + this.boneTextureWidth = boneTextureWidth; + + if (typeof boneTextureHeight == 'undefined') { + boneTextureHeight = 0; + } + this.boneTextureHeight = boneTextureHeight; + + if (typeof boneMatrices == 'undefined') { + boneMatrices = []; + } + this.boneMatrices = boneMatrices; + + if (typeof boneTexture == 'undefined') { + boneTexture = []; + } + this.boneTexture = boneTexture; +}; + diff --git a/src/game-lib-sky-box.js b/src/game-lib-sky-box.js new file mode 100644 index 0000000..e37c343 --- /dev/null +++ b/src/game-lib-sky-box.js @@ -0,0 +1,65 @@ +GameLib.D3.SkyBox = function ( + +) { + this.id = null; + this.texturesFolder = null; +}; + +GameLib.D3.SkyBox.prototype.Load = function ( + texturesFolder +) { + this.texturesFolder = texturesFolder; + this.textures = []; + this.materials = []; + this.mesh = {}; + this.scene = new THREE.Scene(); + this.textureCube = null; + + var textureLoader = new THREE.TextureLoader(); + + // this textures are used to display the skybox + this.textures.push(textureLoader.load(this.texturesFolder + "px.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nx.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "py.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "ny.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "pz.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nz.png")); + + // assign textures to each cube face + for (var i = 0; i < 6; i ++) { + this.materials.push(new THREE.MeshBasicMaterial({ map: this.textures[i] })); + } + + // create cube geometry + this.mesh = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshFaceMaterial(this.materials)); + this.mesh.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1)); + this.scene.add(this.mesh); + + // Load env textureCube + // this is used for reflections on meshes + // mesh.material.envMap = this.textureCube; + this.textureCube = new THREE.CubeTextureLoader().load([ + this.texturesFolder + "px.png", this.texturesFolder + "nx.png", + this.texturesFolder + "py.png", this.texturesFolder + "ny.png", + this.texturesFolder + "pz.png", this.texturesFolder + "nz.png" + ]); +}; + +GameLib.D3.SkyBox.prototype.Render = function ( + threeRenderer, + threeCamera +) { + var cameraPosition = new THREE.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z); + + threeCamera.position.set(0, 0, 0); + + var gl = threeRenderer.context; + + gl.disable(gl.DEPTH_TEST); + + threeRenderer.render(this.scene, threeCamera); + + gl.enable(gl.DEPTH_TEST); + + threeCamera.position.copy(cameraPosition); +}; diff --git a/src/game-lib-solver.js b/src/game-lib-solver.js new file mode 100644 index 0000000..74f7777 --- /dev/null +++ b/src/game-lib-solver.js @@ -0,0 +1,38 @@ +/** + * Physics Solver Superset + * @param id + * @param name + * @param solverType + * @param iterations + * @param tolerance + * @constructor + */ +GameLib.D3.Physics.Solver = function( + id, + name, + solverType, + iterations, + tolerance +) { + this.id = id; + if (typeof name == 'undefined') { + if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + name = 'split solver'; + } else if (solverType == GameLib.D3.Physics.GS_SOLVER) { + name = 'gs solver'; + } else { + name = 'unknown solver'; + } + } + this.name = name; + this.solverType = solverType; + this.iterations = iterations; + this.tolerance = tolerance; +}; + +/** + * Solver Types + * @type {number} + */ +GameLib.D3.Physics.SPLIT_SOLVER = 0x1; +GameLib.D3.Physics.GS_SOLVER = 0x2; diff --git a/src/game-lib-texture.js b/src/game-lib-texture.js new file mode 100644 index 0000000..6c51723 --- /dev/null +++ b/src/game-lib-texture.js @@ -0,0 +1,370 @@ +/** + * Texture Superset + * @param id + * @param path + * @param name + * @param image + * @param wrapS + * @param wrapT + * @param repeat + * @param data + * @param format + * @param mapping + * @param magFilter + * @param minFilter + * @param textureType + * @param anisotropy + * @param offset + * @param generateMipmaps + * @param flipY + * @param mipmaps + * @param unpackAlignment + * @param premultiplyAlpha + * @param encoding + * @constructor + */ +GameLib.D3.Texture = function( + id, + name, + image, + wrapS, + wrapT, + repeat, + data, + format, + mapping, + magFilter, + minFilter, + textureType, + anisotropy, + offset, + generateMipmaps, + flipY, + mipmaps, + unpackAlignment, + premultiplyAlpha, + encoding +) { + this.id = id; + this.name = name; + this.image = image; + + if (typeof wrapS == 'undefined') { + wrapS = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; + } + this.wrapS = wrapS; + + if (typeof wrapT == 'undefined') { + wrapT = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; + } + this.wrapT = wrapT; + + if (typeof repeat == 'undefined') { + repeat = new GameLib.D3.Vector2(1, 1); + } + this.repeat = repeat; + + if (typeof data == 'undefined') { + data = null; + } + this.data = data; + + if (typeof format == 'undefined') { + format = GameLib.D3.Texture.TYPE_RGBA_FORMAT; + } + this.format = format; + + if (typeof mapping == 'undefined') { + mapping = GameLib.D3.Texture.TYPE_UV_MAPPING; + } + this.mapping = mapping; + + if (typeof magFilter == 'undefined') { + magFilter = GameLib.D3.Texture.TYPE_LINEAR_FILTER; + } + this.magFilter = magFilter; + + if (typeof minFilter == 'undefined') { + minFilter = GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER; + } + this.minFilter = minFilter; + + if (typeof textureType == 'undefined') { + textureType = GameLib.D3.Texture.TYPE_UNSIGNED_BYTE; + } + this.textureType = textureType; + + if (typeof anisotropy == 'undefined') { + anisotropy = 1; + } + this.anisotropy = anisotropy; + + if (typeof offset == 'undefined') { + offset = new GameLib.D3.Vector2(0, 0); + } + this.offset = offset; + + if (typeof generateMipmaps == 'undefined') { + generateMipmaps = true; + } + this.generateMipmaps = generateMipmaps; + + if (typeof flipY == 'undefined') { + flipY = true; + } + this.flipY = flipY; + + if (typeof mipmaps == 'undefined') { + mipmaps = []; + } + this.mipmaps = mipmaps; + + if (typeof unpackAlignment == 'undefined') { + unpackAlignment = 4; + } + this.unpackAlignment = unpackAlignment; + + if (typeof premultiplyAlpha == 'undefined') { + premultiplyAlpha = false; + } + this.premultiplyAlpha = premultiplyAlpha; + + if (typeof encoding == 'undefined') { + encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING; + } + this.encoding = encoding; +}; + +/** + * Texture Formats + * @type {number} + */ +GameLib.D3.Texture.TYPE_ALPHA_FORMAT = 1019; +GameLib.D3.Texture.TYPE_RGB_FORMAT = 1020; +GameLib.D3.Texture.TYPE_RGBA_FORMAT = 1021; +GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT = 1022; +GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023; +GameLib.D3.Texture.TYPE_DEPTH_FORMAT = 1026; + +/** + * Mapping modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_UV_MAPPING = 300; +GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301; +GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302; +GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303; +GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304; +GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305; +GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306; +GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307; + +/** + * Wrapping Modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_REPEAT_WRAPPING = 1000; +GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001; +GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002; + +/** + * Mipmap Filters + * @type {number} + */ +GameLib.D3.Texture.TYPE_NEAREST_FILTER = 1003; +GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004; +GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005; +GameLib.D3.Texture.TYPE_LINEAR_FILTER = 1006; +GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007; +GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008; + +/** + * Texture Data Types + * @type {number} + */ +GameLib.D3.Texture.TYPE_UNSIGNED_BYTE = 1009; +GameLib.D3.Texture.TYPE_BYTE = 1010; +GameLib.D3.Texture.TYPE_SHORT = 1011; +GameLib.D3.Texture.TYPE_UNSIGNED_SHORT = 1012; +GameLib.D3.Texture.TYPE_INT = 1013; +GameLib.D3.Texture.TYPE_UNSIGNED_INT = 1014; +GameLib.D3.Texture.TYPE_FLOAT = 1015; +GameLib.D3.Texture.TYPE_HALF_FLOAT = 1025; + +/** + * Encoding Modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL. +GameLib.D3.Texture.TYPE_SRGB_ENCODING = 3001; +GameLib.D3.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT +GameLib.D3.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE. +GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING = 3003; +GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004; +GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; +GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. + + + +/** + * Defers loading of an image and resolves once image is loaded + * @param gameLibTexture + * @param threeMaterial + * @param threeMaterialMapType + * @returns {Promise} + */ +GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) { + + var q = this.Q.defer(); + + var imagePath = null; + + if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { + /** + * Else, load from upload source + */ + imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; + } + + if (imagePath) { + + this.textureLoader.crossOrigin = ''; + + this.textureLoader.load( + imagePath, + function(texture) { + /** + * onLoad + */ + threeMaterial[threeMaterialMapType] = texture; + threeMaterial[threeMaterialMapType].name = gameLibTexture.name; + threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy; + threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding; + threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY; + /** + * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes + */ + threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; + threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter; + threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter; + threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping; + threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps; + threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2( + gameLibTexture.offset.x, + gameLibTexture.offset.y + ); + threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; + threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType; + threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS; + threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT; + threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; + threeMaterial.needsUpdate = true; + q.resolve(true); + }, + function(xhr) { + /** + * onProgress + */ + if (this.editor) { + this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success'); + } + }, + function(error) { + /** + * onError + */ + console.log("an error occurred while trying to load the image : " + imagePath); + q.resolve(null); + } + ); + + } else { + q.resolve(null); + } + + return q.promise; +}; + + +/** + * Returns an array of image loading Promises + * @param blenderMaterial + * @param blenderMaps + * @param threeMaterial + * @returns Q[] + */ +GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) { + + var textureMaps = []; + + for (var ti = 0; ti < blenderMaps.length; ti++) { + + var map = blenderMaps[ti]; + + if (blenderMaterial.maps.hasOwnProperty(map)) { + + var blenderTexture = blenderMaterial.maps[map]; + + if ( + blenderTexture && + blenderTexture.image && + blenderTexture.image.filename + ) { + + var threeMap = null; + + if (map == 'alpha') { + threeMap = 'alhpaMap'; + } + + if (map == 'ao') { + threeMap = 'aoMap'; + } + + if (map == 'bump') { + threeMap = 'bumpMap'; + } + + if (map == 'displacement') { + threeMap = 'displacementMap'; + } + + if (map == 'emissive') { + threeMap = 'emissiveMap'; + } + + if (map == 'environment') { + threeMap = 'envMap'; + } + + if (map == 'light') { + threeMap = 'lightMap'; + } + + if (map == 'specular') { + threeMap = 'specularMap'; + } + + if (map == 'diffuse') { + threeMap = 'map'; + } + + if (map == 'roughness') { + threeMap = 'roughnessMap'; + } + + if (map == 'metalness') { + threeMap = 'metalnessMap'; + } + + if (threeMap == null) { + console.warn("unsupported map type : " + map); + } + + textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap)); + } + } + } + + return textureMaps; +}; diff --git a/src/game-lib-triangle-edge.js b/src/game-lib-triangle-edge.js new file mode 100644 index 0000000..5aecd92 --- /dev/null +++ b/src/game-lib-triangle-edge.js @@ -0,0 +1,13 @@ +/** + * TriangleEdge + * @param triangle + * @param edge + * @constructor + */ +GameLib.D3.TriangleEdge = function( + triangle, + edge +) { + this.triangle = triangle; + this.edge = edge; +}; \ No newline at end of file diff --git a/src/game-lib-triangle-face.js b/src/game-lib-triangle-face.js new file mode 100644 index 0000000..aba5f52 --- /dev/null +++ b/src/game-lib-triangle-face.js @@ -0,0 +1,125 @@ +/** + * TriangleFace + * @param v0 + * @param v1 + * @param v2 + * @param materialIndex + * @param v0uv + * @param v1uv + * @param v2uv + * @param color + * @param vertexColors + * @param vertexNormals + * @param normal + * @constructor + */ +GameLib.D3.TriangleFace = function( + v0, + v1, + v2, + materialIndex, + v0uv, + v1uv, + v2uv, + color, + vertexColors, + vertexNormals, + normal +) { + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + this.materialIndex = materialIndex; + this.v0uv = v0uv; + this.v1uv = v1uv; + this.v2uv = v2uv; + if (!color) { + color = new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff); + } + this.color = color; + + if (!vertexColors) { + vertexColors = [ + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff) + ]; + } + this.vertexColors = vertexColors; + + if (!vertexNormals) { + vertexNormals = [ + new GameLib.D3.Vector3(), + new GameLib.D3.Vector3(), + new GameLib.D3.Vector3() + ] + } + this.vertexNormals = vertexNormals; + + if (!normal) { + normal = new GameLib.D3.Vector3(0); + } + + this.normal = normal; +}; + +/** + * Clone a TriangleFace + * @returns {GameLib.D3.TriangleFace} + */ +GameLib.D3.TriangleFace.prototype.clone = function(){ + return new GameLib.D3.TriangleFace( + this.v0, + this.v1, + this.v2, + this.materialIndex, + this.v0uv.copy(), + this.v1uv.copy(), + this.v2uv.copy() + ); +}; + +/** + * Returns true if two triangles are equal (their vertex indices match in some order) + * @param triangle + * @returns {boolean} + */ +GameLib.D3.TriangleFace.prototype.equals = function(triangle) { + return !!( + ( + (this.v0 == triangle.v0) && + (this.v1 == triangle.v1) && + (this.v2 == triangle.v2) + ) + || + ( + (this.v0 == triangle.v0) && + (this.v1 == triangle.v2) && + (this.v2 == triangle.v1) + ) + || + ( + (this.v0 == triangle.v1) && + (this.v1 == triangle.v0) && + (this.v2 == triangle.v2) + ) + || + ( + (this.v0 == triangle.v1) && + (this.v1 == triangle.v2) && + (this.v2 == triangle.v0) + ) + || + ( + (this.v0 == triangle.v2) && + (this.v1 == triangle.v0) && + (this.v2 == triangle.v1) + ) + || + ( + (this.v0 == triangle.v2) && + (this.v1 == triangle.v1) && + (this.v2 == triangle.v0) + )); +}; + diff --git a/src/game-lib-vector-2.js b/src/game-lib-vector-2.js new file mode 100644 index 0000000..460e5a9 --- /dev/null +++ b/src/game-lib-vector-2.js @@ -0,0 +1,27 @@ +GameLib.D3.Vector2 = function(x, y) { + + this.x = 0; + this.y = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } +}; + +GameLib.D3.Vector2.prototype.copy = function() { + return new GameLib.D3.Vector2( + this.x, + this.y + ); +}; + +GameLib.D3.Vector2.prototype.equals = function(v) { + return !!(((this.x == v.x) && + (this.y == v.y)) || + ((this.y == v.x) && + (this.x == v.y))); +}; diff --git a/src/game-lib-vector-3.js b/src/game-lib-vector-3.js new file mode 100644 index 0000000..fee45c1 --- /dev/null +++ b/src/game-lib-vector-3.js @@ -0,0 +1,134 @@ +GameLib.D3.Vector3 = function(x, y, z) { + + this.x = 0; + this.y = 0; + this.z = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } + + if (z) { + this.z = z; + } +}; + +GameLib.D3.Vector3.prototype.subtract = function (v) { + + if (v instanceof GameLib.D3.Vector3) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + + if (v instanceof GameLib.D3.Vector4) { + console.warn("trying to subtract vector of bigger length (4 vs 3))"); + } + + return this; +}; + +GameLib.D3.Vector3.prototype.cross = function (v) { + return new GameLib.D3.Vector3( + this.y * v.z - this.z * v.y, + this.z * v.x - this.x * v.z, + this.x * v.y - this.y * v.x + ); +}; + +GameLib.D3.Vector3.prototype.negative = function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + return this; +}; + +GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) { + + var normal = GameLib.D3.Vector3.normal(u, v, w); + + var uv = u.copy(); + + var winding = normal.dot(uv.subtract(viewPoint)); + + return (winding > 0); +}; + +GameLib.D3.Vector3.normal = function (u, v, w) { + var vv = v.copy(); + var wv = w.copy(); + return vv.subtract(u).cross(wv.subtract(u)); +}; + +GameLib.D3.Vector3.prototype.lookAt = function (at, up) { + + var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up); + + this.multiply(lookAtMatrix); +}; + +GameLib.D3.Vector3.prototype.translate = function (v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +GameLib.D3.Vector3.prototype.squared = function () { + return this.x * this.x + this.y * this.y + this.z * this.z; +}; + +GameLib.D3.Vector3.prototype.copy = function () { + return new GameLib.D3.Vector3( + this.x, + this.y, + this.z + ); +}; + +GameLib.D3.Vector3.prototype.multiply = function (s) { + if (s instanceof GameLib.D3.Vector3) { + this.x *= s.x; + this.y *= s.y; + this.z *= s.z; + } else if (s instanceof GameLib.D3.Matrix4) { + var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z; + var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z; + var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z; + this.x = x; + this.y = y; + this.z = z; + } else { + console.log("functionality not implemented - please do this"); + throw new Error("not implemented"); + } + return this; +}; + + +GameLib.D3.Vector3.prototype.dot = function (v) { + return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); +}; + +GameLib.D3.Vector3.prototype.normalize = function () { + + var EPSILON = 0.000001; + + var v2 = this.squared(); + + if (v2 < EPSILON) { + return this; //do nothing for zero vector + } + + var invLength = 1 / Math.sqrt(v2); + + this.x *= invLength; + this.y *= invLength; + this.z *= invLength; + + return this; +}; diff --git a/src/game-lib-vector-4-points.js b/src/game-lib-vector-4-points.js new file mode 100644 index 0000000..15fad95 --- /dev/null +++ b/src/game-lib-vector-4-points.js @@ -0,0 +1,224 @@ +GameLib.D3.Vector4.Points = function () { + this.vectors = []; +}; + +GameLib.D3.Vector4.Points.prototype.add = function (vector) { + + if (vector instanceof GameLib.D3.Vector3) { + vector = new GameLib.D3.Vector4( + vector.x, + vector.y, + vector.z, + 1 + ) + } + + if (!vector instanceof GameLib.D3.Vector4) { + console.warn("Vector needs to be of type Vector4"); + throw new Error("Vector needs to be of type Vector4"); + } + + this.vectors.push(vector); + + return this; +}; + +GameLib.D3.Vector4.Points.prototype.copy = function () { + + var vectors = []; + + for (var i = 0; i < this.vectors.length; i++) { + vectors.push(this.vectors[i].copy()); + } + + return vectors; +}; + +GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxXDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.x > maxXDistance) { + + maxXDistance = distances.x; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxXDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + +GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxYDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.y > maxYDistance) { + maxYDistance = distances.y; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxYDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + + +GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) { + + var polyCenter = this.average(); + + console.log("poly center : " + JSON.stringify(polyCenter)); + + var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up); + + lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0); + lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0); + lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0); + + console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); + + for (var i = 0; i < this.vectors.length; i++) { + console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); + this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); + console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); + } +}; + +GameLib.D3.Vector4.Points.prototype.distances = function () { + + var minX = this.vectors[0].x; + var minY = this.vectors[0].y; + var minZ = this.vectors[0].z; + + var maxX = this.vectors[0].x; + var maxY = this.vectors[0].y; + var maxZ = this.vectors[0].z; + + for (var i = 0; i < this.vectors.length; i++) { + if (this.vectors[i].x < minX) { + minX = this.vectors[i].x; + } + if (this.vectors[i].y < minY) { + minY = this.vectors[i].y; + } + if (this.vectors[i].z < minZ) { + minZ = this.vectors[i].z; + } + + if (this.vectors[i].x > maxX) { + maxX = this.vectors[i].x; + } + if (this.vectors[i].y > maxY) { + maxY = this.vectors[i].y; + } + if (this.vectors[i].z > maxZ) { + maxZ = this.vectors[i].z; + } + } + + return new GameLib.D3.Vector3( + Math.abs(maxX - minX), + Math.abs(maxY - minY), + Math.abs(maxY - minZ) + ) +}; + +GameLib.D3.Vector4.Points.prototype.average = function () { + var averageX = 0; + var averageY = 0; + var averageZ = 0; + + for (var i = 0; i < this.vectors.length; i++) { + averageX += this.vectors[i].x; + averageY += this.vectors[i].y; + averageZ += this.vectors[i].z; + } + + return new GameLib.D3.Vector3( + averageX / this.vectors.length, + averageY / this.vectors.length, + averageZ / this.vectors.length + ); +}; + +GameLib.D3.Vector4.Points.prototype.negative = function () { + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].x *= -1; + this.vectors[i].y *= -1; + this.vectors[i].z *= -1; + } + + return this; +}; + + +GameLib.D3.Vector4.Points.prototype.toOrigin = function () { + + var distanceFromOrigin = this.average().negative(); + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].translate(distanceFromOrigin); + } +}; \ No newline at end of file diff --git a/src/game-lib-vector-4.js b/src/game-lib-vector-4.js new file mode 100644 index 0000000..18ee60f --- /dev/null +++ b/src/game-lib-vector-4.js @@ -0,0 +1,99 @@ +GameLib.D3.Vector4 = function(x, y, z, w) { + + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } + + if (z) { + this.z = z; + } + + if (w) { + this.w = w; + } +}; + +GameLib.D3.Vector4.prototype.translate = function (v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +GameLib.D3.Vector4.prototype.copy = function () { + return new GameLib.D3.Vector4( + this.x, + this.y, + this.z, + this.w + ); +}; + +GameLib.D3.Vector4.prototype.multiply = function (s) { + if (s instanceof GameLib.D3.Vector3) { + this.x *= s.x; + this.y *= s.y; + this.z *= s.z; + } else if (s instanceof GameLib.D3.Matrix4) { + var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w; + var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w; + var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w; + var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w; + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } else { + console.log("functionality not implemented - please do this"); + throw new Error("not implemented"); + } +}; + + +GameLib.D3.Vector4.prototype.normalize = function () { + + // note - leave w untouched + var EPSILON = 0.000001; + + var v2 = this.x * this.x + this.y * this.y + this.z * this.z; + + if (v2 < EPSILON) { + return this; //do nothing for zero vector + } + + var invLength = 1 / Math.sqrt(v2); + + this.x *= invLength; + this.y *= invLength; + this.z *= invLength; + + return this; +}; + +GameLib.D3.Vector4.prototype.subtract = function (v) { + + if (v instanceof GameLib.D3.Vector3) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + + if (v instanceof GameLib.D3.Vector4) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + this.w -= v.w; + } + + return this; +}; + diff --git a/src/game-lib-vertex.js b/src/game-lib-vertex.js new file mode 100644 index 0000000..2e09dae --- /dev/null +++ b/src/game-lib-vertex.js @@ -0,0 +1,13 @@ +/** + * The normal gets assigned when the face calculates its normal + * @param position + * @param boneWeights GameLib.D3.BoneWeight[] + * @constructor + */ +GameLib.D3.Vertex = function( + position, + boneWeights +) { + this.position = position; + this.boneWeights = boneWeights; +}; \ No newline at end of file diff --git a/src/game-lib-world.js b/src/game-lib-world.js new file mode 100644 index 0000000..d9f8854 --- /dev/null +++ b/src/game-lib-world.js @@ -0,0 +1,448 @@ +/** + * World SuperSet - contains the custom world instance + * @param id + * @param name + * @param engine + * @param gravity + * @param broadphase + * @param solver + * @param rigidBodies + * @constructor + */ +GameLib.D3.World = function( + id, + name, + engine, + gravity, + broadphase, + solver, + rigidBodies +) { + + this.id = id; + + this.name = name; + + if (typeof gravity == 'undefined') { + gravity = new GameLib.D3.Vector3(0, -9.81, 0); + } + this.gravity = gravity; + + if (typeof broadphase == 'undefined') { + broadphase = new GameLib.D3.Physics.Broadphase( + null, + 'broadPhaseNaive', + GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE + ); + } + this.broadphase = broadphase; + + if (typeof solver == 'undefined') { + solver = new GameLib.D3.Physics.Solver( + null, + 'GSSolver', + GameLib.D3.Physics.GS_SOLVER + ); + } + this.solver = solver; + + if (typeof rigidBodies == 'undefined') { + rigidBodies = []; + } + this.rigidBodies = rigidBodies; + + this.engine = null; + + this.worldInstance = null; + + /** + * We only set the physics property if we pass it in the constructor, + * because we don't always want the physics object (ex. when we store this world to the API - we also don't then + * want to store the custom worlds - we want to generate them after loading from API) + */ + if (engine) { + this.engine = engine; + this.worldInstance = this.createWorldInstance(); + } +}; + + +GameLib.D3.World.prototype.createWorldInstance = function() { + + this.engine.isNotCannonThrow(); + + var customWorld = new this.engine.instance.World(); + + var cannonBroadphase = null; + + if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { + cannonBroadphase = new this.engine.instance.NaiveBroadphase(); + } else if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { + cannonBroadphase = new this.engine.instance.GridBroadphase(); + } else if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { + cannonBroadphase = new this.engine.instance.SAPBroardphase(); + } else { + console.warn('Unsupported broadphase type: ' + this.broadphase.broadphaseType); + throw new Error('Unsupported broadphase type: ' + this.broadphase.broadphaseType); + } + + customWorld.broadphase = cannonBroadphase; + + var cannonSolver = null; + + if (this.solver.solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + cannonSolver = new this.engine.instance.SplitSolver(); + } else if (this.solver.solverType == GameLib.D3.Physics.GS_SOLVER) { + cannonSolver = new this.engine.instance.GSSolver(); + cannonSolver.iterations = this.solver.iterations; + } + + customWorld.solver = cannonSolver; + + customWorld.gravity.x = this.gravity.x; + customWorld.gravity.y = this.gravity.y; + customWorld.gravity.z = this.gravity.z; + + for (var b = 0; b < this.rigidBodies.length; b++) { + + var customBody = this.createCustomBody(this.rigidBodies[b]); + + //customWorld.AddRigidBody(); + } + + customWorld.name = this.name; + + return customWorld; +}; + +GameLib.D3.Physics.World.prototype.AddShape = function( + shape, // d3.physics.shape + rigidBody, + offset, // vec3 + orientation //quaternion +) { + shape.shape = shape; + + /** + * TODO:: fix this? + */ + if (this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + + var _offset = null; + var _orientation = null; + + if(offset != null && typeof offset !== 'undefined') { + _offset = new this.physics.CANNON.Vec3(offset.x, offset.y, offset.z); + } + + if(orientation != null && typeof orientation !== 'undefined') { + _orientation = new this.physics.CANNON.Quaternion(orientation.x, orientation.y, orientation.z, orientation.w); + } + + rigidBody.bodyObject.addShape(shape.shapeObject, _offset, _orientation); + } +}; + +GameLib.D3.Physics.World.prototype.Wheel = function() { + +}; + +GameLib.D3.Physics.World.prototype.CreateRigidVehicle = function( + chassisBody // Physics.RigidBody +) { + var rigidVehicle = new GameLib.D3.Physics.RigidVehicle(); + + if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var vehicle = new this.physics.CANNON.RigidVehicle({ + chassisBody: chassisBody.bodyObject + }); + rigidVehicle.vehicleObject = vehicle; + return rigidVehicle; + } +}; + +GameLib.D3.Physics.World.prototype.CreateRaycastVehicle = function( + chassisBody // Physics.RigidBody +) { + var raycastVehicle = new GameLib.D3.Physics.RaycastVehicle(); + + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var vehicle = new this.physics.CANNON.RaycastVehicle({ + chassisBody: chassisBody.bodyObject + }); + raycastVehicle.vehicleObject = vehicle; + return raycastVehicle; + } +}; + +GameLib.D3.Physics.World.prototype.AddWheelToRigidVehicle = function( + vehicle, + rigidBody, + position, + axis, + direction +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addWheel({ + body: rigidBody.bodyObject, + position: new this.physics.CANNON.Vec3(position.x, position.y, position.z), + axis: new this.physics.CANNON.Vec3(axis.x, axis.y, axis.z), + direction: new this.physics.CANNON.Vec3(direction.x, direction.y, direction.z) + }); + } +}; + +GameLib.D3.Physics.World.prototype.AddWheelToRaycastVehicle = function ( + vehicle, // physics.raycastvehicle + options // cannon options +) { + if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addWheel(options); + } else { + console.log("function for engine not implemented"); + } +}; + +GameLib.D3.Physics.World.prototype.RigidVehicle.prototype.GetWheelInfo = function( + +) { + // note: need a way to determine which engine we are currently using + return this.vehicleObject.wheelBodies; +}; + +GameLib.D3.Physics.World.prototype.RaycastVehicle.prototype.GetWheelInfo = function( + +) { + // note: need a way to determine which engine we are currently using + return this.vehicleObject.wheelInfos; +}; + + +GameLib.D3.Physics.World.prototype.CreateTriMeshShape = function( + vertices, // flat list of floats + indices // flat list of floats +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Trimesh(vertices, indices), GameLib.D3.Physics.SHAPE_TYPE_TRIMESH); + } +}; + +GameLib.D3.Physics.World.prototype.CreateSphereShape = function ( + radius +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Sphere(radius), GameLib.D3.Physics.SHAPE_TYPE_SPHERE); + } +}; + +GameLib.D3.Physics.World.prototype.CreateBoxShape = function( + halfExtensions // vec3 +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Box(new this.physics.CANNON.Vec3(halfExtensions.x, halfExtensions.y, halfExtensions.z)), GameLib.D3.Physics.SHAPE_TYPE_BOX); + } +}; + +GameLib.D3.Physics.World.prototype.CreateCylinderShape = function( + radiusTop, + radiusBottom, + height, + numSegments +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments), GameLib.D3.Physics.SHAPE_TYPE_CYLINDER); + } +}; + +GameLib.D3.Physics.World.prototype.AddRigidBody = function( + rigidBody // Physics.RigidBody +) { + if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + this.worldObject.addBody(rigidBody.bodyObject); + } +}; + +GameLib.D3.Physics.World.prototype.AddVehicle = function( + vehicle // note: physics.vehicle +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addToWorld(this.worldObject); + } +}; + +GameLib.D3.Physics.World.prototype.Step = function( + timeStep +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + // todo: figure out, why this call to internal step is more stable for trimesh collisions..... + //this.worldObject.internalStep(timeStep); + //return; + + var now = performance.now() / 1000; + + if(!this.lastCallTime){ + // last call time not saved, cant guess elapsed time. Take a simple step. + this.worldObject.step(timeStep); + this.lastCallTime = now; + return; + } + + var timeSinceLastCall = now - this.lastCallTime; + + this.worldObject.step(timeStep, timeSinceLastCall); + + this.lastCallTime = now; + } +}; + +GameLib.D3.Physics.World.prototype.GetIndexedVertices = function( + triangleMeshShape +) { + + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + return { + vertices : triangleMeshShape.vertices, + indices : triangleMeshShape.indices + }; + + } else { + // todo: implement this for other physics engines. + return null; + } + +}; + +GameLib.D3.Physics.World.prototype.GenerateWireframeViewMesh = function( + triangleMeshShape, + normalLength, + scale, + opacity, + wireframeColor +) { + var geometryTHREE = new THREE.Geometry(); + var wireframeTHREEMesh = new THREE.Mesh + ( + geometryTHREE, + new THREE.MeshBasicMaterial({ + color: wireframeColor ? wireframeColor : 0xfefefe, + wireframe: true, + opacity: opacity ? opacity : 0.5 + }) + ); + + var data = this.GetIndexedVertices(triangleMeshShape); + + for(var i = 0, l = data.vertices.length / 3; i < l; i++) { + geometryTHREE.vertices.push(new THREE.Vector3(data.vertices[i * 3], data.vertices[i * 3 + 1], data.vertices[i * 3 + 2])); + } + + for(var i = 0, l = data.indices.length / 3; i < l; i++) { + var i0 = data.indices[i * 3]; + var i1 = data.indices[i * 3 + 1]; + var i2 = data.indices[i * 3 + 2]; + + geometryTHREE.faces.push(new THREE.Face3(i0, i1, i2)); + + // Create debug view for normals + + // Center point on the mesh itself + var centroid = new THREE.Vector3() + .add(geometryTHREE.vertices[i0]) + .add(geometryTHREE.vertices[i1]) + .add(geometryTHREE.vertices[i2]) + .divideScalar(3); + + var normal = null; + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var normal = new this.physics.CANNON.Vec3(); + triangleMeshShape.getNormal(i, normal); + } else { + // todo: calculate the normal for v0, v1 & v2 here. + } + + var arrow = new THREE.ArrowHelper(new THREE.Vector3(normal.x, normal.y, normal.z), centroid, normalLength, new THREE.Color(normal.x, normal.y, normal.z)); + wireframeTHREEMesh.add( arrow ); + } + + wireframeTHREEMesh.scale.x = scale.x; + wireframeTHREEMesh.scale.y = scale.y; + wireframeTHREEMesh.scale.z = scale.z; + + return wireframeTHREEMesh; +}; + +GameLib.D3.Physics.World.prototype.GenerateTriangleCollisionMesh = function( + threeMesh, + mass, // default = 0 + friction, // default = 10 + createCollisionSubMeshes, // boolean. default = false + facesPerSubsection, // int. default = 0 + subsectionsToMerge // int. default = 0 +) { + var processedFaces = 0; + var facesPerSubSection = facesPerSubsection || 0; + var subMeshesToMerge = subsectionsToMerge || 0; + var totalAmtFaces = threeMesh.geometry.faces.length; + var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces; + + var pairs = []; // output + + var vertices = []; + var indicies = []; + + for(var i = 0; i <= totalAmtFaces; i++) { + if(processedFaces == facesToProcess || i == totalAmtFaces) { + + var body = null; + + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + var meshShape = new this.physics.CANNON.Trimesh(vertices, indicies); + meshShape.setScale(new this.physics.CANNON.Vec3(threeMesh.scale.x, threeMesh.scale.y, threeMesh.scale.z)); + meshShape.updateAABB(); + meshShape.updateNormals(); + meshShape.updateEdges(); + meshShape.updateBoundingSphereRadius(); + meshShape.updateTree(); + + body = new this.physics.CANNON.Body({ mass: mass ? mass : 0, friction: friction ? friction : 10 }); + body.addShape(meshShape); + + } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_AMMO) { + + } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_GOBLIN) { + + } + + pairs.push({ + threeObject : createCollisionSubMeshes ? null : threeMesh, + physicsObject : body + }); + + vertices = []; + indicies = []; + processedFaces = 0; + + if(i == totalAmtFaces) { + return pairs; + } + } + + var face = threeMesh.geometry.faces[i]; + indicies.push(indicies.length); + indicies.push(indicies.length); + indicies.push(indicies.length); + + var v0 = threeMesh.geometry.vertices[face.a]; + var v1 = threeMesh.geometry.vertices[face.b]; + var v2 = threeMesh.geometry.vertices[face.c]; + + vertices.push(v0.x, v0.y, v0.z); + vertices.push(v1.x, v1.y, v1.z); + vertices.push(v2.x, v2.y, v2.z); + + processedFaces++; + } +}; diff --git a/src/game-lib-z.js b/src/game-lib-z.js new file mode 100644 index 0000000..771958c --- /dev/null +++ b/src/game-lib-z.js @@ -0,0 +1,3 @@ +if (typeof module !== 'undefined') { + module.exports = GameLib; +} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..f462b5b --- /dev/null +++ b/src/index.js @@ -0,0 +1,94 @@ +if (typeof GameLib === 'undefined') { + function GameLib() {} +} + +if (typeof GameLib.D3 === 'undefined') { + GameLib.D3 = function() {}; +} + +if (typeof require != 'undefined') { + GameLib.D3.Bone = require('./game-lib-bone.js'); + GameLib.D3.BoneWeight = require('./game-lib-bone-weight'); + GameLib.D3.Broadphase = require('./game-lib-broadphase'); + GameLib.D3.Color = require('./game-lib-color'); + GameLib.D3.FlyControls = require('./game-lib-fly-controls'); + GameLib.D3.Engine = require('./game-lib-engine'); + GameLib.D3.Game = require('./game-lib-game'); + GameLib.D3.Heightmap = require('./game-lib-heightmap'); + GameLib.D3.Image = require('./game-lib-image'); + GameLib.D3.Light = require('./game-lib-light'); + GameLib.D3.Material = require('./game-lib-material'); + GameLib.D3.Matrix3 = require('./game-lib-matrix-3'); + GameLib.D3.Matrix4 = require('./game-lib-matrix-4'); + GameLib.D3.Mesh = require('./game-lib-mesh'); + GameLib.D3.Physics = require('./game-lib-physics'); + GameLib.D3.PolyVertex = require('./game-lib-poly-vertex'); + GameLib.D3.RaycastVehicle = require('./game-lib-raycast-vehicle'); + GameLib.D3.RigidBody = require('./game-lib-rigid-body'); + GameLib.D3.RigidBodyVehicle = require('./game-lib-rigid-body-vehicle'); + GameLib.D3.Scene = require('./game-lib-scene'); + GameLib.D3.Shape = require('./game-lib-shape'); + GameLib.D3.Skeleton = require('./game-lib-skeleton'); + GameLib.D3.SkyBox = require('./game-lib-sky-box'); + GameLib.D3.Solver = require('./game-lib-solver'); + GameLib.D3.Texture = require('./game-lib-texture'); + GameLib.D3.TriangleEdge = require('./game-lib-triangle-edge'); + GameLib.D3.TriangleFace = require('./game-lib-triangle-face'); + GameLib.D3.Vector2 = require('./game-lib-vector-2'); + GameLib.D3.Vector3 = require('./game-lib-vector-3'); + GameLib.D3.Vector4 = require('./game-lib-vector-4'); + GameLib.D3.Vector4.Points = require('./game-lib-vector-4-points'); + GameLib.D3.Vertex = require('./game-lib-vertex'); + GameLib.D3.World = require('./game-lib-world'); +} + +if (typeof module != 'undefined') { + module.exports = GameLib; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +if (typeof module != 'undefined') { + module.exports = GameLib; +} \ No newline at end of file From 48c44abf93e53963ec1bbb0ada9a9413572950e7 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Fri, 14 Oct 2016 13:08:22 +0200 Subject: [PATCH 09/15] start to fix - at 'Heightmap' --- build/game-lib-min.js | 2 + build/game-lib.js | 4668 ++++++++++++++++++++++++++++++++++ gulpfile.js | 4 +- src/game-lib-broadphase.js | 55 +- src/game-lib-color.js | 6 +- src/game-lib-engine.js | 9 +- src/game-lib-fly-controls.js | 91 +- src/game-lib-heightmap.js | 39 +- src/game-lib-world.js | 10 - 9 files changed, 4802 insertions(+), 82 deletions(-) create mode 100644 build/game-lib-min.js create mode 100644 build/game-lib.js diff --git a/build/game-lib-min.js b/build/game-lib-min.js new file mode 100644 index 0000000..1595b67 --- /dev/null +++ b/build/game-lib-min.js @@ -0,0 +1,2 @@ +function GameLib(){}"undefined"==typeof GameLib.D3&&(GameLib.D3=function(){}),GameLib.D3.BoneWeight=function(e,i){this.boneIndex=e,this.weight=i},GameLib.D3.Bone=function(e,i,t,n,s,o,a,r,h,l){this.id=e,this.name=t,this.boneId=i,"undefined"==typeof n&&(n=[]),this.childBoneIds=n,"undefined"==typeof s&&(s=null),this.parentBoneId=s,"undefined"==typeof o&&(o=new GameLib.D3.Vector4),this.quaternion=o,"undefined"==typeof a&&(a=new GameLib.D3.Vector3(0,0,0)),this.position=a,"undefined"==typeof r&&(r=new GameLib.D3.Vector3(0,0,0)),this.rotation=r,"undefined"==typeof h&&(h=new GameLib.D3.Vector3(1,1,1)),this.scale=h,"undefined"==typeof l&&(l=new GameLib.D3.Vector3(0,1,0)),this.up=l},GameLib.D3.Broadphase=function(e,i,t,n,s){this.id=e,"undefined"==typeof i&&(i="broadphase-"+t),this.name=i,"undefined"==typeof t&&(t=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=t,"undefined"==typeof n&&(n=null),this.engine=n,this.instance=null,s&&this.createInstance()},GameLib.D3.Broadphase.prototype.createInstance=function(){if(!(this.engine instanceof GameLib.D3.Engine))throw console.warn("No Engine"),new Error("No Engine");this.engine.isNotCannonThrow();var e=null;if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)e=new this.engine.instance.NaiveBroadphase;else if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)e=new this.engine.instance.GridBroadphase;else{if(this.broadphaseType!=GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);e=new this.engine.instance.SAPBroardphase}return this.instance=e,e},GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Color=function(e,i,t,n){this.r=e,this.g=i,this.b=t,this.a=n},GameLib.D3.Engine=function(e,i){this.engineType=e,this.instance=i},GameLib.D3.Engine.prototype.isCannon=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_CANNON},GameLib.D3.Engine.prototype.isNotCannonThrow=function(){if(this.engineType!=GameLib.D3.Engine.ENGINE_TYPE_CANNON)throw console.warn("Only CANNON supported for this function"),new Error("Only CANNON supported for this function")},GameLib.D3.Engine.prototype.isAmmo=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_AMMO},GameLib.D3.Engine.prototype.isGoblin=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_GOBLIN},GameLib.D3.Engine.ENGINE_TYPE_CANNON=1,GameLib.D3.Engine.ENGINE_TYPE_AMMO=2,GameLib.D3.Engine.ENGINE_TYPE_GOBLIN=3,GameLib.D3.FlyControls=function(e,i,t){this.flySpeed=100,this.canvas=t,this.THREE=i,this.yaw=0,this.pitch=0,this.canRotate=!1,this.moveForward=!1,this.moveBackward=!1,this.moveLeft=!1,this.moveRight=!1,this.moveUp=!1,this.moveDown=!1,this.mouseUpCallback=this.onMouseUp.bind(this),this.mouseDownCallback=this.onMouseDown.bind(this),this.mouseMoveCallback=this.onMouseMove.bind(this),this.mouseWheelCallback=this.onMouseWheel.bind(this),this.keyDownCallback=this.onKeyDown.bind(this),this.keyUpCallback=this.onKeyUp.bind(this),this.camera=e,this.canvas.addEventListener("keydown",this.keyDownCallback,!1),this.canvas.addEventListener("keyup",this.keyUpCallback,!1),this.canvas.addEventListener("mousedown",this.mouseDownCallback,!1),this.canvas.addEventListener("mouseup",this.mouseUpCallback,!1),this.canvas.addEventListener("mousewheel",this.mouseWheelCallback,!1),this.havePointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.element=document.body,this.havePointerLock&&(this.element.requestPointerLock=this.element.requestPointerLock||this.element.mozRequestPointerLock||this.element.webkitRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock)},GameLib.D3.FlyControls.prototype.onMouseWheel=function(e){this.moveForward=!0,this.applyTranslation(.001*e.wheelDelta),e.preventDefault(),this.moveForward=!1},GameLib.D3.FlyControls.prototype.onMouseDown=function(e){1==e.button&&(this.canRotate=!0,this.canvas.addEventListener("mousemove",this.mouseMoveCallback,!1))},GameLib.D3.FlyControls.prototype.onMouseUp=function(e){1==e.button&&(this.canRotate=!1,this.canvas.removeEventListener("mousemove",this.mouseMoveCallback))},GameLib.D3.FlyControls.prototype.applyRotation=function(){this.camera.rotation.set(this.pitch,this.yaw,0,"YXZ")},GameLib.D3.FlyControls.prototype.applyTranslation=function(e){var i=new this.THREE.Vector3(0,0,-1),t=new this.THREE.Euler(0,0,0,"YXZ");t.set(this.pitch,this.yaw,0,"YXZ"),i=i.applyEuler(t);var n=i.normalize(),s=n.cross(new this.THREE.Vector3(0,1,0));this.moveForward?(this.camera.position.x+=n.x*(e*this.flySpeed),this.camera.position.y+=n.y*(e*this.flySpeed),this.camera.position.z+=n.z*(e*this.flySpeed)):this.moveBackward&&(this.camera.position.x-=n.x*(e*this.flySpeed),this.camera.position.y-=n.y*(e*this.flySpeed),this.camera.position.z-=n.z*(e*this.flySpeed)),this.moveLeft?(this.camera.position.x-=s.x*(e*this.flySpeed),this.camera.position.y-=s.y*(e*this.flySpeed),this.camera.position.z-=s.z*(e*this.flySpeed)):this.moveRight&&(this.camera.position.x+=s.x*(e*this.flySpeed),this.camera.position.y+=s.y*(e*this.flySpeed),this.camera.position.z+=s.z*(e*this.flySpeed)),this.moveUp?this.camera.position.y+=e*this.flySpeed:this.moveDown&&(this.camera.position.y-=e*this.flySpeed)},GameLib.D3.FlyControls.prototype.update=function(e){this.applyRotation(),this.applyTranslation(e)},GameLib.D3.FlyControls.prototype.onMouseMove=function(e){if(this.canRotate){var i=e.movementX||e.mozMovementX||e.webkitMovementX||0,t=e.movementY||e.mozMovementY||e.webkitMovementY||0;this.yaw-=.002*i,this.pitch-=.002*t}},GameLib.D3.FlyControls.prototype.onKeyDown=function(e){switch(e.keyCode){case 87:this.moveForward=!0;break;case 65:this.moveLeft=!0;break;case 83:this.moveBackward=!0;break;case 68:this.moveRight=!0;break;case 104:this.moveUp=!0;break;case 98:this.moveDown=!0}},GameLib.D3.FlyControls.prototype.onKeyUp=function(e){switch(e.keyCode){case 38:case 87:this.moveForward=!1;break;case 37:case 65:this.moveLeft=!1;break;case 40:case 83:this.moveBackward=!1;break;case 39:case 68:this.moveRight=!1;break;case 104:this.moveUp=!1;break;case 98:this.moveDown=!1}},GameLib.D3.Game=function(){this.scenes={},this.physicsWorlds=[],this.sceneToPhysicsWorldsMap={}},GameLib.D3.Game.prototype.AddScene=function(e){this.scenes[e.name]=e},GameLib.D3.Game.prototype.AddPhysicsWorld=function(e){this.physicsWorlds.push(e)},GameLib.D3.Game.prototype.LinkPhysicsWorldToScene=function(e,i){this.sceneToPhysicsWorldsMap[i.name]=this.sceneToPhysicsWorldsMap[i.name]||[],this.sceneToPhysicsWorldsMap[i.name].push(e)},GameLib.D3.Game.prototype.GetPhysicsWorldsForScene=function(e){return this.sceneToPhysicsWorldsMap[e.name]},GameLib.D3.Game.prototype.ProcessPhysics=function(e){for(var i in this.sceneToPhysicsWorldsMap){var t=this.sceneToPhysicsWorldsMap[i],n=this.scenes[i];if(n&&t)for(var s=0,o=t.length;s0){var s=this.loadMaps(e,n,t);Q.all(s).then(function(){i.resolve(t)}).catch(function(e){console.log(e),i.reject(e)})}else i.resolve(t);return i.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,l,c,p,m,d,y,u,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof l&&(l=[]),this.skinWeights=l,"undefined"==typeof c&&(c=[]),this.materials=c,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(1,1,1)),this.scale=y,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(0,1,0)),this.up=u,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.prototype.createThreeMesh=function(e,i,t){var n=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(n=new this.THREE.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var s=e.skeleton.bones,o=e.skinIndices,a=e.skinWeights,r=[],h=0;h0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var l=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],c=0;c9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var a=0;a0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixY(n),c=0;co&&(o=h.y,n=i*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixX(n),c=0;cn&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n 0) { + var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial); + Q.all(textureMaps).then( + function(){ + defer.resolve(threeMaterial); + } + ).catch( + function(error){ + console.log(error); + defer.reject(error); + } + ) + } else { + defer.resolve(threeMaterial); + } + + return defer.promise; +}; +/** + * Matrix 3 Maths + * @param row0 GameLib.D3.Vector3 + * @param row1 GameLib.D3.Vector3 + * @param row2 GameLib.D3.Vector3 + * @constructor + */ +GameLib.D3.Matrix3 = function( + row0, + row1, + row2 +) { + this.identity(); + + if (row0) { + this.rows[0] = row0; + } + + if (row1) { + this.rows[1] = row1; + } + + if (row2) { + this.rows[2] = row2; + } +}; + +/** + * Set matrix to identity + */ +GameLib.D3.Matrix3.prototype.identity = function () { + this.rows = [ + new GameLib.D3.Vector4(1, 0, 0), + new GameLib.D3.Vector4(0, 1, 0), + new GameLib.D3.Vector4(0, 0, 1) + ]; +}; +GameLib.D3.Matrix4 = function( + row0, + row1, + row2, + row3 +) { + + this.identity(); + + if (row0) { + this.rows[0] = row0; + } + + if (row1) { + this.rows[1] = row1; + } + + if (row2) { + this.rows[2] = row2; + } + + if (row3) { + this.rows[3] = row3; + } +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) { + this.identity(); + this.rows[1] = new GameLib.D3.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0); + this.rows[2] = new GameLib.D3.Vector4(0, Math.sin(radians), Math.cos(radians), 0); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixY = function (radians) { + this.identity(); + this.rows[0] = new GameLib.D3.Vector4( + Math.cos(radians), + 0, + Math.sin(radians), + 0 + ); + this.rows[2] = new GameLib.D3.Vector4( + -1 * Math.sin(radians), + 0, + Math.cos(radians), + 0 + ); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotationMatrixZ = function (radians) { + this.identity(); + this.rows[0] = new GameLib.D3.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0); + this.rows[1] = new GameLib.D3.Vector4(Math.sin(radians), Math.cos(radians), 0, 0); + return this; +}; + +GameLib.D3.Matrix4.prototype.rotateX = function (radians, point) { + this.identity(); + this.rotationMatrixX(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.rotateY = function (radians, point) { + this.identity(); + this.rotationMatrixY(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.rotateZ = function (radians, point) { + this.identity(); + this.rotationMatrixZ(radians); + return this.multiply(point); +}; + +GameLib.D3.Matrix4.prototype.multiply = function (mvp) { + if (mvp instanceof GameLib.D3.Vector4) { + return new GameLib.D3.Vector4( + this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w, + this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w, + this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w, + this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w + ); + } else if (mvp instanceof GameLib.D3.Vector3) { + return new GameLib.D3.Vector3( + this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z, + this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z, + this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + ); + } +}; + +GameLib.D3.Matrix4.prototype.identity = function () { + this.rows = [ + new GameLib.D3.Vector4(1, 0, 0, 0), + new GameLib.D3.Vector4(0, 1, 0, 0), + new GameLib.D3.Vector4(0, 0, 1, 0), + new GameLib.D3.Vector4(0, 0, 0, 1) + ]; +}; + +GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) { + + var pv = new GameLib.D3.Vector3(position.x, position.y, position.z); + + var z = pv.subtract(target).normalize(); + + if (z.squared() === 0) { + z.z = 1; + } + + var x = up.cross(z).normalize(); + + if (x.squared() === 0) { + z.x += 0.0001; + x = up.cross(z).normalize(); + } + + var y = z.cross(x); + + this.rows[0].x = x.x; + this.rows[0].y = x.y; + this.rows[0].z = x.z; + + this.rows[1].x = y.x; + this.rows[1].y = y.y; + this.rows[1].z = y.z; + + this.rows[2].x = z.x; + this.rows[2].y = z.y; + this.rows[2].z = z.z; + + return this; + + // te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x; + // te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y; + // te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z; + + + // var matrix4 = new Matrix4(); + // + // matrix4.rows[0] = side.negative(); + // matrix4.rows[1] = _up; + // matrix4.rows[2] = forward; + + // + // matrix4.setColumn(0, side.negative()); + // matrix4.setColumn(1, _up); + // matrix4.setColumn(2, forward); + + //return matrix4; + + // return new Matrix4( + // new Vector4( + // side.x, + // side.y, + // side.z, + // side.negative().dot(position) + // ), + // new Vector4( + // _up.x, + // _up.y, + // _up.z, + // _up.negative().dot(position) + // ), + // new Vector4( + // forward.negative().x, + // forward.negative().y, + // forward.negative().z, + // forward.dot(position) + // ) + // ) +}; + +/** + * Mesh Superset + * @param id + * @param path + * @param name + * @param meshType + * @param vertices + * @param faces + * @param skeleton + * @param faceVertexUvs + * @param skinIndices + * @param skinWeights + * @param materials + * @param position + * @param quaternion + * @param rotation + * @param scale + * @param up + * @param physics + * @param parentMeshId + * @param parentSceneId + * @param rawData + * @constructor + */ +GameLib.D3.Mesh = function( + id, + path, + name, + meshType, + vertices, + faces, + skeleton, + faceVertexUvs, + skinIndices, + skinWeights, + materials, + position, + quaternion, + rotation, + scale, + up, + physics, + parentMeshId, + parentSceneId, + rawData +) { + this.id = id; + this.path = path; + this.name = name; + this.meshType = meshType; + this.vertices = vertices; + this.faces = faces; + + if (typeof skeleton == 'undefined') { + skeleton = null; + } + this.skeleton = skeleton; + + if (typeof faceVertexUvs == 'undefined') { + faceVertexUvs = []; + } + this.faceVertexUvs = faceVertexUvs; + + if (typeof skinIndices == 'undefined') { + skinIndices = []; + } + this.skinIndices = skinIndices; + + if (typeof skinWeights == 'undefined') { + skinWeights = []; + } + this.skinWeights = skinWeights; + + if (typeof materials == 'undefined') { + materials = []; + } + this.materials = materials; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof quaternion == 'undefined') { + new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof rotation == 'undefined') { + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined') { + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof up == 'undefined') { + up = new GameLib.D3.Vector3(0,1,0); + } + this.up = up; + + this.physics = physics; + + this.parentMeshId = parentMeshId; + + this.parentSceneId = parentSceneId; + + this.rawData = null;// rawData; +}; + + +/** + * Mesh Type + * @type {number} + */ +GameLib.D3.Mesh.TYPE_NORMAL = 0; +GameLib.D3.Mesh.TYPE_SKINNED = 1; + + +/** + * Creates a THREE Mesh from GameLib.D3.Mesh + * @param gameLibMesh + * @param threeGeometry + * @param threeMaterial + * @returns {*} + */ +GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) { + + var threeMesh = null; + + if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) { + threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial); + } + + if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) { + + var bones = gameLibMesh.skeleton.bones; + + var skinIndices = gameLibMesh.skinIndices; + + var skinWeights = gameLibMesh.skinWeights; + + var threeBones = []; + + for (var bi = 0; bi < bones.length; bi++) { + + var bone = new this.THREE.Bone(); + + bone.name = bones[bi].name; + + bone.position.x = bones[bi].position.x; + bone.position.y = bones[bi].position.y; + bone.position.z = bones[bi].position.z; + + bone.rotation.x = bones[bi].rotation.x; + bone.rotation.y = bones[bi].rotation.y; + bone.rotation.z = bones[bi].rotation.z; + + bone.quaternion.x = bones[bi].quaternion.x; + bone.quaternion.y = bones[bi].quaternion.y; + bone.quaternion.z = bones[bi].quaternion.z; + bone.quaternion.w = bones[bi].quaternion.w; + + bone.scale.x = bones[bi].scale.x; + bone.scale.y = bones[bi].scale.y; + bone.scale.z = bones[bi].scale.z; + + bone.up.x = bones[bi].up.x; + bone.up.y = bones[bi].up.y; + bone.up.z = bones[bi].up.z; + + threeBones.push(bone); + } + + /** + * Setup the bone relationships + */ + for (var br = 0; br < bones.length; br++) { + for (var cbi = 0; cbi < bones[br].childBoneIds.length; cbi++) { + threeBones[br].add(threeBones[bones[br].childBoneIds[cbi]]); + } + } + + /** + * Setup bones (indexes) + */ + for (var si = 0; si < skinIndices.length; si++) { + threeGeometry.skinIndices.push( + new this.THREE.Vector4( + skinIndices[si].x, + skinIndices[si].y, + skinIndices[si].z, + skinIndices[si].w + ) + ); + } + + /** + * Setup bones (weights) + */ + for (var sw = 0; sw < skinWeights.length; sw++) { + threeGeometry.skinWeights.push( + new this.THREE.Vector4( + skinWeights[sw].x, + skinWeights[sw].y, + skinWeights[sw].z, + skinWeights[sw].w + ) + ); + } + + threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial); + + var skeleton = new this.THREE.Skeleton(threeBones); + + skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture; + + for (var i = 0; i < bones.length; i++) { + if (bones[i].parentBoneId === null) { + threeMesh.add(threeBones[i]); + break; + } + } + + threeMesh.bind(skeleton); + + threeMesh.pose(); + + threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh); + threeMesh.skeleton.skeletonHelper.material.linewidth = 5; + } + + if (threeMesh == null) { + console.log('cannot handle meshes of type ' + gameLibMesh.meshType + ' yet.'); + } + + gameLibMesh.threeMeshId = threeMesh.id; + + return threeMesh; +}; + +GameLib.D3.prototype.invertWindingOrder = function(triangles) { + + for (var i = 0; i < triangles.length; i++) { + var v1 = triangles[i].v1; + triangles[i].v1 = triangles[i].v2; + triangles[i].v2 = v1; + + var backupUV = triangles[i].triangle.v1uv; + triangles[i].triangle.v1uv = triangles[i].triangle.v2uv; + triangles[i].triangle.v2uv = backupUV; + } + + return triangles; +}; + +/** + * This function resets a the winding order of a mesh from a reference point V (the average center of the mesh) + */ +GameLib.D3.prototype.resetWindingOrder = function(faces, vertices) { + + var vertexList = new GameLib.D3.Vector3.Points(); + + for (var v = 0; v < vertices.length; v++) { + vertexList.add(new GameLib.D3.Vector3( + vertices[v].position.x, + vertices[v].position.y, + vertices[v].position.z + )); + } + + var V = vertexList.average(); + + var triangles = []; + + for (var s = 0; s < faces.length; s += 3) { + + var v0 = faces[s]; + var v1 = faces[s+1]; + var v2 = faces[s+2]; + + triangles.push( + { + v0 : v0, + v1 : v1, + v2 : v2, + edges : [ + {v0: v0, v1: v1}, + {v0: v1, v1: v2}, + {v0: v2, v1: v0} + ], + winding : 0, + edgeIndex : -1, + processed : false + } + ); + } + + for (var i = 0; i < triangles.length; i++) { + if ( + GameLib.D3.Vector3.clockwise( + vertices[triangles[i].v0].position, + vertices[triangles[i].v1].position, + vertices[triangles[i].v2].position, + V + ) + ) { + console.log('clockwise'); + var bv1 = triangles[i].v1; + triangles[i].v1 = triangles[i].v2; + triangles[i].v2 = bv1; + } else { + console.log('not clockwise'); + } + } + + return triangles; +}; + +/** + * This function resets the winding order for triangles in faces, given an initial triangle and orientation edge + * used pseudocode from + * http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh + * We need to use a graph traversal algorithm, + * lets assume we have method that returns neighbor of triangle on given edge + * + * neighbor_on_egde( next_tria, edge ) + * + * to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it + * processed = set of processed triangles; initial empty + * + * while to_process is not empty: + * next_tria, orientation_edge = to_process.pop() + * add next_tria in processed + * if next_tria is not opposite oriented than orientation_edge: + * change next_tria (ABC) orientation (B<->C) + * for each edge (AB) in next_tria: + * neighbor_tria = neighbor_on_egde( next_tria, edge ) + * if neighbor_tria exists and neighbor_tria not in processed: + * to_process add (neighbor_tria, edge opposite oriented (BA)) + * @param faces GameLib.D3.TriangleFace[] + * @param orientationEdge GameLib.D3.Vector2 + * @returns {Array} + */ +GameLib.D3.fixWindingOrder = function(faces, orientationEdge) { + + /** + * Checks if a TriangleFace belonging to a TriangleEdge has already been processed + * @param processed TriangleEdge[] + * @param triangle TriangleFace + * @returns {boolean} + */ + function inProcessed(processed, triangle) { + + for (var i = 0; i < processed.length; i++) { + if (processed[i].triangle.equals(triangle)) { + return true; + } + } + + return false; + } + + /** + * Returns a neighbouring triangle on a specific edge - preserving the edge orientation + * @param edge GameLib.D3.Vector2 + * @param faces GameLib.D3.TriangleFace[] + * @param currentTriangle + * @returns {*} + */ + function neighbourOnEdge(edge, faces, currentTriangle) { + + for (var i = 0; i < faces.length; i++) { + if ( + (faces[i].v0 == edge.x && faces[i].v1 == edge.y) || + (faces[i].v1 == edge.x && faces[i].v2 == edge.y) || + (faces[i].v2 == edge.x && faces[i].v0 == edge.y) || + (faces[i].v0 == edge.y && faces[i].v1 == edge.x) || + (faces[i].v1 == edge.y && faces[i].v2 == edge.x) || + (faces[i].v2 == edge.y && faces[i].v0 == edge.x) + ) { + + var triangle = new GameLib.D3.TriangleFace( + faces[i].v0, + faces[i].v1, + faces[i].v2, + faces[i].materialIndex, + faces[i].v0uv, + faces[i].v1uv, + faces[i].v2uv + ); + + if (triangle.equals(currentTriangle)) { + continue; + } + + return new GameLib.D3.TriangleEdge( + triangle, + edge + ); + } + } + + return null; + } + + var toProcess = [ + new GameLib.D3.TriangleEdge( + new GameLib.D3.TriangleFace( + faces[0].v0, + faces[0].v1, + faces[0].v2, + faces[0].materialIndex, + faces[0].v0uv, + faces[0].v1uv, + faces[0].v2uv + ), + orientationEdge + ) + ]; + + var processed = []; + + while (toProcess.length > 0) { + + var triangleEdge = toProcess.pop(); + + /** + * If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed + * to have the same winding order) + */ + if ( + (triangleEdge.triangle.v0 == triangleEdge.edge.x && + triangleEdge.triangle.v1 == triangleEdge.edge.y) || + (triangleEdge.triangle.v1 == triangleEdge.edge.x && + triangleEdge.triangle.v2 == triangleEdge.edge.y) || + (triangleEdge.triangle.v2 == triangleEdge.edge.x && + triangleEdge.triangle.v0 == triangleEdge.edge.y) + ) { + var backupV = triangleEdge.triangle.v1; + triangleEdge.triangle.v1 = triangleEdge.triangle.v2; + triangleEdge.triangle.v2 = backupV; + + var backupUV = triangleEdge.triangle.v1uv; + triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv; + triangleEdge.triangle.v2uv = backupUV; + } + + processed.push(triangleEdge); + + var edges = [ + new GameLib.D3.Vector2( + triangleEdge.triangle.v0, + triangleEdge.triangle.v1 + ), + new GameLib.D3.Vector2( + triangleEdge.triangle.v1, + triangleEdge.triangle.v2 + ), + new GameLib.D3.Vector2( + triangleEdge.triangle.v2, + triangleEdge.triangle.v0 + ) + ]; + + for (var j = 0; j < edges.length; j++) { + var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle); + if (neighbour && !inProcessed(processed, neighbour.triangle)) { + toProcess.push(neighbour); + } + } + } + + /** + * In processed - we will have some duplicates - only add the unique ones + * @type {Array} + */ + var triangles = []; + for (var i = 0; i < processed.length; i++) { + var found = false; + for (var k = 0; k < triangles.length; k++) { + if (triangles[k].equals(processed[i].triangle)){ + found = true; + break; + } + } + if (!found) { + triangles.push(processed[i].triangle); + } + } + + return triangles; +}; + +/** + * This is a work-around function to fix polys which don't triangulate because + * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around + * Z then Y axis + * @param verticesFlat [] + * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY + * @return [] + */ +GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) { + + if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) { + console.log("The vertices are not in the right length : " + verticesFlat.length); + } + + var vertices = []; + + var points = new GameLib.D3.Vector4.Points(); + + for (var i = 0; i < verticesFlat.length; i += 3) { + points.add(new GameLib.D3.Vector3( + verticesFlat[i], + verticesFlat[i + 1], + verticesFlat[i + 2] + )); + } + + points.toOrigin(); + + points.maximizeXDistance(grain); + + points.maximizeYDistance(grain); + + for (i = 0; i < points.vectors.length; i++) { + vertices.push( + [ + points.vectors[i].x, + points.vectors[i].y + ] + ); + } + + return vertices; +}; +/** + * Physics SuperSet Namespace Object + * @param id + * @param name + * @param engine GameLib.D3.Engine + * @param worlds + * @returns {{World: World}} + * @constructor + */ +GameLib.D3.Physics = function( + id, + name, + engine, + worlds +) { + this.id = id; + this.name = name; + this.engine = engine; + + if (typeof worlds == 'undefined') { + worlds = []; + } + this.worlds = worlds; +}; + + +/** + * Solver Types + * @type {number} + */ +GameLib.D3.Physics.SPLIT_SOLVER = 0x1; +GameLib.D3.Physics.GS_SOLVER = 0x2; +/** + * Contains a Poly vertex data structure + * @param localIndex + * @param mvertIndex + * @param uv GameLib.D3.Vector2 + * @param materialIndex + * @param edgeIndex + * @constructor + */ +GameLib.D3.PolyVertex = function( + localIndex, + mvertIndex, + uv, + materialIndex, + edgeIndex +) { + this.localIndex = localIndex; + this.mvertIndex = mvertIndex; + this.uv = uv; + this.materialIndex = materialIndex; + this.edgeIndex = edgeIndex; +}; + +/** + * Clone a PolyVertex + * @returns {GameLib.D3.PolyVertex} + */ +GameLib.D3.PolyVertex.prototype.clone = function() { + return new GameLib.D3.PolyVertex( + this.localIndex, + this.mvertIndex, + this.uv.copy(), + this.materialIndex, + this.edgeIndex + ) +}; +/** + * Physics Raycast Vehicle Superset + * TODO: body + wheels[] + * @constructor + */ +GameLib.D3.Physics.RaycastVehicle = function( +) { + this.vehicleObject = null; +}; + + +/** + * Physics Rigid Body Vehicle Superset + * TODO: body + wheels[] + * @constructor + */ +GameLib.D3.Physics.RigidVehicle = function( +) { + this.vehicleObject = null; +}; + +/** + * RigidBody Superset + * @param mass + * @param friction + * @param position + * @param quaternion + * @param velocity + * @param angularVelocity + * @param linearDamping + * @param angularDamping + * @param allowSleep + * @param sleepSpeedLimit + * @param sleepTimeLimit + * @param collisionFilterGroup + * @param collisionFilterMask + * @param fixedRotation + * @param shape + * @returns {GameLib.D3.Physics.RigidBody} + * @constructor + */ +GameLib.D3.Physics.RigidBody = function( + mass, + friction, + position, + quaternion, + velocity, + angularVelocity, + linearDamping, + angularDamping, + allowSleep, + sleepSpeedLimit, + sleepTimeLimit, + collisionFilterGroup, + collisionFilterMask, + fixedRotation, + shape +) { + + this.position = position || new GameLib.D3.Vector3(); + this.velocity = velocity || new GameLib.D3.Vector3(); + this.angularVelocity = angularVelocity || new GameLib.D3.Vector3(); + this.quaternion = quaternion || new GameLib.D3.Vector4(0, 0, 0, 1); + this.mass = typeof mass == "undefined" ? 0 : mass; + this.friction = typeof friction == "undefined" ? 5 : friction; + this.linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping; + this.angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping; + this.allowSleep = typeof allowSleep == "undefined" ? true : allowSleep; + this.sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit; + this.sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit; + this.collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup; + this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask; + this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation; + this.shape = typeof shape == "undefined" ? null : shape; + + this.rigidBodyInstance = this.createRigidBodyInstance(); +}; + +/** + * + * @returns {*} + */ +GameLib.D3.Physics.World.RigidBody.prototype.createRigidBodyInstance = function() { + + var rigidBody = null; + + // Create the bodyObject + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + rigidBody = new this.physics.CANNON.Body( + { + mass: mass, + friction: friction, + position: new this.physics.CANNON.Vec3(position.x, position.y, position.z), + velocity: new this.physics.CANNON.Vec3(velocity.x, velocity.y, velocity.z), + quaternion: new this.physics.CANNON.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w), + angularVelocity: new this.physics.CANNON.Vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z), + linearDamping: linearDamping, + angularDamping: angularDamping, + allowSleep: allowSleep, + sleepSpeedLimit: sleepSpeedLimit, + sleepTimeLimit: sleepTimeLimit, + collisionFilterGroup: collisionFilterGroup, + collisionFilterMask: collisionFilterMask, + fixedRotation: fixedRotation, + shape: shape + } + ); + + } + + return rigidBody; +}; + + +/** + * Scenes are objects putting meshes into 'world space' + * @param id + * @param path String + * @param name String + * @param meshes GameLib.D3.Mesh[] + * @param quaternion + * @param position + * @param rotation + * @param scale + * @param parentSceneId + * @param lights + * @constructor + */ +GameLib.D3.Scene = function( + id, + path, + name, + meshes, + quaternion, + position, + rotation, + scale, + parentSceneId, + lights, + physics +) { + this.id = id; + this.path = path; + this.name = name; + if (this.name.trim() == "") { + this.name = 'unnamed'; + } + this.meshes = meshes; + + if (typeof quaternion == 'undefined') { + quaternion = new GameLib.D3.Vector4(); + } + this.quaternion = quaternion; + + if (typeof position == 'undefined') { + position = new GameLib.D3.Vector3(0,0,0); + } + this.position = position; + + if (typeof rotation == 'undefined') { + rotation = new GameLib.D3.Vector3(0,0,0); + } + this.rotation = rotation; + + if (typeof scale == 'undefined') { + scale = new GameLib.D3.Vector3(1,1,1); + } + this.scale = scale; + + if (typeof parentSceneId == 'undefined') { + parentSceneId = null; + } + this.parentSceneId = parentSceneId; + + if (typeof lights == 'undefined') { + lights = []; + } + this.lights = lights; + + if (typeof physics == 'undefined') { + physics = []; + } + this.physics = physics; +}; + +/** + * Loads a scene directly from the API + * @param sceneName + * @param onLoaded callback + */ +GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { + + /** + * First check if this is a client or server side request + */ + if (typeof XMLHttpRequest == 'undefined') { + console.warn('implement server side loading from API here'); + return onLoaded(null, new Error('not implemented')); + } + + var xhr = new XMLHttpRequest(); + xhr.open( + 'GET', + this.apiUrl + '/scene/load' + scene.path + '/' + scene.name + ); + + xhr.onreadystatechange = function(xhr, gameLibD3) { + return function() { + if (xhr.readyState == 4) { + + var response = JSON.parse(xhr.responseText); + + if (!response.scene || response.scene.length == 0) { + return onLoaded(null, null, new Error('Could not load scene')); + } + + var scene = response.scene[0]; + + var physics3ds = []; + + if (scene.physics && scene.physics.length > 0) { + + for (var p = 0; p < scene.physics.length; p++) { + + var physics = scene.physics[p]; + + var physics3d = new GameLib.D3.Physics( + physics.id, + physics.name, + physics.engineType, + gameLibD3.CANNON, + null, + null + ); + + var worlds3d = []; + + for (var w = 0; w < physics.worlds.length; w++) { + + var world = physics.worlds[w]; + + var broadphase = world.broadphase; + + var broadphase3d = new GameLib.D3.Physics.Broadphase( + broadphase.id, + broadphase.name, + broadphase.broadphaseType + ); + + var solver = world.solver; + + var solver3d = new GameLib.D3.Physics.Solver( + solver.id, + solver.name, + solver.solverType, + solver.iterations, + solver.tolerance + ); + + var bodies = world.rigidBodies; + + var bodies3d = []; + + for (var b = 0; b < bodies.length; b++) { + + var body = bodies[b]; + + //TODO: add all body properties here + var body3d = new GameLib.D3.Physics.RigidBody( + body.id, + body.name + ); + + bodies3d.push(body3d); + } + + var world3d = new GameLib.D3.Physics.World( + null, + world.name, + physics3d, + new GameLib.D3.Vector3( + world.gravity.x, + world.gravity.y, + world.gravity.z + ), + broadphase3d, + solver3d, + bodies3d + ); + + worlds3d.push(world3d); + } + + physics3ds.push(physics3d); + } + } + + var lights3d = []; + + for (var l = 0; l < scene.lights.length; l++) { + + var light = scene.lights[l]; + + var light3d = new GameLib.D3.Light( + light.id, + light.lightType, + light.name, + new GameLib.D3.Color( + light.color.r, + light.color.g, + light.color.b, + light.color.a + ), + light.intensity, + new GameLib.D3.Vector3( + light.position.x, + light.position.y, + light.position.z + ), + new GameLib.D3.Vector3( + light.targetPosition.x, + light.targetPosition.y, + light.targetPosition.z + ), + new GameLib.D3.Vector4( + light.quaternion.x, + light.quaternion.y, + light.quaternion.z, + light.quaternion.w + ), + new GameLib.D3.Vector3( + light.rotation.x, + light.rotation.y, + light.rotation.z + ), + new GameLib.D3.Vector3( + light.scale.x, + light.scale.y, + light.scale.z + ), + light.distance, + light.decay, + light.power, + light.angle, + light.penumbra + ); + + lights3d.push(light3d); + }; + + var scene3d = new GameLib.D3.Scene( + scene._id || scene.id, + scene.path, + scene.name, + scene.meshes, + new GameLib.D3.Vector4( + scene.quaternion.x, + scene.quaternion.y, + scene.quaternion.z, + scene.quaternion.w + ), + new GameLib.D3.Vector3( + scene.position.x, + scene.position.y, + scene.position.z + ), + new GameLib.D3.Vector3( + scene.rotation.x, + scene.rotation.y, + scene.rotation.z + ), + new GameLib.D3.Vector3( + scene.scale.x, + scene.scale.y, + scene.scale.z + ), + scene.parentSceneId, + lights3d, + physics3ds + ); + + gameLibD3.loadScene(scene3d, onLoaded, false); + } + } + }(xhr, this); + + xhr.send(); +}; + + +/** + * Loads a GameLib.D3.Scene object into a ThreeJS Scene object + * @param gameLibScene GameLib.D3.Scene + * @param onLoaded callback when all meshes have loaded + * @param computeNormals set to true to compute new face and vertex normals during load + */ +GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) { + + console.log("loading scene " + gameLibScene.name); + + this.path = gameLibScene.path; + + var meshQ = []; + + for (var m = 0; m < gameLibScene.meshes.length; m++) { + + var mesh = gameLibScene.meshes[m]; + + console.log("loading mesh " + mesh.name); + + var geometry = new this.THREE.Geometry(); + + var vertices = mesh.vertices; + + var faces = mesh.faces; + + var faceVertexUvs = mesh.faceVertexUvs; + + var materials = mesh.materials; + + /** + * Setup vertices + */ + for (var v = 0; v < vertices.length; v++) { + geometry.vertices.push( + new this.THREE.Vector3( + vertices[v].position.x, + vertices[v].position.y, + vertices[v].position.z + ) + ) + } + + /** + * Setup faces + */ + for (var f = 0; f < faces.length; f++) { + + var face = new this.THREE.Face3( + faces[f].v0, + faces[f].v1, + faces[f].v2, + new this.THREE.Vector3( + faces[f].normal.x, + faces[f].normal.y, + faces[f].normal.z + ), + new this.THREE.Color( + faces[f].color.r, + faces[f].color.g, + faces[f].color.b + ), + faces[f].materialIndex + ); + + face.vertexColors = [ + new this.THREE.Color( + faces[f].vertexColors[0].r, + faces[f].vertexColors[0].g, + faces[f].vertexColors[0].b + ), + new this.THREE.Color( + faces[f].vertexColors[1].r, + faces[f].vertexColors[1].g, + faces[f].vertexColors[1].b + ), + new this.THREE.Color( + faces[f].vertexColors[2].r, + faces[f].vertexColors[2].g, + faces[f].vertexColors[2].b + ) + ]; + + face.normal = new this.THREE.Vector3( + faces[f].normal.x, + faces[f].normal.y, + faces[f].normal.z + ); + + face.vertexNormals = [ + new this.THREE.Vector3( + faces[f].vertexNormals[0].x, + faces[f].vertexNormals[0].y, + faces[f].vertexNormals[0].z + ), + new this.THREE.Vector3( + faces[f].vertexNormals[1].x, + faces[f].vertexNormals[1].y, + faces[f].vertexNormals[1].z + ), + new this.THREE.Vector3( + faces[f].vertexNormals[2].x, + faces[f].vertexNormals[2].y, + faces[f].vertexNormals[2].z + ) + ]; + + geometry.faces.push(face); + } + + geometry.faceVertexUvs = []; + + /** + * Setup face UVs + */ + for (var fm = 0; fm < faceVertexUvs.length; fm++) { + + var faceMaterialVertexUvs = faceVertexUvs[fm]; + + geometry.faceVertexUvs[fm] = []; + + for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) { + geometry.faceVertexUvs[fm][fuv] = []; + geometry.faceVertexUvs[fm][fuv].push( + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][0].x, + faceMaterialVertexUvs[fuv][0].y + ), + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][1].x, + faceMaterialVertexUvs[fuv][1].y + ), + new this.THREE.Vector2( + faceMaterialVertexUvs[fuv][2].x, + faceMaterialVertexUvs[fuv][2].y + ) + ); + } + } + + /** + * Re-calculate normals (if we have to) + * @type {Array} + */ + if (computeNormals) { + geometry.computeFaceNormals(); + geometry.computeVertexNormals(); + } + + var threeMaterialLoaders = []; + + /** + * Setup materials + */ + for (var mi = 0; mi < materials.length; mi++) { + threeMaterialLoaders.push(this.createThreeMaterial(materials[mi])); + } + + var result = this.Q.all(threeMaterialLoaders).then( + function(gl3d, mesh, geometry) { + return function(materials) { + + console.log("loaded material : " + materials[0].name); + + /** + * We don't support MultiMaterial atm - it doesn't work with raycasting + */ + var material = materials[0]; + + var threeMesh = gl3d.createThreeMesh(mesh, geometry, material); + threeMesh.name = mesh.name; + + threeMesh.position.x = mesh.position.x; + threeMesh.position.y = mesh.position.y; + threeMesh.position.z = mesh.position.z; + + threeMesh.rotation.x = mesh.rotation.x; + threeMesh.rotation.y = mesh.rotation.y; + threeMesh.rotation.z = mesh.rotation.z; + + threeMesh.scale.x = mesh.scale.x; + threeMesh.scale.y = mesh.scale.y; + threeMesh.scale.z = mesh.scale.z; + + threeMesh.quaternion.x = mesh.quaternion.x; + threeMesh.quaternion.y = mesh.quaternion.y; + threeMesh.quaternion.z = mesh.quaternion.z; + threeMesh.quaternion.w = mesh.quaternion.w; + + return threeMesh; + }; + }(this, mesh, geometry) + ).catch(function(error){ + console.log(error); + }); + + meshQ.push(result); + } + + this.Q.all(meshQ).then(function(threeMeshes){ + console.log("all meshes have loaded"); + if (typeof onLoaded != 'undefined') { + + var threeLights = []; + + for (var sli = 0; sli < gameLibScene.lights.length; sli++) { + + var blenderLight = gameLibScene.lights[sli]; + + var light = null; + + if (blenderLight.lightType == 'AmbientLight') { + light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity); + } + + if (blenderLight.lightType == 'DirectionalLight') { + light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity); + } + + if (blenderLight.lightType == 'PointLight') { + light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity); + light.distance = blenderLight.distance; + light.decay = blenderLight.decay; + } + + if (blenderLight.lightType == 'SpotLight') { + light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity); + light.distance = blenderLight.distance; + light.angle = blenderLight.angle; + light.penumbra = blenderLight.penumbra; + light.decay = blenderLight.decay; + } + + light.position.x = blenderLight.position.x; + light.position.y = blenderLight.position.y; + light.position.z = blenderLight.position.z; + + light.rotation.x = blenderLight.rotation.x; + light.rotation.y = blenderLight.rotation.y; + light.rotation.z = blenderLight.rotation.z; + + // light.scale.x = blenderLight.scale.x; + // light.scale.y = blenderLight.scale.y; + // light.scale.z = blenderLight.scale.z; + + if (light == null) { + console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported'); + } else { + light.name = blenderLight.name; + threeLights.push(light); + } + } + + var threeScene = new this.THREE.Scene(); + + threeScene.name = gameLibScene.name; + + threeScene.position.x = gameLibScene.position.x; + threeScene.position.y = gameLibScene.position.y; + threeScene.position.z = gameLibScene.position.z; + + threeScene.rotation.x = gameLibScene.rotation.x; + threeScene.rotation.y = gameLibScene.rotation.y; + threeScene.rotation.z = gameLibScene.rotation.z; + + threeScene.scale.x = gameLibScene.scale.x; + threeScene.scale.y = gameLibScene.scale.y; + threeScene.scale.z = gameLibScene.scale.z; + + threeScene.quaternion.x = gameLibScene.quaternion.x; + threeScene.quaternion.y = gameLibScene.quaternion.y; + threeScene.quaternion.z = gameLibScene.quaternion.z; + threeScene.quaternion.w = gameLibScene.quaternion.w; + + for (var m = 0; m < threeMeshes.length; m++) { + threeScene.add(threeMeshes[m]); + } + + for (var l = 0; l < threeLights.length; l++) { + threeScene.add(threeLights[l]); + } + + onLoaded( + gameLibScene, + { + scene: threeScene, + lights: threeLights, + meshes: threeMeshes + } + ); + } + }.bind(this)).catch(function(error){ + console.log(error); + }); +}; +/** + * Physics Shape Superset + * @constructor + */ +GameLib.D3.Physics.Shape = function( + shapeObject, // Physics engine specific + shapeType +) { + this.shapeObject = shapeObject; + this.shapeType = shapeType; + this.scale = new GameLib.D3.Vector3(1, 1, 1); +}; + +GameLib.D3.Physics.SHAPE_TYPE_SPHERE = 1; +GameLib.D3.Physics.SHAPE_TYPE_BOX = 2; +GameLib.D3.Physics.SHAPE_TYPE_TRIMESH = 3; +GameLib.D3.Physics.SHAPE_TYPE_CYLINDER = 4; + + +GameLib.D3.Physics.Shape.prototype.Update = function() { + if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + if(this.shapeType === GameLib.D3.Physics.SHAPE_TYPE_TRIMESH) { + this.shapeObject.setScale( + new this.physics.CANNON.Vec3( + this.scale.x, + this.scale.y, + this.scale.z + ) + ); + this.shapeObject.updateAABB(); + this.shapeObject.updateNormals(); + this.shapeObject.updateEdges(); + this.shapeObject.updateBoundingSphereRadius(); + this.shapeObject.updateTree(); + } + } +}; + +/** + * Skeleton Superset + * @param id + * @param bones GameLib.D3.Bone + * @param boneInverses + * @param useVertexTexture + * @param boneTextureWidth + * @param boneTextureHeight + * @param boneMatrices + * @param boneTexture + * @constructor + */ +GameLib.D3.Skeleton = function( + id, + bones, + boneInverses, + useVertexTexture, + boneTextureWidth, + boneTextureHeight, + boneMatrices, + boneTexture +) { + this.id = id; + + this.bones = bones; + + /** + * An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones. + * @type GameLib.D3.Matrix4[] + */ + if (typeof boneInverses == 'undefined') { + boneInverses = []; + } + this.boneInverses = boneInverses; + + /** + * Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices + * @type {boolean} + */ + if (typeof useVertexTexture == 'undefined') { + useVertexTexture = false; + } + this.useVertexTexture = useVertexTexture; + + if (this.useVertexTexture == true) { + console.warn('support for vertex texture bones is not supported yet - something could break somewhere'); + } + + if (typeof boneTextureWidth == 'undefined') { + boneTextureWidth = 0; + } + this.boneTextureWidth = boneTextureWidth; + + if (typeof boneTextureHeight == 'undefined') { + boneTextureHeight = 0; + } + this.boneTextureHeight = boneTextureHeight; + + if (typeof boneMatrices == 'undefined') { + boneMatrices = []; + } + this.boneMatrices = boneMatrices; + + if (typeof boneTexture == 'undefined') { + boneTexture = []; + } + this.boneTexture = boneTexture; +}; + + +GameLib.D3.SkyBox = function ( + +) { + this.id = null; + this.texturesFolder = null; +}; + +GameLib.D3.SkyBox.prototype.Load = function ( + texturesFolder +) { + this.texturesFolder = texturesFolder; + this.textures = []; + this.materials = []; + this.mesh = {}; + this.scene = new THREE.Scene(); + this.textureCube = null; + + var textureLoader = new THREE.TextureLoader(); + + // this textures are used to display the skybox + this.textures.push(textureLoader.load(this.texturesFolder + "px.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nx.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "py.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "ny.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "pz.png")); + this.textures.push(textureLoader.load(this.texturesFolder + "nz.png")); + + // assign textures to each cube face + for (var i = 0; i < 6; i ++) { + this.materials.push(new THREE.MeshBasicMaterial({ map: this.textures[i] })); + } + + // create cube geometry + this.mesh = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshFaceMaterial(this.materials)); + this.mesh.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1)); + this.scene.add(this.mesh); + + // Load env textureCube + // this is used for reflections on meshes + // mesh.material.envMap = this.textureCube; + this.textureCube = new THREE.CubeTextureLoader().load([ + this.texturesFolder + "px.png", this.texturesFolder + "nx.png", + this.texturesFolder + "py.png", this.texturesFolder + "ny.png", + this.texturesFolder + "pz.png", this.texturesFolder + "nz.png" + ]); +}; + +GameLib.D3.SkyBox.prototype.Render = function ( + threeRenderer, + threeCamera +) { + var cameraPosition = new THREE.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z); + + threeCamera.position.set(0, 0, 0); + + var gl = threeRenderer.context; + + gl.disable(gl.DEPTH_TEST); + + threeRenderer.render(this.scene, threeCamera); + + gl.enable(gl.DEPTH_TEST); + + threeCamera.position.copy(cameraPosition); +}; + +/** + * Physics Solver Superset + * @param id + * @param name + * @param solverType + * @param iterations + * @param tolerance + * @constructor + */ +GameLib.D3.Physics.Solver = function( + id, + name, + solverType, + iterations, + tolerance +) { + this.id = id; + if (typeof name == 'undefined') { + if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + name = 'split solver'; + } else if (solverType == GameLib.D3.Physics.GS_SOLVER) { + name = 'gs solver'; + } else { + name = 'unknown solver'; + } + } + this.name = name; + this.solverType = solverType; + this.iterations = iterations; + this.tolerance = tolerance; +}; + +/** + * Solver Types + * @type {number} + */ +GameLib.D3.Physics.SPLIT_SOLVER = 0x1; +GameLib.D3.Physics.GS_SOLVER = 0x2; + +/** + * Texture Superset + * @param id + * @param path + * @param name + * @param image + * @param wrapS + * @param wrapT + * @param repeat + * @param data + * @param format + * @param mapping + * @param magFilter + * @param minFilter + * @param textureType + * @param anisotropy + * @param offset + * @param generateMipmaps + * @param flipY + * @param mipmaps + * @param unpackAlignment + * @param premultiplyAlpha + * @param encoding + * @constructor + */ +GameLib.D3.Texture = function( + id, + name, + image, + wrapS, + wrapT, + repeat, + data, + format, + mapping, + magFilter, + minFilter, + textureType, + anisotropy, + offset, + generateMipmaps, + flipY, + mipmaps, + unpackAlignment, + premultiplyAlpha, + encoding +) { + this.id = id; + this.name = name; + this.image = image; + + if (typeof wrapS == 'undefined') { + wrapS = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; + } + this.wrapS = wrapS; + + if (typeof wrapT == 'undefined') { + wrapT = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING; + } + this.wrapT = wrapT; + + if (typeof repeat == 'undefined') { + repeat = new GameLib.D3.Vector2(1, 1); + } + this.repeat = repeat; + + if (typeof data == 'undefined') { + data = null; + } + this.data = data; + + if (typeof format == 'undefined') { + format = GameLib.D3.Texture.TYPE_RGBA_FORMAT; + } + this.format = format; + + if (typeof mapping == 'undefined') { + mapping = GameLib.D3.Texture.TYPE_UV_MAPPING; + } + this.mapping = mapping; + + if (typeof magFilter == 'undefined') { + magFilter = GameLib.D3.Texture.TYPE_LINEAR_FILTER; + } + this.magFilter = magFilter; + + if (typeof minFilter == 'undefined') { + minFilter = GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER; + } + this.minFilter = minFilter; + + if (typeof textureType == 'undefined') { + textureType = GameLib.D3.Texture.TYPE_UNSIGNED_BYTE; + } + this.textureType = textureType; + + if (typeof anisotropy == 'undefined') { + anisotropy = 1; + } + this.anisotropy = anisotropy; + + if (typeof offset == 'undefined') { + offset = new GameLib.D3.Vector2(0, 0); + } + this.offset = offset; + + if (typeof generateMipmaps == 'undefined') { + generateMipmaps = true; + } + this.generateMipmaps = generateMipmaps; + + if (typeof flipY == 'undefined') { + flipY = true; + } + this.flipY = flipY; + + if (typeof mipmaps == 'undefined') { + mipmaps = []; + } + this.mipmaps = mipmaps; + + if (typeof unpackAlignment == 'undefined') { + unpackAlignment = 4; + } + this.unpackAlignment = unpackAlignment; + + if (typeof premultiplyAlpha == 'undefined') { + premultiplyAlpha = false; + } + this.premultiplyAlpha = premultiplyAlpha; + + if (typeof encoding == 'undefined') { + encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING; + } + this.encoding = encoding; +}; + +/** + * Texture Formats + * @type {number} + */ +GameLib.D3.Texture.TYPE_ALPHA_FORMAT = 1019; +GameLib.D3.Texture.TYPE_RGB_FORMAT = 1020; +GameLib.D3.Texture.TYPE_RGBA_FORMAT = 1021; +GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT = 1022; +GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023; +GameLib.D3.Texture.TYPE_DEPTH_FORMAT = 1026; + +/** + * Mapping modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_UV_MAPPING = 300; +GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301; +GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302; +GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303; +GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304; +GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305; +GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306; +GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307; + +/** + * Wrapping Modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_REPEAT_WRAPPING = 1000; +GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001; +GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002; + +/** + * Mipmap Filters + * @type {number} + */ +GameLib.D3.Texture.TYPE_NEAREST_FILTER = 1003; +GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004; +GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005; +GameLib.D3.Texture.TYPE_LINEAR_FILTER = 1006; +GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007; +GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008; + +/** + * Texture Data Types + * @type {number} + */ +GameLib.D3.Texture.TYPE_UNSIGNED_BYTE = 1009; +GameLib.D3.Texture.TYPE_BYTE = 1010; +GameLib.D3.Texture.TYPE_SHORT = 1011; +GameLib.D3.Texture.TYPE_UNSIGNED_SHORT = 1012; +GameLib.D3.Texture.TYPE_INT = 1013; +GameLib.D3.Texture.TYPE_UNSIGNED_INT = 1014; +GameLib.D3.Texture.TYPE_FLOAT = 1015; +GameLib.D3.Texture.TYPE_HALF_FLOAT = 1025; + +/** + * Encoding Modes + * @type {number} + */ +GameLib.D3.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL. +GameLib.D3.Texture.TYPE_SRGB_ENCODING = 3001; +GameLib.D3.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT +GameLib.D3.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE. +GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING = 3003; +GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004; +GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; +GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. + + + +/** + * Defers loading of an image and resolves once image is loaded + * @param gameLibTexture + * @param threeMaterial + * @param threeMaterialMapType + * @returns {Promise} + */ +GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) { + + var q = this.Q.defer(); + + var imagePath = null; + + if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { + /** + * Else, load from upload source + */ + imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; + } + + if (imagePath) { + + this.textureLoader.crossOrigin = ''; + + this.textureLoader.load( + imagePath, + function(texture) { + /** + * onLoad + */ + threeMaterial[threeMaterialMapType] = texture; + threeMaterial[threeMaterialMapType].name = gameLibTexture.name; + threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy; + threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding; + threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY; + /** + * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes + */ + threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; + threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter; + threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter; + threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping; + threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps; + threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2( + gameLibTexture.offset.x, + gameLibTexture.offset.y + ); + threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; + threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType; + threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS; + threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT; + threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; + threeMaterial.needsUpdate = true; + q.resolve(true); + }, + function(xhr) { + /** + * onProgress + */ + if (this.editor) { + this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success'); + } + }, + function(error) { + /** + * onError + */ + console.log("an error occurred while trying to load the image : " + imagePath); + q.resolve(null); + } + ); + + } else { + q.resolve(null); + } + + return q.promise; +}; + + +/** + * Returns an array of image loading Promises + * @param blenderMaterial + * @param blenderMaps + * @param threeMaterial + * @returns Q[] + */ +GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) { + + var textureMaps = []; + + for (var ti = 0; ti < blenderMaps.length; ti++) { + + var map = blenderMaps[ti]; + + if (blenderMaterial.maps.hasOwnProperty(map)) { + + var blenderTexture = blenderMaterial.maps[map]; + + if ( + blenderTexture && + blenderTexture.image && + blenderTexture.image.filename + ) { + + var threeMap = null; + + if (map == 'alpha') { + threeMap = 'alhpaMap'; + } + + if (map == 'ao') { + threeMap = 'aoMap'; + } + + if (map == 'bump') { + threeMap = 'bumpMap'; + } + + if (map == 'displacement') { + threeMap = 'displacementMap'; + } + + if (map == 'emissive') { + threeMap = 'emissiveMap'; + } + + if (map == 'environment') { + threeMap = 'envMap'; + } + + if (map == 'light') { + threeMap = 'lightMap'; + } + + if (map == 'specular') { + threeMap = 'specularMap'; + } + + if (map == 'diffuse') { + threeMap = 'map'; + } + + if (map == 'roughness') { + threeMap = 'roughnessMap'; + } + + if (map == 'metalness') { + threeMap = 'metalnessMap'; + } + + if (threeMap == null) { + console.warn("unsupported map type : " + map); + } + + textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap)); + } + } + } + + return textureMaps; +}; + +/** + * TriangleEdge + * @param triangle + * @param edge + * @constructor + */ +GameLib.D3.TriangleEdge = function( + triangle, + edge +) { + this.triangle = triangle; + this.edge = edge; +}; +/** + * TriangleFace + * @param v0 + * @param v1 + * @param v2 + * @param materialIndex + * @param v0uv + * @param v1uv + * @param v2uv + * @param color + * @param vertexColors + * @param vertexNormals + * @param normal + * @constructor + */ +GameLib.D3.TriangleFace = function( + v0, + v1, + v2, + materialIndex, + v0uv, + v1uv, + v2uv, + color, + vertexColors, + vertexNormals, + normal +) { + this.v0 = v0; + this.v1 = v1; + this.v2 = v2; + this.materialIndex = materialIndex; + this.v0uv = v0uv; + this.v1uv = v1uv; + this.v2uv = v2uv; + if (!color) { + color = new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff); + } + this.color = color; + + if (!vertexColors) { + vertexColors = [ + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff), + new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff) + ]; + } + this.vertexColors = vertexColors; + + if (!vertexNormals) { + vertexNormals = [ + new GameLib.D3.Vector3(), + new GameLib.D3.Vector3(), + new GameLib.D3.Vector3() + ] + } + this.vertexNormals = vertexNormals; + + if (!normal) { + normal = new GameLib.D3.Vector3(0); + } + + this.normal = normal; +}; + +/** + * Clone a TriangleFace + * @returns {GameLib.D3.TriangleFace} + */ +GameLib.D3.TriangleFace.prototype.clone = function(){ + return new GameLib.D3.TriangleFace( + this.v0, + this.v1, + this.v2, + this.materialIndex, + this.v0uv.copy(), + this.v1uv.copy(), + this.v2uv.copy() + ); +}; + +/** + * Returns true if two triangles are equal (their vertex indices match in some order) + * @param triangle + * @returns {boolean} + */ +GameLib.D3.TriangleFace.prototype.equals = function(triangle) { + return !!( + ( + (this.v0 == triangle.v0) && + (this.v1 == triangle.v1) && + (this.v2 == triangle.v2) + ) + || + ( + (this.v0 == triangle.v0) && + (this.v1 == triangle.v2) && + (this.v2 == triangle.v1) + ) + || + ( + (this.v0 == triangle.v1) && + (this.v1 == triangle.v0) && + (this.v2 == triangle.v2) + ) + || + ( + (this.v0 == triangle.v1) && + (this.v1 == triangle.v2) && + (this.v2 == triangle.v0) + ) + || + ( + (this.v0 == triangle.v2) && + (this.v1 == triangle.v0) && + (this.v2 == triangle.v1) + ) + || + ( + (this.v0 == triangle.v2) && + (this.v1 == triangle.v1) && + (this.v2 == triangle.v0) + )); +}; + + +GameLib.D3.Vector2 = function(x, y) { + + this.x = 0; + this.y = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } +}; + +GameLib.D3.Vector2.prototype.copy = function() { + return new GameLib.D3.Vector2( + this.x, + this.y + ); +}; + +GameLib.D3.Vector2.prototype.equals = function(v) { + return !!(((this.x == v.x) && + (this.y == v.y)) || + ((this.y == v.x) && + (this.x == v.y))); +}; + +GameLib.D3.Vector3 = function(x, y, z) { + + this.x = 0; + this.y = 0; + this.z = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } + + if (z) { + this.z = z; + } +}; + +GameLib.D3.Vector3.prototype.subtract = function (v) { + + if (v instanceof GameLib.D3.Vector3) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + + if (v instanceof GameLib.D3.Vector4) { + console.warn("trying to subtract vector of bigger length (4 vs 3))"); + } + + return this; +}; + +GameLib.D3.Vector3.prototype.cross = function (v) { + return new GameLib.D3.Vector3( + this.y * v.z - this.z * v.y, + this.z * v.x - this.x * v.z, + this.x * v.y - this.y * v.x + ); +}; + +GameLib.D3.Vector3.prototype.negative = function () { + this.x *= -1; + this.y *= -1; + this.z *= -1; + return this; +}; + +GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) { + + var normal = GameLib.D3.Vector3.normal(u, v, w); + + var uv = u.copy(); + + var winding = normal.dot(uv.subtract(viewPoint)); + + return (winding > 0); +}; + +GameLib.D3.Vector3.normal = function (u, v, w) { + var vv = v.copy(); + var wv = w.copy(); + return vv.subtract(u).cross(wv.subtract(u)); +}; + +GameLib.D3.Vector3.prototype.lookAt = function (at, up) { + + var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up); + + this.multiply(lookAtMatrix); +}; + +GameLib.D3.Vector3.prototype.translate = function (v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +GameLib.D3.Vector3.prototype.squared = function () { + return this.x * this.x + this.y * this.y + this.z * this.z; +}; + +GameLib.D3.Vector3.prototype.copy = function () { + return new GameLib.D3.Vector3( + this.x, + this.y, + this.z + ); +}; + +GameLib.D3.Vector3.prototype.multiply = function (s) { + if (s instanceof GameLib.D3.Vector3) { + this.x *= s.x; + this.y *= s.y; + this.z *= s.z; + } else if (s instanceof GameLib.D3.Matrix4) { + var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z; + var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z; + var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z; + this.x = x; + this.y = y; + this.z = z; + } else { + console.log("functionality not implemented - please do this"); + throw new Error("not implemented"); + } + return this; +}; + + +GameLib.D3.Vector3.prototype.dot = function (v) { + return (this.x * v.x) + (this.y * v.y) + (this.z * v.z); +}; + +GameLib.D3.Vector3.prototype.normalize = function () { + + var EPSILON = 0.000001; + + var v2 = this.squared(); + + if (v2 < EPSILON) { + return this; //do nothing for zero vector + } + + var invLength = 1 / Math.sqrt(v2); + + this.x *= invLength; + this.y *= invLength; + this.z *= invLength; + + return this; +}; + +GameLib.D3.Vector4.Points = function () { + this.vectors = []; +}; + +GameLib.D3.Vector4.Points.prototype.add = function (vector) { + + if (vector instanceof GameLib.D3.Vector3) { + vector = new GameLib.D3.Vector4( + vector.x, + vector.y, + vector.z, + 1 + ) + } + + if (!vector instanceof GameLib.D3.Vector4) { + console.warn("Vector needs to be of type Vector4"); + throw new Error("Vector needs to be of type Vector4"); + } + + this.vectors.push(vector); + + return this; +}; + +GameLib.D3.Vector4.Points.prototype.copy = function () { + + var vectors = []; + + for (var i = 0; i < this.vectors.length; i++) { + vectors.push(this.vectors[i].copy()); + } + + return vectors; +}; + +GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxXDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.x > maxXDistance) { + + maxXDistance = distances.x; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxXDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + +GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxYDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.y > maxYDistance) { + maxYDistance = distances.y; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxYDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + + +GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) { + + var polyCenter = this.average(); + + console.log("poly center : " + JSON.stringify(polyCenter)); + + var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up); + + lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0); + lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0); + lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0); + + console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); + + for (var i = 0; i < this.vectors.length; i++) { + console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); + this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); + console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); + } +}; + +GameLib.D3.Vector4.Points.prototype.distances = function () { + + var minX = this.vectors[0].x; + var minY = this.vectors[0].y; + var minZ = this.vectors[0].z; + + var maxX = this.vectors[0].x; + var maxY = this.vectors[0].y; + var maxZ = this.vectors[0].z; + + for (var i = 0; i < this.vectors.length; i++) { + if (this.vectors[i].x < minX) { + minX = this.vectors[i].x; + } + if (this.vectors[i].y < minY) { + minY = this.vectors[i].y; + } + if (this.vectors[i].z < minZ) { + minZ = this.vectors[i].z; + } + + if (this.vectors[i].x > maxX) { + maxX = this.vectors[i].x; + } + if (this.vectors[i].y > maxY) { + maxY = this.vectors[i].y; + } + if (this.vectors[i].z > maxZ) { + maxZ = this.vectors[i].z; + } + } + + return new GameLib.D3.Vector3( + Math.abs(maxX - minX), + Math.abs(maxY - minY), + Math.abs(maxY - minZ) + ) +}; + +GameLib.D3.Vector4.Points.prototype.average = function () { + var averageX = 0; + var averageY = 0; + var averageZ = 0; + + for (var i = 0; i < this.vectors.length; i++) { + averageX += this.vectors[i].x; + averageY += this.vectors[i].y; + averageZ += this.vectors[i].z; + } + + return new GameLib.D3.Vector3( + averageX / this.vectors.length, + averageY / this.vectors.length, + averageZ / this.vectors.length + ); +}; + +GameLib.D3.Vector4.Points.prototype.negative = function () { + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].x *= -1; + this.vectors[i].y *= -1; + this.vectors[i].z *= -1; + } + + return this; +}; + + +GameLib.D3.Vector4.Points.prototype.toOrigin = function () { + + var distanceFromOrigin = this.average().negative(); + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].translate(distanceFromOrigin); + } +}; +GameLib.D3.Vector4 = function(x, y, z, w) { + + this.x = 0; + this.y = 0; + this.z = 0; + this.w = 0; + + if (x) { + this.x = x; + } + + if (y) { + this.y = y; + } + + if (z) { + this.z = z; + } + + if (w) { + this.w = w; + } +}; + +GameLib.D3.Vector4.prototype.translate = function (v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; +}; + +GameLib.D3.Vector4.prototype.copy = function () { + return new GameLib.D3.Vector4( + this.x, + this.y, + this.z, + this.w + ); +}; + +GameLib.D3.Vector4.prototype.multiply = function (s) { + if (s instanceof GameLib.D3.Vector3) { + this.x *= s.x; + this.y *= s.y; + this.z *= s.z; + } else if (s instanceof GameLib.D3.Matrix4) { + var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w; + var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w; + var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w; + var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w; + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } else { + console.log("functionality not implemented - please do this"); + throw new Error("not implemented"); + } +}; + + +GameLib.D3.Vector4.prototype.normalize = function () { + + // note - leave w untouched + var EPSILON = 0.000001; + + var v2 = this.x * this.x + this.y * this.y + this.z * this.z; + + if (v2 < EPSILON) { + return this; //do nothing for zero vector + } + + var invLength = 1 / Math.sqrt(v2); + + this.x *= invLength; + this.y *= invLength; + this.z *= invLength; + + return this; +}; + +GameLib.D3.Vector4.prototype.subtract = function (v) { + + if (v instanceof GameLib.D3.Vector3) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + } + + if (v instanceof GameLib.D3.Vector4) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + this.w -= v.w; + } + + return this; +}; + + +/** + * The normal gets assigned when the face calculates its normal + * @param position + * @param boneWeights GameLib.D3.BoneWeight[] + * @constructor + */ +GameLib.D3.Vertex = function( + position, + boneWeights +) { + this.position = position; + this.boneWeights = boneWeights; +}; +/** + * World SuperSet - contains the custom world instance + * @param id + * @param name + * @param engine + * @param gravity + * @param broadphase + * @param solver + * @param rigidBodies + * @constructor + */ +GameLib.D3.World = function( + id, + name, + engine, + gravity, + broadphase, + solver, + rigidBodies +) { + + this.id = id; + + this.name = name; + + if (typeof gravity == 'undefined') { + gravity = new GameLib.D3.Vector3(0, -9.81, 0); + } + this.gravity = gravity; + + if (typeof broadphase == 'undefined') { + broadphase = new GameLib.D3.Physics.Broadphase( + null, + 'broadPhaseNaive', + GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE + ); + } + this.broadphase = broadphase; + + if (typeof solver == 'undefined') { + solver = new GameLib.D3.Physics.Solver( + null, + 'GSSolver', + GameLib.D3.Physics.GS_SOLVER + ); + } + this.solver = solver; + + if (typeof rigidBodies == 'undefined') { + rigidBodies = []; + } + this.rigidBodies = rigidBodies; + + this.engine = null; + + this.worldInstance = null; + + /** + * We only set the physics property if we pass it in the constructor, + * because we don't always want the physics object (ex. when we store this world to the API - we also don't then + * want to store the custom worlds - we want to generate them after loading from API) + */ + if (engine) { + this.engine = engine; + this.worldInstance = this.createWorldInstance(); + } +}; + + +GameLib.D3.World.prototype.createWorldInstance = function() { + + this.engine.isNotCannonThrow(); + + var customWorld = new this.engine.instance.World(); + + var cannonBroadphase = null; + + + customWorld.broadphase = cannonBroadphase; + + var cannonSolver = null; + + if (this.solver.solverType == GameLib.D3.Physics.SPLIT_SOLVER) { + cannonSolver = new this.engine.instance.SplitSolver(); + } else if (this.solver.solverType == GameLib.D3.Physics.GS_SOLVER) { + cannonSolver = new this.engine.instance.GSSolver(); + cannonSolver.iterations = this.solver.iterations; + } + + customWorld.solver = cannonSolver; + + customWorld.gravity.x = this.gravity.x; + customWorld.gravity.y = this.gravity.y; + customWorld.gravity.z = this.gravity.z; + + for (var b = 0; b < this.rigidBodies.length; b++) { + + var customBody = this.createCustomBody(this.rigidBodies[b]); + + //customWorld.AddRigidBody(); + } + + customWorld.name = this.name; + + return customWorld; +}; + +GameLib.D3.Physics.World.prototype.AddShape = function( + shape, // d3.physics.shape + rigidBody, + offset, // vec3 + orientation //quaternion +) { + shape.shape = shape; + + /** + * TODO:: fix this? + */ + if (this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + + var _offset = null; + var _orientation = null; + + if(offset != null && typeof offset !== 'undefined') { + _offset = new this.physics.CANNON.Vec3(offset.x, offset.y, offset.z); + } + + if(orientation != null && typeof orientation !== 'undefined') { + _orientation = new this.physics.CANNON.Quaternion(orientation.x, orientation.y, orientation.z, orientation.w); + } + + rigidBody.bodyObject.addShape(shape.shapeObject, _offset, _orientation); + } +}; + +GameLib.D3.Physics.World.prototype.Wheel = function() { + +}; + +GameLib.D3.Physics.World.prototype.CreateRigidVehicle = function( + chassisBody // Physics.RigidBody +) { + var rigidVehicle = new GameLib.D3.Physics.RigidVehicle(); + + if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var vehicle = new this.physics.CANNON.RigidVehicle({ + chassisBody: chassisBody.bodyObject + }); + rigidVehicle.vehicleObject = vehicle; + return rigidVehicle; + } +}; + +GameLib.D3.Physics.World.prototype.CreateRaycastVehicle = function( + chassisBody // Physics.RigidBody +) { + var raycastVehicle = new GameLib.D3.Physics.RaycastVehicle(); + + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var vehicle = new this.physics.CANNON.RaycastVehicle({ + chassisBody: chassisBody.bodyObject + }); + raycastVehicle.vehicleObject = vehicle; + return raycastVehicle; + } +}; + +GameLib.D3.Physics.World.prototype.AddWheelToRigidVehicle = function( + vehicle, + rigidBody, + position, + axis, + direction +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addWheel({ + body: rigidBody.bodyObject, + position: new this.physics.CANNON.Vec3(position.x, position.y, position.z), + axis: new this.physics.CANNON.Vec3(axis.x, axis.y, axis.z), + direction: new this.physics.CANNON.Vec3(direction.x, direction.y, direction.z) + }); + } +}; + +GameLib.D3.Physics.World.prototype.AddWheelToRaycastVehicle = function ( + vehicle, // physics.raycastvehicle + options // cannon options +) { + if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addWheel(options); + } else { + console.log("function for engine not implemented"); + } +}; + +GameLib.D3.Physics.World.prototype.RigidVehicle.prototype.GetWheelInfo = function( + +) { + // note: need a way to determine which engine we are currently using + return this.vehicleObject.wheelBodies; +}; + +GameLib.D3.Physics.World.prototype.RaycastVehicle.prototype.GetWheelInfo = function( + +) { + // note: need a way to determine which engine we are currently using + return this.vehicleObject.wheelInfos; +}; + + +GameLib.D3.Physics.World.prototype.CreateTriMeshShape = function( + vertices, // flat list of floats + indices // flat list of floats +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Trimesh(vertices, indices), GameLib.D3.Physics.SHAPE_TYPE_TRIMESH); + } +}; + +GameLib.D3.Physics.World.prototype.CreateSphereShape = function ( + radius +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Sphere(radius), GameLib.D3.Physics.SHAPE_TYPE_SPHERE); + } +}; + +GameLib.D3.Physics.World.prototype.CreateBoxShape = function( + halfExtensions // vec3 +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Box(new this.physics.CANNON.Vec3(halfExtensions.x, halfExtensions.y, halfExtensions.z)), GameLib.D3.Physics.SHAPE_TYPE_BOX); + } +}; + +GameLib.D3.Physics.World.prototype.CreateCylinderShape = function( + radiusTop, + radiusBottom, + height, + numSegments +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments), GameLib.D3.Physics.SHAPE_TYPE_CYLINDER); + } +}; + +GameLib.D3.Physics.World.prototype.AddRigidBody = function( + rigidBody // Physics.RigidBody +) { + if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { + this.worldObject.addBody(rigidBody.bodyObject); + } +}; + +GameLib.D3.Physics.World.prototype.AddVehicle = function( + vehicle // note: physics.vehicle +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + vehicle.vehicleObject.addToWorld(this.worldObject); + } +}; + +GameLib.D3.Physics.World.prototype.Step = function( + timeStep +) { + if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + // todo: figure out, why this call to internal step is more stable for trimesh collisions..... + //this.worldObject.internalStep(timeStep); + //return; + + var now = performance.now() / 1000; + + if(!this.lastCallTime){ + // last call time not saved, cant guess elapsed time. Take a simple step. + this.worldObject.step(timeStep); + this.lastCallTime = now; + return; + } + + var timeSinceLastCall = now - this.lastCallTime; + + this.worldObject.step(timeStep, timeSinceLastCall); + + this.lastCallTime = now; + } +}; + +GameLib.D3.Physics.World.prototype.GetIndexedVertices = function( + triangleMeshShape +) { + + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + return { + vertices : triangleMeshShape.vertices, + indices : triangleMeshShape.indices + }; + + } else { + // todo: implement this for other physics engines. + return null; + } + +}; + +GameLib.D3.Physics.World.prototype.GenerateWireframeViewMesh = function( + triangleMeshShape, + normalLength, + scale, + opacity, + wireframeColor +) { + var geometryTHREE = new THREE.Geometry(); + var wireframeTHREEMesh = new THREE.Mesh + ( + geometryTHREE, + new THREE.MeshBasicMaterial({ + color: wireframeColor ? wireframeColor : 0xfefefe, + wireframe: true, + opacity: opacity ? opacity : 0.5 + }) + ); + + var data = this.GetIndexedVertices(triangleMeshShape); + + for(var i = 0, l = data.vertices.length / 3; i < l; i++) { + geometryTHREE.vertices.push(new THREE.Vector3(data.vertices[i * 3], data.vertices[i * 3 + 1], data.vertices[i * 3 + 2])); + } + + for(var i = 0, l = data.indices.length / 3; i < l; i++) { + var i0 = data.indices[i * 3]; + var i1 = data.indices[i * 3 + 1]; + var i2 = data.indices[i * 3 + 2]; + + geometryTHREE.faces.push(new THREE.Face3(i0, i1, i2)); + + // Create debug view for normals + + // Center point on the mesh itself + var centroid = new THREE.Vector3() + .add(geometryTHREE.vertices[i0]) + .add(geometryTHREE.vertices[i1]) + .add(geometryTHREE.vertices[i2]) + .divideScalar(3); + + var normal = null; + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + var normal = new this.physics.CANNON.Vec3(); + triangleMeshShape.getNormal(i, normal); + } else { + // todo: calculate the normal for v0, v1 & v2 here. + } + + var arrow = new THREE.ArrowHelper(new THREE.Vector3(normal.x, normal.y, normal.z), centroid, normalLength, new THREE.Color(normal.x, normal.y, normal.z)); + wireframeTHREEMesh.add( arrow ); + } + + wireframeTHREEMesh.scale.x = scale.x; + wireframeTHREEMesh.scale.y = scale.y; + wireframeTHREEMesh.scale.z = scale.z; + + return wireframeTHREEMesh; +}; + +GameLib.D3.Physics.World.prototype.GenerateTriangleCollisionMesh = function( + threeMesh, + mass, // default = 0 + friction, // default = 10 + createCollisionSubMeshes, // boolean. default = false + facesPerSubsection, // int. default = 0 + subsectionsToMerge // int. default = 0 +) { + var processedFaces = 0; + var facesPerSubSection = facesPerSubsection || 0; + var subMeshesToMerge = subsectionsToMerge || 0; + var totalAmtFaces = threeMesh.geometry.faces.length; + var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces; + + var pairs = []; // output + + var vertices = []; + var indicies = []; + + for(var i = 0; i <= totalAmtFaces; i++) { + if(processedFaces == facesToProcess || i == totalAmtFaces) { + + var body = null; + + if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) { + + var meshShape = new this.physics.CANNON.Trimesh(vertices, indicies); + meshShape.setScale(new this.physics.CANNON.Vec3(threeMesh.scale.x, threeMesh.scale.y, threeMesh.scale.z)); + meshShape.updateAABB(); + meshShape.updateNormals(); + meshShape.updateEdges(); + meshShape.updateBoundingSphereRadius(); + meshShape.updateTree(); + + body = new this.physics.CANNON.Body({ mass: mass ? mass : 0, friction: friction ? friction : 10 }); + body.addShape(meshShape); + + } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_AMMO) { + + } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_GOBLIN) { + + } + + pairs.push({ + threeObject : createCollisionSubMeshes ? null : threeMesh, + physicsObject : body + }); + + vertices = []; + indicies = []; + processedFaces = 0; + + if(i == totalAmtFaces) { + return pairs; + } + } + + var face = threeMesh.geometry.faces[i]; + indicies.push(indicies.length); + indicies.push(indicies.length); + indicies.push(indicies.length); + + var v0 = threeMesh.geometry.vertices[face.a]; + var v1 = threeMesh.geometry.vertices[face.b]; + var v2 = threeMesh.geometry.vertices[face.c]; + + vertices.push(v0.x, v0.y, v0.z); + vertices.push(v1.x, v1.y, v1.z); + vertices.push(v2.x, v2.y, v2.z); + + processedFaces++; + } +}; + +if (typeof module !== 'undefined') { + module.exports = GameLib; +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index fdb7e86..1ae5504 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -11,8 +11,8 @@ gulp.task( .pipe(concat('game-lib.js')) .pipe(minify({ ext:{ - src:'-debug.js', - min:'.js' + src:'.js', + min:'-min.js' } })) .pipe(gulp.dest('./build/')); diff --git a/src/game-lib-broadphase.js b/src/game-lib-broadphase.js index af8aeaf..4be0c57 100644 --- a/src/game-lib-broadphase.js +++ b/src/game-lib-broadphase.js @@ -1,14 +1,18 @@ /** * Physics Broadphase Superset * @param id - * @param name - * @param broadphaseType + * @param name String + * @param broadphaseType Number + * @param engine GameLib.D3.Engine + * @param createInstance Boolean * @constructor */ GameLib.D3.Broadphase = function( id, name, - broadphaseType + broadphaseType, + engine, + createInstance ) { this.id = id; @@ -18,11 +22,50 @@ GameLib.D3.Broadphase = function( this.name = name; if (typeof broadphaseType == 'undefined') { - console.warn('undefined broadphase type'); - throw new Error('undefined broadphase type'); + broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE; + } + this.broadphaseType = broadphaseType; + + if (typeof engine == 'undefined') { + engine = null; + } + this.engine = engine; + + this.instance = null; + + if (createInstance) { + this.createInstance(); + } +}; + +/** + * Creates a custom Broadphase instance based on the engine type + */ +GameLib.D3.Broadphase.prototype.createInstance = function() { + + if (!(this.engine instanceof GameLib.D3.Engine)) { + console.warn('No Engine'); + throw new Error('No Engine'); } - this.broadphaseType = broadphaseType; + this.engine.isNotCannonThrow(); + + var instance = null; + + if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { + instance = new this.engine.instance.NaiveBroadphase(); + } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { + instance = new this.engine.instance.GridBroadphase(); + } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { + instance = new this.engine.instance.SAPBroardphase(); + } else { + console.warn('Unsupported broadphase type: ' + this.broadphaseType); + throw new Error('Unsupported broadphase type: ' + this.broadphaseType); + } + + this.instance = instance; + + return instance; }; /** diff --git a/src/game-lib-color.js b/src/game-lib-color.js index bf8e40e..caf8055 100644 --- a/src/game-lib-color.js +++ b/src/game-lib-color.js @@ -11,8 +11,4 @@ GameLib.D3.Color = function(r, g, b, a) { this.g = g; this.b = b; this.a = a; -}; - -if (typeof module !== 'undefined') { - module.exports = GameLib.D3.Color; -} \ No newline at end of file +}; \ No newline at end of file diff --git a/src/game-lib-engine.js b/src/game-lib-engine.js index 241ed20..e019c55 100644 --- a/src/game-lib-engine.js +++ b/src/game-lib-engine.js @@ -1,7 +1,7 @@ /** * Engine Superset * @param engineType - * @param instance + * @param instance {CANNON | Ammo | Goblin} * @constructor */ GameLib.D3.Engine = function( @@ -30,7 +30,6 @@ GameLib.D3.Engine.prototype.isNotCannonThrow = function() { } }; - /** * True if Ammo physics * @returns {boolean} @@ -53,8 +52,4 @@ GameLib.D3.Engine.prototype.isGoblin = function() { */ GameLib.D3.Engine.ENGINE_TYPE_CANNON = 0x1; GameLib.D3.Engine.ENGINE_TYPE_AMMO = 0x2; -GameLib.D3.Engine.ENGINE_TYPE_GOBLIN = 0x3; - -if (typeof module !== 'undefined') { - module.exports = GameLib.D3.Engine; -} \ No newline at end of file +GameLib.D3.Engine.ENGINE_TYPE_GOBLIN = 0x3; \ No newline at end of file diff --git a/src/game-lib-fly-controls.js b/src/game-lib-fly-controls.js index 36d1c80..8daa8a1 100644 --- a/src/game-lib-fly-controls.js +++ b/src/game-lib-fly-controls.js @@ -49,9 +49,12 @@ GameLib.D3.FlyControls = function( this.element.requestPointerLock = this.element.requestPointerLock || this.element.mozRequestPointerLock || this.element.webkitRequestPointerLock; document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock; } - }; +/** + * Go forward / backward on mouse wheel + * @param event + */ GameLib.D3.FlyControls.prototype.onMouseWheel = function(event) { this.moveForward = true; this.applyTranslation(event.wheelDelta * 0.001); @@ -59,42 +62,39 @@ GameLib.D3.FlyControls.prototype.onMouseWheel = function(event) { this.moveForward = false; }; +/** + * Start rotating the camera on mouse middle button down + * @param event + */ GameLib.D3.FlyControls.prototype.onMouseDown = function(event) { - - // if (event.button == 0) { - // this.canRotate = true; - // this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); - // if (this.havePointerLock) { - // this.element.requestPointerLock(); - // } - // } - if (event.button == 1) { this.canRotate = true; this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false); } }; +/** + * Stop rotating on middle mouse button down + * @param event + */ GameLib.D3.FlyControls.prototype.onMouseUp = function(event) { - - // if (event.button == 0) { - // this.canRotate = false; - // this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); - // if (this.havePointerLock) { - // document.exitPointerLock(); - // } - // } - if (event.button == 1) { this.canRotate = false; this.canvas.removeEventListener('mousemove', this.mouseMoveCallback); } }; +/** + * Apply current yaw and pitch to camera + */ GameLib.D3.FlyControls.prototype.applyRotation = function() { this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ"); }; +/** + * Apply current position to camera + * @param deltaTime + */ GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) { var direction = new this.THREE.Vector3(0, 0, -1); var rotation = new this.THREE.Euler(0, 0, 0, "YXZ"); @@ -102,41 +102,35 @@ GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) { direction = direction.applyEuler(rotation); + var forward = direction.normalize(); + var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); + if(this.moveForward) { - var newPos = direction.normalize(); - this.camera.position.x += newPos.x * (deltaTime * this.flySpeed); - this.camera.position.y += newPos.y * (deltaTime * this.flySpeed); - this.camera.position.z += newPos.z * (deltaTime * this.flySpeed); + this.camera.position.x += forward.x * (deltaTime * this.flySpeed); + this.camera.position.y += forward.y * (deltaTime * this.flySpeed); + this.camera.position.z += forward.z * (deltaTime * this.flySpeed); } else if(this.moveBackward) { - var newPos = direction.normalize(); - this.camera.position.x -= newPos.x * (deltaTime * this.flySpeed); - this.camera.position.y -= newPos.y * (deltaTime * this.flySpeed); - this.camera.position.z -= newPos.z * (deltaTime * this.flySpeed); + this.camera.position.x -= forward.x * (deltaTime * this.flySpeed); + this.camera.position.y -= forward.y * (deltaTime * this.flySpeed); + this.camera.position.z -= forward.z * (deltaTime * this.flySpeed); } if(this.moveLeft) { - var forward = direction.normalize(); - var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); - var newPos = right; - this.camera.position.x -= newPos.x * (deltaTime * this.flySpeed); - this.camera.position.y -= newPos.y * (deltaTime * this.flySpeed); - this.camera.position.z -= newPos.z * (deltaTime * this.flySpeed); + this.camera.position.x -= right.x * (deltaTime * this.flySpeed); + this.camera.position.y -= right.y * (deltaTime * this.flySpeed); + this.camera.position.z -= right.z * (deltaTime * this.flySpeed); } else if(this.moveRight) { - var forward = direction.normalize(); - var right = forward.cross(new this.THREE.Vector3(0, 1, 0)); - var newPos = right; - this.camera.position.x += newPos.x * (deltaTime * this.flySpeed); - this.camera.position.y += newPos.y * (deltaTime * this.flySpeed); - this.camera.position.z += newPos.z * (deltaTime * this.flySpeed); + this.camera.position.x += right.x * (deltaTime * this.flySpeed); + this.camera.position.y += right.y * (deltaTime * this.flySpeed); + this.camera.position.z += right.z * (deltaTime * this.flySpeed); } - // Absolute Y-Axis if(this.moveUp) { this.camera.position.y += (deltaTime * this.flySpeed); @@ -148,11 +142,20 @@ GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) { } }; +/** + * This update function should be called from the animation function in order to apply the 'frame rate independent' + * movement to the camera + * @param deltaTime + */ GameLib.D3.FlyControls.prototype.update = function(deltaTime) { this.applyRotation(); this.applyTranslation(deltaTime); }; +/** + * Rotate on mouse move + * @param event + */ GameLib.D3.FlyControls.prototype.onMouseMove = function ( event ) { if (this.canRotate) { var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; @@ -163,6 +166,10 @@ GameLib.D3.FlyControls.prototype.onMouseMove = function ( event ) { } }; +/** + * Keyboard controls + * @param event + */ GameLib.D3.FlyControls.prototype.onKeyDown = function ( event ) { switch ( event.keyCode ) { @@ -192,6 +199,10 @@ GameLib.D3.FlyControls.prototype.onKeyDown = function ( event ) { } }; +/** + * Keyboard controls + * @param event + */ GameLib.D3.FlyControls.prototype.onKeyUp = function ( event ) { switch ( event.keyCode ) { diff --git a/src/game-lib-heightmap.js b/src/game-lib-heightmap.js index a08ca63..b5ed5c8 100644 --- a/src/game-lib-heightmap.js +++ b/src/game-lib-heightmap.js @@ -1,22 +1,36 @@ -GameLib.D3.HeightmapData = function ( +/** + * + * @param sizeX Number + * @param sizeY Number + * @param matrix matrix 2D Array with height data (Column Major) + * @constructor + */ +GameLib.D3.Heightmap = function( sizeX, sizeY, matrix ) { - this.sizeX = sizeX || 0; - this.sizeY = sizeY || 0; + if (typeof sizeX == 'undefined') { + sizeX = 0; + } + this.sizeX = sizeX; - // 2D Array with height data - // Column-major - this.matrix = matrix || []; + if (typeof sizeY == 'undefined') { + sizeY = 0; + } + this.sizeY = sizeY; + + if (typeof matrix == 'undefined') { + matrix = []; + } + this.matrix = matrix; }; -// Note: this currently only works for cannon! -GameLib.D3.GenerateThreeMeshFromHeightField = function ( - heightFieldShape - // Physics type..... +GameLib.D3.Heightmap.prototype.generateThreeMeshFromHeightField = function( + THREE, + heightFieldShape, + engine ) { - var geometry = new THREE.Geometry(); var v0 = new this.physics.CANNON.Vec3(); @@ -50,7 +64,8 @@ GameLib.D3.GenerateThreeMeshFromHeightField = function ( return new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({ wireframe : false, shading : THREE.SmoothShading })); }; -GameLib.D3.GenerateHeightmapDataFromImage = function ( + +GameLib.D3.Heightmap.prototype.generateHeightmapDataFromImage = function ( imagePath, callback // receives HeightmapData instance as the first argument ) { diff --git a/src/game-lib-world.js b/src/game-lib-world.js index d9f8854..1c008a7 100644 --- a/src/game-lib-world.js +++ b/src/game-lib-world.js @@ -75,16 +75,6 @@ GameLib.D3.World.prototype.createWorldInstance = function() { var cannonBroadphase = null; - if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { - cannonBroadphase = new this.engine.instance.NaiveBroadphase(); - } else if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { - cannonBroadphase = new this.engine.instance.GridBroadphase(); - } else if (this.broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { - cannonBroadphase = new this.engine.instance.SAPBroardphase(); - } else { - console.warn('Unsupported broadphase type: ' + this.broadphase.broadphaseType); - throw new Error('Unsupported broadphase type: ' + this.broadphase.broadphaseType); - } customWorld.broadphase = cannonBroadphase; From d9c4cee85fbf805596a214fcd16775b13601e752 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Tue, 18 Oct 2016 13:37:38 +0200 Subject: [PATCH 10/15] start writing tests --- build/game-lib-min.js | 4 +- build/game-lib.js | 284 ++++++++++++++--------------- config.js | 1 + gulpfile.js | 36 ++++ package.json | 10 +- src/game-lib-material.js | 19 +- src/game-lib-raycast-vehicle.js | 8 +- src/game-lib-rigid-body-vehicle.js | 9 +- src/game-lib-rigid-body.js | 4 +- src/game-lib-texture.js | 1 - src/game-lib-vector-4-points.js | 224 ----------------------- src/game-lib-vector-4.js | 224 +++++++++++++++++++++++ src/game-lib-world.js | 45 ++--- test/test.GameLib.js | 49 +++++ 14 files changed, 506 insertions(+), 412 deletions(-) create mode 120000 config.js delete mode 100644 src/game-lib-vector-4-points.js create mode 100644 test/test.GameLib.js diff --git a/build/game-lib-min.js b/build/game-lib-min.js index 1595b67..afdab8c 100644 --- a/build/game-lib-min.js +++ b/build/game-lib-min.js @@ -1,2 +1,2 @@ -function GameLib(){}"undefined"==typeof GameLib.D3&&(GameLib.D3=function(){}),GameLib.D3.BoneWeight=function(e,i){this.boneIndex=e,this.weight=i},GameLib.D3.Bone=function(e,i,t,n,s,o,a,r,h,l){this.id=e,this.name=t,this.boneId=i,"undefined"==typeof n&&(n=[]),this.childBoneIds=n,"undefined"==typeof s&&(s=null),this.parentBoneId=s,"undefined"==typeof o&&(o=new GameLib.D3.Vector4),this.quaternion=o,"undefined"==typeof a&&(a=new GameLib.D3.Vector3(0,0,0)),this.position=a,"undefined"==typeof r&&(r=new GameLib.D3.Vector3(0,0,0)),this.rotation=r,"undefined"==typeof h&&(h=new GameLib.D3.Vector3(1,1,1)),this.scale=h,"undefined"==typeof l&&(l=new GameLib.D3.Vector3(0,1,0)),this.up=l},GameLib.D3.Broadphase=function(e,i,t,n,s){this.id=e,"undefined"==typeof i&&(i="broadphase-"+t),this.name=i,"undefined"==typeof t&&(t=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=t,"undefined"==typeof n&&(n=null),this.engine=n,this.instance=null,s&&this.createInstance()},GameLib.D3.Broadphase.prototype.createInstance=function(){if(!(this.engine instanceof GameLib.D3.Engine))throw console.warn("No Engine"),new Error("No Engine");this.engine.isNotCannonThrow();var e=null;if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)e=new this.engine.instance.NaiveBroadphase;else if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)e=new this.engine.instance.GridBroadphase;else{if(this.broadphaseType!=GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);e=new this.engine.instance.SAPBroardphase}return this.instance=e,e},GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Color=function(e,i,t,n){this.r=e,this.g=i,this.b=t,this.a=n},GameLib.D3.Engine=function(e,i){this.engineType=e,this.instance=i},GameLib.D3.Engine.prototype.isCannon=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_CANNON},GameLib.D3.Engine.prototype.isNotCannonThrow=function(){if(this.engineType!=GameLib.D3.Engine.ENGINE_TYPE_CANNON)throw console.warn("Only CANNON supported for this function"),new Error("Only CANNON supported for this function")},GameLib.D3.Engine.prototype.isAmmo=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_AMMO},GameLib.D3.Engine.prototype.isGoblin=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_GOBLIN},GameLib.D3.Engine.ENGINE_TYPE_CANNON=1,GameLib.D3.Engine.ENGINE_TYPE_AMMO=2,GameLib.D3.Engine.ENGINE_TYPE_GOBLIN=3,GameLib.D3.FlyControls=function(e,i,t){this.flySpeed=100,this.canvas=t,this.THREE=i,this.yaw=0,this.pitch=0,this.canRotate=!1,this.moveForward=!1,this.moveBackward=!1,this.moveLeft=!1,this.moveRight=!1,this.moveUp=!1,this.moveDown=!1,this.mouseUpCallback=this.onMouseUp.bind(this),this.mouseDownCallback=this.onMouseDown.bind(this),this.mouseMoveCallback=this.onMouseMove.bind(this),this.mouseWheelCallback=this.onMouseWheel.bind(this),this.keyDownCallback=this.onKeyDown.bind(this),this.keyUpCallback=this.onKeyUp.bind(this),this.camera=e,this.canvas.addEventListener("keydown",this.keyDownCallback,!1),this.canvas.addEventListener("keyup",this.keyUpCallback,!1),this.canvas.addEventListener("mousedown",this.mouseDownCallback,!1),this.canvas.addEventListener("mouseup",this.mouseUpCallback,!1),this.canvas.addEventListener("mousewheel",this.mouseWheelCallback,!1),this.havePointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.element=document.body,this.havePointerLock&&(this.element.requestPointerLock=this.element.requestPointerLock||this.element.mozRequestPointerLock||this.element.webkitRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock)},GameLib.D3.FlyControls.prototype.onMouseWheel=function(e){this.moveForward=!0,this.applyTranslation(.001*e.wheelDelta),e.preventDefault(),this.moveForward=!1},GameLib.D3.FlyControls.prototype.onMouseDown=function(e){1==e.button&&(this.canRotate=!0,this.canvas.addEventListener("mousemove",this.mouseMoveCallback,!1))},GameLib.D3.FlyControls.prototype.onMouseUp=function(e){1==e.button&&(this.canRotate=!1,this.canvas.removeEventListener("mousemove",this.mouseMoveCallback))},GameLib.D3.FlyControls.prototype.applyRotation=function(){this.camera.rotation.set(this.pitch,this.yaw,0,"YXZ")},GameLib.D3.FlyControls.prototype.applyTranslation=function(e){var i=new this.THREE.Vector3(0,0,-1),t=new this.THREE.Euler(0,0,0,"YXZ");t.set(this.pitch,this.yaw,0,"YXZ"),i=i.applyEuler(t);var n=i.normalize(),s=n.cross(new this.THREE.Vector3(0,1,0));this.moveForward?(this.camera.position.x+=n.x*(e*this.flySpeed),this.camera.position.y+=n.y*(e*this.flySpeed),this.camera.position.z+=n.z*(e*this.flySpeed)):this.moveBackward&&(this.camera.position.x-=n.x*(e*this.flySpeed),this.camera.position.y-=n.y*(e*this.flySpeed),this.camera.position.z-=n.z*(e*this.flySpeed)),this.moveLeft?(this.camera.position.x-=s.x*(e*this.flySpeed),this.camera.position.y-=s.y*(e*this.flySpeed),this.camera.position.z-=s.z*(e*this.flySpeed)):this.moveRight&&(this.camera.position.x+=s.x*(e*this.flySpeed),this.camera.position.y+=s.y*(e*this.flySpeed),this.camera.position.z+=s.z*(e*this.flySpeed)),this.moveUp?this.camera.position.y+=e*this.flySpeed:this.moveDown&&(this.camera.position.y-=e*this.flySpeed)},GameLib.D3.FlyControls.prototype.update=function(e){this.applyRotation(),this.applyTranslation(e)},GameLib.D3.FlyControls.prototype.onMouseMove=function(e){if(this.canRotate){var i=e.movementX||e.mozMovementX||e.webkitMovementX||0,t=e.movementY||e.mozMovementY||e.webkitMovementY||0;this.yaw-=.002*i,this.pitch-=.002*t}},GameLib.D3.FlyControls.prototype.onKeyDown=function(e){switch(e.keyCode){case 87:this.moveForward=!0;break;case 65:this.moveLeft=!0;break;case 83:this.moveBackward=!0;break;case 68:this.moveRight=!0;break;case 104:this.moveUp=!0;break;case 98:this.moveDown=!0}},GameLib.D3.FlyControls.prototype.onKeyUp=function(e){switch(e.keyCode){case 38:case 87:this.moveForward=!1;break;case 37:case 65:this.moveLeft=!1;break;case 40:case 83:this.moveBackward=!1;break;case 39:case 68:this.moveRight=!1;break;case 104:this.moveUp=!1;break;case 98:this.moveDown=!1}},GameLib.D3.Game=function(){this.scenes={},this.physicsWorlds=[],this.sceneToPhysicsWorldsMap={}},GameLib.D3.Game.prototype.AddScene=function(e){this.scenes[e.name]=e},GameLib.D3.Game.prototype.AddPhysicsWorld=function(e){this.physicsWorlds.push(e)},GameLib.D3.Game.prototype.LinkPhysicsWorldToScene=function(e,i){this.sceneToPhysicsWorldsMap[i.name]=this.sceneToPhysicsWorldsMap[i.name]||[],this.sceneToPhysicsWorldsMap[i.name].push(e)},GameLib.D3.Game.prototype.GetPhysicsWorldsForScene=function(e){return this.sceneToPhysicsWorldsMap[e.name]},GameLib.D3.Game.prototype.ProcessPhysics=function(e){for(var i in this.sceneToPhysicsWorldsMap){var t=this.sceneToPhysicsWorldsMap[i],n=this.scenes[i];if(n&&t)for(var s=0,o=t.length;s0){var s=this.loadMaps(e,n,t);Q.all(s).then(function(){i.resolve(t)}).catch(function(e){console.log(e),i.reject(e)})}else i.resolve(t);return i.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,l,c,p,m,d,y,u,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof l&&(l=[]),this.skinWeights=l,"undefined"==typeof c&&(c=[]),this.materials=c,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(1,1,1)),this.scale=y,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(0,1,0)),this.up=u,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.prototype.createThreeMesh=function(e,i,t){var n=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(n=new this.THREE.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var s=e.skeleton.bones,o=e.skinIndices,a=e.skinWeights,r=[],h=0;h0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var l=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],c=0;c9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var a=0;a0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixY(n),c=0;co&&(o=h.y,n=i*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixX(n),c=0;cn&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n0){var o=this.loadMaps(e,s,n);Q.all(o).then(function(){i.resolve(n)}).catch(function(e){console.log(e),i.reject(e)})}else i.resolve(n);return i.promise},GameLib.D3.Matrix3=function(e,t,i){this.identity(),e&&(this.rows[0]=e),t&&(this.rows[1]=t),i&&(this.rows[2]=i)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,t,i,n){this.identity(),e&&(this.rows[0]=e),t&&(this.rows[1]=t),i&&(this.rows[2]=i),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,t){return this.identity(),this.rotationMatrixX(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.rotateY=function(e,t){return this.identity(),this.rotationMatrixY(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,t){return this.identity(),this.rotationMatrixZ(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,t,i){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(t).normalize();0===s.squared()&&(s.z=1);var o=i.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=i.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,t,i,n,s,o,a,r,h,l,c,p,m,d,y,u,f,b,L,v){this.id=e,this.path=t,this.name=i,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof l&&(l=[]),this.skinWeights=l,"undefined"==typeof c&&(c=[]),this.materials=c,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(1,1,1)),this.scale=y,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(0,1,0)),this.up=u,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.prototype.createThreeMesh=function(e,t,i){var n=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(n=new this.THREE.Mesh(t,i)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var s=e.skeleton.bones,o=e.skinIndices,a=e.skinWeights,r=[],h=0;h0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var l=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],c=0;c9||console.log("The vertices are not in the right length : "+e.length);for(var i=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var a=0;a0},GameLib.D3.Vector3.normal=function(e,t,i){var n=t.copy(),s=i.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,t){var i=GameLib.D3.Matrix4.lookAt(this,e,t);this.multiply(i)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var t=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,i=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=t,this.y=i,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z};GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,t=this.squared();if(to&&(o=h.x,n=t*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixY(n),c=0;co&&(o=h.y,n=t*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixX(n),c=0;cn&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-t),Math.abs(s-i))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,t=0,i=0,n=0;n maxXDistance) { - - maxXDistance = distances.x; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxXDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - -GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) { - -// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); - - var multiplier = 0; - - var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain); - - var totalRadians = 0; - - var backupVectors = this.copy(); - - var maxYDistance = 0; - - for (var i = 0; i < Math.PI * 2; i += grain) { - - multiplier++; - - for (var j = 0; j < this.vectors.length; j++) { - this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); - } - - var distances = this.distances(); - - if (distances.y > maxYDistance) { - maxYDistance = distances.y; - totalRadians = multiplier * grain; - } - } - - this.vectors = backupVectors; - -// console.log("distance: " + maxYDistance + " radians : " + totalRadians); - - var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians); - - for (var k = 0; k < this.vectors.length; k++) { - this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); - } - -// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); - -}; - - -GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) { - - var polyCenter = this.average(); - - console.log("poly center : " + JSON.stringify(polyCenter)); - - var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up); - - lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0); - lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0); - lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0); - - console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); - - for (var i = 0; i < this.vectors.length; i++) { - console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); - this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); - console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); - } -}; - -GameLib.D3.Vector4.Points.prototype.distances = function () { - - var minX = this.vectors[0].x; - var minY = this.vectors[0].y; - var minZ = this.vectors[0].z; - - var maxX = this.vectors[0].x; - var maxY = this.vectors[0].y; - var maxZ = this.vectors[0].z; - - for (var i = 0; i < this.vectors.length; i++) { - if (this.vectors[i].x < minX) { - minX = this.vectors[i].x; - } - if (this.vectors[i].y < minY) { - minY = this.vectors[i].y; - } - if (this.vectors[i].z < minZ) { - minZ = this.vectors[i].z; - } - - if (this.vectors[i].x > maxX) { - maxX = this.vectors[i].x; - } - if (this.vectors[i].y > maxY) { - maxY = this.vectors[i].y; - } - if (this.vectors[i].z > maxZ) { - maxZ = this.vectors[i].z; - } - } - - return new GameLib.D3.Vector3( - Math.abs(maxX - minX), - Math.abs(maxY - minY), - Math.abs(maxY - minZ) - ) -}; - -GameLib.D3.Vector4.Points.prototype.average = function () { - var averageX = 0; - var averageY = 0; - var averageZ = 0; - - for (var i = 0; i < this.vectors.length; i++) { - averageX += this.vectors[i].x; - averageY += this.vectors[i].y; - averageZ += this.vectors[i].z; - } - - return new GameLib.D3.Vector3( - averageX / this.vectors.length, - averageY / this.vectors.length, - averageZ / this.vectors.length - ); -}; - -GameLib.D3.Vector4.Points.prototype.negative = function () { - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].x *= -1; - this.vectors[i].y *= -1; - this.vectors[i].z *= -1; - } - - return this; -}; - - -GameLib.D3.Vector4.Points.prototype.toOrigin = function () { - - var distanceFromOrigin = this.average().negative(); - - for (var i = 0; i < this.vectors.length; i++) { - this.vectors[i].translate(distanceFromOrigin); - } -}; \ No newline at end of file diff --git a/src/game-lib-vector-4.js b/src/game-lib-vector-4.js index 18ee60f..b19eaaf 100644 --- a/src/game-lib-vector-4.js +++ b/src/game-lib-vector-4.js @@ -97,3 +97,227 @@ GameLib.D3.Vector4.prototype.subtract = function (v) { return this; }; +GameLib.D3.Vector4.Points = function () { + this.vectors = []; +}; + +GameLib.D3.Vector4.Points.prototype.add = function (vector) { + + if (vector instanceof GameLib.D3.Vector3) { + vector = new GameLib.D3.Vector4( + vector.x, + vector.y, + vector.z, + 1 + ) + } + + if (!vector instanceof GameLib.D3.Vector4) { + console.warn("Vector needs to be of type Vector4"); + throw new Error("Vector needs to be of type Vector4"); + } + + this.vectors.push(vector); + + return this; +}; + +GameLib.D3.Vector4.Points.prototype.copy = function () { + + var vectors = []; + + for (var i = 0; i < this.vectors.length; i++) { + vectors.push(this.vectors[i].copy()); + } + + return vectors; +}; + +GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxXDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.x > maxXDistance) { + + maxXDistance = distances.x; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxXDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + +GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) { + +// console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2)); + + var multiplier = 0; + + var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain); + + var totalRadians = 0; + + var backupVectors = this.copy(); + + var maxYDistance = 0; + + for (var i = 0; i < Math.PI * 2; i += grain) { + + multiplier++; + + for (var j = 0; j < this.vectors.length; j++) { + this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]); + } + + var distances = this.distances(); + + if (distances.y > maxYDistance) { + maxYDistance = distances.y; + totalRadians = multiplier * grain; + } + } + + this.vectors = backupVectors; + +// console.log("distance: " + maxYDistance + " radians : " + totalRadians); + + var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians); + + for (var k = 0; k < this.vectors.length; k++) { + this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]); + } + +// console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2)); + +}; + + +GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) { + + var polyCenter = this.average(); + + console.log("poly center : " + JSON.stringify(polyCenter)); + + var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up); + + lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0); + lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0); + lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0); + + console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2)); + + for (var i = 0; i < this.vectors.length; i++) { + console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i])); + this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]); + console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i])); + } +}; + +GameLib.D3.Vector4.Points.prototype.distances = function () { + + var minX = this.vectors[0].x; + var minY = this.vectors[0].y; + var minZ = this.vectors[0].z; + + var maxX = this.vectors[0].x; + var maxY = this.vectors[0].y; + var maxZ = this.vectors[0].z; + + for (var i = 0; i < this.vectors.length; i++) { + if (this.vectors[i].x < minX) { + minX = this.vectors[i].x; + } + if (this.vectors[i].y < minY) { + minY = this.vectors[i].y; + } + if (this.vectors[i].z < minZ) { + minZ = this.vectors[i].z; + } + + if (this.vectors[i].x > maxX) { + maxX = this.vectors[i].x; + } + if (this.vectors[i].y > maxY) { + maxY = this.vectors[i].y; + } + if (this.vectors[i].z > maxZ) { + maxZ = this.vectors[i].z; + } + } + + return new GameLib.D3.Vector3( + Math.abs(maxX - minX), + Math.abs(maxY - minY), + Math.abs(maxY - minZ) + ) +}; + +GameLib.D3.Vector4.Points.prototype.average = function () { + var averageX = 0; + var averageY = 0; + var averageZ = 0; + + for (var i = 0; i < this.vectors.length; i++) { + averageX += this.vectors[i].x; + averageY += this.vectors[i].y; + averageZ += this.vectors[i].z; + } + + return new GameLib.D3.Vector3( + averageX / this.vectors.length, + averageY / this.vectors.length, + averageZ / this.vectors.length + ); +}; + +GameLib.D3.Vector4.Points.prototype.negative = function () { + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].x *= -1; + this.vectors[i].y *= -1; + this.vectors[i].z *= -1; + } + + return this; +}; + + +GameLib.D3.Vector4.Points.prototype.toOrigin = function () { + + var distanceFromOrigin = this.average().negative(); + + for (var i = 0; i < this.vectors.length; i++) { + this.vectors[i].translate(distanceFromOrigin); + } +}; diff --git a/src/game-lib-world.js b/src/game-lib-world.js index 1c008a7..a0a387f 100644 --- a/src/game-lib-world.js +++ b/src/game-lib-world.js @@ -105,7 +105,7 @@ GameLib.D3.World.prototype.createWorldInstance = function() { return customWorld; }; -GameLib.D3.Physics.World.prototype.AddShape = function( +GameLib.D3.World.prototype.AddShape = function( shape, // d3.physics.shape rigidBody, offset, // vec3 @@ -133,11 +133,11 @@ GameLib.D3.Physics.World.prototype.AddShape = function( } }; -GameLib.D3.Physics.World.prototype.Wheel = function() { +GameLib.D3.World.prototype.Wheel = function() { }; -GameLib.D3.Physics.World.prototype.CreateRigidVehicle = function( +GameLib.D3.World.prototype.CreateRigidVehicle = function( chassisBody // Physics.RigidBody ) { var rigidVehicle = new GameLib.D3.Physics.RigidVehicle(); @@ -151,7 +151,7 @@ GameLib.D3.Physics.World.prototype.CreateRigidVehicle = function( } }; -GameLib.D3.Physics.World.prototype.CreateRaycastVehicle = function( +GameLib.D3.World.prototype.CreateRaycastVehicle = function( chassisBody // Physics.RigidBody ) { var raycastVehicle = new GameLib.D3.Physics.RaycastVehicle(); @@ -165,7 +165,7 @@ GameLib.D3.Physics.World.prototype.CreateRaycastVehicle = function( } }; -GameLib.D3.Physics.World.prototype.AddWheelToRigidVehicle = function( +GameLib.D3.World.prototype.AddWheelToRigidVehicle = function( vehicle, rigidBody, position, @@ -182,7 +182,7 @@ GameLib.D3.Physics.World.prototype.AddWheelToRigidVehicle = function( } }; -GameLib.D3.Physics.World.prototype.AddWheelToRaycastVehicle = function ( +GameLib.D3.World.prototype.AddWheelToRaycastVehicle = function ( vehicle, // physics.raycastvehicle options // cannon options ) { @@ -193,22 +193,9 @@ GameLib.D3.Physics.World.prototype.AddWheelToRaycastVehicle = function ( } }; -GameLib.D3.Physics.World.prototype.RigidVehicle.prototype.GetWheelInfo = function( - -) { - // note: need a way to determine which engine we are currently using - return this.vehicleObject.wheelBodies; -}; - -GameLib.D3.Physics.World.prototype.RaycastVehicle.prototype.GetWheelInfo = function( - -) { - // note: need a way to determine which engine we are currently using - return this.vehicleObject.wheelInfos; -}; -GameLib.D3.Physics.World.prototype.CreateTriMeshShape = function( +GameLib.D3.World.prototype.CreateTriMeshShape = function( vertices, // flat list of floats indices // flat list of floats ) { @@ -217,7 +204,7 @@ GameLib.D3.Physics.World.prototype.CreateTriMeshShape = function( } }; -GameLib.D3.Physics.World.prototype.CreateSphereShape = function ( +GameLib.D3.World.prototype.CreateSphereShape = function ( radius ) { if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { @@ -225,7 +212,7 @@ GameLib.D3.Physics.World.prototype.CreateSphereShape = function ( } }; -GameLib.D3.Physics.World.prototype.CreateBoxShape = function( +GameLib.D3.World.prototype.CreateBoxShape = function( halfExtensions // vec3 ) { if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { @@ -233,7 +220,7 @@ GameLib.D3.Physics.World.prototype.CreateBoxShape = function( } }; -GameLib.D3.Physics.World.prototype.CreateCylinderShape = function( +GameLib.D3.World.prototype.CreateCylinderShape = function( radiusTop, radiusBottom, height, @@ -244,7 +231,7 @@ GameLib.D3.Physics.World.prototype.CreateCylinderShape = function( } }; -GameLib.D3.Physics.World.prototype.AddRigidBody = function( +GameLib.D3.World.prototype.AddRigidBody = function( rigidBody // Physics.RigidBody ) { if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) { @@ -252,7 +239,7 @@ GameLib.D3.Physics.World.prototype.AddRigidBody = function( } }; -GameLib.D3.Physics.World.prototype.AddVehicle = function( +GameLib.D3.World.prototype.AddVehicle = function( vehicle // note: physics.vehicle ) { if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { @@ -260,7 +247,7 @@ GameLib.D3.Physics.World.prototype.AddVehicle = function( } }; -GameLib.D3.Physics.World.prototype.Step = function( +GameLib.D3.World.prototype.Step = function( timeStep ) { if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) { @@ -286,7 +273,7 @@ GameLib.D3.Physics.World.prototype.Step = function( } }; -GameLib.D3.Physics.World.prototype.GetIndexedVertices = function( +GameLib.D3.World.prototype.GetIndexedVertices = function( triangleMeshShape ) { @@ -304,7 +291,7 @@ GameLib.D3.Physics.World.prototype.GetIndexedVertices = function( }; -GameLib.D3.Physics.World.prototype.GenerateWireframeViewMesh = function( +GameLib.D3.World.prototype.GenerateWireframeViewMesh = function( triangleMeshShape, normalLength, scale, @@ -363,7 +350,7 @@ GameLib.D3.Physics.World.prototype.GenerateWireframeViewMesh = function( return wireframeTHREEMesh; }; -GameLib.D3.Physics.World.prototype.GenerateTriangleCollisionMesh = function( +GameLib.D3.World.prototype.GenerateTriangleCollisionMesh = function( threeMesh, mass, // default = 0 friction, // default = 10 diff --git a/test/test.GameLib.js b/test/test.GameLib.js new file mode 100644 index 0000000..af1d51d --- /dev/null +++ b/test/test.GameLib.js @@ -0,0 +1,49 @@ +var chai = require('chai'), + sinon = require("sinon"), + sinonChai = require("sinon-chai"), + config = require('../config.js'), + assert = chai.assert, + GameLib = require('../build/game-lib'); + +chai.use(sinonChai); + +describe('Bone', function(){ + + this.timeout(0); + + before(function(){ + + }); + + after(function(){ + + }); + + beforeEach(function(done) { + done(); + }); + + afterEach(function(done){ + done(); + }); + + it('Should create a Bone object', function (done) { + + var bone = new GameLib.D3.Bone( + null, + 1, + 'test bone 1', + [2, 3, 4] + ); + + assert(bone.position instanceof GameLib.D3.Vector3); + assert(bone.rotation instanceof GameLib.D3.Vector3); + assert(bone.scale instanceof GameLib.D3.Vector3); + assert(bone.up instanceof GameLib.D3.Vector3); + assert(bone.quaternion instanceof GameLib.D3.Vector4); + assert(bone.parentBoneId == null); + assert.deepEqual(bone.childBoneIds, [2,3,4]); + + done(); + }); +}); \ No newline at end of file From 3281faf67ac1de82b13437a39d54995b21780ff6 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Tue, 18 Oct 2016 13:49:03 +0200 Subject: [PATCH 11/15] include code coverage reports --- build/coverage/lcov-report/base.css | 213 + .../lcov-report/build/game-lib.js.html | 14066 ++++++++++++++++ build/coverage/lcov-report/build/index.html | 93 + build/coverage/lcov-report/index.html | 93 + build/coverage/lcov-report/prettify.css | 1 + build/coverage/lcov-report/prettify.js | 1 + .../lcov-report/sort-arrow-sprite.png | Bin 0 -> 209 bytes build/coverage/lcov-report/sorter.js | 158 + build/coverage/lcov.info | 2743 +++ gulpfile.js | 8 +- 10 files changed, 17374 insertions(+), 2 deletions(-) create mode 100644 build/coverage/lcov-report/base.css create mode 100644 build/coverage/lcov-report/build/game-lib.js.html create mode 100644 build/coverage/lcov-report/build/index.html create mode 100644 build/coverage/lcov-report/index.html create mode 100644 build/coverage/lcov-report/prettify.css create mode 100644 build/coverage/lcov-report/prettify.js create mode 100644 build/coverage/lcov-report/sort-arrow-sprite.png create mode 100644 build/coverage/lcov-report/sorter.js create mode 100644 build/coverage/lcov.info diff --git a/build/coverage/lcov-report/base.css b/build/coverage/lcov-report/base.css new file mode 100644 index 0000000..29737bc --- /dev/null +++ b/build/coverage/lcov-report/base.css @@ -0,0 +1,213 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.medium .chart { border:1px solid #f9cd0b; } +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } +/* light gray */ +span.cline-neutral { background: #eaeaea; } + +.cbranch-no { background: yellow !important; color: #111; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/build/coverage/lcov-report/build/game-lib.js.html b/build/coverage/lcov-report/build/game-lib.js.html new file mode 100644 index 0000000..a69c4c0 --- /dev/null +++ b/build/coverage/lcov-report/build/game-lib.js.html @@ -0,0 +1,14066 @@ + + + + Code coverage report for build/game-lib.js + + + + + + + +
+
+

+ all files / build/ game-lib.js +

+
+
+ 16.22% + Statements + 283/1745 +
+
+ 2.87% + Branches + 20/697 +
+
+ 2.05% + Functions + 3/146 +
+
+ 16.22% + Lines + 283/1745 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +653 +654 +655 +656 +657 +658 +659 +660 +661 +662 +663 +664 +665 +666 +667 +668 +669 +670 +671 +672 +673 +674 +675 +676 +677 +678 +679 +680 +681 +682 +683 +684 +685 +686 +687 +688 +689 +690 +691 +692 +693 +694 +695 +696 +697 +698 +699 +700 +701 +702 +703 +704 +705 +706 +707 +708 +709 +710 +711 +712 +713 +714 +715 +716 +717 +718 +719 +720 +721 +722 +723 +724 +725 +726 +727 +728 +729 +730 +731 +732 +733 +734 +735 +736 +737 +738 +739 +740 +741 +742 +743 +744 +745 +746 +747 +748 +749 +750 +751 +752 +753 +754 +755 +756 +757 +758 +759 +760 +761 +762 +763 +764 +765 +766 +767 +768 +769 +770 +771 +772 +773 +774 +775 +776 +777 +778 +779 +780 +781 +782 +783 +784 +785 +786 +787 +788 +789 +790 +791 +792 +793 +794 +795 +796 +797 +798 +799 +800 +801 +802 +803 +804 +805 +806 +807 +808 +809 +810 +811 +812 +813 +814 +815 +816 +817 +818 +819 +820 +821 +822 +823 +824 +825 +826 +827 +828 +829 +830 +831 +832 +833 +834 +835 +836 +837 +838 +839 +840 +841 +842 +843 +844 +845 +846 +847 +848 +849 +850 +851 +852 +853 +854 +855 +856 +857 +858 +859 +860 +861 +862 +863 +864 +865 +866 +867 +868 +869 +870 +871 +872 +873 +874 +875 +876 +877 +878 +879 +880 +881 +882 +883 +884 +885 +886 +887 +888 +889 +890 +891 +892 +893 +894 +895 +896 +897 +898 +899 +900 +901 +902 +903 +904 +905 +906 +907 +908 +909 +910 +911 +912 +913 +914 +915 +916 +917 +918 +919 +920 +921 +922 +923 +924 +925 +926 +927 +928 +929 +930 +931 +932 +933 +934 +935 +936 +937 +938 +939 +940 +941 +942 +943 +944 +945 +946 +947 +948 +949 +950 +951 +952 +953 +954 +955 +956 +957 +958 +959 +960 +961 +962 +963 +964 +965 +966 +967 +968 +969 +970 +971 +972 +973 +974 +975 +976 +977 +978 +979 +980 +981 +982 +983 +984 +985 +986 +987 +988 +989 +990 +991 +992 +993 +994 +995 +996 +997 +998 +999 +1000 +1001 +1002 +1003 +1004 +1005 +1006 +1007 +1008 +1009 +1010 +1011 +1012 +1013 +1014 +1015 +1016 +1017 +1018 +1019 +1020 +1021 +1022 +1023 +1024 +1025 +1026 +1027 +1028 +1029 +1030 +1031 +1032 +1033 +1034 +1035 +1036 +1037 +1038 +1039 +1040 +1041 +1042 +1043 +1044 +1045 +1046 +1047 +1048 +1049 +1050 +1051 +1052 +1053 +1054 +1055 +1056 +1057 +1058 +1059 +1060 +1061 +1062 +1063 +1064 +1065 +1066 +1067 +1068 +1069 +1070 +1071 +1072 +1073 +1074 +1075 +1076 +1077 +1078 +1079 +1080 +1081 +1082 +1083 +1084 +1085 +1086 +1087 +1088 +1089 +1090 +1091 +1092 +1093 +1094 +1095 +1096 +1097 +1098 +1099 +1100 +1101 +1102 +1103 +1104 +1105 +1106 +1107 +1108 +1109 +1110 +1111 +1112 +1113 +1114 +1115 +1116 +1117 +1118 +1119 +1120 +1121 +1122 +1123 +1124 +1125 +1126 +1127 +1128 +1129 +1130 +1131 +1132 +1133 +1134 +1135 +1136 +1137 +1138 +1139 +1140 +1141 +1142 +1143 +1144 +1145 +1146 +1147 +1148 +1149 +1150 +1151 +1152 +1153 +1154 +1155 +1156 +1157 +1158 +1159 +1160 +1161 +1162 +1163 +1164 +1165 +1166 +1167 +1168 +1169 +1170 +1171 +1172 +1173 +1174 +1175 +1176 +1177 +1178 +1179 +1180 +1181 +1182 +1183 +1184 +1185 +1186 +1187 +1188 +1189 +1190 +1191 +1192 +1193 +1194 +1195 +1196 +1197 +1198 +1199 +1200 +1201 +1202 +1203 +1204 +1205 +1206 +1207 +1208 +1209 +1210 +1211 +1212 +1213 +1214 +1215 +1216 +1217 +1218 +1219 +1220 +1221 +1222 +1223 +1224 +1225 +1226 +1227 +1228 +1229 +1230 +1231 +1232 +1233 +1234 +1235 +1236 +1237 +1238 +1239 +1240 +1241 +1242 +1243 +1244 +1245 +1246 +1247 +1248 +1249 +1250 +1251 +1252 +1253 +1254 +1255 +1256 +1257 +1258 +1259 +1260 +1261 +1262 +1263 +1264 +1265 +1266 +1267 +1268 +1269 +1270 +1271 +1272 +1273 +1274 +1275 +1276 +1277 +1278 +1279 +1280 +1281 +1282 +1283 +1284 +1285 +1286 +1287 +1288 +1289 +1290 +1291 +1292 +1293 +1294 +1295 +1296 +1297 +1298 +1299 +1300 +1301 +1302 +1303 +1304 +1305 +1306 +1307 +1308 +1309 +1310 +1311 +1312 +1313 +1314 +1315 +1316 +1317 +1318 +1319 +1320 +1321 +1322 +1323 +1324 +1325 +1326 +1327 +1328 +1329 +1330 +1331 +1332 +1333 +1334 +1335 +1336 +1337 +1338 +1339 +1340 +1341 +1342 +1343 +1344 +1345 +1346 +1347 +1348 +1349 +1350 +1351 +1352 +1353 +1354 +1355 +1356 +1357 +1358 +1359 +1360 +1361 +1362 +1363 +1364 +1365 +1366 +1367 +1368 +1369 +1370 +1371 +1372 +1373 +1374 +1375 +1376 +1377 +1378 +1379 +1380 +1381 +1382 +1383 +1384 +1385 +1386 +1387 +1388 +1389 +1390 +1391 +1392 +1393 +1394 +1395 +1396 +1397 +1398 +1399 +1400 +1401 +1402 +1403 +1404 +1405 +1406 +1407 +1408 +1409 +1410 +1411 +1412 +1413 +1414 +1415 +1416 +1417 +1418 +1419 +1420 +1421 +1422 +1423 +1424 +1425 +1426 +1427 +1428 +1429 +1430 +1431 +1432 +1433 +1434 +1435 +1436 +1437 +1438 +1439 +1440 +1441 +1442 +1443 +1444 +1445 +1446 +1447 +1448 +1449 +1450 +1451 +1452 +1453 +1454 +1455 +1456 +1457 +1458 +1459 +1460 +1461 +1462 +1463 +1464 +1465 +1466 +1467 +1468 +1469 +1470 +1471 +1472 +1473 +1474 +1475 +1476 +1477 +1478 +1479 +1480 +1481 +1482 +1483 +1484 +1485 +1486 +1487 +1488 +1489 +1490 +1491 +1492 +1493 +1494 +1495 +1496 +1497 +1498 +1499 +1500 +1501 +1502 +1503 +1504 +1505 +1506 +1507 +1508 +1509 +1510 +1511 +1512 +1513 +1514 +1515 +1516 +1517 +1518 +1519 +1520 +1521 +1522 +1523 +1524 +1525 +1526 +1527 +1528 +1529 +1530 +1531 +1532 +1533 +1534 +1535 +1536 +1537 +1538 +1539 +1540 +1541 +1542 +1543 +1544 +1545 +1546 +1547 +1548 +1549 +1550 +1551 +1552 +1553 +1554 +1555 +1556 +1557 +1558 +1559 +1560 +1561 +1562 +1563 +1564 +1565 +1566 +1567 +1568 +1569 +1570 +1571 +1572 +1573 +1574 +1575 +1576 +1577 +1578 +1579 +1580 +1581 +1582 +1583 +1584 +1585 +1586 +1587 +1588 +1589 +1590 +1591 +1592 +1593 +1594 +1595 +1596 +1597 +1598 +1599 +1600 +1601 +1602 +1603 +1604 +1605 +1606 +1607 +1608 +1609 +1610 +1611 +1612 +1613 +1614 +1615 +1616 +1617 +1618 +1619 +1620 +1621 +1622 +1623 +1624 +1625 +1626 +1627 +1628 +1629 +1630 +1631 +1632 +1633 +1634 +1635 +1636 +1637 +1638 +1639 +1640 +1641 +1642 +1643 +1644 +1645 +1646 +1647 +1648 +1649 +1650 +1651 +1652 +1653 +1654 +1655 +1656 +1657 +1658 +1659 +1660 +1661 +1662 +1663 +1664 +1665 +1666 +1667 +1668 +1669 +1670 +1671 +1672 +1673 +1674 +1675 +1676 +1677 +1678 +1679 +1680 +1681 +1682 +1683 +1684 +1685 +1686 +1687 +1688 +1689 +1690 +1691 +1692 +1693 +1694 +1695 +1696 +1697 +1698 +1699 +1700 +1701 +1702 +1703 +1704 +1705 +1706 +1707 +1708 +1709 +1710 +1711 +1712 +1713 +1714 +1715 +1716 +1717 +1718 +1719 +1720 +1721 +1722 +1723 +1724 +1725 +1726 +1727 +1728 +1729 +1730 +1731 +1732 +1733 +1734 +1735 +1736 +1737 +1738 +1739 +1740 +1741 +1742 +1743 +1744 +1745 +1746 +1747 +1748 +1749 +1750 +1751 +1752 +1753 +1754 +1755 +1756 +1757 +1758 +1759 +1760 +1761 +1762 +1763 +1764 +1765 +1766 +1767 +1768 +1769 +1770 +1771 +1772 +1773 +1774 +1775 +1776 +1777 +1778 +1779 +1780 +1781 +1782 +1783 +1784 +1785 +1786 +1787 +1788 +1789 +1790 +1791 +1792 +1793 +1794 +1795 +1796 +1797 +1798 +1799 +1800 +1801 +1802 +1803 +1804 +1805 +1806 +1807 +1808 +1809 +1810 +1811 +1812 +1813 +1814 +1815 +1816 +1817 +1818 +1819 +1820 +1821 +1822 +1823 +1824 +1825 +1826 +1827 +1828 +1829 +1830 +1831 +1832 +1833 +1834 +1835 +1836 +1837 +1838 +1839 +1840 +1841 +1842 +1843 +1844 +1845 +1846 +1847 +1848 +1849 +1850 +1851 +1852 +1853 +1854 +1855 +1856 +1857 +1858 +1859 +1860 +1861 +1862 +1863 +1864 +1865 +1866 +1867 +1868 +1869 +1870 +1871 +1872 +1873 +1874 +1875 +1876 +1877 +1878 +1879 +1880 +1881 +1882 +1883 +1884 +1885 +1886 +1887 +1888 +1889 +1890 +1891 +1892 +1893 +1894 +1895 +1896 +1897 +1898 +1899 +1900 +1901 +1902 +1903 +1904 +1905 +1906 +1907 +1908 +1909 +1910 +1911 +1912 +1913 +1914 +1915 +1916 +1917 +1918 +1919 +1920 +1921 +1922 +1923 +1924 +1925 +1926 +1927 +1928 +1929 +1930 +1931 +1932 +1933 +1934 +1935 +1936 +1937 +1938 +1939 +1940 +1941 +1942 +1943 +1944 +1945 +1946 +1947 +1948 +1949 +1950 +1951 +1952 +1953 +1954 +1955 +1956 +1957 +1958 +1959 +1960 +1961 +1962 +1963 +1964 +1965 +1966 +1967 +1968 +1969 +1970 +1971 +1972 +1973 +1974 +1975 +1976 +1977 +1978 +1979 +1980 +1981 +1982 +1983 +1984 +1985 +1986 +1987 +1988 +1989 +1990 +1991 +1992 +1993 +1994 +1995 +1996 +1997 +1998 +1999 +2000 +2001 +2002 +2003 +2004 +2005 +2006 +2007 +2008 +2009 +2010 +2011 +2012 +2013 +2014 +2015 +2016 +2017 +2018 +2019 +2020 +2021 +2022 +2023 +2024 +2025 +2026 +2027 +2028 +2029 +2030 +2031 +2032 +2033 +2034 +2035 +2036 +2037 +2038 +2039 +2040 +2041 +2042 +2043 +2044 +2045 +2046 +2047 +2048 +2049 +2050 +2051 +2052 +2053 +2054 +2055 +2056 +2057 +2058 +2059 +2060 +2061 +2062 +2063 +2064 +2065 +2066 +2067 +2068 +2069 +2070 +2071 +2072 +2073 +2074 +2075 +2076 +2077 +2078 +2079 +2080 +2081 +2082 +2083 +2084 +2085 +2086 +2087 +2088 +2089 +2090 +2091 +2092 +2093 +2094 +2095 +2096 +2097 +2098 +2099 +2100 +2101 +2102 +2103 +2104 +2105 +2106 +2107 +2108 +2109 +2110 +2111 +2112 +2113 +2114 +2115 +2116 +2117 +2118 +2119 +2120 +2121 +2122 +2123 +2124 +2125 +2126 +2127 +2128 +2129 +2130 +2131 +2132 +2133 +2134 +2135 +2136 +2137 +2138 +2139 +2140 +2141 +2142 +2143 +2144 +2145 +2146 +2147 +2148 +2149 +2150 +2151 +2152 +2153 +2154 +2155 +2156 +2157 +2158 +2159 +2160 +2161 +2162 +2163 +2164 +2165 +2166 +2167 +2168 +2169 +2170 +2171 +2172 +2173 +2174 +2175 +2176 +2177 +2178 +2179 +2180 +2181 +2182 +2183 +2184 +2185 +2186 +2187 +2188 +2189 +2190 +2191 +2192 +2193 +2194 +2195 +2196 +2197 +2198 +2199 +2200 +2201 +2202 +2203 +2204 +2205 +2206 +2207 +2208 +2209 +2210 +2211 +2212 +2213 +2214 +2215 +2216 +2217 +2218 +2219 +2220 +2221 +2222 +2223 +2224 +2225 +2226 +2227 +2228 +2229 +2230 +2231 +2232 +2233 +2234 +2235 +2236 +2237 +2238 +2239 +2240 +2241 +2242 +2243 +2244 +2245 +2246 +2247 +2248 +2249 +2250 +2251 +2252 +2253 +2254 +2255 +2256 +2257 +2258 +2259 +2260 +2261 +2262 +2263 +2264 +2265 +2266 +2267 +2268 +2269 +2270 +2271 +2272 +2273 +2274 +2275 +2276 +2277 +2278 +2279 +2280 +2281 +2282 +2283 +2284 +2285 +2286 +2287 +2288 +2289 +2290 +2291 +2292 +2293 +2294 +2295 +2296 +2297 +2298 +2299 +2300 +2301 +2302 +2303 +2304 +2305 +2306 +2307 +2308 +2309 +2310 +2311 +2312 +2313 +2314 +2315 +2316 +2317 +2318 +2319 +2320 +2321 +2322 +2323 +2324 +2325 +2326 +2327 +2328 +2329 +2330 +2331 +2332 +2333 +2334 +2335 +2336 +2337 +2338 +2339 +2340 +2341 +2342 +2343 +2344 +2345 +2346 +2347 +2348 +2349 +2350 +2351 +2352 +2353 +2354 +2355 +2356 +2357 +2358 +2359 +2360 +2361 +2362 +2363 +2364 +2365 +2366 +2367 +2368 +2369 +2370 +2371 +2372 +2373 +2374 +2375 +2376 +2377 +2378 +2379 +2380 +2381 +2382 +2383 +2384 +2385 +2386 +2387 +2388 +2389 +2390 +2391 +2392 +2393 +2394 +2395 +2396 +2397 +2398 +2399 +2400 +2401 +2402 +2403 +2404 +2405 +2406 +2407 +2408 +2409 +2410 +2411 +2412 +2413 +2414 +2415 +2416 +2417 +2418 +2419 +2420 +2421 +2422 +2423 +2424 +2425 +2426 +2427 +2428 +2429 +2430 +2431 +2432 +2433 +2434 +2435 +2436 +2437 +2438 +2439 +2440 +2441 +2442 +2443 +2444 +2445 +2446 +2447 +2448 +2449 +2450 +2451 +2452 +2453 +2454 +2455 +2456 +2457 +2458 +2459 +2460 +2461 +2462 +2463 +2464 +2465 +2466 +2467 +2468 +2469 +2470 +2471 +2472 +2473 +2474 +2475 +2476 +2477 +2478 +2479 +2480 +2481 +2482 +2483 +2484 +2485 +2486 +2487 +2488 +2489 +2490 +2491 +2492 +2493 +2494 +2495 +2496 +2497 +2498 +2499 +2500 +2501 +2502 +2503 +2504 +2505 +2506 +2507 +2508 +2509 +2510 +2511 +2512 +2513 +2514 +2515 +2516 +2517 +2518 +2519 +2520 +2521 +2522 +2523 +2524 +2525 +2526 +2527 +2528 +2529 +2530 +2531 +2532 +2533 +2534 +2535 +2536 +2537 +2538 +2539 +2540 +2541 +2542 +2543 +2544 +2545 +2546 +2547 +2548 +2549 +2550 +2551 +2552 +2553 +2554 +2555 +2556 +2557 +2558 +2559 +2560 +2561 +2562 +2563 +2564 +2565 +2566 +2567 +2568 +2569 +2570 +2571 +2572 +2573 +2574 +2575 +2576 +2577 +2578 +2579 +2580 +2581 +2582 +2583 +2584 +2585 +2586 +2587 +2588 +2589 +2590 +2591 +2592 +2593 +2594 +2595 +2596 +2597 +2598 +2599 +2600 +2601 +2602 +2603 +2604 +2605 +2606 +2607 +2608 +2609 +2610 +2611 +2612 +2613 +2614 +2615 +2616 +2617 +2618 +2619 +2620 +2621 +2622 +2623 +2624 +2625 +2626 +2627 +2628 +2629 +2630 +2631 +2632 +2633 +2634 +2635 +2636 +2637 +2638 +2639 +2640 +2641 +2642 +2643 +2644 +2645 +2646 +2647 +2648 +2649 +2650 +2651 +2652 +2653 +2654 +2655 +2656 +2657 +2658 +2659 +2660 +2661 +2662 +2663 +2664 +2665 +2666 +2667 +2668 +2669 +2670 +2671 +2672 +2673 +2674 +2675 +2676 +2677 +2678 +2679 +2680 +2681 +2682 +2683 +2684 +2685 +2686 +2687 +2688 +2689 +2690 +2691 +2692 +2693 +2694 +2695 +2696 +2697 +2698 +2699 +2700 +2701 +2702 +2703 +2704 +2705 +2706 +2707 +2708 +2709 +2710 +2711 +2712 +2713 +2714 +2715 +2716 +2717 +2718 +2719 +2720 +2721 +2722 +2723 +2724 +2725 +2726 +2727 +2728 +2729 +2730 +2731 +2732 +2733 +2734 +2735 +2736 +2737 +2738 +2739 +2740 +2741 +2742 +2743 +2744 +2745 +2746 +2747 +2748 +2749 +2750 +2751 +2752 +2753 +2754 +2755 +2756 +2757 +2758 +2759 +2760 +2761 +2762 +2763 +2764 +2765 +2766 +2767 +2768 +2769 +2770 +2771 +2772 +2773 +2774 +2775 +2776 +2777 +2778 +2779 +2780 +2781 +2782 +2783 +2784 +2785 +2786 +2787 +2788 +2789 +2790 +2791 +2792 +2793 +2794 +2795 +2796 +2797 +2798 +2799 +2800 +2801 +2802 +2803 +2804 +2805 +2806 +2807 +2808 +2809 +2810 +2811 +2812 +2813 +2814 +2815 +2816 +2817 +2818 +2819 +2820 +2821 +2822 +2823 +2824 +2825 +2826 +2827 +2828 +2829 +2830 +2831 +2832 +2833 +2834 +2835 +2836 +2837 +2838 +2839 +2840 +2841 +2842 +2843 +2844 +2845 +2846 +2847 +2848 +2849 +2850 +2851 +2852 +2853 +2854 +2855 +2856 +2857 +2858 +2859 +2860 +2861 +2862 +2863 +2864 +2865 +2866 +2867 +2868 +2869 +2870 +2871 +2872 +2873 +2874 +2875 +2876 +2877 +2878 +2879 +2880 +2881 +2882 +2883 +2884 +2885 +2886 +2887 +2888 +2889 +2890 +2891 +2892 +2893 +2894 +2895 +2896 +2897 +2898 +2899 +2900 +2901 +2902 +2903 +2904 +2905 +2906 +2907 +2908 +2909 +2910 +2911 +2912 +2913 +2914 +2915 +2916 +2917 +2918 +2919 +2920 +2921 +2922 +2923 +2924 +2925 +2926 +2927 +2928 +2929 +2930 +2931 +2932 +2933 +2934 +2935 +2936 +2937 +2938 +2939 +2940 +2941 +2942 +2943 +2944 +2945 +2946 +2947 +2948 +2949 +2950 +2951 +2952 +2953 +2954 +2955 +2956 +2957 +2958 +2959 +2960 +2961 +2962 +2963 +2964 +2965 +2966 +2967 +2968 +2969 +2970 +2971 +2972 +2973 +2974 +2975 +2976 +2977 +2978 +2979 +2980 +2981 +2982 +2983 +2984 +2985 +2986 +2987 +2988 +2989 +2990 +2991 +2992 +2993 +2994 +2995 +2996 +2997 +2998 +2999 +3000 +3001 +3002 +3003 +3004 +3005 +3006 +3007 +3008 +3009 +3010 +3011 +3012 +3013 +3014 +3015 +3016 +3017 +3018 +3019 +3020 +3021 +3022 +3023 +3024 +3025 +3026 +3027 +3028 +3029 +3030 +3031 +3032 +3033 +3034 +3035 +3036 +3037 +3038 +3039 +3040 +3041 +3042 +3043 +3044 +3045 +3046 +3047 +3048 +3049 +3050 +3051 +3052 +3053 +3054 +3055 +3056 +3057 +3058 +3059 +3060 +3061 +3062 +3063 +3064 +3065 +3066 +3067 +3068 +3069 +3070 +3071 +3072 +3073 +3074 +3075 +3076 +3077 +3078 +3079 +3080 +3081 +3082 +3083 +3084 +3085 +3086 +3087 +3088 +3089 +3090 +3091 +3092 +3093 +3094 +3095 +3096 +3097 +3098 +3099 +3100 +3101 +3102 +3103 +3104 +3105 +3106 +3107 +3108 +3109 +3110 +3111 +3112 +3113 +3114 +3115 +3116 +3117 +3118 +3119 +3120 +3121 +3122 +3123 +3124 +3125 +3126 +3127 +3128 +3129 +3130 +3131 +3132 +3133 +3134 +3135 +3136 +3137 +3138 +3139 +3140 +3141 +3142 +3143 +3144 +3145 +3146 +3147 +3148 +3149 +3150 +3151 +3152 +3153 +3154 +3155 +3156 +3157 +3158 +3159 +3160 +3161 +3162 +3163 +3164 +3165 +3166 +3167 +3168 +3169 +3170 +3171 +3172 +3173 +3174 +3175 +3176 +3177 +3178 +3179 +3180 +3181 +3182 +3183 +3184 +3185 +3186 +3187 +3188 +3189 +3190 +3191 +3192 +3193 +3194 +3195 +3196 +3197 +3198 +3199 +3200 +3201 +3202 +3203 +3204 +3205 +3206 +3207 +3208 +3209 +3210 +3211 +3212 +3213 +3214 +3215 +3216 +3217 +3218 +3219 +3220 +3221 +3222 +3223 +3224 +3225 +3226 +3227 +3228 +3229 +3230 +3231 +3232 +3233 +3234 +3235 +3236 +3237 +3238 +3239 +3240 +3241 +3242 +3243 +3244 +3245 +3246 +3247 +3248 +3249 +3250 +3251 +3252 +3253 +3254 +3255 +3256 +3257 +3258 +3259 +3260 +3261 +3262 +3263 +3264 +3265 +3266 +3267 +3268 +3269 +3270 +3271 +3272 +3273 +3274 +3275 +3276 +3277 +3278 +3279 +3280 +3281 +3282 +3283 +3284 +3285 +3286 +3287 +3288 +3289 +3290 +3291 +3292 +3293 +3294 +3295 +3296 +3297 +3298 +3299 +3300 +3301 +3302 +3303 +3304 +3305 +3306 +3307 +3308 +3309 +3310 +3311 +3312 +3313 +3314 +3315 +3316 +3317 +3318 +3319 +3320 +3321 +3322 +3323 +3324 +3325 +3326 +3327 +3328 +3329 +3330 +3331 +3332 +3333 +3334 +3335 +3336 +3337 +3338 +3339 +3340 +3341 +3342 +3343 +3344 +3345 +3346 +3347 +3348 +3349 +3350 +3351 +3352 +3353 +3354 +3355 +3356 +3357 +3358 +3359 +3360 +3361 +3362 +3363 +3364 +3365 +3366 +3367 +3368 +3369 +3370 +3371 +3372 +3373 +3374 +3375 +3376 +3377 +3378 +3379 +3380 +3381 +3382 +3383 +3384 +3385 +3386 +3387 +3388 +3389 +3390 +3391 +3392 +3393 +3394 +3395 +3396 +3397 +3398 +3399 +3400 +3401 +3402 +3403 +3404 +3405 +3406 +3407 +3408 +3409 +3410 +3411 +3412 +3413 +3414 +3415 +3416 +3417 +3418 +3419 +3420 +3421 +3422 +3423 +3424 +3425 +3426 +3427 +3428 +3429 +3430 +3431 +3432 +3433 +3434 +3435 +3436 +3437 +3438 +3439 +3440 +3441 +3442 +3443 +3444 +3445 +3446 +3447 +3448 +3449 +3450 +3451 +3452 +3453 +3454 +3455 +3456 +3457 +3458 +3459 +3460 +3461 +3462 +3463 +3464 +3465 +3466 +3467 +3468 +3469 +3470 +3471 +3472 +3473 +3474 +3475 +3476 +3477 +3478 +3479 +3480 +3481 +3482 +3483 +3484 +3485 +3486 +3487 +3488 +3489 +3490 +3491 +3492 +3493 +3494 +3495 +3496 +3497 +3498 +3499 +3500 +3501 +3502 +3503 +3504 +3505 +3506 +3507 +3508 +3509 +3510 +3511 +3512 +3513 +3514 +3515 +3516 +3517 +3518 +3519 +3520 +3521 +3522 +3523 +3524 +3525 +3526 +3527 +3528 +3529 +3530 +3531 +3532 +3533 +3534 +3535 +3536 +3537 +3538 +3539 +3540 +3541 +3542 +3543 +3544 +3545 +3546 +3547 +3548 +3549 +3550 +3551 +3552 +3553 +3554 +3555 +3556 +3557 +3558 +3559 +3560 +3561 +3562 +3563 +3564 +3565 +3566 +3567 +3568 +3569 +3570 +3571 +3572 +3573 +3574 +3575 +3576 +3577 +3578 +3579 +3580 +3581 +3582 +3583 +3584 +3585 +3586 +3587 +3588 +3589 +3590 +3591 +3592 +3593 +3594 +3595 +3596 +3597 +3598 +3599 +3600 +3601 +3602 +3603 +3604 +3605 +3606 +3607 +3608 +3609 +3610 +3611 +3612 +3613 +3614 +3615 +3616 +3617 +3618 +3619 +3620 +3621 +3622 +3623 +3624 +3625 +3626 +3627 +3628 +3629 +3630 +3631 +3632 +3633 +3634 +3635 +3636 +3637 +3638 +3639 +3640 +3641 +3642 +3643 +3644 +3645 +3646 +3647 +3648 +3649 +3650 +3651 +3652 +3653 +3654 +3655 +3656 +3657 +3658 +3659 +3660 +3661 +3662 +3663 +3664 +3665 +3666 +3667 +3668 +3669 +3670 +3671 +3672 +3673 +3674 +3675 +3676 +3677 +3678 +3679 +3680 +3681 +3682 +3683 +3684 +3685 +3686 +3687 +3688 +3689 +3690 +3691 +3692 +3693 +3694 +3695 +3696 +3697 +3698 +3699 +3700 +3701 +3702 +3703 +3704 +3705 +3706 +3707 +3708 +3709 +3710 +3711 +3712 +3713 +3714 +3715 +3716 +3717 +3718 +3719 +3720 +3721 +3722 +3723 +3724 +3725 +3726 +3727 +3728 +3729 +3730 +3731 +3732 +3733 +3734 +3735 +3736 +3737 +3738 +3739 +3740 +3741 +3742 +3743 +3744 +3745 +3746 +3747 +3748 +3749 +3750 +3751 +3752 +3753 +3754 +3755 +3756 +3757 +3758 +3759 +3760 +3761 +3762 +3763 +3764 +3765 +3766 +3767 +3768 +3769 +3770 +3771 +3772 +3773 +3774 +3775 +3776 +3777 +3778 +3779 +3780 +3781 +3782 +3783 +3784 +3785 +3786 +3787 +3788 +3789 +3790 +3791 +3792 +3793 +3794 +3795 +3796 +3797 +3798 +3799 +3800 +3801 +3802 +3803 +3804 +3805 +3806 +3807 +3808 +3809 +3810 +3811 +3812 +3813 +3814 +3815 +3816 +3817 +3818 +3819 +3820 +3821 +3822 +3823 +3824 +3825 +3826 +3827 +3828 +3829 +3830 +3831 +3832 +3833 +3834 +3835 +3836 +3837 +3838 +3839 +3840 +3841 +3842 +3843 +3844 +3845 +3846 +3847 +3848 +3849 +3850 +3851 +3852 +3853 +3854 +3855 +3856 +3857 +3858 +3859 +3860 +3861 +3862 +3863 +3864 +3865 +3866 +3867 +3868 +3869 +3870 +3871 +3872 +3873 +3874 +3875 +3876 +3877 +3878 +3879 +3880 +3881 +3882 +3883 +3884 +3885 +3886 +3887 +3888 +3889 +3890 +3891 +3892 +3893 +3894 +3895 +3896 +3897 +3898 +3899 +3900 +3901 +3902 +3903 +3904 +3905 +3906 +3907 +3908 +3909 +3910 +3911 +3912 +3913 +3914 +3915 +3916 +3917 +3918 +3919 +3920 +3921 +3922 +3923 +3924 +3925 +3926 +3927 +3928 +3929 +3930 +3931 +3932 +3933 +3934 +3935 +3936 +3937 +3938 +3939 +3940 +3941 +3942 +3943 +3944 +3945 +3946 +3947 +3948 +3949 +3950 +3951 +3952 +3953 +3954 +3955 +3956 +3957 +3958 +3959 +3960 +3961 +3962 +3963 +3964 +3965 +3966 +3967 +3968 +3969 +3970 +3971 +3972 +3973 +3974 +3975 +3976 +3977 +3978 +3979 +3980 +3981 +3982 +3983 +3984 +3985 +3986 +3987 +3988 +3989 +3990 +3991 +3992 +3993 +3994 +3995 +3996 +3997 +3998 +3999 +4000 +4001 +4002 +4003 +4004 +4005 +4006 +4007 +4008 +4009 +4010 +4011 +4012 +4013 +4014 +4015 +4016 +4017 +4018 +4019 +4020 +4021 +4022 +4023 +4024 +4025 +4026 +4027 +4028 +4029 +4030 +4031 +4032 +4033 +4034 +4035 +4036 +4037 +4038 +4039 +4040 +4041 +4042 +4043 +4044 +4045 +4046 +4047 +4048 +4049 +4050 +4051 +4052 +4053 +4054 +4055 +4056 +4057 +4058 +4059 +4060 +4061 +4062 +4063 +4064 +4065 +4066 +4067 +4068 +4069 +4070 +4071 +4072 +4073 +4074 +4075 +4076 +4077 +4078 +4079 +4080 +4081 +4082 +4083 +4084 +4085 +4086 +4087 +4088 +4089 +4090 +4091 +4092 +4093 +4094 +4095 +4096 +4097 +4098 +4099 +4100 +4101 +4102 +4103 +4104 +4105 +4106 +4107 +4108 +4109 +4110 +4111 +4112 +4113 +4114 +4115 +4116 +4117 +4118 +4119 +4120 +4121 +4122 +4123 +4124 +4125 +4126 +4127 +4128 +4129 +4130 +4131 +4132 +4133 +4134 +4135 +4136 +4137 +4138 +4139 +4140 +4141 +4142 +4143 +4144 +4145 +4146 +4147 +4148 +4149 +4150 +4151 +4152 +4153 +4154 +4155 +4156 +4157 +4158 +4159 +4160 +4161 +4162 +4163 +4164 +4165 +4166 +4167 +4168 +4169 +4170 +4171 +4172 +4173 +4174 +4175 +4176 +4177 +4178 +4179 +4180 +4181 +4182 +4183 +4184 +4185 +4186 +4187 +4188 +4189 +4190 +4191 +4192 +4193 +4194 +4195 +4196 +4197 +4198 +4199 +4200 +4201 +4202 +4203 +4204 +4205 +4206 +4207 +4208 +4209 +4210 +4211 +4212 +4213 +4214 +4215 +4216 +4217 +4218 +4219 +4220 +4221 +4222 +4223 +4224 +4225 +4226 +4227 +4228 +4229 +4230 +4231 +4232 +4233 +4234 +4235 +4236 +4237 +4238 +4239 +4240 +4241 +4242 +4243 +4244 +4245 +4246 +4247 +4248 +4249 +4250 +4251 +4252 +4253 +4254 +4255 +4256 +4257 +4258 +4259 +4260 +4261 +4262 +4263 +4264 +4265 +4266 +4267 +4268 +4269 +4270 +4271 +4272 +4273 +4274 +4275 +4276 +4277 +4278 +4279 +4280 +4281 +4282 +4283 +4284 +4285 +4286 +4287 +4288 +4289 +4290 +4291 +4292 +4293 +4294 +4295 +4296 +4297 +4298 +4299 +4300 +4301 +4302 +4303 +4304 +4305 +4306 +4307 +4308 +4309 +4310 +4311 +4312 +4313 +4314 +4315 +4316 +4317 +4318 +4319 +4320 +4321 +4322 +4323 +4324 +4325 +4326 +4327 +4328 +4329 +4330 +4331 +4332 +4333 +4334 +4335 +4336 +4337 +4338 +4339 +4340 +4341 +4342 +4343 +4344 +4345 +4346 +4347 +4348 +4349 +4350 +4351 +4352 +4353 +4354 +4355 +4356 +4357 +4358 +4359 +4360 +4361 +4362 +4363 +4364 +4365 +4366 +4367 +4368 +4369 +4370 +4371 +4372 +4373 +4374 +4375 +4376 +4377 +4378 +4379 +4380 +4381 +4382 +4383 +4384 +4385 +4386 +4387 +4388 +4389 +4390 +4391 +4392 +4393 +4394 +4395 +4396 +4397 +4398 +4399 +4400 +4401 +4402 +4403 +4404 +4405 +4406 +4407 +4408 +4409 +4410 +4411 +4412 +4413 +4414 +4415 +4416 +4417 +4418 +4419 +4420 +4421 +4422 +4423 +4424 +4425 +4426 +4427 +4428 +4429 +4430 +4431 +4432 +4433 +4434 +4435 +4436 +4437 +4438 +4439 +4440 +4441 +4442 +4443 +4444 +4445 +4446 +4447 +4448 +4449 +4450 +4451 +4452 +4453 +4454 +4455 +4456 +4457 +4458 +4459 +4460 +4461 +4462 +4463 +4464 +4465 +4466 +4467 +4468 +4469 +4470 +4471 +4472 +4473 +4474 +4475 +4476 +4477 +4478 +4479 +4480 +4481 +4482 +4483 +4484 +4485 +4486 +4487 +4488 +4489 +4490 +4491 +4492 +4493 +4494 +4495 +4496 +4497 +4498 +4499 +4500 +4501 +4502 +4503 +4504 +4505 +4506 +4507 +4508 +4509 +4510 +4511 +4512 +4513 +4514 +4515 +4516 +4517 +4518 +4519 +4520 +4521 +4522 +4523 +4524 +4525 +4526 +4527 +4528 +4529 +4530 +4531 +4532 +4533 +4534 +4535 +4536 +4537 +4538 +4539 +4540 +4541 +4542 +4543 +4544 +4545 +4546 +4547 +4548 +4549 +4550 +4551 +4552 +4553 +4554 +4555 +4556 +4557 +4558 +4559 +4560 +4561 +4562 +4563 +4564 +4565 +4566 +4567 +4568 +4569 +4570 +4571 +4572 +4573 +4574 +4575 +4576 +4577 +4578 +4579 +4580 +4581 +4582 +4583 +4584 +4585 +4586 +4587 +4588 +4589 +4590 +4591 +4592 +4593 +4594 +4595 +4596 +4597 +4598 +4599 +4600 +4601 +4602 +4603 +4604 +4605 +4606 +4607 +4608 +4609 +4610 +4611 +4612 +4613 +4614 +4615 +4616 +4617 +4618 +4619 +4620 +4621 +4622 +4623 +4624 +4625 +4626 +4627 +4628 +4629 +4630 +4631 +4632 +4633 +4634 +4635 +4636 +4637 +4638 +4639 +4640 +4641 +4642 +4643 +4644 +4645 +4646 +4647 +4648 +4649 +4650 +4651 +4652 +4653 +4654 +4655 +4656 +4657 +4658 +4659 +4660 +4661 +4662 +4663 +4664 +4665 +4666 +4667 +46681× +1× +  +  +1× +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +1× +1× +1× +  +1× +  +  +1× +  +1× +1× +  +1× +  +1× +1× +  +1× +  +1× +1× +  +1× +  +1× +1× +  +1× +  +1× +1× +  +1× +  +1× +1× +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +1× +1× +1× +1× +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +1× +1× +1× +1× +1× +1× +1× +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +4× +4× +4× +  +4× +1× +  +  +4× +2× +  +  +4× +1× +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +1× +1× +1× +1× +  +1× +  +  +  +1× +  +  +  +1× +  +  +  +1× +  +  +  +  +1× +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1× +1× + 
Iif (typeof GameLib == 'undefined') {
+    function GameLib() {}
+}
+ 
+Eif (typeof GameLib.D3 == 'undefined') {
+    GameLib.D3 = function(){};
+}
+/**
+ * BoneWeight object - associates a vertex to a bone with some weight
+ * @param boneIndex int
+ * @param weight float
+ * @constructor
+ */
+GameLib.D3.BoneWeight = function(
+    boneIndex,
+    weight
+) {
+    this.boneIndex = boneIndex;
+    this.weight = weight;
+};
+/**
+ * Bone Superset
+ * @param id
+ * @param name string
+ * @param boneId
+ * @param childBoneIds
+ * @param parentBoneId
+ * @param quaternion
+ * @param position
+ * @param rotation
+ * @param scale GameLib.D3.Vector3
+ * @param up
+ * @constructor
+ */
+GameLib.D3.Bone = function(
+    id,
+    boneId,
+    name,
+    childBoneIds,
+    parentBoneId,
+    quaternion,
+    position,
+    rotation,
+    scale,
+    up
+) {
+    this.id = id;
+    this.name = name;
+    this.boneId = boneId;
+ 
+    Iif (typeof childBoneIds == 'undefined') {
+        childBoneIds = [];
+    }
+    this.childBoneIds = childBoneIds;
+ 
+    Eif (typeof parentBoneId == 'undefined') {
+        parentBoneId = null;
+    }
+    this.parentBoneId = parentBoneId;
+ 
+    Eif (typeof quaternion == 'undefined') {
+        quaternion = new GameLib.D3.Vector4();
+    }
+    this.quaternion = quaternion;
+ 
+    Eif (typeof position == 'undefined') {
+        position = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.position = position;
+ 
+    Eif (typeof rotation == 'undefined') {
+        rotation = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.rotation = rotation;
+ 
+    Eif (typeof scale == 'undefined') {
+        scale = new GameLib.D3.Vector3(1,1,1);
+    }
+    this.scale = scale;
+ 
+    Eif (typeof up == 'undefined') {
+        up = new GameLib.D3.Vector3(0,1,0);
+    }
+    this.up = up;
+};
+/**
+ * Physics Broadphase Superset
+ * @param id
+ * @param name String
+ * @param broadphaseType Number
+ * @param engine GameLib.D3.Engine
+ * @param createInstance Boolean
+ * @constructor
+ */
+GameLib.D3.Broadphase = function(
+    id,
+    name,
+    broadphaseType,
+    engine,
+    createInstance
+) {
+    this.id = id;
+ 
+    if (typeof name == 'undefined') {
+        name = 'broadphase-' + broadphaseType;
+    }
+    this.name = name;
+ 
+    if (typeof broadphaseType == 'undefined') {
+        broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE;
+    }
+    this.broadphaseType = broadphaseType;
+ 
+    if (typeof engine == 'undefined') {
+        engine = null;
+    }
+    this.engine = engine;
+ 
+    this.instance = null;
+ 
+    if (createInstance) {
+        this.createInstance();
+    }
+};
+ 
+/**
+ * Creates a custom Broadphase instance based on the engine type
+ */
+GameLib.D3.Broadphase.prototype.createInstance = function() {
+ 
+    if (!(this.engine instanceof GameLib.D3.Engine)) {
+        console.warn('No Engine');
+        throw new Error('No Engine');
+    }
+ 
+    this.engine.isNotCannonThrow();
+ 
+    var instance = null;
+ 
+    if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) {
+        instance = new this.engine.instance.NaiveBroadphase();
+    } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) {
+        instance = new this.engine.instance.GridBroadphase();
+    } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) {
+        instance = new this.engine.instance.SAPBroardphase();
+    } else {
+        console.warn('Unsupported broadphase type: ' + this.broadphaseType);
+        throw new Error('Unsupported broadphase type: ' + this.broadphaseType);
+    }
+ 
+    this.instance = instance;
+ 
+    return instance;
+};
+ 
+/**
+ * Broadphase Types
+ * @type {number}
+ */
+GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE = 0x1;
+GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID = 0x2;
+GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3;
+/**
+ * Color Superset
+ * @param r
+ * @param g
+ * @param b
+ * @param a
+ * @constructor
+ */
+GameLib.D3.Color = function(r, g, b, a) {
+    this.r = r;
+    this.g = g;
+    this.b = b;
+    this.a = a;
+};
+/**
+ * Engine Superset
+ * @param engineType
+ * @param instance {CANNON | Ammo | Goblin}
+ * @constructor
+ */
+GameLib.D3.Engine = function(
+    engineType,
+    instance
+) {
+    this.engineType = engineType;
+    this.instance = instance;
+};
+ 
+/**
+ * True if CANNON physics
+ * @returns {boolean}
+ */
+GameLib.D3.Engine.prototype.isCannon = function() {
+    return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON)
+};
+ 
+/**
+ * Logs a warning and throws an error if not cannon
+ */
+GameLib.D3.Engine.prototype.isNotCannonThrow = function() {
+    if (this.engineType != GameLib.D3.Engine.ENGINE_TYPE_CANNON) {
+        console.warn('Only CANNON supported for this function');
+        throw new Error('Only CANNON supported for this function');
+    }
+};
+ 
+/**
+ * True if Ammo physics
+ * @returns {boolean}
+ */
+GameLib.D3.Engine.prototype.isAmmo = function() {
+    return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_AMMO)
+};
+ 
+/**
+ * True if Goblin physics
+ * @returns {boolean}
+ */
+GameLib.D3.Engine.prototype.isGoblin = function() {
+    return (this.engineType == GameLib.D3.Engine.ENGINE_TYPE_GOBLIN)
+};
+ 
+/**
+ * Physics GameLib.D3.Engine Types
+ * @type {number}
+ */
+GameLib.D3.Engine.ENGINE_TYPE_CANNON = 0x1;
+GameLib.D3.Engine.ENGINE_TYPE_AMMO = 0x2;
+GameLib.D3.Engine.ENGINE_TYPE_GOBLIN = 0x3;
+/**
+ * Fly Controls
+ * @param camera
+ * @param THREE
+ * @param canvas
+ * @constructor
+ */
+GameLib.D3.FlyControls = function(
+    camera,
+    THREE,
+    canvas
+) {
+    this.flySpeed = 100;
+ 
+    this.canvas = canvas;
+ 
+    this.THREE = THREE;
+ 
+    this.yaw = 0;
+    this.pitch = 0;
+    this.canRotate = false;
+ 
+    this.moveForward = false;
+    this.moveBackward = false;
+    this.moveLeft = false;
+    this.moveRight = false;
+    this.moveUp = false;
+    this.moveDown = false;
+ 
+    this.mouseUpCallback = this.onMouseUp.bind(this);
+    this.mouseDownCallback = this.onMouseDown.bind(this);
+    this.mouseMoveCallback = this.onMouseMove.bind(this);
+    this.mouseWheelCallback = this.onMouseWheel.bind(this);
+    this.keyDownCallback = this.onKeyDown.bind(this);
+    this.keyUpCallback = this.onKeyUp.bind(this);
+ 
+    this.camera = camera;
+ 
+    this.canvas.addEventListener('keydown', this.keyDownCallback, false);
+    this.canvas.addEventListener('keyup', this.keyUpCallback, false);
+    this.canvas.addEventListener('mousedown', this.mouseDownCallback, false);
+    this.canvas.addEventListener('mouseup', this.mouseUpCallback, false);
+    this.canvas.addEventListener('mousewheel', this.mouseWheelCallback, false);
+ 
+    this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
+    this.element = document.body;
+ 
+    if (this.havePointerLock) {
+        this.element.requestPointerLock = this.element.requestPointerLock || this.element.mozRequestPointerLock || this.element.webkitRequestPointerLock;
+        document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock;
+    }
+};
+ 
+/**
+ * Go forward / backward on mouse wheel
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onMouseWheel = function(event) {
+    this.moveForward = true;
+    this.applyTranslation(event.wheelDelta * 0.001);
+    event.preventDefault();
+    this.moveForward = false;
+};
+ 
+/**
+ * Start rotating the camera on mouse middle button down
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onMouseDown = function(event) {
+    if (event.button == 1) {
+        this.canRotate = true;
+        this.canvas.addEventListener('mousemove', this.mouseMoveCallback, false);
+    }
+};
+ 
+/**
+ * Stop rotating on middle mouse button down
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onMouseUp = function(event) {
+    if (event.button == 1) {
+        this.canRotate = false;
+        this.canvas.removeEventListener('mousemove', this.mouseMoveCallback);
+    }
+};
+ 
+/**
+ * Apply current yaw and pitch to camera
+ */
+GameLib.D3.FlyControls.prototype.applyRotation = function() {
+    this.camera.rotation.set(this.pitch, this.yaw, 0, "YXZ");
+};
+ 
+/**
+ * Apply current position to camera
+ * @param deltaTime
+ */
+GameLib.D3.FlyControls.prototype.applyTranslation = function(deltaTime) {
+    var direction = new this.THREE.Vector3(0, 0, -1);
+    var rotation = new this.THREE.Euler(0, 0, 0, "YXZ");
+    rotation.set(this.pitch, this.yaw, 0, "YXZ");
+ 
+    direction = direction.applyEuler(rotation);
+ 
+    var forward = direction.normalize();
+    var right = forward.cross(new this.THREE.Vector3(0, 1, 0));
+ 
+    if(this.moveForward) {
+ 
+        this.camera.position.x += forward.x * (deltaTime * this.flySpeed);
+        this.camera.position.y += forward.y * (deltaTime * this.flySpeed);
+        this.camera.position.z += forward.z * (deltaTime * this.flySpeed);
+ 
+    } else if(this.moveBackward) {
+ 
+        this.camera.position.x -= forward.x * (deltaTime * this.flySpeed);
+        this.camera.position.y -= forward.y * (deltaTime * this.flySpeed);
+        this.camera.position.z -= forward.z * (deltaTime * this.flySpeed);
+    }
+ 
+    if(this.moveLeft) {
+ 
+        this.camera.position.x -= right.x * (deltaTime * this.flySpeed);
+        this.camera.position.y -= right.y * (deltaTime * this.flySpeed);
+        this.camera.position.z -= right.z * (deltaTime * this.flySpeed);
+ 
+    } else if(this.moveRight) {
+ 
+        this.camera.position.x += right.x * (deltaTime * this.flySpeed);
+        this.camera.position.y += right.y * (deltaTime * this.flySpeed);
+        this.camera.position.z += right.z * (deltaTime * this.flySpeed);
+    }
+ 
+    if(this.moveUp) {
+ 
+        this.camera.position.y += (deltaTime * this.flySpeed);
+ 
+    } else if(this.moveDown) {
+ 
+        this.camera.position.y -= (deltaTime * this.flySpeed);
+ 
+    }
+};
+ 
+/**
+ * This update function should be called from the animation function in order to apply the 'frame rate independent'
+ * movement to the camera
+ * @param deltaTime
+ */
+GameLib.D3.FlyControls.prototype.update = function(deltaTime) {
+    this.applyRotation();
+    this.applyTranslation(deltaTime);
+};
+ 
+/**
+ * Rotate on mouse move
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onMouseMove = function ( event ) {
+    if (this.canRotate) {
+        var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
+        var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
+ 
+        this.yaw -= movementX * 0.002;
+        this.pitch -= movementY * 0.002;
+    }
+};
+ 
+/**
+ * Keyboard controls
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onKeyDown = function ( event ) {
+    switch ( event.keyCode ) {
+ 
+        case 87: // w
+            this.moveForward = true;
+            break;
+ 
+        case 65: // a
+            this.moveLeft = true;
+            break;
+ 
+        case 83: // s
+            this.moveBackward = true;
+            break;
+ 
+        case 68: // d
+            this.moveRight = true;
+            break;
+ 
+        case 104: // keypad up arrow
+            this.moveUp = true;
+            break;
+ 
+        case 98: // keypad down arrow
+            this.moveDown = true;
+            break;
+    }
+};
+ 
+/**
+ * Keyboard controls
+ * @param event
+ */
+GameLib.D3.FlyControls.prototype.onKeyUp = function ( event ) {
+    switch ( event.keyCode ) {
+ 
+        case 38: // up
+        case 87: // w
+            this.moveForward = false;
+            break;
+ 
+        case 37: // left
+        case 65: // a
+            this.moveLeft = false;
+            break;
+ 
+        case 40: // down
+        case 83: // s
+            this.moveBackward = false;
+            break;
+ 
+        case 39: // right
+        case 68: // d
+            this.moveRight = false;
+            break;
+ 
+        case 104: // keypad up arrow
+            this.moveUp = false;
+            break;
+ 
+        case 98: // keypad down arrow
+            this.moveDown = false;
+            break;
+    }
+};
+GameLib.D3.Game = function (
+ 
+) {
+    this.scenes = {};
+    this.physicsWorlds = [];
+    this.sceneToPhysicsWorldsMap = {};
+};
+ 
+GameLib.D3.Game.prototype.AddScene = function(
+    scene
+) {
+    this.scenes[scene.name] = scene;
+};
+ 
+GameLib.D3.Game.prototype.AddPhysicsWorld = function(
+    physicsWorld
+) {
+    this.physicsWorlds.push(physicsWorld);
+};
+ 
+GameLib.D3.Game.prototype.LinkPhysicsWorldToScene = function(
+    physicsWorld,
+    scene
+) {
+    this.sceneToPhysicsWorldsMap[scene.name] = this.sceneToPhysicsWorldsMap[scene.name] || [];
+    this.sceneToPhysicsWorldsMap[scene.name].push(physicsWorld);
+};
+ 
+GameLib.D3.Game.prototype.GetPhysicsWorldsForScene = function (
+    scene
+) {
+    return this.sceneToPhysicsWorldsMap[scene.name];
+};
+ 
+GameLib.D3.Game.prototype.ProcessPhysics = function (
+    timestep
+) {
+    for(var s in this.sceneToPhysicsWorldsMap) {
+ 
+        var physicsWorldArray = this.sceneToPhysicsWorldsMap[s];
+        var scene = this.scenes[s];
+ 
+        if(scene && physicsWorldArray) {
+ 
+            for(var i = 0, l = physicsWorldArray.length; i < l; i++) {
+ 
+                var physicsWorld = physicsWorldArray[i];
+                physicsWorld.Step(timestep);
+ 
+                for(var p in physicsWorld.linkedPairs) {
+                    var pair = physicsWorld.linkedPairs[p];
+                    var mesh = pair.threeMesh;
+                    var body = pair.physicsBody;
+ 
+                    if(mesh) {
+                        if(physicsWorld.engineType === GameLib.D3.Physics.TYPE_CANNON) {
+ 
+                            var quaternion = new THREE.Quaternion();
+                            quaternion.copy(body.rigidBodyInstance.quaternion);
+ 
+                            var quaternionCopy = quaternion.clone();
+ 
+                            var position = new THREE.Vector3();
+                            position.copy(body.rigidBodyInstance.position);
+ 
+                            if(mesh.permutate) {
+ 
+                                if(mesh.permutate.offset) {
+                                    if(mesh.permutate.offset.quaternion) {
+                                        var offsetQuaternion = new THREE.Quaternion();
+                                        offsetQuaternion.copy(mesh.permutate.offset.quaternion);
+                                        quaternion = quaternion.multiply(offsetQuaternion).normalize();
+                                    }
+ 
+                                    if(mesh.permutate.offset.position) {
+                                        var offsetPosition = new THREE.Vector3();
+                                        offsetPosition.copy(mesh.permutate.offset.position);
+                                        //position = position.add(offsetPosition);
+                                        position = position.add(offsetPosition.applyQuaternion(quaternionCopy));
+                                    }
+                                }
+                            }
+ 
+                            mesh.position.copy(position);
+                            mesh.quaternion.copy(quaternion);
+                        }
+                    }
+                }
+            }
+        }
+ 
+    }
+};
+ 
+GameLib.D3.Game.prototype.LinkPair = function (
+    threeMesh,
+    physicsBody,
+    physicsWorld
+) {
+    physicsWorld.linkedPairs = physicsWorld.linkedPairs || [];
+ 
+    physicsWorld.linkedPairs.push({
+        threeMesh : threeMesh,
+        physicsBody : physicsBody
+    });
+};
+/**
+ *
+ * @param sizeX Number
+ * @param sizeY Number
+ * @param matrix matrix 2D Array with height data (Column Major)
+ * @constructor
+ */
+GameLib.D3.Heightmap = function(
+    sizeX,
+    sizeY,
+    matrix
+) {
+    if (typeof sizeX == 'undefined') {
+        sizeX = 0;
+    }
+    this.sizeX = sizeX;
+ 
+    if (typeof sizeY == 'undefined') {
+        sizeY = 0;
+    }
+    this.sizeY = sizeY;
+ 
+    if (typeof matrix == 'undefined') {
+        matrix = [];
+    }
+    this.matrix = matrix;
+};
+ 
+GameLib.D3.Heightmap.prototype.generateThreeMeshFromHeightField = function(
+    THREE,
+    heightFieldShape,
+    engine
+) {
+    var geometry = new THREE.Geometry();
+ 
+    var v0 = new this.physics.CANNON.Vec3();
+    var v1 = new this.physics.CANNON.Vec3();
+    var v2 = new this.physics.CANNON.Vec3();
+ 
+    var shape = heightFieldShape;
+    for (var xi = 0; xi < shape.data.length - 1; xi++) {
+        for (var yi = 0; yi < shape.data[xi].length - 1; yi++) {
+            for (var k = 0; k < 2; k++) {
+                shape.getConvexTrianglePillar(xi, yi, k===0);
+                v0.copy(shape.pillarConvex.vertices[0]);
+                v1.copy(shape.pillarConvex.vertices[1]);
+                v2.copy(shape.pillarConvex.vertices[2]);
+                v0.vadd(shape.pillarOffset, v0);
+                v1.vadd(shape.pillarOffset, v1);
+                v2.vadd(shape.pillarOffset, v2);
+                geometry.vertices.push(
+                    new THREE.Vector3(v0.x, v0.y, v0.z),
+                    new THREE.Vector3(v1.x, v1.y, v1.z),
+                    new THREE.Vector3(v2.x, v2.y, v2.z)
+                );
+                var i = geometry.vertices.length - 3;
+                geometry.faces.push(new THREE.Face3(i, i+1, i+2));
+            }
+        }
+    }
+    geometry.computeBoundingSphere();
+    geometry.computeFaceNormals();
+ 
+    return new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({ wireframe : false, shading : THREE.SmoothShading }));
+};
+ 
+ 
+GameLib.D3.Heightmap.prototype.generateHeightmapDataFromImage = function (
+    imagePath,
+    callback    // receives HeightmapData instance as the first argument
+) {
+    var img = new Image();
+ 
+    img.onload = function () {
+ 
+        var canvas = document.createElement('canvas');
+        canvas.width = img.width;
+        canvas.height = img.height;
+ 
+        var context = canvas.getContext('2d');
+        context.drawImage(img, 0, 0);
+ 
+        var imgd = context.getImageData(0, 0, img.width, img.height);
+        var pixels = imgd.data;
+ 
+        var heightList = [];
+        for (var i = 0, n = pixels.length; i < n; i += (4)) {
+            heightList.push(pixels[i]);
+        }
+ 
+        var matrix = [];
+        var sizeX = img.width,
+            sizeY = img.height;
+ 
+        for (var i = 0; i < sizeX; i++) {
+            matrix.push([]);
+            for (var j = 0; j < sizeY; j++) {
+                var height = (heightList[(sizeX - i) + j * sizeY] / 255) * 15;
+                matrix[i].push(height);
+            }
+        }
+ 
+ 
+        // todo: delete canvas here
+ 
+        callback(new GameLib.D3.HeightmapData(sizeX, sizeY, matrix));
+    };
+ 
+    img.src = imagePath;
+};
+/**
+ * Image
+ * @param id
+ * @param textureLink
+ * @param filename
+ * @param size
+ * @param contentType
+ * @constructor
+ */
+GameLib.D3.Image = function(
+    id,
+    textureLink,
+    filename,
+    size,
+    contentType
+) {
+    this.id = id;
+ 
+    this.filename = filename;
+ 
+    this.textureLink = textureLink;
+ 
+    if (typeof size == 'undefined') {
+        size = 0;
+    }
+    this.size = size;
+ 
+    if (typeof contentType == 'undefined') {
+ 
+        contentType = 'application/octet-stream';
+ 
+        if (this.filename.match(/(png)$/i)) {
+            contentType = 'image/png';
+        }
+ 
+        if (this.filename.match(/(jpg|jpeg)$/i)) {
+            contentType = 'image/jpeg';
+        }
+ 
+        if (this.filename.match(/(gif)$/i)) {
+            contentType = 'image/gif';
+        }
+    }
+    this.contentType = contentType;
+};
+/**
+ * Light Superset
+ * @param id
+ * @param lightType
+ * @param name
+ * @param color
+ * @param intensity
+ * @param position
+ * @param targetPosition
+ * @param quaternion
+ * @param rotation
+ * @param scale
+ * @param distance
+ * @param decay
+ * @param power
+ * @param angle
+ * @param penumbra
+ * @constructor
+ */
+GameLib.D3.Light = function(
+    id,
+    lightType,
+    name,
+    color,
+    intensity,
+    position,
+    targetPosition,
+    quaternion,
+    rotation,
+    scale,
+    distance,
+    decay,
+    power,
+    angle,
+    penumbra
+) {
+    this.id = id;
+    this.lightType = lightType;
+    this.name = name;
+    this.color = color;
+    this.intensity = intensity;
+ 
+    if (typeof position == 'undefined') {
+        position = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.position = position;
+ 
+    if (typeof targetPosition == 'undefined') {
+        targetPosition = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.targetPosition = targetPosition;
+ 
+    if (typeof quaternion == 'undefined'){
+        quaternion = new GameLib.D3.Vector4();
+    }
+    this.quaternion = quaternion;
+ 
+    if (typeof rotation == 'undefined'){
+        rotation = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.rotation = rotation;
+ 
+    if (typeof scale == 'undefined'){
+        scale = new GameLib.D3.Vector3(1,1,1);
+    }
+    this.scale = scale;
+ 
+    if (typeof distance == 'undefined'){
+        distance = 0;
+    }
+    this.distance = distance;
+ 
+    if (typeof decay == 'undefined'){
+        decay = 1;
+    }
+    this.decay = decay;
+ 
+    if (typeof power == 'undefined'){
+        power = 4 * Math.PI;
+    }
+    this.power = power;
+ 
+    if (typeof angle == 'undefined'){
+        angle = Math.PI / 3;
+    }
+    this.angle = angle;
+ 
+    if (typeof penumbra == 'undefined'){
+        penumbra = 0;
+    }
+    this.penumbra = penumbra;
+};
+/**
+ * Material Superset
+ * @param id
+ * @param name
+ * @param materialType
+ * @param opacity
+ * @param side
+ * @param transparent
+ * @param maps
+ * @param specular
+ * @param lightMapIntensity
+ * @param aoMapIntensity
+ * @param color
+ * @param emissive
+ * @param emissiveIntensity
+ * @param combine
+ * @param shininess
+ * @param reflectivity
+ * @param refractionRatio
+ * @param fog
+ * @param wireframe
+ * @param wireframeLineWidth
+ * @param wireframeLineCap
+ * @param wireframeLineJoin
+ * @param vertexColors
+ * @param skinning
+ * @param morphTargets
+ * @param morphNormals
+ * @param lineWidth
+ * @param lineCap
+ * @param lineJoin
+ * @param dashSize
+ * @param gapWidth
+ * @param blending
+ * @param blendSrc
+ * @param blendDst
+ * @param blendEquation
+ * @param depthTest
+ * @param depthFunc
+ * @param depthWrite
+ * @param polygonOffset
+ * @param polygonOffsetFactor
+ * @param polygonOffsetUnits
+ * @param alphaTest
+ * @param clippingPlanes
+ * @param clipShadows
+ * @param visible
+ * @param overdraw
+ * @param shading
+ * @param bumpScale
+ * @param normalScale
+ * @param displacementScale
+ * @param displacementBias
+ * @param roughness
+ * @param metalness
+ * @param pointSize
+ * @param pointSizeAttenuation
+ * @param spriteRotation
+ * @param envMapIntensity
+ * @constructor
+ */
+GameLib.D3.Material = function(
+    id,
+    name,
+    materialType,
+    opacity,
+    side,
+    transparent,
+    maps,
+    specular,
+    lightMapIntensity,
+    aoMapIntensity,
+    color,
+    emissive,
+    emissiveIntensity,
+    combine,
+    shininess,
+    reflectivity,
+    refractionRatio,
+    fog,
+    wireframe,
+    wireframeLineWidth,
+    wireframeLineCap,
+    wireframeLineJoin,
+    vertexColors,
+    skinning,
+    morphTargets,
+    morphNormals,
+    lineWidth,
+    lineCap,
+    lineJoin,
+    dashSize,
+    gapWidth,
+    blending,
+    blendSrc,
+    blendDst,
+    blendEquation,
+    depthTest,
+    depthFunc,
+    depthWrite,
+    polygonOffset,
+    polygonOffsetFactor,
+    polygonOffsetUnits,
+    alphaTest,
+    clippingPlanes,
+    clipShadows,
+    visible,
+    overdraw,
+    shading,
+    bumpScale,
+    normalScale,
+    displacementScale,
+    displacementBias,
+    roughness,
+    metalness,
+    pointSize,
+    pointSizeAttenuation,
+    spriteRotation,
+    envMapIntensity
+) {
+    this.id = id;
+    this.name = name;
+    if (typeof materialType == 'undefined') {
+        materialType = GameLib.D3.Material.TYPE_MESH_STANDARD;
+    }
+    this.materialType = materialType;
+ 
+    if (typeof opacity == 'undefined') {
+        opacity = 1.0;
+    }
+    this.opacity = opacity;
+ 
+    if (typeof side == 'undefined') {
+        side = GameLib.D3.Material.TYPE_FRONT_SIDE;
+    }
+    this.side = side;
+ 
+    if (typeof transparent == 'undefined') {
+        transparent = false;
+    }
+    this.transparent = transparent;
+ 
+    if (typeof maps == 'undefined') {
+        maps = {
+            alpha: null,
+            ao: null,
+            bump: null,
+            diffuse: null,
+            displacement: null,
+            emissive: null,
+            environment: null,
+            light: null,
+            metalness: null,
+            normal: null,
+            roughness: null,
+            specular: null
+        };
+    }
+    this.maps = maps;
+ 
+    if (typeof specular == 'undefined') {
+        specular = new GameLib.D3.Color(0.06, 0.06, 0.06, 0.06);
+    }
+    this.specular = specular;
+ 
+    if (typeof lightMapIntensity == 'undefined') {
+        lightMapIntensity = 1;
+    }
+    this.lightMapIntensity = lightMapIntensity;
+ 
+    if (typeof aoMapIntensity == 'undefined') {
+        aoMapIntensity = 1;
+    }
+    this.aoMapIntensity = aoMapIntensity;
+ 
+    if (typeof color == 'undefined') {
+        color = new GameLib.D3.Color(1, 1, 1, 1)
+    }
+    this.color = color;
+ 
+    if (typeof emissive == 'undefined') {
+        emissive = new GameLib.D3.Color(0, 0, 0, 0);
+    }
+    this.emissive = emissive;
+ 
+    if (typeof emissiveIntensity == 'undefined') {
+        emissiveIntensity = 1;
+    }
+    this.emissiveIntensity = emissiveIntensity;
+ 
+    if (typeof combine == 'undefined') {
+        combine = GameLib.D3.Material.TYPE_MULTIPLY_OPERATION;
+    }
+    this.combine = combine;
+ 
+    if (typeof shininess == 'undefined') {
+        shininess = 30;
+    }
+    this.shininess = shininess;
+ 
+    if (typeof reflectivity == 'undefined') {
+        reflectivity = 1;
+    }
+    this.reflectivity = reflectivity;
+ 
+    if (typeof refractionRatio == 'undefined') {
+        refractionRatio = 0.98;
+    }
+    this.refractionRatio = refractionRatio;
+ 
+    if (typeof fog == 'undefined') {
+        fog = true;
+    }
+    this.fog = fog;
+ 
+    if (typeof wireframe == 'undefined') {
+        wireframe = false;
+    }
+    this.wireframe = wireframe;
+ 
+    if (typeof wireframeLineWidth == 'undefined') {
+        wireframeLineWidth = 1;
+    }
+    this.wireframeLineWidth = wireframeLineWidth;
+ 
+    if (typeof wireframeLineCap == 'undefined') {
+        wireframeLineCap = 'round';
+    }
+    this.wireframeLineCap = wireframeLineCap;
+ 
+    if (typeof wireframeLineJoin == 'undefined') {
+        wireframeLineJoin = 'round';
+    }
+    this.wireframeLineJoin = wireframeLineJoin;
+ 
+    if (typeof vertexColors == 'undefined') {
+        vertexColors = GameLib.D3.Material.TYPE_NO_COLORS;
+    }
+    this.vertexColors = vertexColors;
+ 
+    if (typeof skinning == 'undefined') {
+        skinning = false;
+    }
+    this.skinning = skinning;
+ 
+    if (typeof morphTargets == 'undefined') {
+        morphTargets = false;
+    }
+    this.morphTargets = morphTargets;
+ 
+    if (typeof morphNormals == 'undefined') {
+        morphNormals = false;
+    }
+    this.morphNormals = morphNormals;
+ 
+    if (typeof overdraw == 'undefined') {
+        overdraw = 0;
+    }
+    this.overdraw = overdraw;
+ 
+    if (typeof lineWidth == 'undefined') {
+        lineWidth = 1;
+    }
+    this.lineWidth = lineWidth;
+ 
+    if (typeof lineCap == 'undefined') {
+        lineCap = 'round';
+    }
+    this.lineCap = lineCap;
+ 
+    if (typeof lineJoin == 'undefined') {
+        lineJoin = 'round';
+    }
+    this.lineJoin = lineJoin;
+ 
+    if (typeof dashSize == 'undefined') {
+        dashSize = 3;
+    }
+    this.dashSize = dashSize;
+ 
+    if (typeof gapWidth == 'undefined') {
+        gapWidth = 1;
+    }
+    this.gapWidth = gapWidth;
+ 
+    if (typeof blending == 'undefined') {
+        blending = GameLib.D3.Material.TYPE_NORMAL_BLENDING;
+    }
+    this.blending = blending;
+ 
+    if (typeof blendSrc == 'undefined') {
+        blendSrc = GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR;
+    }
+    this.blendSrc = blendSrc;
+ 
+    if (typeof blendDst == 'undefined') {
+        blendDst = GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR;
+    }
+    this.blendDst = blendDst;
+ 
+    if (typeof blendEquation == 'undefined') {
+        blendEquation = GameLib.D3.Material.TYPE_ADD_EQUATION;
+    }
+    this.blendEquation = blendEquation;
+ 
+    if (typeof depthTest == 'undefined') {
+        depthTest = true;
+    }
+    this.depthTest = depthTest;
+ 
+    if (typeof depthFunc == 'undefined') {
+        depthFunc = GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH;
+    }
+    this.depthFunc = depthFunc;
+ 
+    if (typeof depthWrite == 'undefined') {
+        depthWrite = true;
+    }
+    this.depthWrite = depthWrite;
+ 
+    if (typeof polygonOffset == 'undefined') {
+        polygonOffset = false;
+    }
+    this.polygonOffset = polygonOffset;
+ 
+    if (typeof polygonOffsetFactor == 'undefined') {
+        polygonOffsetFactor = 1;
+    }
+    this.polygonOffsetFactor = polygonOffsetFactor;
+ 
+    if (typeof polygonOffsetUnits == 'undefined') {
+        polygonOffsetUnits = 1;
+    }
+    this.polygonOffsetUnits = polygonOffsetUnits;
+ 
+    if (typeof alphaTest == 'undefined') {
+        alphaTest = 0;
+    }
+    this.alphaTest = alphaTest;
+ 
+    if (typeof clippingPlanes == 'undefined') {
+        clippingPlanes = [];
+    }
+    this.clippingPlanes = clippingPlanes;
+ 
+    if (typeof clipShadows == 'undefined') {
+        clipShadows = false;
+    }
+    this.clipShadows = clipShadows;
+ 
+    if (typeof visible == 'undefined') {
+        visible = true;
+    }
+    this.visible = visible;
+ 
+    if (typeof shading == 'undefined') {
+        shading = GameLib.D3.Material.TYPE_FLAT_SHADING;
+    }
+    this.shading = shading;
+ 
+    if (typeof bumpScale == 'undefined') {
+        bumpScale = 1;
+    }
+    this.bumpScale = bumpScale;
+ 
+    if (typeof normalScale == 'undefined') {
+        normalScale = 1;
+    }
+    this.normalScale = normalScale;
+ 
+    if (typeof displacementScale == 'undefined') {
+        displacementScale = 1;
+    }
+    this.displacementScale = displacementScale;
+ 
+    if (typeof displacementBias == 'undefined') {
+        displacementBias = 0;
+    }
+    this.displacementBias = displacementBias;
+ 
+    if (typeof roughness == 'undefined') {
+        roughness = 0.5;
+    }
+    this.roughness = roughness;
+ 
+    if (typeof metalness == 'undefined') {
+        metalness = 0.5;
+    }
+    this.metalness = metalness;
+ 
+    if (typeof pointSize == 'undefined') {
+        pointSize = 1;
+    }
+    this.pointSize = pointSize;
+ 
+    if (typeof pointSizeAttenuation == 'undefined') {
+        pointSizeAttenuation = true;
+    }
+    this.pointSizeAttenuation = pointSizeAttenuation;
+ 
+    if (typeof spriteRotation == 'undefined') {
+        spriteRotation = 0;
+    }
+    this.spriteRotation = spriteRotation;
+ 
+    if (typeof envMapIntensity == 'undefined') {
+        envMapIntensity = 1.0;
+    }
+    this.envMapIntensity = envMapIntensity;
+ 
+};
+ 
+/**
+ * Combine Method
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_MULTIPLY_OPERATION = 0;
+GameLib.D3.Material.TYPE_MIX_OPERATION = 1;
+GameLib.D3.Material.TYPE_ADD_OPERATION = 2;
+ 
+/**
+ * Vertex Color Mode
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_NO_COLORS = 0;
+GameLib.D3.Material.TYPE_FACE_COLORS = 1;
+GameLib.D3.Material.TYPE_VERTEX_COLORS = 2;
+ 
+/**
+ * Blending Mode
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_NORMAL_BLENDING = 1;
+GameLib.D3.Material.TYPE_ADDITIVE_BLENDING = 2;
+GameLib.D3.Material.TYPE_SUBTRACTIVE_BLENDING = 3;
+GameLib.D3.Material.TYPE_MULTIPLY_BLENDING = 4;
+GameLib.D3.Material.TYPE_CUSTOM_BLENDING = 5;
+ 
+/**
+ * Blend Source and Destination
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_ZERO_FACTOR = 200;
+GameLib.D3.Material.TYPE_ONE_FACTOR = 201;
+GameLib.D3.Material.TYPE_SRC_COLOR_FACTOR = 202;
+GameLib.D3.Material.TYPE_ONE_MINUS_SRC_COLOR_FACTOR = 203;
+GameLib.D3.Material.TYPE_SRC_ALPHA_FACTOR = 204;
+GameLib.D3.Material.TYPE_ONE_MINUS_SRC_ALPHA_FACTOR = 205;
+GameLib.D3.Material.TYPE_DST_ALPHA_FACTOR = 206;
+GameLib.D3.Material.TYPE_ONE_MINUS_DST_ALPHA_FACTOR = 207;
+GameLib.D3.Material.TYPE_DST_COLOR_FACTOR = 208;
+GameLib.D3.Material.TYPE_ONE_MINUS_DST_COLOR_FACTOR = 209;
+GameLib.D3.Material.TYPE_SRC_ALPHA_SATURATE_FACTOR = 210;
+ 
+/**
+ * Blend Operation
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_ADD_EQUATION = 100;
+GameLib.D3.Material.TYPE_SUBTRACT_EQUATION = 101;
+GameLib.D3.Material.TYPE_REVERSE_SUBTRACT_EQUATION = 102;
+GameLib.D3.Material.TYPE_MIN_EQUATION = 103;
+GameLib.D3.Material.TYPE_MAX_EQUATION = 104;
+ 
+/**
+ * Depth Function
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_NEVER_DEPTH = 0;
+GameLib.D3.Material.TYPE_ALWAYS_DEPTH = 1;
+GameLib.D3.Material.TYPE_LESS_DEPTH = 2;
+GameLib.D3.Material.TYPE_LESS_EQUAL_DEPTH = 3;
+GameLib.D3.Material.TYPE_EQUAL_DEPTH = 4;
+GameLib.D3.Material.TYPE_GREATER_EQUAL_DEPTH = 5;
+GameLib.D3.Material.TYPE_GREATER_DEPTH = 6;
+GameLib.D3.Material.TYPE_NOT_EQUAL_DEPTH = 7;
+ 
+/**
+ * Culling Mode
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_FRONT_SIDE = 0;
+GameLib.D3.Material.TYPE_BACK_SIDE = 1;
+GameLib.D3.Material.TYPE_DOUBLE_SIDE = 2;
+ 
+/**
+ * Shading Type
+ * @type {number}
+ */
+GameLib.D3.Material.TYPE_FLAT_SHADING = 1;
+GameLib.D3.Material.TYPE_SMOOTH_SHADING = 2;
+ 
+/**
+ * Material Type
+ * @type {string}
+ */
+GameLib.D3.Material.TYPE_LINE_BASIC    = "LineBasicMaterial";
+GameLib.D3.Material.TYPE_LINE_DASHED   = "LineDashedMaterial";
+GameLib.D3.Material.TYPE_MESH_BASIC    = "MeshBasicMaterial";
+GameLib.D3.Material.TYPE_MESH_DEPTH    = "MeshDepthMaterial";
+GameLib.D3.Material.TYPE_MESH_LAMBERT  = "MeshLambertMaterial";
+GameLib.D3.Material.TYPE_MESH_NORMAL   = "MeshNormalMaterial";
+GameLib.D3.Material.TYPE_MESH_PHONG    = "MeshPhongMaterial";
+GameLib.D3.Material.TYPE_MESH_STANDARD = "MeshStandardMaterial";
+GameLib.D3.Material.TYPE_POINTS        = "PointsMaterial";
+GameLib.D3.Material.TYPE_SPRITE        = "SpriteMaterial";
+GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial";
+ 
+/**
+ * Creates a THREE.Material from a GameLib.D3.Material
+ * @param blenderMaterial GameLib.D3.Material
+ * @param THREE THREE.js
+ */
+GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) {
+ 
+    var defer = this.Q.defer();
+ 
+    var threeMaterial = null;
+ 
+    var blenderMaps = [];
+ 
+    if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) {
+ 
+        threeMaterial = new THREE.MeshStandardMaterial({
+            name: blenderMaterial.name,
+            opacity: blenderMaterial.opacity,
+            transparent: blenderMaterial.transparent,
+            blending: blenderMaterial.blending,
+            blendSrc: blenderMaterial.blendSrc,
+            blendDst: blenderMaterial.blendDst,
+            blendEquation: blenderMaterial.blendEquation,
+            depthTest: blenderMaterial.depthTest,
+            depthFunc: blenderMaterial.depthFunc,
+            depthWrite: blenderMaterial.depthWrite,
+            polygonOffset: blenderMaterial.polygonOffset,
+            polygonOffsetFactor: blenderMaterial.polygonOffsetFactor,
+            polygonOffsetUnits: blenderMaterial.polygonOffsetUnits,
+            alphaTest: blenderMaterial.alphaTest,
+            clippingPlanes: blenderMaterial.clippingPlanes,
+            clipShadows: blenderMaterial.clipShadows,
+            overdraw: blenderMaterial.overdraw,
+            visible: blenderMaterial.visible,
+            side: blenderMaterial.side,
+            color: new THREE.Color(
+                blenderMaterial.color.r,
+                blenderMaterial.color.g,
+                blenderMaterial.color.b
+            ),
+            roughness: blenderMaterial.roughness,
+            metalness: blenderMaterial.metalness,
+            lightMapIntensity: blenderMaterial.lightMapIntensity,
+            aoMapIntensity: blenderMaterial.aoMapIntensity,
+            emissive: new THREE.Color(
+                blenderMaterial.emissive.r,
+                blenderMaterial.emissive.g,
+                blenderMaterial.emissive.b
+            ),
+            emissiveIntensity: blenderMaterial.emissiveIntensity,
+            bumpScale: blenderMaterial.bumpScale,
+            normalScale: blenderMaterial.normalScale,
+            displacementScale: blenderMaterial.displacementScale,
+            refractionRatio: blenderMaterial.refractionRatio,
+            fog: blenderMaterial.fog,
+            shading: blenderMaterial.shading,
+            wireframe: blenderMaterial.wireframe,
+            wireframeLinewidth: blenderMaterial.wireframeLineWidth,
+            wireframeLinecap: blenderMaterial.wireframeLineCap,
+            wireframeLinejoin: blenderMaterial.wireframeLineJoin,
+            vertexColors: blenderMaterial.vertexColors,
+            skinning: blenderMaterial.skinning,
+            morphTargets: blenderMaterial.morphTargets,
+            morphNormals: blenderMaterial.morphNormals
+        });
+ 
+        blenderMaps.push(
+            'diffuse',
+            'light',
+            'ao',
+            'emissive',
+            'bump',
+            'normal',
+            'displacement',
+            'roughness',
+            'metalness',
+            'alpha',
+            'environment'
+        );
+    } else if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) {
+ 
+        threeMaterial = new THREE.MeshPhongMaterial({
+            name: blenderMaterial.name,
+            opacity: blenderMaterial.opacity,
+            transparent: blenderMaterial.transparent,
+            blending: blenderMaterial.blending,
+            blendSrc: blenderMaterial.blendSrc,
+            blendDst: blenderMaterial.blendDst,
+            blendEquation: blenderMaterial.blendEquation,
+            depthTest: blenderMaterial.depthTest,
+            depthFunc: blenderMaterial.depthFunc,
+            depthWrite: blenderMaterial.depthWrite,
+            polygonOffset: blenderMaterial.polygonOffset,
+            polygonOffsetFactor: blenderMaterial.polygonOffsetFactor,
+            polygonOffsetUnits: blenderMaterial.polygonOffsetUnits,
+            alphaTest: blenderMaterial.alphaTest,
+            clippingPlanes: blenderMaterial.clippingPlanes,
+            clipShadows: blenderMaterial.clipShadows,
+            overdraw: blenderMaterial.overdraw,
+            visible: blenderMaterial.visible,
+            side: blenderMaterial.side,
+            color: new THREE.Color(
+                blenderMaterial.color.r,
+                blenderMaterial.color.g,
+                blenderMaterial.color.b
+            ),
+            specular: new THREE.Color(
+                blenderMaterial.specular.r,
+                blenderMaterial.specular.g,
+                blenderMaterial.specular.b
+            ),
+            shininess: blenderMaterial.shininess,
+            lightMapIntensity: blenderMaterial.lightMapIntensity,
+            aoMapIntensity: blenderMaterial.aoMapIntensity,
+            emissive: new THREE.Color(
+                blenderMaterial.emissive.r,
+                blenderMaterial.emissive.g,
+                blenderMaterial.emissive.b
+            ),
+            emissiveIntensity: blenderMaterial.emissiveIntensity,
+            bumpScale: blenderMaterial.bumpScale,
+            normalScale: blenderMaterial.normalScale,
+            displacementScale: blenderMaterial.displacementScale,
+            combine: blenderMaterial.combine,
+            refractionRatio: blenderMaterial.refractionRatio,
+            fog: blenderMaterial.fog,
+            shading: blenderMaterial.shading,
+            wireframe: blenderMaterial.wireframe,
+            wireframeLinewidth: blenderMaterial.wireframeLineWidth,
+            wireframeLinecap: blenderMaterial.wireframeLineCap,
+            wireframeLinejoin: blenderMaterial.wireframeLineJoin,
+            vertexColors: blenderMaterial.vertexColors,
+            skinning: blenderMaterial.skinning,
+            morphTargets: blenderMaterial.morphTargets,
+            morphNormals: blenderMaterial.morphNormals
+        });
+ 
+        blenderMaps.push(
+            'diffuse',
+            'light',
+            'ao',
+            'emissive',
+            'bump',
+            'normal',
+            'displacement',
+            'specular',
+            'alpha',
+            'environment'
+        );
+ 
+    } else {
+        console.log("material type is not implemented yet: " + blenderMaterial.materialType + " - material indexes could be screwed up");
+    }
+ 
+    if (blenderMaps.length > 0) {
+        var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial);
+        Q.all(textureMaps).then(
+            function(){
+                defer.resolve(threeMaterial);
+            }
+        ).catch(
+            function(error){
+                console.log(error);
+                defer.reject(error);
+            }
+        )
+    } else {
+        defer.resolve(threeMaterial);
+    }
+ 
+    return defer.promise;
+};
+/**
+ * Matrix 3 Maths
+ * @param row0 GameLib.D3.Vector3
+ * @param row1 GameLib.D3.Vector3
+ * @param row2 GameLib.D3.Vector3
+ * @constructor
+ */
+GameLib.D3.Matrix3 = function(
+    row0,
+    row1,
+    row2
+) {
+    this.identity();
+ 
+    if (row0) {
+        this.rows[0] = row0;
+    }
+ 
+    if (row1) {
+        this.rows[1] = row1;
+    }
+ 
+    if (row2) {
+        this.rows[2] = row2;
+    }
+};
+ 
+/**
+ * Set matrix to identity
+ */
+GameLib.D3.Matrix3.prototype.identity = function () {
+    this.rows = [
+        new GameLib.D3.Vector4(1, 0, 0),
+        new GameLib.D3.Vector4(0, 1, 0),
+        new GameLib.D3.Vector4(0, 0, 1)
+    ];
+};
+GameLib.D3.Matrix4 = function(
+    row0,
+    row1,
+    row2,
+    row3
+) {
+ 
+    this.identity();
+ 
+    if (row0) {
+        this.rows[0] = row0;
+    }
+ 
+    if (row1) {
+        this.rows[1] = row1;
+    }
+ 
+    if (row2) {
+        this.rows[2] = row2;
+    }
+ 
+    if (row3) {
+        this.rows[3] = row3;
+    }
+};
+ 
+GameLib.D3.Matrix4.prototype.rotationMatrixX = function (radians) {
+    this.identity();
+    this.rows[1] = new GameLib.D3.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0);
+    this.rows[2] = new GameLib.D3.Vector4(0, Math.sin(radians), Math.cos(radians), 0);
+    return this;
+};
+ 
+GameLib.D3.Matrix4.prototype.rotationMatrixY = function (radians) {
+    this.identity();
+    this.rows[0] = new GameLib.D3.Vector4(
+        Math.cos(radians),
+        0,
+        Math.sin(radians),
+        0
+    );
+    this.rows[2] = new GameLib.D3.Vector4(
+        -1 * Math.sin(radians),
+        0,
+        Math.cos(radians),
+        0
+    );
+    return this;
+};
+ 
+GameLib.D3.Matrix4.prototype.rotationMatrixZ = function (radians) {
+    this.identity();
+    this.rows[0] = new GameLib.D3.Vector4(Math.cos(radians), -1 * Math.sin(radians), 0, 0);
+    this.rows[1] = new GameLib.D3.Vector4(Math.sin(radians), Math.cos(radians), 0, 0);
+    return this;
+};
+ 
+GameLib.D3.Matrix4.prototype.rotateX = function (radians, point) {
+    this.identity();
+    this.rotationMatrixX(radians);
+    return this.multiply(point);
+};
+ 
+GameLib.D3.Matrix4.prototype.rotateY = function (radians, point) {
+    this.identity();
+    this.rotationMatrixY(radians);
+    return this.multiply(point);
+};
+ 
+GameLib.D3.Matrix4.prototype.rotateZ = function (radians, point) {
+    this.identity();
+    this.rotationMatrixZ(radians);
+    return this.multiply(point);
+};
+ 
+GameLib.D3.Matrix4.prototype.multiply = function (mvp) {
+    if (mvp instanceof GameLib.D3.Vector4) {
+        return new GameLib.D3.Vector4(
+            this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z + this.rows[0].w * mvp.w,
+            this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z + this.rows[1].w * mvp.w,
+            this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z + this.rows[2].w * mvp.w,
+            this.rows[3].x * mvp.x + this.rows[3].y * mvp.y + this.rows[3].z * mvp.z + this.rows[3].w * mvp.w
+        );
+    } else if (mvp instanceof GameLib.D3.Vector3) {
+        return new GameLib.D3.Vector3(
+            this.rows[0].x * mvp.x + this.rows[0].y * mvp.y + this.rows[0].z * mvp.z,
+            this.rows[1].x * mvp.x + this.rows[1].y * mvp.y + this.rows[1].z * mvp.z,
+            this.rows[2].x * mvp.x + this.rows[2].y * mvp.y + this.rows[2].z * mvp.z
+        );
+    }
+};
+ 
+GameLib.D3.Matrix4.prototype.identity = function () {
+    this.rows = [
+        new GameLib.D3.Vector4(1, 0, 0, 0),
+        new GameLib.D3.Vector4(0, 1, 0, 0),
+        new GameLib.D3.Vector4(0, 0, 1, 0),
+        new GameLib.D3.Vector4(0, 0, 0, 1)
+    ];
+};
+ 
+GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) {
+ 
+    var pv = new GameLib.D3.Vector3(position.x, position.y, position.z);
+ 
+    var z = pv.subtract(target).normalize();
+ 
+    if (z.squared() === 0) {
+        z.z = 1;
+    }
+ 
+    var x = up.cross(z).normalize();
+ 
+    if (x.squared() === 0) {
+        z.x += 0.0001;
+        x = up.cross(z).normalize();
+    }
+ 
+    var y = z.cross(x);
+ 
+    this.rows[0].x = x.x;
+    this.rows[0].y = x.y;
+    this.rows[0].z = x.z;
+ 
+    this.rows[1].x = y.x;
+    this.rows[1].y = y.y;
+    this.rows[1].z = y.z;
+ 
+    this.rows[2].x = z.x;
+    this.rows[2].y = z.y;
+    this.rows[2].z = z.z;
+ 
+    return this;
+ 
+    // te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
+    // te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
+    // te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;
+ 
+ 
+    // var matrix4 = new Matrix4();
+    //
+    // matrix4.rows[0] = side.negative();
+    // matrix4.rows[1] = _up;
+    // matrix4.rows[2] = forward;
+ 
+    //
+    // matrix4.setColumn(0, side.negative());
+    // matrix4.setColumn(1, _up);
+    // matrix4.setColumn(2, forward);
+ 
+    //return matrix4;
+ 
+    // return new Matrix4(
+    //     new Vector4(
+    //         side.x,
+    //         side.y,
+    //         side.z,
+    //         side.negative().dot(position)
+    //     ),
+    //     new Vector4(
+    //         _up.x,
+    //         _up.y,
+    //         _up.z,
+    //         _up.negative().dot(position)
+    //     ),
+    //     new Vector4(
+    //         forward.negative().x,
+    //         forward.negative().y,
+    //         forward.negative().z,
+    //         forward.dot(position)
+    //     )
+    // )
+};
+ 
+/**
+ * Mesh Superset
+ * @param id
+ * @param path
+ * @param name
+ * @param meshType
+ * @param vertices
+ * @param faces
+ * @param skeleton
+ * @param faceVertexUvs
+ * @param skinIndices
+ * @param skinWeights
+ * @param materials
+ * @param position
+ * @param quaternion
+ * @param rotation
+ * @param scale
+ * @param up
+ * @param physics
+ * @param parentMeshId
+ * @param parentSceneId
+ * @param rawData
+ * @constructor
+ */
+GameLib.D3.Mesh = function(
+    id,
+    path,
+    name,
+    meshType,
+    vertices,
+    faces,
+    skeleton,
+    faceVertexUvs,
+    skinIndices,
+    skinWeights,
+    materials,
+    position,
+    quaternion,
+    rotation,
+    scale,
+    up,
+    physics,
+    parentMeshId,
+    parentSceneId,
+    rawData
+) {
+    this.id = id;
+    this.path = path;
+    this.name = name;
+    this.meshType = meshType;
+    this.vertices = vertices;
+    this.faces = faces;
+ 
+    if (typeof skeleton == 'undefined') {
+        skeleton = null;
+    }
+    this.skeleton = skeleton;
+ 
+    if (typeof faceVertexUvs == 'undefined') {
+        faceVertexUvs = [];
+    }
+    this.faceVertexUvs = faceVertexUvs;
+ 
+    if (typeof skinIndices == 'undefined') {
+        skinIndices = [];
+    }
+    this.skinIndices = skinIndices;
+ 
+    if (typeof skinWeights == 'undefined') {
+        skinWeights = [];
+    }
+    this.skinWeights = skinWeights;
+ 
+    if (typeof materials == 'undefined') {
+        materials = [];
+    }
+    this.materials = materials;
+ 
+    if (typeof position == 'undefined') {
+        position = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.position = position;
+ 
+    if (typeof quaternion == 'undefined') {
+        new GameLib.D3.Vector4();
+    }
+    this.quaternion = quaternion;
+ 
+    if (typeof rotation == 'undefined') {
+        rotation = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.rotation = rotation;
+ 
+    if (typeof scale == 'undefined') {
+        scale = new GameLib.D3.Vector3(1,1,1);
+    }
+    this.scale = scale;
+ 
+    if (typeof up == 'undefined') {
+        up = new GameLib.D3.Vector3(0,1,0);
+    }
+    this.up = up;
+ 
+    this.physics = physics;
+ 
+    this.parentMeshId = parentMeshId;
+ 
+    this.parentSceneId = parentSceneId;
+ 
+    this.rawData = null;// rawData;
+};
+ 
+ 
+/**
+ * Mesh Type
+ * @type {number}
+ */
+GameLib.D3.Mesh.TYPE_NORMAL = 0;
+GameLib.D3.Mesh.TYPE_SKINNED = 1;
+ 
+ 
+/**
+ * Creates a THREE Mesh from GameLib.D3.Mesh
+ * @param gameLibMesh
+ * @param threeGeometry
+ * @param threeMaterial
+ * @returns {*}
+ */
+GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) {
+ 
+    var threeMesh = null;
+ 
+    if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) {
+        threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial);
+    }
+ 
+    if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) {
+ 
+        var bones = gameLibMesh.skeleton.bones;
+ 
+        var skinIndices = gameLibMesh.skinIndices;
+ 
+        var skinWeights = gameLibMesh.skinWeights;
+ 
+        var threeBones = [];
+ 
+        for (var bi = 0; bi < bones.length; bi++) {
+ 
+            var bone = new this.THREE.Bone();
+ 
+            bone.name = bones[bi].name;
+ 
+            bone.position.x = bones[bi].position.x;
+            bone.position.y = bones[bi].position.y;
+            bone.position.z = bones[bi].position.z;
+ 
+            bone.rotation.x = bones[bi].rotation.x;
+            bone.rotation.y = bones[bi].rotation.y;
+            bone.rotation.z = bones[bi].rotation.z;
+ 
+            bone.quaternion.x = bones[bi].quaternion.x;
+            bone.quaternion.y = bones[bi].quaternion.y;
+            bone.quaternion.z = bones[bi].quaternion.z;
+            bone.quaternion.w = bones[bi].quaternion.w;
+ 
+            bone.scale.x = bones[bi].scale.x;
+            bone.scale.y = bones[bi].scale.y;
+            bone.scale.z = bones[bi].scale.z;
+ 
+            bone.up.x = bones[bi].up.x;
+            bone.up.y = bones[bi].up.y;
+            bone.up.z = bones[bi].up.z;
+ 
+            threeBones.push(bone);
+        }
+ 
+        /**
+         * Setup the bone relationships
+         */
+        for (var br = 0; br < bones.length; br++) {
+            for (var cbi = 0; cbi < bones[br].childBoneIds.length; cbi++) {
+                threeBones[br].add(threeBones[bones[br].childBoneIds[cbi]]);
+            }
+        }
+ 
+        /**
+         * Setup bones (indexes)
+         */
+        for (var si = 0; si < skinIndices.length; si++) {
+            threeGeometry.skinIndices.push(
+                new this.THREE.Vector4(
+                    skinIndices[si].x,
+                    skinIndices[si].y,
+                    skinIndices[si].z,
+                    skinIndices[si].w
+                )
+            );
+        }
+ 
+        /**
+         * Setup bones (weights)
+         */
+        for (var sw = 0; sw < skinWeights.length; sw++) {
+            threeGeometry.skinWeights.push(
+                new this.THREE.Vector4(
+                    skinWeights[sw].x,
+                    skinWeights[sw].y,
+                    skinWeights[sw].z,
+                    skinWeights[sw].w
+                )
+            );
+        }
+ 
+        threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial);
+ 
+        var skeleton = new this.THREE.Skeleton(threeBones);
+ 
+        skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture;
+ 
+        for (var i = 0; i < bones.length; i++) {
+            if (bones[i].parentBoneId === null) {
+                threeMesh.add(threeBones[i]);
+                break;
+            }
+        }
+ 
+        threeMesh.bind(skeleton);
+ 
+        threeMesh.pose();
+ 
+        threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh);
+        threeMesh.skeleton.skeletonHelper.material.linewidth = 5;
+    }
+ 
+    if (threeMesh == null) {
+        console.log('cannot handle meshes of type ' + gameLibMesh.meshType + ' yet.');
+    }
+ 
+    gameLibMesh.threeMeshId = threeMesh.id;
+ 
+    return threeMesh;
+};
+ 
+GameLib.D3.prototype.invertWindingOrder = function(triangles) {
+ 
+    for (var i = 0; i < triangles.length; i++) {
+        var v1 = triangles[i].v1;
+        triangles[i].v1 = triangles[i].v2;
+        triangles[i].v2 = v1;
+ 
+        var backupUV = triangles[i].triangle.v1uv;
+        triangles[i].triangle.v1uv = triangles[i].triangle.v2uv;
+        triangles[i].triangle.v2uv = backupUV;
+    }
+ 
+    return triangles;
+};
+ 
+/**
+ * This function resets a the winding order of a mesh from a reference point V (the average center of the mesh)
+ */
+GameLib.D3.prototype.resetWindingOrder = function(faces, vertices) {
+ 
+    var vertexList = new GameLib.D3.Vector3.Points();
+ 
+    for (var v = 0; v < vertices.length; v++) {
+        vertexList.add(new GameLib.D3.Vector3(
+            vertices[v].position.x,
+            vertices[v].position.y,
+            vertices[v].position.z
+        ));
+    }
+ 
+    var V = vertexList.average();
+ 
+    var triangles = [];
+ 
+    for (var s = 0; s < faces.length; s += 3) {
+ 
+        var v0 = faces[s];
+        var v1 = faces[s+1];
+        var v2 = faces[s+2];
+ 
+        triangles.push(
+            {
+                v0 : v0,
+                v1 : v1,
+                v2 : v2,
+                edges : [
+                    {v0: v0, v1: v1},
+                    {v0: v1, v1: v2},
+                    {v0: v2, v1: v0}
+                ],
+                winding : 0,
+                edgeIndex : -1,
+                processed : false
+            }
+        );
+    }
+ 
+    for (var i = 0; i < triangles.length; i++) {
+        if (
+            GameLib.D3.Vector3.clockwise(
+                vertices[triangles[i].v0].position,
+                vertices[triangles[i].v1].position,
+                vertices[triangles[i].v2].position,
+                V
+            )
+        ) {
+            console.log('clockwise');
+            var bv1 = triangles[i].v1;
+            triangles[i].v1 = triangles[i].v2;
+            triangles[i].v2 = bv1;
+        } else {
+            console.log('not clockwise');
+        }
+    }
+ 
+    return triangles;
+};
+ 
+/**
+ * This function resets the winding order for triangles in faces, given an initial triangle and orientation edge
+ * used pseudocode from
+ * http://stackoverflow.com/questions/17036970/how-to-correct-winding-of-triangles-to-counter-clockwise-direction-of-a-3d-mesh
+ *  We need to use a graph traversal algorithm,
+ *  lets assume we have method that returns neighbor of triangle on given edge
+ *
+ *      neighbor_on_egde( next_tria, edge )
+ *
+ *  to_process = set of pairs triangle and orientation edge, initial state is one good oriented triangle with any edge on it
+ *  processed = set of processed triangles; initial empty
+ *
+ *  while to_process is not empty:
+ *      next_tria, orientation_edge = to_process.pop()
+ *      add next_tria in processed
+ *      if next_tria is not opposite oriented than orientation_edge:
+ *          change next_tria (ABC) orientation  (B<->C)
+ *      for each edge (AB) in next_tria:
+ *          neighbor_tria = neighbor_on_egde( next_tria, edge )
+ *          if neighbor_tria exists and neighbor_tria not in processed:
+ *              to_process add (neighbor_tria, edge opposite oriented (BA))
+ * @param faces GameLib.D3.TriangleFace[]
+ * @param orientationEdge GameLib.D3.Vector2
+ * @returns {Array}
+ */
+GameLib.D3.fixWindingOrder = function(faces, orientationEdge) {
+ 
+    /**
+     * Checks if a TriangleFace belonging to a TriangleEdge has already been processed
+     * @param processed TriangleEdge[]
+     * @param triangle TriangleFace
+     * @returns {boolean}
+     */
+    function inProcessed(processed, triangle) {
+ 
+        for (var i = 0; i < processed.length; i++) {
+            if (processed[i].triangle.equals(triangle)) {
+                return true;
+            }
+        }
+ 
+        return false;
+    }
+ 
+    /**
+     * Returns a neighbouring triangle on a specific edge - preserving the edge orientation
+     * @param edge GameLib.D3.Vector2
+     * @param faces GameLib.D3.TriangleFace[]
+     * @param currentTriangle
+     * @returns {*}
+     */
+    function neighbourOnEdge(edge, faces, currentTriangle) {
+ 
+        for (var i = 0; i < faces.length; i++) {
+            if (
+                (faces[i].v0 == edge.x && faces[i].v1 == edge.y) ||
+                (faces[i].v1 == edge.x && faces[i].v2 == edge.y) ||
+                (faces[i].v2 == edge.x && faces[i].v0 == edge.y) ||
+                (faces[i].v0 == edge.y && faces[i].v1 == edge.x) ||
+                (faces[i].v1 == edge.y && faces[i].v2 == edge.x) ||
+                (faces[i].v2 == edge.y && faces[i].v0 == edge.x)
+            ) {
+ 
+                var triangle = new GameLib.D3.TriangleFace(
+                    faces[i].v0,
+                    faces[i].v1,
+                    faces[i].v2,
+                    faces[i].materialIndex,
+                    faces[i].v0uv,
+                    faces[i].v1uv,
+                    faces[i].v2uv
+                );
+ 
+                if (triangle.equals(currentTriangle)) {
+                    continue;
+                }
+ 
+                return new GameLib.D3.TriangleEdge(
+                    triangle,
+                    edge
+                );
+            }
+        }
+ 
+        return null;
+    }
+ 
+    var toProcess = [
+        new GameLib.D3.TriangleEdge(
+            new GameLib.D3.TriangleFace(
+                faces[0].v0,
+                faces[0].v1,
+                faces[0].v2,
+                faces[0].materialIndex,
+                faces[0].v0uv,
+                faces[0].v1uv,
+                faces[0].v2uv
+            ),
+            orientationEdge
+        )
+    ];
+ 
+    var processed = [];
+ 
+    while (toProcess.length > 0) {
+ 
+        var triangleEdge = toProcess.pop();
+ 
+        /**
+         * If edge is the same orientation (i.e. the edge order is the same as the given triangle edge) it needs to be reversed
+         * to have the same winding order)
+         */
+        if (
+            (triangleEdge.triangle.v0 == triangleEdge.edge.x &&
+            triangleEdge.triangle.v1 == triangleEdge.edge.y) ||
+            (triangleEdge.triangle.v1 == triangleEdge.edge.x &&
+            triangleEdge.triangle.v2 == triangleEdge.edge.y) ||
+            (triangleEdge.triangle.v2 == triangleEdge.edge.x &&
+            triangleEdge.triangle.v0 == triangleEdge.edge.y)
+        ) {
+            var backupV = triangleEdge.triangle.v1;
+            triangleEdge.triangle.v1 = triangleEdge.triangle.v2;
+            triangleEdge.triangle.v2 = backupV;
+ 
+            var backupUV = triangleEdge.triangle.v1uv;
+            triangleEdge.triangle.v1uv = triangleEdge.triangle.v2uv;
+            triangleEdge.triangle.v2uv = backupUV;
+        }
+ 
+        processed.push(triangleEdge);
+ 
+        var edges = [
+            new GameLib.D3.Vector2(
+                triangleEdge.triangle.v0,
+                triangleEdge.triangle.v1
+            ),
+            new GameLib.D3.Vector2(
+                triangleEdge.triangle.v1,
+                triangleEdge.triangle.v2
+            ),
+            new GameLib.D3.Vector2(
+                triangleEdge.triangle.v2,
+                triangleEdge.triangle.v0
+            )
+        ];
+ 
+        for (var j = 0; j < edges.length; j++) {
+            var neighbour = neighbourOnEdge(edges[j], faces, triangleEdge.triangle);
+            if (neighbour && !inProcessed(processed, neighbour.triangle)) {
+                toProcess.push(neighbour);
+            }
+        }
+    }
+ 
+    /**
+     * In processed - we will have some duplicates - only add the unique ones
+     * @type {Array}
+     */
+    var triangles = [];
+    for (var i = 0; i < processed.length; i++) {
+        var found = false;
+        for (var k = 0; k < triangles.length; k++) {
+            if (triangles[k].equals(processed[i].triangle)){
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            triangles.push(processed[i].triangle);
+        }
+    }
+ 
+    return triangles;
+};
+ 
+/**
+ * This is a work-around function to fix polys which don't triangulate because
+ * they could lie on Z-plane (XZ or YZ)) - we translate the poly to the origin, systematically rotate the poly around
+ * Z then Y axis
+ * @param verticesFlat []
+ * @param grain is the amount to systematically rotate the poly by - a finer grain means a more accurate maximum XY
+ * @return []
+ */
+GameLib.D3.fixPolyZPlane = function(verticesFlat, grain) {
+ 
+    if ((verticesFlat.length % 3) != 0 && !(verticesFlat.length > 9)) {
+        console.log("The vertices are not in the right length : " + verticesFlat.length);
+    }
+ 
+    var vertices = [];
+ 
+    var points = new GameLib.D3.Vector4.Points();
+ 
+    for (var i = 0; i < verticesFlat.length; i += 3) {
+        points.add(new GameLib.D3.Vector3(
+            verticesFlat[i],
+            verticesFlat[i + 1],
+            verticesFlat[i + 2]
+        ));
+    }
+ 
+    points.toOrigin();
+ 
+    points.maximizeXDistance(grain);
+ 
+    points.maximizeYDistance(grain);
+ 
+    for (i = 0; i < points.vectors.length; i++) {
+        vertices.push(
+            [
+                points.vectors[i].x,
+                points.vectors[i].y
+            ]
+        );
+    }
+ 
+    return vertices;
+};
+/**
+ * Physics SuperSet Namespace Object
+ * @param id
+ * @param name
+ * @param engine GameLib.D3.Engine
+ * @param worlds
+ * @returns {{World: World}}
+ * @constructor
+ */
+GameLib.D3.Physics = function(
+    id,
+    name,
+    engine,
+    worlds
+) {
+    this.id = id;
+    this.name = name;
+    this.engine = engine;
+ 
+    if (typeof worlds == 'undefined') {
+        worlds = [];
+    }
+    this.worlds = worlds;
+};
+ 
+ 
+/**
+ * Solver Types
+ * @type {number}
+ */
+GameLib.D3.Physics.SPLIT_SOLVER = 0x1;
+GameLib.D3.Physics.GS_SOLVER = 0x2;
+/**
+ * Contains a Poly vertex data structure
+ * @param localIndex
+ * @param mvertIndex
+ * @param uv GameLib.D3.Vector2
+ * @param materialIndex
+ * @param edgeIndex
+ * @constructor
+ */
+GameLib.D3.PolyVertex = function(
+    localIndex,
+    mvertIndex,
+    uv,
+    materialIndex,
+    edgeIndex
+) {
+    this.localIndex = localIndex;
+    this.mvertIndex = mvertIndex;
+    this.uv = uv;
+    this.materialIndex = materialIndex;
+    this.edgeIndex = edgeIndex;
+};
+ 
+/**
+ * Clone a PolyVertex
+ * @returns {GameLib.D3.PolyVertex}
+ */
+GameLib.D3.PolyVertex.prototype.clone = function() {
+    return new GameLib.D3.PolyVertex(
+        this.localIndex,
+        this.mvertIndex,
+        this.uv.copy(),
+        this.materialIndex,
+        this.edgeIndex
+    )
+};
+/**
+ * Physics Raycast Vehicle Superset
+ * TODO: body + wheels[]
+ * @constructor
+ */
+GameLib.D3.RaycastVehicle = function(
+) {
+    this.vehicleObject = null;
+};
+ 
+GameLib.D3.RaycastVehicle.prototype.GetWheelInfo = function(
+ 
+) {
+    // note: need a way to determine which engine we are currently using
+    return this.vehicleObject.wheelInfos;
+};
+ 
+/**
+ * Physics Rigid Body Vehicle Superset
+ * TODO: body + wheels[]
+ * @constructor
+ */
+GameLib.D3.RigidVehicle = function(
+) {
+    this.vehicleObject = null;
+};
+ 
+GameLib.D3.RigidVehicle.prototype.GetWheelInfo = function(
+ 
+) {
+    // note: need a way to determine which engine we are currently using
+    return this.vehicleObject.wheelBodies;
+};
+ 
+/**
+ * RigidBody Superset
+ * @param mass
+ * @param friction
+ * @param position
+ * @param quaternion
+ * @param velocity
+ * @param angularVelocity
+ * @param linearDamping
+ * @param angularDamping
+ * @param allowSleep
+ * @param sleepSpeedLimit
+ * @param sleepTimeLimit
+ * @param collisionFilterGroup
+ * @param collisionFilterMask
+ * @param fixedRotation
+ * @param shape
+ * @returns {GameLib.D3.Physics.RigidBody}
+ * @constructor
+ */
+GameLib.D3.RigidBody = function(
+    mass,
+    friction,
+    position,
+    quaternion,
+    velocity,
+    angularVelocity,
+    linearDamping,
+    angularDamping,
+    allowSleep,
+    sleepSpeedLimit,
+    sleepTimeLimit,
+    collisionFilterGroup,
+    collisionFilterMask,
+    fixedRotation,
+    shape
+) {
+ 
+    this.position = position || new GameLib.D3.Vector3();
+    this.velocity = velocity || new GameLib.D3.Vector3();
+    this.angularVelocity = angularVelocity || new GameLib.D3.Vector3();
+    this.quaternion = quaternion || new GameLib.D3.Vector4(0, 0, 0, 1);
+    this.mass = typeof mass == "undefined" ? 0 : mass;
+    this.friction = typeof friction == "undefined" ? 5 : friction;
+    this.linearDamping = typeof linearDamping == "undefined" ? 0.01 : linearDamping;
+    this.angularDamping = typeof angularDamping == "undefined" ? 0.01 : angularDamping;
+    this.allowSleep = typeof allowSleep == "undefined" ? true : allowSleep;
+    this.sleepSpeedLimit = typeof sleepSpeedLimit == "undefined" ? 0.1 : sleepSpeedLimit;
+    this.sleepTimeLimit = typeof sleepTimeLimit == "undefined" ? 1.0 : sleepTimeLimit;
+    this.collisionFilterGroup = typeof collisionFilterGroup == "undefined" ? 1 : collisionFilterGroup;
+    this.collisionFilterMask = typeof collisionFilterMask == "undefined" ? 1 : collisionFilterMask;
+    this.fixedRotation = typeof fixedRotation == "undefined" ? false : fixedRotation;
+    this.shape = typeof shape == "undefined" ? null : shape;
+ 
+    this.rigidBodyInstance = this.createRigidBodyInstance();
+};
+ 
+/**
+ *
+ * @returns {*}
+ */
+GameLib.D3.RigidBody.prototype.createRigidBodyInstance = function() {
+ 
+    var rigidBody = null;
+ 
+    // Create the bodyObject
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        rigidBody = new this.physics.CANNON.Body(
+            {
+                mass: mass,
+                friction: friction,
+                position: new this.physics.CANNON.Vec3(position.x, position.y, position.z),
+                velocity: new this.physics.CANNON.Vec3(velocity.x, velocity.y, velocity.z),
+                quaternion: new this.physics.CANNON.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w),
+                angularVelocity: new this.physics.CANNON.Vec3(angularVelocity.x, angularVelocity.y, angularVelocity.z),
+                linearDamping: linearDamping,
+                angularDamping: angularDamping,
+                allowSleep: allowSleep,
+                sleepSpeedLimit: sleepSpeedLimit,
+                sleepTimeLimit: sleepTimeLimit,
+                collisionFilterGroup: collisionFilterGroup,
+                collisionFilterMask: collisionFilterMask,
+                fixedRotation: fixedRotation,
+                shape: shape
+            }
+        );
+ 
+    }
+ 
+    return rigidBody;
+};
+ 
+ 
+/**
+ * Scenes are objects putting meshes into 'world space'
+ * @param id
+ * @param path String
+ * @param name String
+ * @param meshes GameLib.D3.Mesh[]
+ * @param quaternion
+ * @param position
+ * @param rotation
+ * @param scale
+ * @param parentSceneId
+ * @param lights
+ * @constructor
+ */
+GameLib.D3.Scene = function(
+    id,
+    path,
+    name,
+    meshes,
+    quaternion,
+    position,
+    rotation,
+    scale,
+    parentSceneId,
+    lights,
+    physics
+) {
+    this.id = id;
+    this.path = path;
+    this.name = name;
+    if (this.name.trim() == "") {
+        this.name = 'unnamed';
+    }
+    this.meshes = meshes;
+ 
+    if (typeof quaternion == 'undefined') {
+        quaternion = new GameLib.D3.Vector4();
+    }
+    this.quaternion = quaternion;
+ 
+    if (typeof position == 'undefined') {
+        position = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.position = position;
+ 
+    if (typeof rotation == 'undefined') {
+        rotation = new GameLib.D3.Vector3(0,0,0);
+    }
+    this.rotation = rotation;
+ 
+    if (typeof scale == 'undefined') {
+        scale = new GameLib.D3.Vector3(1,1,1);
+    }
+    this.scale = scale;
+ 
+    if (typeof parentSceneId == 'undefined') {
+        parentSceneId = null;
+    }
+    this.parentSceneId = parentSceneId;
+ 
+    if (typeof lights == 'undefined') {
+        lights = [];
+    }
+    this.lights = lights;
+ 
+    if (typeof physics == 'undefined') {
+        physics = [];
+    }
+    this.physics = physics;
+};
+ 
+/**
+ * Loads a scene directly from the API
+ * @param sceneName
+ * @param onLoaded callback
+ */
+GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) {
+ 
+    /**
+     * First check if this is a client or server side request
+     */
+    if (typeof XMLHttpRequest == 'undefined') {
+        console.warn('implement server side loading from API here');
+        return onLoaded(null, new Error('not implemented'));
+    }
+ 
+    var xhr = new XMLHttpRequest();
+    xhr.open(
+        'GET',
+        this.apiUrl + '/scene/load' + scene.path + '/' + scene.name
+    );
+ 
+    xhr.onreadystatechange = function(xhr, gameLibD3) {
+        return function() {
+            if (xhr.readyState == 4) {
+ 
+                var response = JSON.parse(xhr.responseText);
+ 
+                if (!response.scene || response.scene.length == 0) {
+                    return onLoaded(null, null, new Error('Could not load scene'));
+                }
+ 
+                var scene = response.scene[0];
+ 
+                var physics3ds = [];
+ 
+                if (scene.physics && scene.physics.length > 0) {
+ 
+                    for (var p = 0; p < scene.physics.length; p++) {
+ 
+                        var physics = scene.physics[p];
+ 
+                        var physics3d = new GameLib.D3.Physics(
+                            physics.id,
+                            physics.name,
+                            physics.engineType,
+                            gameLibD3.CANNON,
+                            null,
+                            null
+                        );
+ 
+                        var worlds3d = [];
+ 
+                        for (var w = 0; w < physics.worlds.length; w++) {
+ 
+                            var world = physics.worlds[w];
+ 
+                            var broadphase = world.broadphase;
+ 
+                            var broadphase3d = new GameLib.D3.Physics.Broadphase(
+                                broadphase.id,
+                                broadphase.name,
+                                broadphase.broadphaseType
+                            );
+ 
+                            var solver = world.solver;
+ 
+                            var solver3d = new GameLib.D3.Physics.Solver(
+                                solver.id,
+                                solver.name,
+                                solver.solverType,
+                                solver.iterations,
+                                solver.tolerance
+                            );
+ 
+                            var bodies = world.rigidBodies;
+ 
+                            var bodies3d = [];
+ 
+                            for (var b = 0; b < bodies.length; b++) {
+ 
+                                var body = bodies[b];
+ 
+                                //TODO: add all body properties here
+                                var body3d = new GameLib.D3.Physics.RigidBody(
+                                    body.id,
+                                    body.name
+                                );
+ 
+                                bodies3d.push(body3d);
+                            }
+ 
+                            var world3d = new GameLib.D3.Physics.World(
+                                null,
+                                world.name,
+                                physics3d,
+                                new GameLib.D3.Vector3(
+                                    world.gravity.x,
+                                    world.gravity.y,
+                                    world.gravity.z
+                                ),
+                                broadphase3d,
+                                solver3d,
+                                bodies3d
+                            );
+ 
+                            worlds3d.push(world3d);
+                        }
+ 
+                        physics3ds.push(physics3d);
+                    }
+                }
+ 
+                var lights3d = [];
+ 
+                for (var l = 0; l < scene.lights.length; l++) {
+ 
+                    var light = scene.lights[l];
+ 
+                    var light3d = new GameLib.D3.Light(
+                        light.id,
+                        light.lightType,
+                        light.name,
+                        new GameLib.D3.Color(
+                            light.color.r,
+                            light.color.g,
+                            light.color.b,
+                            light.color.a
+                        ),
+                        light.intensity,
+                        new GameLib.D3.Vector3(
+                            light.position.x,
+                            light.position.y,
+                            light.position.z
+                        ),
+                        new GameLib.D3.Vector3(
+                            light.targetPosition.x,
+                            light.targetPosition.y,
+                            light.targetPosition.z
+                        ),
+                        new GameLib.D3.Vector4(
+                            light.quaternion.x,
+                            light.quaternion.y,
+                            light.quaternion.z,
+                            light.quaternion.w
+                        ),
+                        new GameLib.D3.Vector3(
+                            light.rotation.x,
+                            light.rotation.y,
+                            light.rotation.z
+                        ),
+                        new GameLib.D3.Vector3(
+                            light.scale.x,
+                            light.scale.y,
+                            light.scale.z
+                        ),
+                        light.distance,
+                        light.decay,
+                        light.power,
+                        light.angle,
+                        light.penumbra
+                    );
+ 
+                    lights3d.push(light3d);
+                };
+ 
+                var scene3d = new GameLib.D3.Scene(
+                    scene._id || scene.id,
+                    scene.path,
+                    scene.name,
+                    scene.meshes,
+                    new GameLib.D3.Vector4(
+                        scene.quaternion.x,
+                        scene.quaternion.y,
+                        scene.quaternion.z,
+                        scene.quaternion.w
+                    ),
+                    new GameLib.D3.Vector3(
+                        scene.position.x,
+                        scene.position.y,
+                        scene.position.z
+                    ),
+                    new GameLib.D3.Vector3(
+                        scene.rotation.x,
+                        scene.rotation.y,
+                        scene.rotation.z
+                    ),
+                    new GameLib.D3.Vector3(
+                        scene.scale.x,
+                        scene.scale.y,
+                        scene.scale.z
+                    ),
+                    scene.parentSceneId,
+                    lights3d,
+                    physics3ds
+                );
+ 
+                gameLibD3.loadScene(scene3d, onLoaded, false);
+            }
+        }
+    }(xhr, this);
+ 
+    xhr.send();
+};
+ 
+ 
+/**
+ * Loads a GameLib.D3.Scene object into a ThreeJS Scene object
+ * @param gameLibScene GameLib.D3.Scene
+ * @param onLoaded callback when all meshes have loaded
+ * @param computeNormals set to true to compute new face and vertex normals during load
+ */
+GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) {
+ 
+    console.log("loading scene " + gameLibScene.name);
+ 
+    this.path = gameLibScene.path;
+ 
+    var meshQ = [];
+ 
+    for (var m = 0; m < gameLibScene.meshes.length; m++) {
+ 
+        var mesh = gameLibScene.meshes[m];
+ 
+        console.log("loading mesh " + mesh.name);
+ 
+        var geometry = new this.THREE.Geometry();
+ 
+        var vertices = mesh.vertices;
+ 
+        var faces = mesh.faces;
+ 
+        var faceVertexUvs = mesh.faceVertexUvs;
+ 
+        var materials = mesh.materials;
+ 
+        /**
+         * Setup vertices
+         */
+        for (var v = 0; v < vertices.length; v++) {
+            geometry.vertices.push(
+                new this.THREE.Vector3(
+                    vertices[v].position.x,
+                    vertices[v].position.y,
+                    vertices[v].position.z
+                )
+            )
+        }
+ 
+        /**
+         * Setup faces
+         */
+        for (var f = 0; f < faces.length; f++) {
+ 
+            var face = new this.THREE.Face3(
+                faces[f].v0,
+                faces[f].v1,
+                faces[f].v2,
+                new this.THREE.Vector3(
+                    faces[f].normal.x,
+                    faces[f].normal.y,
+                    faces[f].normal.z
+                ),
+                new this.THREE.Color(
+                    faces[f].color.r,
+                    faces[f].color.g,
+                    faces[f].color.b
+                ),
+                faces[f].materialIndex
+            );
+ 
+            face.vertexColors = [
+                new this.THREE.Color(
+                    faces[f].vertexColors[0].r,
+                    faces[f].vertexColors[0].g,
+                    faces[f].vertexColors[0].b
+                ),
+                new this.THREE.Color(
+                    faces[f].vertexColors[1].r,
+                    faces[f].vertexColors[1].g,
+                    faces[f].vertexColors[1].b
+                ),
+                new this.THREE.Color(
+                    faces[f].vertexColors[2].r,
+                    faces[f].vertexColors[2].g,
+                    faces[f].vertexColors[2].b
+                )
+            ];
+ 
+            face.normal = new this.THREE.Vector3(
+                faces[f].normal.x,
+                faces[f].normal.y,
+                faces[f].normal.z
+            );
+ 
+            face.vertexNormals = [
+                new this.THREE.Vector3(
+                    faces[f].vertexNormals[0].x,
+                    faces[f].vertexNormals[0].y,
+                    faces[f].vertexNormals[0].z
+                ),
+                new this.THREE.Vector3(
+                    faces[f].vertexNormals[1].x,
+                    faces[f].vertexNormals[1].y,
+                    faces[f].vertexNormals[1].z
+                ),
+                new this.THREE.Vector3(
+                    faces[f].vertexNormals[2].x,
+                    faces[f].vertexNormals[2].y,
+                    faces[f].vertexNormals[2].z
+                )
+            ];
+ 
+            geometry.faces.push(face);
+        }
+ 
+        geometry.faceVertexUvs = [];
+ 
+        /**
+         * Setup face UVs
+         */
+        for (var fm = 0; fm < faceVertexUvs.length; fm++) {
+ 
+            var faceMaterialVertexUvs = faceVertexUvs[fm];
+ 
+            geometry.faceVertexUvs[fm] = [];
+ 
+            for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) {
+                geometry.faceVertexUvs[fm][fuv] = [];
+                geometry.faceVertexUvs[fm][fuv].push(
+                    new this.THREE.Vector2(
+                        faceMaterialVertexUvs[fuv][0].x,
+                        faceMaterialVertexUvs[fuv][0].y
+                    ),
+                    new this.THREE.Vector2(
+                        faceMaterialVertexUvs[fuv][1].x,
+                        faceMaterialVertexUvs[fuv][1].y
+                    ),
+                    new this.THREE.Vector2(
+                        faceMaterialVertexUvs[fuv][2].x,
+                        faceMaterialVertexUvs[fuv][2].y
+                    )
+                );
+            }
+        }
+ 
+        /**
+         * Re-calculate normals (if we have to)
+         * @type {Array}
+         */
+        if (computeNormals) {
+            geometry.computeFaceNormals();
+            geometry.computeVertexNormals();
+        }
+ 
+        var threeMaterialLoaders = [];
+ 
+        /**
+         * Setup materials
+         */
+        for (var mi = 0; mi < materials.length; mi++) {
+            threeMaterialLoaders.push(this.createThreeMaterial(materials[mi]));
+        }
+ 
+        var result = this.Q.all(threeMaterialLoaders).then(
+            function(gl3d, mesh, geometry) {
+                return function(materials) {
+ 
+                    console.log("loaded material : " + materials[0].name);
+ 
+                    /**
+                     * We don't support MultiMaterial atm - it doesn't work with raycasting
+                     */
+                    var material = materials[0];
+ 
+                    var threeMesh = gl3d.createThreeMesh(mesh, geometry, material);
+                    threeMesh.name = mesh.name;
+ 
+                    threeMesh.position.x = mesh.position.x;
+                    threeMesh.position.y = mesh.position.y;
+                    threeMesh.position.z = mesh.position.z;
+ 
+                    threeMesh.rotation.x = mesh.rotation.x;
+                    threeMesh.rotation.y = mesh.rotation.y;
+                    threeMesh.rotation.z = mesh.rotation.z;
+ 
+                    threeMesh.scale.x = mesh.scale.x;
+                    threeMesh.scale.y = mesh.scale.y;
+                    threeMesh.scale.z = mesh.scale.z;
+ 
+                    threeMesh.quaternion.x = mesh.quaternion.x;
+                    threeMesh.quaternion.y = mesh.quaternion.y;
+                    threeMesh.quaternion.z = mesh.quaternion.z;
+                    threeMesh.quaternion.w = mesh.quaternion.w;
+ 
+                    return threeMesh;
+                };
+            }(this, mesh, geometry)
+        ).catch(function(error){
+            console.log(error);
+        });
+ 
+        meshQ.push(result);
+    }
+ 
+    this.Q.all(meshQ).then(function(threeMeshes){
+        console.log("all meshes have loaded");
+        if (typeof onLoaded != 'undefined') {
+ 
+            var threeLights = [];
+ 
+            for (var sli = 0; sli < gameLibScene.lights.length; sli++) {
+ 
+                var blenderLight = gameLibScene.lights[sli];
+ 
+                var light = null;
+ 
+                if (blenderLight.lightType == 'AmbientLight') {
+                    light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity);
+                }
+ 
+                if (blenderLight.lightType == 'DirectionalLight') {
+                    light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity);
+                }
+ 
+                if (blenderLight.lightType == 'PointLight') {
+                    light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity);
+                    light.distance = blenderLight.distance;
+                    light.decay = blenderLight.decay;
+                }
+ 
+                if (blenderLight.lightType == 'SpotLight') {
+                    light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity);
+                    light.distance = blenderLight.distance;
+                    light.angle = blenderLight.angle;
+                    light.penumbra = blenderLight.penumbra;
+                    light.decay = blenderLight.decay;
+                }
+ 
+                light.position.x = blenderLight.position.x;
+                light.position.y = blenderLight.position.y;
+                light.position.z = blenderLight.position.z;
+ 
+                light.rotation.x = blenderLight.rotation.x;
+                light.rotation.y = blenderLight.rotation.y;
+                light.rotation.z = blenderLight.rotation.z;
+ 
+                // light.scale.x = blenderLight.scale.x;
+                // light.scale.y = blenderLight.scale.y;
+                // light.scale.z = blenderLight.scale.z;
+ 
+                if (light == null) {
+                    console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported');
+                } else {
+                    light.name = blenderLight.name;
+                    threeLights.push(light);
+                }
+            }
+ 
+            var threeScene = new this.THREE.Scene();
+ 
+            threeScene.name = gameLibScene.name;
+ 
+            threeScene.position.x = gameLibScene.position.x;
+            threeScene.position.y = gameLibScene.position.y;
+            threeScene.position.z = gameLibScene.position.z;
+ 
+            threeScene.rotation.x = gameLibScene.rotation.x;
+            threeScene.rotation.y = gameLibScene.rotation.y;
+            threeScene.rotation.z = gameLibScene.rotation.z;
+ 
+            threeScene.scale.x = gameLibScene.scale.x;
+            threeScene.scale.y = gameLibScene.scale.y;
+            threeScene.scale.z = gameLibScene.scale.z;
+ 
+            threeScene.quaternion.x = gameLibScene.quaternion.x;
+            threeScene.quaternion.y = gameLibScene.quaternion.y;
+            threeScene.quaternion.z = gameLibScene.quaternion.z;
+            threeScene.quaternion.w = gameLibScene.quaternion.w;
+ 
+            for (var m = 0; m < threeMeshes.length; m++) {
+                threeScene.add(threeMeshes[m]);
+            }
+ 
+            for (var l = 0; l < threeLights.length; l++) {
+                threeScene.add(threeLights[l]);
+            }
+ 
+            onLoaded(
+                gameLibScene,
+                {
+                    scene: threeScene,
+                    lights: threeLights,
+                    meshes: threeMeshes
+                }
+            );
+        }
+    }.bind(this)).catch(function(error){
+        console.log(error);
+    });
+};
+/**
+ * Physics Shape Superset
+ * @constructor
+ */
+GameLib.D3.Physics.Shape = function(
+    shapeObject,     // Physics engine specific
+    shapeType
+) {
+    this.shapeObject = shapeObject;
+    this.shapeType = shapeType;
+    this.scale = new GameLib.D3.Vector3(1, 1, 1);
+};
+ 
+GameLib.D3.Physics.SHAPE_TYPE_SPHERE        = 1;
+GameLib.D3.Physics.SHAPE_TYPE_BOX           = 2;
+GameLib.D3.Physics.SHAPE_TYPE_TRIMESH       = 3;
+GameLib.D3.Physics.SHAPE_TYPE_CYLINDER      = 4;
+ 
+ 
+GameLib.D3.Physics.Shape.prototype.Update = function() {
+    if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) {
+        if(this.shapeType === GameLib.D3.Physics.SHAPE_TYPE_TRIMESH) {
+            this.shapeObject.setScale(
+                new this.physics.CANNON.Vec3(
+                    this.scale.x,
+                    this.scale.y,
+                    this.scale.z
+                )
+            );
+            this.shapeObject.updateAABB();
+            this.shapeObject.updateNormals();
+            this.shapeObject.updateEdges();
+            this.shapeObject.updateBoundingSphereRadius();
+            this.shapeObject.updateTree();
+        }
+    }
+};
+ 
+/**
+ * Skeleton Superset
+ * @param id
+ * @param bones GameLib.D3.Bone
+ * @param boneInverses
+ * @param useVertexTexture
+ * @param boneTextureWidth
+ * @param boneTextureHeight
+ * @param boneMatrices
+ * @param boneTexture
+ * @constructor
+ */
+GameLib.D3.Skeleton = function(
+    id,
+    bones,
+    boneInverses,
+    useVertexTexture,
+    boneTextureWidth,
+    boneTextureHeight,
+    boneMatrices,
+    boneTexture
+) {
+    this.id = id;
+ 
+    this.bones = bones;
+ 
+    /**
+     * An array of Matrix4s that represent the inverse of the matrixWorld of the individual bones.
+     * @type GameLib.D3.Matrix4[]
+     */
+    if (typeof boneInverses == 'undefined') {
+        boneInverses = [];
+    }
+    this.boneInverses = boneInverses;
+ 
+    /**
+     * Use a vertex texture in the shader - allows for more than 4 bones per vertex, not supported by all devices
+     * @type {boolean}
+     */
+    if (typeof useVertexTexture == 'undefined') {
+        useVertexTexture = false;
+    }
+    this.useVertexTexture = useVertexTexture;
+ 
+    if (this.useVertexTexture == true) {
+        console.warn('support for vertex texture bones is not supported yet - something could break somewhere');
+    }
+ 
+    if (typeof boneTextureWidth == 'undefined') {
+        boneTextureWidth = 0;
+    }
+    this.boneTextureWidth = boneTextureWidth;
+ 
+    if (typeof boneTextureHeight == 'undefined') {
+        boneTextureHeight = 0;
+    }
+    this.boneTextureHeight = boneTextureHeight;
+ 
+    if (typeof boneMatrices == 'undefined') {
+        boneMatrices = [];
+    }
+    this.boneMatrices = boneMatrices;
+ 
+    if (typeof boneTexture == 'undefined') {
+        boneTexture = [];
+    }
+    this.boneTexture = boneTexture;
+};
+ 
+ 
+GameLib.D3.SkyBox = function (
+ 
+) {
+    this.id = null;
+    this.texturesFolder = null;
+};
+ 
+GameLib.D3.SkyBox.prototype.Load = function (
+    texturesFolder
+) {
+    this.texturesFolder = texturesFolder;
+    this.textures = [];
+    this.materials = [];
+    this.mesh = {};
+    this.scene = new THREE.Scene();
+    this.textureCube = null;
+ 
+    var textureLoader = new THREE.TextureLoader();
+ 
+    // this textures are used to display the skybox
+    this.textures.push(textureLoader.load(this.texturesFolder + "px.png"));
+    this.textures.push(textureLoader.load(this.texturesFolder + "nx.png"));
+    this.textures.push(textureLoader.load(this.texturesFolder + "py.png"));
+    this.textures.push(textureLoader.load(this.texturesFolder + "ny.png"));
+    this.textures.push(textureLoader.load(this.texturesFolder + "pz.png"));
+    this.textures.push(textureLoader.load(this.texturesFolder + "nz.png"));
+ 
+    // assign textures to each cube face
+    for (var i = 0; i < 6; i ++) {
+        this.materials.push(new THREE.MeshBasicMaterial({ map: this.textures[i] }));
+    }
+ 
+    // create cube geometry
+    this.mesh = new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshFaceMaterial(this.materials));
+    this.mesh.applyMatrix(new THREE.Matrix4().makeScale(1, 1, -1));
+    this.scene.add(this.mesh);
+ 
+    // Load env textureCube
+    // this is used for reflections on meshes
+    // mesh.material.envMap = this.textureCube;
+    this.textureCube = new THREE.CubeTextureLoader().load([
+        this.texturesFolder + "px.png", this.texturesFolder + "nx.png",
+        this.texturesFolder + "py.png", this.texturesFolder + "ny.png",
+        this.texturesFolder + "pz.png", this.texturesFolder + "nz.png"
+    ]);
+};
+ 
+GameLib.D3.SkyBox.prototype.Render = function (
+    threeRenderer,
+    threeCamera
+) {
+    var cameraPosition = new THREE.Vector3(threeCamera.position.x, threeCamera.position.y, threeCamera.position.z);
+ 
+    threeCamera.position.set(0, 0, 0);
+ 
+    var gl = threeRenderer.context;
+ 
+    gl.disable(gl.DEPTH_TEST);
+ 
+    threeRenderer.render(this.scene, threeCamera);
+ 
+    gl.enable(gl.DEPTH_TEST);
+ 
+    threeCamera.position.copy(cameraPosition);
+};
+ 
+/**
+ * Physics Solver Superset
+ * @param id
+ * @param name
+ * @param solverType
+ * @param iterations
+ * @param tolerance
+ * @constructor
+ */
+GameLib.D3.Physics.Solver = function(
+    id,
+    name,
+    solverType,
+    iterations,
+    tolerance
+) {
+    this.id = id;
+    if (typeof name == 'undefined') {
+        if (solverType == GameLib.D3.Physics.SPLIT_SOLVER) {
+            name = 'split solver';
+        } else if (solverType == GameLib.D3.Physics.GS_SOLVER) {
+            name = 'gs solver';
+        } else {
+            name = 'unknown solver';
+        }
+    }
+    this.name = name;
+    this.solverType = solverType;
+    this.iterations = iterations;
+    this.tolerance = tolerance;
+};
+ 
+/**
+ * Solver Types
+ * @type {number}
+ */
+GameLib.D3.Physics.SPLIT_SOLVER = 0x1;
+GameLib.D3.Physics.GS_SOLVER = 0x2;
+ 
+/**
+ * Texture Superset
+ * @param id
+ * @param name
+ * @param image
+ * @param wrapS
+ * @param wrapT
+ * @param repeat
+ * @param data
+ * @param format
+ * @param mapping
+ * @param magFilter
+ * @param minFilter
+ * @param textureType
+ * @param anisotropy
+ * @param offset
+ * @param generateMipmaps
+ * @param flipY
+ * @param mipmaps
+ * @param unpackAlignment
+ * @param premultiplyAlpha
+ * @param encoding
+ * @constructor
+ */
+GameLib.D3.Texture = function(
+    id,
+    name,
+    image,
+    wrapS,
+    wrapT,
+    repeat,
+    data,
+    format,
+    mapping,
+    magFilter,
+    minFilter,
+    textureType,
+    anisotropy,
+    offset,
+    generateMipmaps,
+    flipY,
+    mipmaps,
+    unpackAlignment,
+    premultiplyAlpha,
+    encoding
+) {
+    this.id = id;
+    this.name = name;
+    this.image = image;
+ 
+    if (typeof wrapS == 'undefined') {
+        wrapS = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING;
+    }
+    this.wrapS = wrapS;
+ 
+    if (typeof wrapT == 'undefined') {
+        wrapT = GameLib.D3.Texture.TYPE_REPEAT_WRAPPING;
+    }
+    this.wrapT = wrapT;
+ 
+    if (typeof repeat == 'undefined') {
+        repeat = new GameLib.D3.Vector2(1, 1);
+    }
+    this.repeat = repeat;
+ 
+    if (typeof data == 'undefined') {
+        data = null;
+    }
+    this.data = data;
+ 
+    if (typeof format == 'undefined') {
+        format = GameLib.D3.Texture.TYPE_RGBA_FORMAT;
+    }
+    this.format = format;
+ 
+    if (typeof mapping == 'undefined') {
+        mapping = GameLib.D3.Texture.TYPE_UV_MAPPING;
+    }
+    this.mapping = mapping;
+ 
+    if (typeof magFilter == 'undefined') {
+        magFilter = GameLib.D3.Texture.TYPE_LINEAR_FILTER;
+    }
+    this.magFilter = magFilter;
+ 
+    if (typeof minFilter == 'undefined') {
+        minFilter = GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER;
+    }
+    this.minFilter = minFilter;
+ 
+    if (typeof textureType == 'undefined') {
+        textureType = GameLib.D3.Texture.TYPE_UNSIGNED_BYTE;
+    }
+    this.textureType = textureType;
+ 
+    if (typeof anisotropy == 'undefined') {
+        anisotropy = 1;
+    }
+    this.anisotropy = anisotropy;
+ 
+    if (typeof offset == 'undefined') {
+        offset = new GameLib.D3.Vector2(0, 0);
+    }
+    this.offset = offset;
+ 
+    if (typeof generateMipmaps == 'undefined') {
+        generateMipmaps = true;
+    }
+    this.generateMipmaps = generateMipmaps;
+ 
+    if (typeof flipY == 'undefined') {
+        flipY = true;
+    }
+    this.flipY = flipY;
+ 
+    if (typeof mipmaps == 'undefined') {
+        mipmaps = [];
+    }
+    this.mipmaps = mipmaps;
+ 
+    if (typeof unpackAlignment == 'undefined') {
+        unpackAlignment = 4;
+    }
+    this.unpackAlignment = unpackAlignment;
+ 
+    if (typeof premultiplyAlpha == 'undefined') {
+        premultiplyAlpha = false;
+    }
+    this.premultiplyAlpha = premultiplyAlpha;
+ 
+    if (typeof encoding == 'undefined') {
+        encoding = GameLib.D3.Texture.TYPE_LINEAR_ENCODING;
+    }
+    this.encoding = encoding;
+};
+ 
+/**
+ * Texture Formats
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_ALPHA_FORMAT = 1019;
+GameLib.D3.Texture.TYPE_RGB_FORMAT = 1020;
+GameLib.D3.Texture.TYPE_RGBA_FORMAT = 1021;
+GameLib.D3.Texture.TYPE_LUMINANCE_FORMAT = 1022;
+GameLib.D3.Texture.TYPE_LUMINANCE_ALPHA_FORMAT = 1023;
+GameLib.D3.Texture.TYPE_DEPTH_FORMAT = 1026;
+ 
+/**
+ * Mapping modes
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_UV_MAPPING = 300;
+GameLib.D3.Texture.TYPE_CUBE_REFLECTION_MAPPING = 301;
+GameLib.D3.Texture.TYPE_CUBE_REFRACTION_MAPPING = 302;
+GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFLECTION_MAPPING = 303;
+GameLib.D3.Texture.TYPE_EQUI_RECTANGULAR_REFRACTION_MAPPING = 304;
+GameLib.D3.Texture.TYPE_SPHERICAL_REFLECTION_MAPPING = 305;
+GameLib.D3.Texture.TYPE_CUBE_UV_REFLECTION_MAPPING = 306;
+GameLib.D3.Texture.TYPE_CUBE_UV_REFRACTION_MAPPING = 307;
+ 
+/**
+ * Wrapping Modes
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_REPEAT_WRAPPING = 1000;
+GameLib.D3.Texture.TYPE_CLAMP_TO_EDGE_WRAPPING = 1001;
+GameLib.D3.Texture.TYPE_MIRRORED_REPEAT_WRAPPING = 1002;
+ 
+/**
+ * Mipmap Filters
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_NEAREST_FILTER = 1003;
+GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_NEAREST_FILTER = 1004;
+GameLib.D3.Texture.TYPE_NEAREST_MIPMAP_LINEAR_FILTER = 1005;
+GameLib.D3.Texture.TYPE_LINEAR_FILTER = 1006;
+GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_NEAREST_FILTER = 1007;
+GameLib.D3.Texture.TYPE_LINEAR_MIPMAP_LINEAR_FILTER = 1008;
+ 
+/**
+ * Texture Data Types
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_UNSIGNED_BYTE = 1009;
+GameLib.D3.Texture.TYPE_BYTE = 1010;
+GameLib.D3.Texture.TYPE_SHORT = 1011;
+GameLib.D3.Texture.TYPE_UNSIGNED_SHORT = 1012;
+GameLib.D3.Texture.TYPE_INT = 1013;
+GameLib.D3.Texture.TYPE_UNSIGNED_INT = 1014;
+GameLib.D3.Texture.TYPE_FLOAT = 1015;
+GameLib.D3.Texture.TYPE_HALF_FLOAT = 1025;
+ 
+/**
+ * Encoding Modes
+ * @type {number}
+ */
+GameLib.D3.Texture.TYPE_LINEAR_ENCODING = 3000; // NO ENCODING AT ALL.
+GameLib.D3.Texture.TYPE_SRGB_ENCODING = 3001;
+GameLib.D3.Texture.TYPE_GAMMA_ENCODING = 3007; // USES GAMMA_FACTOR, FOR BACKWARDS COMPATIBILITY WITH WEBGLRENDERER.GAMMAINPUT/GAMMAOUTPUT
+GameLib.D3.Texture.TYPE_RGBE_ENCODING = 3002; // AKA RADIANCE.
+GameLib.D3.Texture.TYPE_LOG_LUV_ENCODING = 3003;
+GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004;
+GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005;
+GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256.
+ 
+ 
+ 
+/**
+ * Defers loading of an image and resolves once image is loaded
+ * @param gameLibTexture
+ * @param threeMaterial
+ * @param threeMaterialMapType
+ * @returns {Promise}
+ */
+GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) {
+ 
+    var q = this.Q.defer();
+ 
+    var imagePath = null;
+ 
+    if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) {
+        /**
+         * Else, load from upload source
+         */
+        imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename;
+    }
+ 
+    if (imagePath) {
+ 
+        this.textureLoader.crossOrigin = '';
+ 
+        this.textureLoader.load(
+            imagePath,
+            function(texture) {
+                /**
+                 * onLoad
+                 */
+                threeMaterial[threeMaterialMapType] = texture;
+                threeMaterial[threeMaterialMapType].name = gameLibTexture.name;
+                threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy;
+                threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding;
+                threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY;
+                /**
+                 * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes
+                 */
+                threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps;
+                threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter;
+                threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter;
+                threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping;
+                threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps;
+                threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2(
+                    gameLibTexture.offset.x,
+                    gameLibTexture.offset.y
+                );
+                threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha;
+                threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType;
+                threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS;
+                threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT;
+                threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment;
+                threeMaterial.needsUpdate = true;
+                q.resolve(true);
+            },
+            function(xhr) {
+                /**
+                 * onProgress
+                 */
+                if (this.editor) {
+                    this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success');
+                }
+            },
+            function(error) {
+                /**
+                 * onError
+                 */
+                console.log("an error occurred while trying to load the image : " + imagePath);
+                q.resolve(null);
+            }
+        );
+ 
+    } else {
+        q.resolve(null);
+    }
+ 
+    return q.promise;
+};
+ 
+ 
+/**
+ * Returns an array of image loading Promises
+ * @param blenderMaterial
+ * @param blenderMaps
+ * @param threeMaterial
+ * @returns Q[]
+ */
+GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) {
+ 
+    var textureMaps = [];
+ 
+    for (var ti = 0; ti < blenderMaps.length; ti++) {
+ 
+        var map = blenderMaps[ti];
+ 
+        if (blenderMaterial.maps.hasOwnProperty(map)) {
+ 
+            var blenderTexture = blenderMaterial.maps[map];
+ 
+            if (
+                blenderTexture &&
+                blenderTexture.image &&
+                blenderTexture.image.filename
+            ) {
+ 
+                var threeMap = null;
+ 
+                if (map == 'alpha') {
+                    threeMap = 'alhpaMap';
+                }
+ 
+                if (map == 'ao') {
+                    threeMap = 'aoMap';
+                }
+ 
+                if (map == 'bump') {
+                    threeMap = 'bumpMap';
+                }
+ 
+                if (map == 'displacement') {
+                    threeMap = 'displacementMap';
+                }
+ 
+                if (map == 'emissive') {
+                    threeMap = 'emissiveMap';
+                }
+ 
+                if (map == 'environment') {
+                    threeMap = 'envMap';
+                }
+ 
+                if (map == 'light') {
+                    threeMap = 'lightMap';
+                }
+ 
+                if (map == 'specular') {
+                    threeMap = 'specularMap';
+                }
+ 
+                if (map == 'diffuse') {
+                    threeMap = 'map';
+                }
+ 
+                if (map == 'roughness') {
+                    threeMap = 'roughnessMap';
+                }
+ 
+                if (map == 'metalness') {
+                    threeMap = 'metalnessMap';
+                }
+ 
+                if (threeMap == null) {
+                    console.warn("unsupported map type : " + map);
+                }
+ 
+                textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap));
+            }
+        }
+    }
+ 
+    return textureMaps;
+};
+ 
+/**
+ * TriangleEdge
+ * @param triangle
+ * @param edge
+ * @constructor
+ */
+GameLib.D3.TriangleEdge = function(
+    triangle,
+    edge
+) {
+    this.triangle = triangle;
+    this.edge = edge;
+};
+/**
+ * TriangleFace
+ * @param v0
+ * @param v1
+ * @param v2
+ * @param materialIndex
+ * @param v0uv
+ * @param v1uv
+ * @param v2uv
+ * @param color
+ * @param vertexColors
+ * @param vertexNormals
+ * @param normal
+ * @constructor
+ */
+GameLib.D3.TriangleFace = function(
+    v0,
+    v1,
+    v2,
+    materialIndex,
+    v0uv,
+    v1uv,
+    v2uv,
+    color,
+    vertexColors,
+    vertexNormals,
+    normal
+) {
+    this.v0 = v0;
+    this.v1 = v1;
+    this.v2 = v2;
+    this.materialIndex = materialIndex;
+    this.v0uv = v0uv;
+    this.v1uv = v1uv;
+    this.v2uv = v2uv;
+    if (!color) {
+        color = new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff);
+    }
+    this.color = color;
+ 
+    if (!vertexColors) {
+        vertexColors = [
+            new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff),
+            new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff),
+            new GameLib.D3.Color(0xff, 0xff, 0xff, 0xff)
+        ];
+    }
+    this.vertexColors = vertexColors;
+ 
+    if (!vertexNormals) {
+        vertexNormals = [
+            new GameLib.D3.Vector3(),
+            new GameLib.D3.Vector3(),
+            new GameLib.D3.Vector3()
+        ]
+    }
+    this.vertexNormals = vertexNormals;
+ 
+    if (!normal) {
+        normal = new GameLib.D3.Vector3(0);
+    }
+ 
+    this.normal = normal;
+};
+ 
+/**
+ * Clone a TriangleFace
+ * @returns {GameLib.D3.TriangleFace}
+ */
+GameLib.D3.TriangleFace.prototype.clone = function(){
+    return new GameLib.D3.TriangleFace(
+        this.v0,
+        this.v1,
+        this.v2,
+        this.materialIndex,
+        this.v0uv.copy(),
+        this.v1uv.copy(),
+        this.v2uv.copy()
+    );
+};
+ 
+/**
+ * Returns true if two triangles are equal (their vertex indices match in some order)
+ * @param triangle
+ * @returns {boolean}
+ */
+GameLib.D3.TriangleFace.prototype.equals = function(triangle) {
+    return !!(
+    (
+        (this.v0 == triangle.v0) &&
+        (this.v1 == triangle.v1) &&
+        (this.v2 == triangle.v2)
+    )
+    ||
+    (
+        (this.v0 == triangle.v0) &&
+        (this.v1 == triangle.v2) &&
+        (this.v2 == triangle.v1)
+    )
+    ||
+    (
+        (this.v0 == triangle.v1) &&
+        (this.v1 == triangle.v0) &&
+        (this.v2 == triangle.v2)
+    )
+    ||
+    (
+        (this.v0 == triangle.v1) &&
+        (this.v1 == triangle.v2) &&
+        (this.v2 == triangle.v0)
+    )
+    ||
+    (
+        (this.v0 == triangle.v2) &&
+        (this.v1 == triangle.v0) &&
+        (this.v2 == triangle.v1)
+    )
+    ||
+    (
+        (this.v0 == triangle.v2) &&
+        (this.v1 == triangle.v1) &&
+        (this.v2 == triangle.v0)
+    ));
+};
+ 
+ 
+GameLib.D3.Vector2 = function(x, y) {
+ 
+    this.x = 0;
+    this.y = 0;
+ 
+    if (x) {
+        this.x = x;
+    }
+ 
+    if (y) {
+        this.y = y;
+    }
+};
+ 
+GameLib.D3.Vector2.prototype.copy = function() {
+    return new GameLib.D3.Vector2(
+        this.x,
+        this.y
+    );
+};
+ 
+GameLib.D3.Vector2.prototype.equals = function(v) {
+    return !!(((this.x == v.x) &&
+    (this.y == v.y)) ||
+    ((this.y == v.x) &&
+    (this.x == v.y)));
+};
+ 
+GameLib.D3.Vector3 = function(x, y, z) {
+ 
+    this.x = 0;
+    this.y = 0;
+    this.z = 0;
+ 
+    if (x) {
+        this.x = x;
+    }
+ 
+    if (y) {
+        this.y = y;
+    }
+ 
+    if (z) {
+        this.z = z;
+    }
+};
+ 
+GameLib.D3.Vector3.prototype.subtract = function (v) {
+ 
+    if (v instanceof GameLib.D3.Vector3) {
+        this.x -= v.x;
+        this.y -= v.y;
+        this.z -= v.z;
+    }
+ 
+    if (v instanceof GameLib.D3.Vector4) {
+        console.warn("trying to subtract vector of bigger length (4 vs 3))");
+    }
+ 
+    return this;
+};
+ 
+GameLib.D3.Vector3.prototype.cross = function (v) {
+    return new GameLib.D3.Vector3(
+        this.y * v.z - this.z * v.y,
+        this.z * v.x - this.x * v.z,
+        this.x * v.y - this.y * v.x
+    );
+};
+ 
+GameLib.D3.Vector3.prototype.negative = function () {
+    this.x *= -1;
+    this.y *= -1;
+    this.z *= -1;
+    return this;
+};
+ 
+GameLib.D3.Vector3.clockwise = function (u, v, w, viewPoint) {
+ 
+    var normal = GameLib.D3.Vector3.normal(u, v, w);
+ 
+    var uv = u.copy();
+ 
+    var winding = normal.dot(uv.subtract(viewPoint));
+ 
+    return (winding > 0);
+};
+ 
+GameLib.D3.Vector3.normal = function (u, v, w) {
+    var vv = v.copy();
+    var wv = w.copy();
+    return vv.subtract(u).cross(wv.subtract(u));
+};
+ 
+GameLib.D3.Vector3.prototype.lookAt = function (at, up) {
+ 
+    var lookAtMatrix = GameLib.D3.Matrix4.lookAt(this, at, up);
+ 
+    this.multiply(lookAtMatrix);
+};
+ 
+GameLib.D3.Vector3.prototype.translate = function (v) {
+    this.x += v.x;
+    this.y += v.y;
+    this.z += v.z;
+    return this;
+};
+ 
+GameLib.D3.Vector3.prototype.squared = function () {
+    return this.x * this.x + this.y * this.y + this.z * this.z;
+};
+ 
+GameLib.D3.Vector3.prototype.copy = function () {
+    return new GameLib.D3.Vector3(
+        this.x,
+        this.y,
+        this.z
+    );
+};
+ 
+GameLib.D3.Vector3.prototype.multiply = function (s) {
+    if (s instanceof GameLib.D3.Vector3) {
+        this.x *= s.x;
+        this.y *= s.y;
+        this.z *= s.z;
+    } else if (s instanceof GameLib.D3.Matrix4) {
+        var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z;
+        var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z;
+        var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    } else {
+        console.log("functionality not implemented - please do this");
+        throw new Error("not implemented");
+    }
+    return this;
+};
+ 
+ 
+GameLib.D3.Vector3.prototype.dot = function (v) {
+    return (this.x * v.x) + (this.y * v.y) + (this.z * v.z);
+};
+ 
+GameLib.D3.Vector3.prototype.normalize = function () {
+ 
+    var EPSILON = 0.000001;
+ 
+    var v2 = this.squared();
+ 
+    if (v2 < EPSILON) {
+        return this; //do nothing for zero vector
+    }
+ 
+    var invLength = 1 / Math.sqrt(v2);
+ 
+    this.x *= invLength;
+    this.y *= invLength;
+    this.z *= invLength;
+ 
+    return this;
+};
+ 
+GameLib.D3.Vector4 = function(x, y, z, w) {
+ 
+    this.x = 0;
+    this.y = 0;
+    this.z = 0;
+    this.w = 0;
+ 
+    Iif (x) {
+        this.x = x;
+    }
+ 
+    Iif (y) {
+        this.y = y;
+    }
+ 
+    Iif (z) {
+        this.z = z;
+    }
+ 
+    Iif (w) {
+        this.w = w;
+    }
+};
+ 
+GameLib.D3.Vector4.prototype.translate = function (v) {
+    this.x += v.x;
+    this.y += v.y;
+    this.z += v.z;
+    return this;
+};
+ 
+GameLib.D3.Vector4.prototype.copy = function () {
+    return new GameLib.D3.Vector4(
+        this.x,
+        this.y,
+        this.z,
+        this.w
+    );
+};
+ 
+GameLib.D3.Vector4.prototype.multiply = function (s) {
+    if (s instanceof GameLib.D3.Vector3) {
+        this.x *= s.x;
+        this.y *= s.y;
+        this.z *= s.z;
+    } else if (s instanceof GameLib.D3.Matrix4) {
+        var x = s.rows[0].x * this.x + s.rows[0].y * this.y + s.rows[0].z * this.z + s.rows[0].w * this.w;
+        var y = s.rows[1].x * this.x + s.rows[1].y * this.y + s.rows[1].z * this.z + s.rows[1].w * this.w;
+        var z = s.rows[2].x * this.x + s.rows[2].y * this.y + s.rows[2].z * this.z + s.rows[2].w * this.w;
+        var w = s.rows[3].x * this.x + s.rows[3].y * this.y + s.rows[3].z * this.z + s.rows[3].w * this.w;
+        this.x = x;
+        this.y = y;
+        this.z = z;
+        this.w = w;
+    } else {
+        console.log("functionality not implemented - please do this");
+        throw new Error("not implemented");
+    }
+};
+ 
+ 
+GameLib.D3.Vector4.prototype.normalize = function () {
+ 
+    // note - leave w untouched
+    var EPSILON = 0.000001;
+ 
+    var v2 = this.x * this.x + this.y * this.y + this.z * this.z;
+ 
+    if (v2 < EPSILON) {
+        return this; //do nothing for zero vector
+    }
+ 
+    var invLength = 1 / Math.sqrt(v2);
+ 
+    this.x *= invLength;
+    this.y *= invLength;
+    this.z *= invLength;
+ 
+    return this;
+};
+ 
+GameLib.D3.Vector4.prototype.subtract = function (v) {
+ 
+    if (v instanceof GameLib.D3.Vector3) {
+        this.x -= v.x;
+        this.y -= v.y;
+        this.z -= v.z;
+    }
+ 
+    if (v instanceof GameLib.D3.Vector4) {
+        this.x -= v.x;
+        this.y -= v.y;
+        this.z -= v.z;
+        this.w -= v.w;
+    }
+ 
+    return this;
+};
+ 
+GameLib.D3.Vector4.Points = function () {
+    this.vectors = [];
+};
+ 
+GameLib.D3.Vector4.Points.prototype.add = function (vector) {
+ 
+    if (vector instanceof GameLib.D3.Vector3) {
+        vector = new GameLib.D3.Vector4(
+            vector.x,
+            vector.y,
+            vector.z,
+            1
+        )
+    }
+ 
+    if (!vector instanceof GameLib.D3.Vector4) {
+        console.warn("Vector needs to be of type Vector4");
+        throw new Error("Vector needs to be of type Vector4");
+    }
+ 
+    this.vectors.push(vector);
+ 
+    return this;
+};
+ 
+GameLib.D3.Vector4.Points.prototype.copy = function () {
+ 
+    var vectors = [];
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        vectors.push(this.vectors[i].copy());
+    }
+ 
+    return vectors;
+};
+ 
+GameLib.D3.Vector4.Points.prototype.maximizeXDistance = function (grain) {
+ 
+//    console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
+ 
+    var multiplier = 0;
+ 
+    var rotationMatrixY = new GameLib.D3.Matrix4().rotationMatrixY(grain);
+ 
+    var totalRadians = 0;
+ 
+    var backupVectors = this.copy();
+ 
+    var maxXDistance = 0;
+ 
+    for (var i = 0; i < Math.PI * 2; i += grain) {
+ 
+        multiplier++;
+ 
+        for (var j = 0; j < this.vectors.length; j++) {
+            this.vectors[j] = rotationMatrixY.multiply(this.vectors[j]);
+        }
+ 
+        var distances = this.distances();
+ 
+        if (distances.x > maxXDistance) {
+ 
+            maxXDistance = distances.x;
+            totalRadians = multiplier * grain;
+        }
+    }
+ 
+    this.vectors = backupVectors;
+ 
+//    console.log("distance: " + maxXDistance + " radians : " + totalRadians);
+ 
+    var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixY(totalRadians);
+ 
+    for (var k = 0; k < this.vectors.length; k++) {
+        this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
+    }
+ 
+//    console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
+ 
+};
+ 
+GameLib.D3.Vector4.Points.prototype.maximizeYDistance = function (grain) {
+ 
+//    console.log("vectors (before): " + JSON.stringify(this.vectors, null, 2));
+ 
+    var multiplier = 0;
+ 
+    var rotationMatrixX = new GameLib.D3.Matrix4().rotationMatrixX(grain);
+ 
+    var totalRadians = 0;
+ 
+    var backupVectors = this.copy();
+ 
+    var maxYDistance = 0;
+ 
+    for (var i = 0; i < Math.PI * 2; i += grain) {
+ 
+        multiplier++;
+ 
+        for (var j = 0; j < this.vectors.length; j++) {
+            this.vectors[j] = rotationMatrixX.multiply(this.vectors[j]);
+        }
+ 
+        var distances = this.distances();
+ 
+        if (distances.y > maxYDistance) {
+            maxYDistance = distances.y;
+            totalRadians = multiplier * grain;
+        }
+    }
+ 
+    this.vectors = backupVectors;
+ 
+//    console.log("distance: " + maxYDistance + " radians : " + totalRadians);
+ 
+    var maxRotationMatrix = new GameLib.D3.Matrix4().rotationMatrixX(totalRadians);
+ 
+    for (var k = 0; k < this.vectors.length; k++) {
+        this.vectors[k] = maxRotationMatrix.multiply(this.vectors[k]);
+    }
+ 
+//    console.log("vectors (after): " + JSON.stringify(this.vectors, null, 2));
+ 
+};
+ 
+ 
+GameLib.D3.Vector4.Points.prototype.lookAt = function (at, up) {
+ 
+    var polyCenter = this.average();
+ 
+    console.log("poly center : " + JSON.stringify(polyCenter));
+ 
+    var lookAtMatrix = new GameLib.D3.Matrix4().lookAt(polyCenter, at, up);
+ 
+    lookAtMatrix.rows[0] = new GameLib.D3.Vector4(1, 0, 0, 0);
+    lookAtMatrix.rows[1] = new GameLib.D3.Vector4(0, 0, 1, 0);
+    lookAtMatrix.rows[2] = new GameLib.D3.Vector4(0, 1, 0, 0);
+ 
+    console.log("look at matrix : " + JSON.stringify(lookAtMatrix, null, 2));
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        console.log("vector " + i + " (before): " + JSON.stringify(this.vectors[i]));
+        this.vectors[i] = lookAtMatrix.multiply(this.vectors[i]);
+        console.log("vector " + i + " (after) : " + JSON.stringify(this.vectors[i]));
+    }
+};
+ 
+GameLib.D3.Vector4.Points.prototype.distances = function () {
+ 
+    var minX = this.vectors[0].x;
+    var minY = this.vectors[0].y;
+    var minZ = this.vectors[0].z;
+ 
+    var maxX = this.vectors[0].x;
+    var maxY = this.vectors[0].y;
+    var maxZ = this.vectors[0].z;
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        if (this.vectors[i].x < minX) {
+            minX = this.vectors[i].x;
+        }
+        if (this.vectors[i].y < minY) {
+            minY = this.vectors[i].y;
+        }
+        if (this.vectors[i].z < minZ) {
+            minZ = this.vectors[i].z;
+        }
+ 
+        if (this.vectors[i].x > maxX) {
+            maxX = this.vectors[i].x;
+        }
+        if (this.vectors[i].y > maxY) {
+            maxY = this.vectors[i].y;
+        }
+        if (this.vectors[i].z > maxZ) {
+            maxZ = this.vectors[i].z;
+        }
+    }
+ 
+    return new GameLib.D3.Vector3(
+        Math.abs(maxX - minX),
+        Math.abs(maxY - minY),
+        Math.abs(maxY - minZ)
+    )
+};
+ 
+GameLib.D3.Vector4.Points.prototype.average = function () {
+    var averageX = 0;
+    var averageY = 0;
+    var averageZ = 0;
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        averageX += this.vectors[i].x;
+        averageY += this.vectors[i].y;
+        averageZ += this.vectors[i].z;
+    }
+ 
+    return new GameLib.D3.Vector3(
+        averageX / this.vectors.length,
+        averageY / this.vectors.length,
+        averageZ / this.vectors.length
+    );
+};
+ 
+GameLib.D3.Vector4.Points.prototype.negative = function () {
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        this.vectors[i].x *= -1;
+        this.vectors[i].y *= -1;
+        this.vectors[i].z *= -1;
+    }
+ 
+    return this;
+};
+ 
+ 
+GameLib.D3.Vector4.Points.prototype.toOrigin = function () {
+ 
+    var distanceFromOrigin = this.average().negative();
+ 
+    for (var i = 0; i < this.vectors.length; i++) {
+        this.vectors[i].translate(distanceFromOrigin);
+    }
+};
+ 
+/**
+ * The normal gets assigned when the face calculates its normal
+ * @param position
+ * @param boneWeights GameLib.D3.BoneWeight[]
+ * @constructor
+ */
+GameLib.D3.Vertex = function(
+    position,
+    boneWeights
+) {
+    this.position = position;
+    this.boneWeights = boneWeights;
+};
+/**
+ * World SuperSet - contains the custom world instance
+ * @param id
+ * @param name
+ * @param engine
+ * @param gravity
+ * @param broadphase
+ * @param solver
+ * @param rigidBodies
+ * @constructor
+ */
+GameLib.D3.World = function(
+    id,
+    name,
+    engine,
+    gravity,
+    broadphase,
+    solver,
+    rigidBodies
+) {
+ 
+    this.id = id;
+ 
+    this.name = name;
+ 
+    if (typeof gravity == 'undefined') {
+        gravity = new GameLib.D3.Vector3(0, -9.81, 0);
+    }
+    this.gravity = gravity;
+ 
+    if (typeof broadphase == 'undefined') {
+        broadphase = new GameLib.D3.Physics.Broadphase(
+            null,
+            'broadPhaseNaive',
+            GameLib.D3.Physics.BROADPHASE_TYPE_NAIVE
+        );
+    }
+    this.broadphase = broadphase;
+ 
+    if (typeof solver == 'undefined') {
+        solver = new GameLib.D3.Physics.Solver(
+            null,
+            'GSSolver',
+            GameLib.D3.Physics.GS_SOLVER
+        );
+    }
+    this.solver = solver;
+ 
+    if (typeof rigidBodies == 'undefined') {
+        rigidBodies = [];
+    }
+    this.rigidBodies = rigidBodies;
+ 
+    this.engine = null;
+ 
+    this.worldInstance = null;
+ 
+    /**
+     * We only set the physics property if we pass it in the constructor,
+     * because we don't always want the physics object (ex. when we store this world to the API - we also don't then
+     * want to store the custom worlds - we want to generate them after loading from API)
+     */
+    if (engine) {
+        this.engine = engine;
+        this.worldInstance = this.createWorldInstance();
+    }
+};
+ 
+ 
+GameLib.D3.World.prototype.createWorldInstance = function() {
+ 
+    this.engine.isNotCannonThrow();
+ 
+    var customWorld = new this.engine.instance.World();
+ 
+    var cannonBroadphase = null;
+ 
+ 
+    customWorld.broadphase = cannonBroadphase;
+ 
+    var cannonSolver = null;
+ 
+    if (this.solver.solverType == GameLib.D3.Physics.SPLIT_SOLVER) {
+        cannonSolver = new this.engine.instance.SplitSolver();
+    } else if (this.solver.solverType == GameLib.D3.Physics.GS_SOLVER) {
+        cannonSolver = new this.engine.instance.GSSolver();
+        cannonSolver.iterations = this.solver.iterations;
+    }
+ 
+    customWorld.solver = cannonSolver;
+ 
+    customWorld.gravity.x = this.gravity.x;
+    customWorld.gravity.y = this.gravity.y;
+    customWorld.gravity.z = this.gravity.z;
+ 
+    for (var b = 0; b < this.rigidBodies.length; b++) {
+ 
+        var customBody = this.createCustomBody(this.rigidBodies[b]);
+ 
+        //customWorld.AddRigidBody();
+    }
+ 
+    customWorld.name = this.name;
+ 
+    return customWorld;
+};
+ 
+GameLib.D3.World.prototype.AddShape = function(
+    shape, // d3.physics.shape
+    rigidBody,
+    offset, // vec3
+    orientation //quaternion
+) {
+    shape.shape = shape;
+ 
+    /**
+     * TODO:: fix this?
+     */
+    if (this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) {
+ 
+        var _offset = null;
+        var _orientation = null;
+ 
+        if(offset != null && typeof offset !== 'undefined') {
+            _offset = new this.physics.CANNON.Vec3(offset.x, offset.y, offset.z);
+        }
+ 
+        if(orientation != null && typeof orientation !== 'undefined') {
+            _orientation = new this.physics.CANNON.Quaternion(orientation.x, orientation.y, orientation.z, orientation.w);
+        }
+ 
+        rigidBody.bodyObject.addShape(shape.shapeObject, _offset, _orientation);
+    }
+};
+ 
+GameLib.D3.World.prototype.Wheel = function() {
+ 
+};
+ 
+GameLib.D3.World.prototype.CreateRigidVehicle = function(
+    chassisBody // Physics.RigidBody
+) {
+    var rigidVehicle = new GameLib.D3.Physics.RigidVehicle();
+ 
+    if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        var vehicle = new this.physics.CANNON.RigidVehicle({
+            chassisBody: chassisBody.bodyObject
+        });
+        rigidVehicle.vehicleObject = vehicle;
+        return rigidVehicle;
+    }
+};
+ 
+GameLib.D3.World.prototype.CreateRaycastVehicle = function(
+    chassisBody // Physics.RigidBody
+) {
+    var raycastVehicle = new GameLib.D3.Physics.RaycastVehicle();
+ 
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        var vehicle = new this.physics.CANNON.RaycastVehicle({
+            chassisBody: chassisBody.bodyObject
+        });
+        raycastVehicle.vehicleObject = vehicle;
+        return raycastVehicle;
+    }
+};
+ 
+GameLib.D3.World.prototype.AddWheelToRigidVehicle = function(
+    vehicle,
+    rigidBody,
+    position,
+    axis,
+    direction
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        vehicle.vehicleObject.addWheel({
+            body: rigidBody.bodyObject,
+            position: new this.physics.CANNON.Vec3(position.x, position.y, position.z),
+            axis: new this.physics.CANNON.Vec3(axis.x, axis.y, axis.z),
+            direction: new this.physics.CANNON.Vec3(direction.x, direction.y, direction.z)
+        });
+    }
+};
+ 
+GameLib.D3.World.prototype.AddWheelToRaycastVehicle = function (
+    vehicle, // physics.raycastvehicle
+    options // cannon options
+) {
+    if (this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        vehicle.vehicleObject.addWheel(options);
+    } else {
+        console.log("function for engine not implemented");
+    }
+};
+ 
+ 
+ 
+GameLib.D3.World.prototype.CreateTriMeshShape = function(
+    vertices,   // flat list of floats
+    indices     // flat list of floats
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Trimesh(vertices, indices), GameLib.D3.Physics.SHAPE_TYPE_TRIMESH);
+    }
+};
+ 
+GameLib.D3.World.prototype.CreateSphereShape = function (
+    radius
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Sphere(radius), GameLib.D3.Physics.SHAPE_TYPE_SPHERE);
+    }
+};
+ 
+GameLib.D3.World.prototype.CreateBoxShape = function(
+    halfExtensions // vec3
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Box(new this.physics.CANNON.Vec3(halfExtensions.x, halfExtensions.y, halfExtensions.z)), GameLib.D3.Physics.SHAPE_TYPE_BOX);
+    }
+};
+ 
+GameLib.D3.World.prototype.CreateCylinderShape = function(
+    radiusTop,
+    radiusBottom,
+    height,
+    numSegments
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        return new GameLib.D3.Physics.Shape(new this.physics.CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments), GameLib.D3.Physics.SHAPE_TYPE_CYLINDER);
+    }
+};
+ 
+GameLib.D3.World.prototype.AddRigidBody = function(
+    rigidBody   // Physics.RigidBody
+) {
+    if(this.physics.engineType === GameLib.D3.Physics.TYPE_CANNON) {
+        this.worldObject.addBody(rigidBody.bodyObject);
+    }
+};
+ 
+GameLib.D3.World.prototype.AddVehicle = function(
+    vehicle // note: physics.vehicle
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+        vehicle.vehicleObject.addToWorld(this.worldObject);
+    }
+};
+ 
+GameLib.D3.World.prototype.Step = function(
+    timeStep
+) {
+    if(this.physics.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+ 
+        // todo: figure out, why this call to internal step is more stable for trimesh collisions.....
+        //this.worldObject.internalStep(timeStep);
+        //return;
+ 
+        var now = performance.now() / 1000;
+ 
+        if(!this.lastCallTime){
+            // last call time not saved, cant guess elapsed time. Take a simple step.
+            this.worldObject.step(timeStep);
+            this.lastCallTime = now;
+            return;
+        }
+ 
+        var timeSinceLastCall = now - this.lastCallTime;
+ 
+        this.worldObject.step(timeStep, timeSinceLastCall);
+ 
+        this.lastCallTime = now;
+    }
+};
+ 
+GameLib.D3.World.prototype.GetIndexedVertices = function(
+    triangleMeshShape
+) {
+ 
+    if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+ 
+        return {
+            vertices : triangleMeshShape.vertices,
+            indices : triangleMeshShape.indices
+        };
+ 
+    } else {
+        // todo: implement this for other physics engines.
+        return null;
+    }
+ 
+};
+ 
+GameLib.D3.World.prototype.GenerateWireframeViewMesh = function(
+    triangleMeshShape,
+    normalLength,
+    scale,
+    opacity,
+    wireframeColor
+) {
+    var geometryTHREE = new THREE.Geometry();
+    var wireframeTHREEMesh = new THREE.Mesh
+    (
+        geometryTHREE,
+        new THREE.MeshBasicMaterial({
+            color: wireframeColor ? wireframeColor : 0xfefefe,
+            wireframe: true,
+            opacity: opacity ? opacity : 0.5
+        })
+    );
+ 
+    var data = this.GetIndexedVertices(triangleMeshShape);
+ 
+    for(var i = 0, l = data.vertices.length / 3; i < l; i++) {
+        geometryTHREE.vertices.push(new THREE.Vector3(data.vertices[i * 3], data.vertices[i * 3 + 1], data.vertices[i * 3 + 2]));
+    }
+ 
+    for(var i = 0, l = data.indices.length / 3; i < l; i++) {
+        var i0 = data.indices[i * 3];
+        var i1 = data.indices[i * 3 + 1];
+        var i2 = data.indices[i * 3 + 2];
+ 
+        geometryTHREE.faces.push(new THREE.Face3(i0, i1, i2));
+ 
+        // Create debug view for normals
+ 
+        // Center point on the mesh itself
+        var centroid = new THREE.Vector3()
+            .add(geometryTHREE.vertices[i0])
+            .add(geometryTHREE.vertices[i1])
+            .add(geometryTHREE.vertices[i2])
+            .divideScalar(3);
+ 
+        var normal = null;
+        if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+            var normal = new this.physics.CANNON.Vec3();
+            triangleMeshShape.getNormal(i, normal);
+        } else {
+            // todo: calculate the normal for v0, v1 & v2 here.
+        }
+ 
+        var arrow = new THREE.ArrowHelper(new THREE.Vector3(normal.x, normal.y, normal.z), centroid, normalLength, new THREE.Color(normal.x, normal.y, normal.z));
+        wireframeTHREEMesh.add( arrow );
+    }
+ 
+    wireframeTHREEMesh.scale.x = scale.x;
+    wireframeTHREEMesh.scale.y = scale.y;
+    wireframeTHREEMesh.scale.z = scale.z;
+ 
+    return wireframeTHREEMesh;
+};
+ 
+GameLib.D3.World.prototype.GenerateTriangleCollisionMesh = function(
+    threeMesh,
+    mass,                       // default = 0
+    friction,                   // default = 10
+    createCollisionSubMeshes,   // boolean. default = false
+    facesPerSubsection,        // int. default = 0
+    subsectionsToMerge         // int. default = 0
+) {
+    var processedFaces = 0;
+    var facesPerSubSection = facesPerSubsection || 0;
+    var subMeshesToMerge = subsectionsToMerge || 0;
+    var totalAmtFaces = threeMesh.geometry.faces.length;
+    var facesToProcess = createCollisionSubMeshes ? (subMeshesToMerge * facesPerSubSection) : totalAmtFaces;
+ 
+    var pairs = []; // output
+ 
+    var vertices = [];
+    var indicies = [];
+ 
+    for(var i = 0; i <= totalAmtFaces; i++) {
+        if(processedFaces == facesToProcess || i == totalAmtFaces) {
+ 
+            var body = null;
+ 
+            if(this.engine.engineType == GameLib.D3.Physics.TYPE_CANNON) {
+ 
+                var meshShape = new this.physics.CANNON.Trimesh(vertices, indicies);
+                meshShape.setScale(new this.physics.CANNON.Vec3(threeMesh.scale.x, threeMesh.scale.y, threeMesh.scale.z));
+                meshShape.updateAABB();
+                meshShape.updateNormals();
+                meshShape.updateEdges();
+                meshShape.updateBoundingSphereRadius();
+                meshShape.updateTree();
+ 
+                body = new this.physics.CANNON.Body({ mass: mass ? mass : 0, friction: friction ? friction : 10 });
+                body.addShape(meshShape);
+ 
+            } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_AMMO) {
+ 
+            } else if (this.engine.engineType == GameLib.D3.Physics.Engine.TYPE_GOBLIN) {
+ 
+            }
+ 
+            pairs.push({
+                threeObject : createCollisionSubMeshes ? null : threeMesh,
+                physicsObject : body
+            });
+ 
+            vertices = [];
+            indicies = [];
+            processedFaces = 0;
+ 
+            if(i == totalAmtFaces) {
+                return pairs;
+            }
+        }
+ 
+        var face = threeMesh.geometry.faces[i];
+        indicies.push(indicies.length);
+        indicies.push(indicies.length);
+        indicies.push(indicies.length);
+ 
+        var v0 = threeMesh.geometry.vertices[face.a];
+        var v1 = threeMesh.geometry.vertices[face.b];
+        var v2 = threeMesh.geometry.vertices[face.c];
+ 
+        vertices.push(v0.x, v0.y, v0.z);
+        vertices.push(v1.x, v1.y, v1.z);
+        vertices.push(v2.x, v2.y, v2.z);
+ 
+        processedFaces++;
+    }
+};
+ 
+Eif (typeof module !== 'undefined') {
+    module.exports = GameLib;
+}
+
+
+ + + + + + + diff --git a/build/coverage/lcov-report/build/index.html b/build/coverage/lcov-report/build/index.html new file mode 100644 index 0000000..6395199 --- /dev/null +++ b/build/coverage/lcov-report/build/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for build/ + + + + + + + +
+
+

+ all files build/ +

+
+
+ 16.22% + Statements + 283/1745 +
+
+ 2.87% + Branches + 20/697 +
+
+ 2.05% + Functions + 3/146 +
+
+ 16.22% + Lines + 283/1745 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
game-lib.js
16.22%283/17452.87%20/6972.05%3/14616.22%283/1745
+
+
+ + + + + + + diff --git a/build/coverage/lcov-report/index.html b/build/coverage/lcov-report/index.html new file mode 100644 index 0000000..c262352 --- /dev/null +++ b/build/coverage/lcov-report/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for All files + + + + + + + +
+
+

+ / +

+
+
+ 16.22% + Statements + 283/1745 +
+
+ 2.87% + Branches + 20/697 +
+
+ 2.05% + Functions + 3/146 +
+
+ 16.22% + Lines + 283/1745 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
build/
16.22%283/17452.87%20/6972.05%3/14616.22%283/1745
+
+
+ + + + + + + diff --git a/build/coverage/lcov-report/prettify.css b/build/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/build/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/build/coverage/lcov-report/prettify.js b/build/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..ef51e03 --- /dev/null +++ b/build/coverage/lcov-report/prettify.js @@ -0,0 +1 @@ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/build/coverage/lcov-report/sort-arrow-sprite.png b/build/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..03f704a609c6fd0dbfdac63466a7d7c958b5cbf3 GIT binary patch literal 209 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jii$m5978H@?Fn+^JD|Y9yzj{W`447Gxa{7*dM7nnnD-Lb z6^}Hx2)'; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function (a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function (a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function () { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i =0 ; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function () { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(cols); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/build/coverage/lcov.info b/build/coverage/lcov.info new file mode 100644 index 0000000..ad94920 --- /dev/null +++ b/build/coverage/lcov.info @@ -0,0 +1,2743 @@ +TN: +SF:/usr/share/gamewheel/game-lib/build/game-lib.js +FN:2,GameLib +FN:6,(anonymous_2) +FN:14,(anonymous_3) +FN:35,(anonymous_4) +FN:95,(anonymous_5) +FN:129,(anonymous_6) +FN:171,(anonymous_7) +FN:183,(anonymous_8) +FN:195,(anonymous_9) +FN:202,(anonymous_10) +FN:213,(anonymous_11) +FN:221,(anonymous_12) +FN:239,(anonymous_13) +FN:289,(anonymous_14) +FN:300,(anonymous_15) +FN:311,(anonymous_16) +FN:321,(anonymous_17) +FN:329,(anonymous_18) +FN:381,(anonymous_19) +FN:390,(anonymous_20) +FN:404,(anonymous_21) +FN:437,(anonymous_22) +FN:469,(anonymous_23) +FN:477,(anonymous_24) +FN:483,(anonymous_25) +FN:489,(anonymous_26) +FN:497,(anonymous_27) +FN:503,(anonymous_28) +FN:563,(anonymous_29) +FN:582,(anonymous_30) +FN:603,(anonymous_31) +FN:642,(anonymous_32) +FN:648,(anonymous_33) +FN:694,(anonymous_34) +FN:749,(anonymous_35) +FN:883,(anonymous_36) +FN:1335,(anonymous_37) +FN:1487,(anonymous_38) +FN:1491,(anonymous_39) +FN:1509,(anonymous_40) +FN:1532,(anonymous_41) +FN:1539,(anonymous_42) +FN:1565,(anonymous_43) +FN:1572,(anonymous_44) +FN:1589,(anonymous_45) +FN:1596,(anonymous_46) +FN:1602,(anonymous_47) +FN:1608,(anonymous_48) +FN:1614,(anonymous_49) +FN:1631,(anonymous_50) +FN:1640,(anonymous_51) +FN:1737,(anonymous_52) +FN:1841,(anonymous_53) +FN:1956,(anonymous_54) +FN:1974,(anonymous_55) +FN:2059,(anonymous_56) +FN:2067,inProcessed +FN:2085,neighbourOnEdge +FN:2217,(anonymous_59) +FN:2261,(anonymous_60) +FN:2293,(anonymous_61) +FN:2311,(anonymous_62) +FN:2325,(anonymous_63) +FN:2330,(anonymous_64) +FN:2342,(anonymous_65) +FN:2347,(anonymous_66) +FN:2374,(anonymous_67) +FN:2415,(anonymous_68) +FN:2461,(anonymous_69) +FN:2523,(anonymous_70) +FN:2539,(anonymous_71) +FN:2540,(anonymous_72) +FN:2729,(anonymous_73) +FN:2882,(anonymous_74) +FN:2883,(anonymous_75) +FN:2915,(anonymous_76) +FN:2922,(anonymous_77) +FN:3014,(anonymous_78) +FN:3022,(anonymous_79) +FN:3037,(anonymous_80) +FN:3068,(anonymous_81) +FN:3126,(anonymous_82) +FN:3133,(anonymous_83) +FN:3173,(anonymous_84) +FN:3201,(anonymous_85) +FN:3255,(anonymous_86) +FN:3445,(anonymous_87) +FN:3464,(anonymous_88) +FN:3493,(anonymous_89) +FN:3501,(anonymous_90) +FN:3525,(anonymous_91) +FN:3607,(anonymous_92) +FN:3629,(anonymous_93) +FN:3683,(anonymous_94) +FN:3700,(anonymous_95) +FN:3740,(anonymous_96) +FN:3754,(anonymous_97) +FN:3761,(anonymous_98) +FN:3768,(anonymous_99) +FN:3787,(anonymous_100) +FN:3802,(anonymous_101) +FN:3810,(anonymous_102) +FN:3817,(anonymous_103) +FN:3828,(anonymous_104) +FN:3834,(anonymous_105) +FN:3841,(anonymous_106) +FN:3848,(anonymous_107) +FN:3852,(anonymous_108) +FN:3860,(anonymous_109) +FN:3880,(anonymous_110) +FN:3884,(anonymous_111) +FN:3903,(anonymous_112) +FN:3927,(anonymous_113) +FN:3934,(anonymous_114) +FN:3943,(anonymous_115) +FN:3964,(anonymous_116) +FN:3984,(anonymous_117) +FN:4002,(anonymous_118) +FN:4006,(anonymous_119) +FN:4027,(anonymous_120) +FN:4038,(anonymous_121) +FN:4083,(anonymous_122) +FN:4128,(anonymous_123) +FN:4149,(anonymous_124) +FN:4188,(anonymous_125) +FN:4206,(anonymous_126) +FN:4218,(anonymous_127) +FN:4233,(anonymous_128) +FN:4251,(anonymous_129) +FN:4309,(anonymous_130) +FN:4347,(anonymous_131) +FN:4375,(anonymous_132) +FN:4379,(anonymous_133) +FN:4393,(anonymous_134) +FN:4407,(anonymous_135) +FN:4424,(anonymous_136) +FN:4437,(anonymous_137) +FN:4446,(anonymous_138) +FN:4454,(anonymous_139) +FN:4462,(anonymous_140) +FN:4473,(anonymous_141) +FN:4481,(anonymous_142) +FN:4489,(anonymous_143) +FN:4515,(anonymous_144) +FN:4533,(anonymous_145) +FN:4592,(anonymous_146) +FNF:146 +FNH:3 +FNDA:0,GameLib +FNDA:0,(anonymous_2) +FNDA:0,(anonymous_3) +FNDA:1,(anonymous_4) +FNDA:0,(anonymous_5) +FNDA:0,(anonymous_6) +FNDA:0,(anonymous_7) +FNDA:0,(anonymous_8) +FNDA:0,(anonymous_9) +FNDA:0,(anonymous_10) +FNDA:0,(anonymous_11) +FNDA:0,(anonymous_12) +FNDA:0,(anonymous_13) +FNDA:0,(anonymous_14) +FNDA:0,(anonymous_15) +FNDA:0,(anonymous_16) +FNDA:0,(anonymous_17) +FNDA:0,(anonymous_18) +FNDA:0,(anonymous_19) +FNDA:0,(anonymous_20) +FNDA:0,(anonymous_21) +FNDA:0,(anonymous_22) +FNDA:0,(anonymous_23) +FNDA:0,(anonymous_24) +FNDA:0,(anonymous_25) +FNDA:0,(anonymous_26) +FNDA:0,(anonymous_27) +FNDA:0,(anonymous_28) +FNDA:0,(anonymous_29) +FNDA:0,(anonymous_30) +FNDA:0,(anonymous_31) +FNDA:0,(anonymous_32) +FNDA:0,(anonymous_33) +FNDA:0,(anonymous_34) +FNDA:0,(anonymous_35) +FNDA:0,(anonymous_36) +FNDA:0,(anonymous_37) +FNDA:0,(anonymous_38) +FNDA:0,(anonymous_39) +FNDA:0,(anonymous_40) +FNDA:0,(anonymous_41) +FNDA:0,(anonymous_42) +FNDA:0,(anonymous_43) +FNDA:0,(anonymous_44) +FNDA:0,(anonymous_45) +FNDA:0,(anonymous_46) +FNDA:0,(anonymous_47) +FNDA:0,(anonymous_48) +FNDA:0,(anonymous_49) +FNDA:0,(anonymous_50) +FNDA:0,(anonymous_51) +FNDA:0,(anonymous_52) +FNDA:0,(anonymous_53) +FNDA:0,(anonymous_54) +FNDA:0,(anonymous_55) +FNDA:0,(anonymous_56) +FNDA:0,inProcessed +FNDA:0,neighbourOnEdge +FNDA:0,(anonymous_59) +FNDA:0,(anonymous_60) +FNDA:0,(anonymous_61) +FNDA:0,(anonymous_62) +FNDA:0,(anonymous_63) +FNDA:0,(anonymous_64) +FNDA:0,(anonymous_65) +FNDA:0,(anonymous_66) +FNDA:0,(anonymous_67) +FNDA:0,(anonymous_68) +FNDA:0,(anonymous_69) +FNDA:0,(anonymous_70) +FNDA:0,(anonymous_71) +FNDA:0,(anonymous_72) +FNDA:0,(anonymous_73) +FNDA:0,(anonymous_74) +FNDA:0,(anonymous_75) +FNDA:0,(anonymous_76) +FNDA:0,(anonymous_77) +FNDA:0,(anonymous_78) +FNDA:0,(anonymous_79) +FNDA:0,(anonymous_80) +FNDA:0,(anonymous_81) +FNDA:0,(anonymous_82) +FNDA:0,(anonymous_83) +FNDA:0,(anonymous_84) +FNDA:0,(anonymous_85) +FNDA:0,(anonymous_86) +FNDA:0,(anonymous_87) +FNDA:0,(anonymous_88) +FNDA:0,(anonymous_89) +FNDA:0,(anonymous_90) +FNDA:0,(anonymous_91) +FNDA:0,(anonymous_92) +FNDA:0,(anonymous_93) +FNDA:0,(anonymous_94) +FNDA:0,(anonymous_95) +FNDA:0,(anonymous_96) +FNDA:0,(anonymous_97) +FNDA:0,(anonymous_98) +FNDA:4,(anonymous_99) +FNDA:0,(anonymous_100) +FNDA:0,(anonymous_101) +FNDA:0,(anonymous_102) +FNDA:0,(anonymous_103) +FNDA:0,(anonymous_104) +FNDA:0,(anonymous_105) +FNDA:0,(anonymous_106) +FNDA:0,(anonymous_107) +FNDA:0,(anonymous_108) +FNDA:0,(anonymous_109) +FNDA:0,(anonymous_110) +FNDA:0,(anonymous_111) +FNDA:1,(anonymous_112) +FNDA:0,(anonymous_113) +FNDA:0,(anonymous_114) +FNDA:0,(anonymous_115) +FNDA:0,(anonymous_116) +FNDA:0,(anonymous_117) +FNDA:0,(anonymous_118) +FNDA:0,(anonymous_119) +FNDA:0,(anonymous_120) +FNDA:0,(anonymous_121) +FNDA:0,(anonymous_122) +FNDA:0,(anonymous_123) +FNDA:0,(anonymous_124) +FNDA:0,(anonymous_125) +FNDA:0,(anonymous_126) +FNDA:0,(anonymous_127) +FNDA:0,(anonymous_128) +FNDA:0,(anonymous_129) +FNDA:0,(anonymous_130) +FNDA:0,(anonymous_131) +FNDA:0,(anonymous_132) +FNDA:0,(anonymous_133) +FNDA:0,(anonymous_134) +FNDA:0,(anonymous_135) +FNDA:0,(anonymous_136) +FNDA:0,(anonymous_137) +FNDA:0,(anonymous_138) +FNDA:0,(anonymous_139) +FNDA:0,(anonymous_140) +FNDA:0,(anonymous_141) +FNDA:0,(anonymous_142) +FNDA:0,(anonymous_143) +FNDA:0,(anonymous_144) +FNDA:0,(anonymous_145) +FNDA:0,(anonymous_146) +DA:1,1 +DA:2,1 +DA:5,1 +DA:6,1 +DA:14,1 +DA:18,0 +DA:19,0 +DA:35,1 +DA:47,1 +DA:48,1 +DA:49,1 +DA:51,1 +DA:52,0 +DA:54,1 +DA:56,1 +DA:57,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:64,1 +DA:66,1 +DA:67,1 +DA:69,1 +DA:71,1 +DA:72,1 +DA:74,1 +DA:76,1 +DA:77,1 +DA:79,1 +DA:81,1 +DA:82,1 +DA:84,1 +DA:95,1 +DA:102,0 +DA:104,0 +DA:105,0 +DA:107,0 +DA:109,0 +DA:110,0 +DA:112,0 +DA:114,0 +DA:115,0 +DA:117,0 +DA:119,0 +DA:121,0 +DA:122,0 +DA:129,1 +DA:131,0 +DA:132,0 +DA:133,0 +DA:136,0 +DA:138,0 +DA:140,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:147,0 +DA:148,0 +DA:151,0 +DA:153,0 +DA:160,1 +DA:161,1 +DA:162,1 +DA:171,1 +DA:172,0 +DA:173,0 +DA:174,0 +DA:175,0 +DA:183,1 +DA:187,0 +DA:188,0 +DA:195,1 +DA:196,0 +DA:202,1 +DA:203,0 +DA:204,0 +DA:205,0 +DA:213,1 +DA:214,0 +DA:221,1 +DA:222,0 +DA:229,1 +DA:230,1 +DA:231,1 +DA:239,1 +DA:244,0 +DA:246,0 +DA:248,0 +DA:250,0 +DA:251,0 +DA:252,0 +DA:254,0 +DA:255,0 +DA:256,0 +DA:257,0 +DA:258,0 +DA:259,0 +DA:261,0 +DA:262,0 +DA:263,0 +DA:264,0 +DA:265,0 +DA:266,0 +DA:268,0 +DA:270,0 +DA:271,0 +DA:272,0 +DA:273,0 +DA:274,0 +DA:276,0 +DA:277,0 +DA:279,0 +DA:280,0 +DA:281,0 +DA:289,1 +DA:290,0 +DA:291,0 +DA:292,0 +DA:293,0 +DA:300,1 +DA:301,0 +DA:302,0 +DA:303,0 +DA:311,1 +DA:312,0 +DA:313,0 +DA:314,0 +DA:321,1 +DA:322,0 +DA:329,1 +DA:330,0 +DA:331,0 +DA:332,0 +DA:334,0 +DA:336,0 +DA:337,0 +DA:339,0 +DA:341,0 +DA:342,0 +DA:343,0 +DA:345,0 +DA:347,0 +DA:348,0 +DA:349,0 +DA:352,0 +DA:354,0 +DA:355,0 +DA:356,0 +DA:358,0 +DA:360,0 +DA:361,0 +DA:362,0 +DA:365,0 +DA:367,0 +DA:369,0 +DA:371,0 +DA:381,1 +DA:382,0 +DA:383,0 +DA:390,1 +DA:391,0 +DA:392,0 +DA:393,0 +DA:395,0 +DA:396,0 +DA:404,1 +DA:405,0 +DA:408,0 +DA:409,0 +DA:412,0 +DA:413,0 +DA:416,0 +DA:417,0 +DA:420,0 +DA:421,0 +DA:424,0 +DA:425,0 +DA:428,0 +DA:429,0 +DA:437,1 +DA:438,0 +DA:442,0 +DA:443,0 +DA:447,0 +DA:448,0 +DA:452,0 +DA:453,0 +DA:457,0 +DA:458,0 +DA:461,0 +DA:462,0 +DA:465,0 +DA:466,0 +DA:469,1 +DA:472,0 +DA:473,0 +DA:474,0 +DA:477,1 +DA:480,0 +DA:483,1 +DA:486,0 +DA:489,1 +DA:493,0 +DA:494,0 +DA:497,1 +DA:500,0 +DA:503,1 +DA:506,0 +DA:508,0 +DA:509,0 +DA:511,0 +DA:513,0 +DA:515,0 +DA:516,0 +DA:518,0 +DA:519,0 +DA:520,0 +DA:521,0 +DA:523,0 +DA:524,0 +DA:526,0 +DA:527,0 +DA:529,0 +DA:531,0 +DA:532,0 +DA:534,0 +DA:536,0 +DA:537,0 +DA:538,0 +DA:539,0 +DA:540,0 +DA:543,0 +DA:544,0 +DA:545,0 +DA:547,0 +DA:552,0 +DA:553,0 +DA:563,1 +DA:568,0 +DA:570,0 +DA:582,1 +DA:587,0 +DA:588,0 +DA:590,0 +DA:592,0 +DA:593,0 +DA:595,0 +DA:597,0 +DA:598,0 +DA:600,0 +DA:603,1 +DA:608,0 +DA:610,0 +DA:611,0 +DA:612,0 +DA:614,0 +DA:615,0 +DA:616,0 +DA:617,0 +DA:618,0 +DA:619,0 +DA:620,0 +DA:621,0 +DA:622,0 +DA:623,0 +DA:624,0 +DA:625,0 +DA:630,0 +DA:631,0 +DA:635,0 +DA:636,0 +DA:638,0 +DA:642,1 +DA:646,0 +DA:648,0 +DA:650,0 +DA:651,0 +DA:652,0 +DA:654,0 +DA:655,0 +DA:657,0 +DA:658,0 +DA:660,0 +DA:661,0 +DA:662,0 +DA:665,0 +DA:666,0 +DA:669,0 +DA:670,0 +DA:671,0 +DA:672,0 +DA:673,0 +DA:680,0 +DA:683,0 +DA:694,1 +DA:701,0 +DA:703,0 +DA:705,0 +DA:707,0 +DA:708,0 +DA:710,0 +DA:712,0 +DA:714,0 +DA:716,0 +DA:717,0 +DA:720,0 +DA:721,0 +DA:724,0 +DA:725,0 +DA:728,0 +DA:749,1 +DA:766,0 +DA:767,0 +DA:768,0 +DA:769,0 +DA:770,0 +DA:772,0 +DA:773,0 +DA:775,0 +DA:777,0 +DA:778,0 +DA:780,0 +DA:782,0 +DA:783,0 +DA:785,0 +DA:787,0 +DA:788,0 +DA:790,0 +DA:792,0 +DA:793,0 +DA:795,0 +DA:797,0 +DA:798,0 +DA:800,0 +DA:802,0 +DA:803,0 +DA:805,0 +DA:807,0 +DA:808,0 +DA:810,0 +DA:812,0 +DA:813,0 +DA:815,0 +DA:817,0 +DA:818,0 +DA:820,0 +DA:883,1 +DA:942,0 +DA:943,0 +DA:944,0 +DA:945,0 +DA:947,0 +DA:949,0 +DA:950,0 +DA:952,0 +DA:954,0 +DA:955,0 +DA:957,0 +DA:959,0 +DA:960,0 +DA:962,0 +DA:964,0 +DA:965,0 +DA:980,0 +DA:982,0 +DA:983,0 +DA:985,0 +DA:987,0 +DA:988,0 +DA:990,0 +DA:992,0 +DA:993,0 +DA:995,0 +DA:997,0 +DA:998,0 +DA:1000,0 +DA:1002,0 +DA:1003,0 +DA:1005,0 +DA:1007,0 +DA:1008,0 +DA:1010,0 +DA:1012,0 +DA:1013,0 +DA:1015,0 +DA:1017,0 +DA:1018,0 +DA:1020,0 +DA:1022,0 +DA:1023,0 +DA:1025,0 +DA:1027,0 +DA:1028,0 +DA:1030,0 +DA:1032,0 +DA:1033,0 +DA:1035,0 +DA:1037,0 +DA:1038,0 +DA:1040,0 +DA:1042,0 +DA:1043,0 +DA:1045,0 +DA:1047,0 +DA:1048,0 +DA:1050,0 +DA:1052,0 +DA:1053,0 +DA:1055,0 +DA:1057,0 +DA:1058,0 +DA:1060,0 +DA:1062,0 +DA:1063,0 +DA:1065,0 +DA:1067,0 +DA:1068,0 +DA:1070,0 +DA:1072,0 +DA:1073,0 +DA:1075,0 +DA:1077,0 +DA:1078,0 +DA:1080,0 +DA:1082,0 +DA:1083,0 +DA:1085,0 +DA:1087,0 +DA:1088,0 +DA:1090,0 +DA:1092,0 +DA:1093,0 +DA:1095,0 +DA:1097,0 +DA:1098,0 +DA:1100,0 +DA:1102,0 +DA:1103,0 +DA:1105,0 +DA:1107,0 +DA:1108,0 +DA:1110,0 +DA:1112,0 +DA:1113,0 +DA:1115,0 +DA:1117,0 +DA:1118,0 +DA:1120,0 +DA:1122,0 +DA:1123,0 +DA:1125,0 +DA:1127,0 +DA:1128,0 +DA:1130,0 +DA:1132,0 +DA:1133,0 +DA:1135,0 +DA:1137,0 +DA:1138,0 +DA:1140,0 +DA:1142,0 +DA:1143,0 +DA:1145,0 +DA:1147,0 +DA:1148,0 +DA:1150,0 +DA:1152,0 +DA:1153,0 +DA:1155,0 +DA:1157,0 +DA:1158,0 +DA:1160,0 +DA:1162,0 +DA:1163,0 +DA:1165,0 +DA:1167,0 +DA:1168,0 +DA:1170,0 +DA:1172,0 +DA:1173,0 +DA:1175,0 +DA:1177,0 +DA:1178,0 +DA:1180,0 +DA:1182,0 +DA:1183,0 +DA:1185,0 +DA:1187,0 +DA:1188,0 +DA:1190,0 +DA:1192,0 +DA:1193,0 +DA:1195,0 +DA:1197,0 +DA:1198,0 +DA:1200,0 +DA:1202,0 +DA:1203,0 +DA:1205,0 +DA:1207,0 +DA:1208,0 +DA:1210,0 +DA:1212,0 +DA:1213,0 +DA:1215,0 +DA:1217,0 +DA:1218,0 +DA:1220,0 +DA:1222,0 +DA:1223,0 +DA:1225,0 +DA:1227,0 +DA:1228,0 +DA:1230,0 +DA:1238,1 +DA:1239,1 +DA:1240,1 +DA:1246,1 +DA:1247,1 +DA:1248,1 +DA:1254,1 +DA:1255,1 +DA:1256,1 +DA:1257,1 +DA:1258,1 +DA:1264,1 +DA:1265,1 +DA:1266,1 +DA:1267,1 +DA:1268,1 +DA:1269,1 +DA:1270,1 +DA:1271,1 +DA:1272,1 +DA:1273,1 +DA:1274,1 +DA:1280,1 +DA:1281,1 +DA:1282,1 +DA:1283,1 +DA:1284,1 +DA:1290,1 +DA:1291,1 +DA:1292,1 +DA:1293,1 +DA:1294,1 +DA:1295,1 +DA:1296,1 +DA:1297,1 +DA:1303,1 +DA:1304,1 +DA:1305,1 +DA:1311,1 +DA:1312,1 +DA:1318,1 +DA:1319,1 +DA:1320,1 +DA:1321,1 +DA:1322,1 +DA:1323,1 +DA:1324,1 +DA:1325,1 +DA:1326,1 +DA:1327,1 +DA:1328,1 +DA:1335,1 +DA:1337,0 +DA:1339,0 +DA:1341,0 +DA:1343,0 +DA:1345,0 +DA:1396,0 +DA:1409,0 +DA:1411,0 +DA:1467,0 +DA:1481,0 +DA:1484,0 +DA:1485,0 +DA:1486,0 +DA:1488,0 +DA:1492,0 +DA:1493,0 +DA:1497,0 +DA:1500,0 +DA:1509,1 +DA:1514,0 +DA:1516,0 +DA:1517,0 +DA:1520,0 +DA:1521,0 +DA:1524,0 +DA:1525,0 +DA:1532,1 +DA:1533,0 +DA:1539,1 +DA:1546,0 +DA:1548,0 +DA:1549,0 +DA:1552,0 +DA:1553,0 +DA:1556,0 +DA:1557,0 +DA:1560,0 +DA:1561,0 +DA:1565,1 +DA:1566,0 +DA:1567,0 +DA:1568,0 +DA:1569,0 +DA:1572,1 +DA:1573,0 +DA:1574,0 +DA:1580,0 +DA:1586,0 +DA:1589,1 +DA:1590,0 +DA:1591,0 +DA:1592,0 +DA:1593,0 +DA:1596,1 +DA:1597,0 +DA:1598,0 +DA:1599,0 +DA:1602,1 +DA:1603,0 +DA:1604,0 +DA:1605,0 +DA:1608,1 +DA:1609,0 +DA:1610,0 +DA:1611,0 +DA:1614,1 +DA:1615,0 +DA:1616,0 +DA:1622,0 +DA:1623,0 +DA:1631,1 +DA:1632,0 +DA:1640,1 +DA:1642,0 +DA:1644,0 +DA:1646,0 +DA:1647,0 +DA:1650,0 +DA:1652,0 +DA:1653,0 +DA:1654,0 +DA:1657,0 +DA:1659,0 +DA:1660,0 +DA:1661,0 +DA:1663,0 +DA:1664,0 +DA:1665,0 +DA:1667,0 +DA:1668,0 +DA:1669,0 +DA:1671,0 +DA:1737,1 +DA:1759,0 +DA:1760,0 +DA:1761,0 +DA:1762,0 +DA:1763,0 +DA:1764,0 +DA:1766,0 +DA:1767,0 +DA:1769,0 +DA:1771,0 +DA:1772,0 +DA:1774,0 +DA:1776,0 +DA:1777,0 +DA:1779,0 +DA:1781,0 +DA:1782,0 +DA:1784,0 +DA:1786,0 +DA:1787,0 +DA:1789,0 +DA:1791,0 +DA:1792,0 +DA:1794,0 +DA:1796,0 +DA:1797,0 +DA:1799,0 +DA:1801,0 +DA:1802,0 +DA:1804,0 +DA:1806,0 +DA:1807,0 +DA:1809,0 +DA:1811,0 +DA:1812,0 +DA:1814,0 +DA:1816,0 +DA:1818,0 +DA:1820,0 +DA:1822,0 +DA:1830,1 +DA:1831,1 +DA:1841,1 +DA:1843,0 +DA:1845,0 +DA:1846,0 +DA:1849,0 +DA:1851,0 +DA:1853,0 +DA:1855,0 +DA:1857,0 +DA:1859,0 +DA:1861,0 +DA:1863,0 +DA:1865,0 +DA:1866,0 +DA:1867,0 +DA:1869,0 +DA:1870,0 +DA:1871,0 +DA:1873,0 +DA:1874,0 +DA:1875,0 +DA:1876,0 +DA:1878,0 +DA:1879,0 +DA:1880,0 +DA:1882,0 +DA:1883,0 +DA:1884,0 +DA:1886,0 +DA:1892,0 +DA:1893,0 +DA:1894,0 +DA:1901,0 +DA:1902,0 +DA:1915,0 +DA:1916,0 +DA:1926,0 +DA:1928,0 +DA:1930,0 +DA:1932,0 +DA:1933,0 +DA:1934,0 +DA:1935,0 +DA:1939,0 +DA:1941,0 +DA:1943,0 +DA:1944,0 +DA:1947,0 +DA:1948,0 +DA:1951,0 +DA:1953,0 +DA:1956,1 +DA:1958,0 +DA:1959,0 +DA:1960,0 +DA:1961,0 +DA:1963,0 +DA:1964,0 +DA:1965,0 +DA:1968,0 +DA:1974,1 +DA:1976,0 +DA:1978,0 +DA:1979,0 +DA:1986,0 +DA:1988,0 +DA:1990,0 +DA:1992,0 +DA:1993,0 +DA:1994,0 +DA:1996,0 +DA:2013,0 +DA:2014,0 +DA:2022,0 +DA:2023,0 +DA:2024,0 +DA:2025,0 +DA:2027,0 +DA:2031,0 +DA:2059,1 +DA:2067,1 +DA:2069,0 +DA:2070,0 +DA:2071,0 +DA:2075,0 +DA:2085,1 +DA:2087,0 +DA:2088,0 +DA:2097,0 +DA:2107,0 +DA:2108,0 +DA:2111,0 +DA:2118,0 +DA:2121,0 +DA:2136,0 +DA:2138,0 +DA:2140,0 +DA:2146,0 +DA:2154,0 +DA:2155,0 +DA:2156,0 +DA:2158,0 +DA:2159,0 +DA:2160,0 +DA:2163,0 +DA:2165,0 +DA:2180,0 +DA:2181,0 +DA:2182,0 +DA:2183,0 +DA:2192,0 +DA:2193,0 +DA:2194,0 +DA:2195,0 +DA:2196,0 +DA:2197,0 +DA:2198,0 +DA:2201,0 +DA:2202,0 +DA:2206,0 +DA:2217,1 +DA:2219,0 +DA:2220,0 +DA:2223,0 +DA:2225,0 +DA:2227,0 +DA:2228,0 +DA:2235,0 +DA:2237,0 +DA:2239,0 +DA:2241,0 +DA:2242,0 +DA:2250,0 +DA:2261,1 +DA:2267,0 +DA:2268,0 +DA:2269,0 +DA:2271,0 +DA:2272,0 +DA:2274,0 +DA:2282,1 +DA:2283,1 +DA:2293,1 +DA:2300,0 +DA:2301,0 +DA:2302,0 +DA:2303,0 +DA:2304,0 +DA:2311,1 +DA:2312,0 +DA:2325,1 +DA:2327,0 +DA:2330,1 +DA:2334,0 +DA:2342,1 +DA:2344,0 +DA:2347,1 +DA:2351,0 +DA:2374,1 +DA:2392,0 +DA:2393,0 +DA:2394,0 +DA:2395,0 +DA:2396,0 +DA:2397,0 +DA:2398,0 +DA:2399,0 +DA:2400,0 +DA:2401,0 +DA:2402,0 +DA:2403,0 +DA:2404,0 +DA:2405,0 +DA:2406,0 +DA:2408,0 +DA:2415,1 +DA:2417,0 +DA:2420,0 +DA:2421,0 +DA:2443,0 +DA:2461,1 +DA:2474,0 +DA:2475,0 +DA:2476,0 +DA:2477,0 +DA:2478,0 +DA:2480,0 +DA:2482,0 +DA:2483,0 +DA:2485,0 +DA:2487,0 +DA:2488,0 +DA:2490,0 +DA:2492,0 +DA:2493,0 +DA:2495,0 +DA:2497,0 +DA:2498,0 +DA:2500,0 +DA:2502,0 +DA:2503,0 +DA:2505,0 +DA:2507,0 +DA:2508,0 +DA:2510,0 +DA:2512,0 +DA:2513,0 +DA:2515,0 +DA:2523,1 +DA:2528,0 +DA:2529,0 +DA:2530,0 +DA:2533,0 +DA:2534,0 +DA:2539,0 +DA:2540,0 +DA:2541,0 +DA:2543,0 +DA:2545,0 +DA:2546,0 +DA:2549,0 +DA:2551,0 +DA:2553,0 +DA:2555,0 +DA:2557,0 +DA:2559,0 +DA:2568,0 +DA:2570,0 +DA:2572,0 +DA:2574,0 +DA:2576,0 +DA:2582,0 +DA:2584,0 +DA:2592,0 +DA:2594,0 +DA:2596,0 +DA:2598,0 +DA:2601,0 +DA:2606,0 +DA:2609,0 +DA:2623,0 +DA:2626,0 +DA:2630,0 +DA:2632,0 +DA:2634,0 +DA:2636,0 +DA:2680,0 +DA:2683,0 +DA:2714,0 +DA:2719,0 +DA:2729,1 +DA:2731,0 +DA:2733,0 +DA:2735,0 +DA:2737,0 +DA:2739,0 +DA:2741,0 +DA:2743,0 +DA:2745,0 +DA:2747,0 +DA:2749,0 +DA:2751,0 +DA:2756,0 +DA:2757,0 +DA:2769,0 +DA:2771,0 +DA:2788,0 +DA:2806,0 +DA:2812,0 +DA:2830,0 +DA:2833,0 +DA:2838,0 +DA:2840,0 +DA:2842,0 +DA:2844,0 +DA:2845,0 +DA:2846,0 +DA:2867,0 +DA:2868,0 +DA:2869,0 +DA:2872,0 +DA:2877,0 +DA:2878,0 +DA:2881,0 +DA:2883,0 +DA:2885,0 +DA:2890,0 +DA:2892,0 +DA:2893,0 +DA:2895,0 +DA:2896,0 +DA:2897,0 +DA:2899,0 +DA:2900,0 +DA:2901,0 +DA:2903,0 +DA:2904,0 +DA:2905,0 +DA:2907,0 +DA:2908,0 +DA:2909,0 +DA:2910,0 +DA:2912,0 +DA:2916,0 +DA:2919,0 +DA:2922,0 +DA:2923,0 +DA:2924,0 +DA:2926,0 +DA:2928,0 +DA:2930,0 +DA:2932,0 +DA:2934,0 +DA:2935,0 +DA:2938,0 +DA:2939,0 +DA:2942,0 +DA:2943,0 +DA:2944,0 +DA:2945,0 +DA:2948,0 +DA:2949,0 +DA:2950,0 +DA:2951,0 +DA:2952,0 +DA:2953,0 +DA:2956,0 +DA:2957,0 +DA:2958,0 +DA:2960,0 +DA:2961,0 +DA:2962,0 +DA:2968,0 +DA:2969,0 +DA:2971,0 +DA:2972,0 +DA:2976,0 +DA:2978,0 +DA:2980,0 +DA:2981,0 +DA:2982,0 +DA:2984,0 +DA:2985,0 +DA:2986,0 +DA:2988,0 +DA:2989,0 +DA:2990,0 +DA:2992,0 +DA:2993,0 +DA:2994,0 +DA:2995,0 +DA:2997,0 +DA:2998,0 +DA:3001,0 +DA:3002,0 +DA:3005,0 +DA:3015,0 +DA:3022,1 +DA:3026,0 +DA:3027,0 +DA:3028,0 +DA:3031,1 +DA:3032,1 +DA:3033,1 +DA:3034,1 +DA:3037,1 +DA:3038,0 +DA:3039,0 +DA:3040,0 +DA:3047,0 +DA:3048,0 +DA:3049,0 +DA:3050,0 +DA:3051,0 +DA:3068,1 +DA:3078,0 +DA:3080,0 +DA:3086,0 +DA:3087,0 +DA:3089,0 +DA:3095,0 +DA:3096,0 +DA:3098,0 +DA:3100,0 +DA:3101,0 +DA:3104,0 +DA:3105,0 +DA:3107,0 +DA:3109,0 +DA:3110,0 +DA:3112,0 +DA:3114,0 +DA:3115,0 +DA:3117,0 +DA:3119,0 +DA:3120,0 +DA:3122,0 +DA:3126,1 +DA:3129,0 +DA:3130,0 +DA:3133,1 +DA:3136,0 +DA:3137,0 +DA:3138,0 +DA:3139,0 +DA:3140,0 +DA:3141,0 +DA:3143,0 +DA:3146,0 +DA:3147,0 +DA:3148,0 +DA:3149,0 +DA:3150,0 +DA:3151,0 +DA:3154,0 +DA:3155,0 +DA:3159,0 +DA:3160,0 +DA:3161,0 +DA:3166,0 +DA:3173,1 +DA:3177,0 +DA:3179,0 +DA:3181,0 +DA:3183,0 +DA:3185,0 +DA:3187,0 +DA:3189,0 +DA:3201,1 +DA:3208,0 +DA:3209,0 +DA:3210,0 +DA:3211,0 +DA:3212,0 +DA:3213,0 +DA:3215,0 +DA:3218,0 +DA:3219,0 +DA:3220,0 +DA:3221,0 +DA:3228,1 +DA:3229,1 +DA:3255,1 +DA:3277,0 +DA:3278,0 +DA:3279,0 +DA:3281,0 +DA:3282,0 +DA:3284,0 +DA:3286,0 +DA:3287,0 +DA:3289,0 +DA:3291,0 +DA:3292,0 +DA:3294,0 +DA:3296,0 +DA:3297,0 +DA:3299,0 +DA:3301,0 +DA:3302,0 +DA:3304,0 +DA:3306,0 +DA:3307,0 +DA:3309,0 +DA:3311,0 +DA:3312,0 +DA:3314,0 +DA:3316,0 +DA:3317,0 +DA:3319,0 +DA:3321,0 +DA:3322,0 +DA:3324,0 +DA:3326,0 +DA:3327,0 +DA:3329,0 +DA:3331,0 +DA:3332,0 +DA:3334,0 +DA:3336,0 +DA:3337,0 +DA:3339,0 +DA:3341,0 +DA:3342,0 +DA:3344,0 +DA:3346,0 +DA:3347,0 +DA:3349,0 +DA:3351,0 +DA:3352,0 +DA:3354,0 +DA:3356,0 +DA:3357,0 +DA:3359,0 +DA:3361,0 +DA:3362,0 +DA:3364,0 +DA:3371,1 +DA:3372,1 +DA:3373,1 +DA:3374,1 +DA:3375,1 +DA:3376,1 +DA:3382,1 +DA:3383,1 +DA:3384,1 +DA:3385,1 +DA:3386,1 +DA:3387,1 +DA:3388,1 +DA:3389,1 +DA:3395,1 +DA:3396,1 +DA:3397,1 +DA:3403,1 +DA:3404,1 +DA:3405,1 +DA:3406,1 +DA:3407,1 +DA:3408,1 +DA:3414,1 +DA:3415,1 +DA:3416,1 +DA:3417,1 +DA:3418,1 +DA:3419,1 +DA:3420,1 +DA:3421,1 +DA:3427,1 +DA:3428,1 +DA:3429,1 +DA:3430,1 +DA:3431,1 +DA:3432,1 +DA:3433,1 +DA:3434,1 +DA:3445,1 +DA:3447,0 +DA:3449,0 +DA:3451,0 +DA:3455,0 +DA:3458,0 +DA:3460,0 +DA:3462,0 +DA:3468,0 +DA:3469,0 +DA:3470,0 +DA:3471,0 +DA:3472,0 +DA:3476,0 +DA:3477,0 +DA:3478,0 +DA:3479,0 +DA:3480,0 +DA:3481,0 +DA:3485,0 +DA:3486,0 +DA:3487,0 +DA:3488,0 +DA:3489,0 +DA:3490,0 +DA:3491,0 +DA:3497,0 +DA:3498,0 +DA:3505,0 +DA:3506,0 +DA:3511,0 +DA:3514,0 +DA:3525,1 +DA:3527,0 +DA:3529,0 +DA:3531,0 +DA:3533,0 +DA:3535,0 +DA:3537,0 +DA:3543,0 +DA:3545,0 +DA:3546,0 +DA:3549,0 +DA:3550,0 +DA:3553,0 +DA:3554,0 +DA:3557,0 +DA:3558,0 +DA:3561,0 +DA:3562,0 +DA:3565,0 +DA:3566,0 +DA:3569,0 +DA:3570,0 +DA:3573,0 +DA:3574,0 +DA:3577,0 +DA:3578,0 +DA:3581,0 +DA:3582,0 +DA:3585,0 +DA:3586,0 +DA:3589,0 +DA:3590,0 +DA:3593,0 +DA:3598,0 +DA:3607,1 +DA:3611,0 +DA:3612,0 +DA:3629,1 +DA:3642,0 +DA:3643,0 +DA:3644,0 +DA:3645,0 +DA:3646,0 +DA:3647,0 +DA:3648,0 +DA:3649,0 +DA:3650,0 +DA:3652,0 +DA:3654,0 +DA:3655,0 +DA:3661,0 +DA:3663,0 +DA:3664,0 +DA:3670,0 +DA:3672,0 +DA:3673,0 +DA:3676,0 +DA:3683,1 +DA:3684,0 +DA:3700,1 +DA:3701,0 +DA:3740,1 +DA:3742,0 +DA:3743,0 +DA:3745,0 +DA:3746,0 +DA:3749,0 +DA:3750,0 +DA:3754,1 +DA:3755,0 +DA:3761,1 +DA:3762,0 +DA:3768,1 +DA:3770,4 +DA:3771,4 +DA:3772,4 +DA:3774,4 +DA:3775,1 +DA:3778,4 +DA:3779,2 +DA:3782,4 +DA:3783,1 +DA:3787,1 +DA:3789,0 +DA:3790,0 +DA:3791,0 +DA:3792,0 +DA:3795,0 +DA:3796,0 +DA:3799,0 +DA:3802,1 +DA:3803,0 +DA:3810,1 +DA:3811,0 +DA:3812,0 +DA:3813,0 +DA:3814,0 +DA:3817,1 +DA:3819,0 +DA:3821,0 +DA:3823,0 +DA:3825,0 +DA:3828,1 +DA:3829,0 +DA:3830,0 +DA:3831,0 +DA:3834,1 +DA:3836,0 +DA:3838,0 +DA:3841,1 +DA:3842,0 +DA:3843,0 +DA:3844,0 +DA:3845,0 +DA:3848,1 +DA:3849,0 +DA:3852,1 +DA:3853,0 +DA:3860,1 +DA:3861,0 +DA:3862,0 +DA:3863,0 +DA:3864,0 +DA:3865,0 +DA:3866,0 +DA:3867,0 +DA:3868,0 +DA:3869,0 +DA:3870,0 +DA:3871,0 +DA:3873,0 +DA:3874,0 +DA:3876,0 +DA:3880,1 +DA:3881,0 +DA:3884,1 +DA:3886,0 +DA:3888,0 +DA:3890,0 +DA:3891,0 +DA:3894,0 +DA:3896,0 +DA:3897,0 +DA:3898,0 +DA:3900,0 +DA:3903,1 +DA:3905,1 +DA:3906,1 +DA:3907,1 +DA:3908,1 +DA:3910,1 +DA:3911,0 +DA:3914,1 +DA:3915,0 +DA:3918,1 +DA:3919,0 +DA:3922,1 +DA:3923,0 +DA:3927,1 +DA:3928,0 +DA:3929,0 +DA:3930,0 +DA:3931,0 +DA:3934,1 +DA:3935,0 +DA:3943,1 +DA:3944,0 +DA:3945,0 +DA:3946,0 +DA:3947,0 +DA:3948,0 +DA:3949,0 +DA:3950,0 +DA:3951,0 +DA:3952,0 +DA:3953,0 +DA:3954,0 +DA:3955,0 +DA:3956,0 +DA:3958,0 +DA:3959,0 +DA:3964,1 +DA:3967,0 +DA:3969,0 +DA:3971,0 +DA:3972,0 +DA:3975,0 +DA:3977,0 +DA:3978,0 +DA:3979,0 +DA:3981,0 +DA:3984,1 +DA:3986,0 +DA:3987,0 +DA:3988,0 +DA:3989,0 +DA:3992,0 +DA:3993,0 +DA:3994,0 +DA:3995,0 +DA:3996,0 +DA:3999,0 +DA:4002,1 +DA:4003,0 +DA:4006,1 +DA:4008,0 +DA:4009,0 +DA:4017,0 +DA:4018,0 +DA:4019,0 +DA:4022,0 +DA:4024,0 +DA:4027,1 +DA:4029,0 +DA:4031,0 +DA:4032,0 +DA:4035,0 +DA:4038,1 +DA:4042,0 +DA:4044,0 +DA:4046,0 +DA:4048,0 +DA:4050,0 +DA:4052,0 +DA:4054,0 +DA:4056,0 +DA:4057,0 +DA:4060,0 +DA:4062,0 +DA:4064,0 +DA:4065,0 +DA:4069,0 +DA:4073,0 +DA:4075,0 +DA:4076,0 +DA:4083,1 +DA:4087,0 +DA:4089,0 +DA:4091,0 +DA:4093,0 +DA:4095,0 +DA:4097,0 +DA:4099,0 +DA:4101,0 +DA:4102,0 +DA:4105,0 +DA:4107,0 +DA:4108,0 +DA:4109,0 +DA:4113,0 +DA:4117,0 +DA:4119,0 +DA:4120,0 +DA:4128,1 +DA:4130,0 +DA:4132,0 +DA:4134,0 +DA:4136,0 +DA:4137,0 +DA:4138,0 +DA:4140,0 +DA:4142,0 +DA:4143,0 +DA:4144,0 +DA:4145,0 +DA:4149,1 +DA:4151,0 +DA:4152,0 +DA:4153,0 +DA:4155,0 +DA:4156,0 +DA:4157,0 +DA:4159,0 +DA:4160,0 +DA:4161,0 +DA:4163,0 +DA:4164,0 +DA:4166,0 +DA:4167,0 +DA:4170,0 +DA:4171,0 +DA:4173,0 +DA:4174,0 +DA:4176,0 +DA:4177,0 +DA:4181,0 +DA:4188,1 +DA:4189,0 +DA:4190,0 +DA:4191,0 +DA:4193,0 +DA:4194,0 +DA:4195,0 +DA:4196,0 +DA:4199,0 +DA:4206,1 +DA:4208,0 +DA:4209,0 +DA:4210,0 +DA:4211,0 +DA:4214,0 +DA:4218,1 +DA:4220,0 +DA:4222,0 +DA:4223,0 +DA:4233,1 +DA:4237,0 +DA:4238,0 +DA:4251,1 +DA:4261,0 +DA:4263,0 +DA:4265,0 +DA:4266,0 +DA:4268,0 +DA:4270,0 +DA:4271,0 +DA:4277,0 +DA:4279,0 +DA:4280,0 +DA:4286,0 +DA:4288,0 +DA:4289,0 +DA:4291,0 +DA:4293,0 +DA:4295,0 +DA:4302,0 +DA:4303,0 +DA:4304,0 +DA:4309,1 +DA:4311,0 +DA:4313,0 +DA:4315,0 +DA:4318,0 +DA:4320,0 +DA:4322,0 +DA:4323,0 +DA:4324,0 +DA:4325,0 +DA:4326,0 +DA:4329,0 +DA:4331,0 +DA:4332,0 +DA:4333,0 +DA:4335,0 +DA:4337,0 +DA:4342,0 +DA:4344,0 +DA:4347,1 +DA:4353,0 +DA:4358,0 +DA:4360,0 +DA:4361,0 +DA:4363,0 +DA:4364,0 +DA:4367,0 +DA:4368,0 +DA:4371,0 +DA:4375,1 +DA:4379,1 +DA:4382,0 +DA:4384,0 +DA:4385,0 +DA:4388,0 +DA:4389,0 +DA:4393,1 +DA:4396,0 +DA:4398,0 +DA:4399,0 +DA:4402,0 +DA:4403,0 +DA:4407,1 +DA:4414,0 +DA:4415,0 +DA:4424,1 +DA:4428,0 +DA:4429,0 +DA:4431,0 +DA:4437,1 +DA:4441,0 +DA:4442,0 +DA:4446,1 +DA:4449,0 +DA:4450,0 +DA:4454,1 +DA:4457,0 +DA:4458,0 +DA:4462,1 +DA:4468,0 +DA:4469,0 +DA:4473,1 +DA:4476,0 +DA:4477,0 +DA:4481,1 +DA:4484,0 +DA:4485,0 +DA:4489,1 +DA:4492,0 +DA:4498,0 +DA:4500,0 +DA:4502,0 +DA:4503,0 +DA:4504,0 +DA:4507,0 +DA:4509,0 +DA:4511,0 +DA:4515,1 +DA:4519,0 +DA:4521,0 +DA:4528,0 +DA:4533,1 +DA:4540,0 +DA:4541,0 +DA:4551,0 +DA:4553,0 +DA:4554,0 +DA:4557,0 +DA:4558,0 +DA:4559,0 +DA:4560,0 +DA:4562,0 +DA:4567,0 +DA:4573,0 +DA:4574,0 +DA:4575,0 +DA:4576,0 +DA:4581,0 +DA:4582,0 +DA:4585,0 +DA:4586,0 +DA:4587,0 +DA:4589,0 +DA:4592,1 +DA:4600,0 +DA:4601,0 +DA:4602,0 +DA:4603,0 +DA:4604,0 +DA:4606,0 +DA:4608,0 +DA:4609,0 +DA:4611,0 +DA:4612,0 +DA:4614,0 +DA:4616,0 +DA:4618,0 +DA:4619,0 +DA:4620,0 +DA:4621,0 +DA:4622,0 +DA:4623,0 +DA:4624,0 +DA:4626,0 +DA:4627,0 +DA:4629,0 +DA:4631,0 +DA:4635,0 +DA:4640,0 +DA:4641,0 +DA:4642,0 +DA:4644,0 +DA:4645,0 +DA:4649,0 +DA:4650,0 +DA:4651,0 +DA:4652,0 +DA:4654,0 +DA:4655,0 +DA:4656,0 +DA:4658,0 +DA:4659,0 +DA:4660,0 +DA:4662,0 +DA:4666,1 +DA:4667,1 +LF:1745 +LH:283 +BRDA:1,1,0,0 +BRDA:1,1,1,1 +BRDA:5,2,0,1 +BRDA:5,2,1,0 +BRDA:51,3,0,0 +BRDA:51,3,1,1 +BRDA:56,4,0,1 +BRDA:56,4,1,0 +BRDA:61,5,0,1 +BRDA:61,5,1,0 +BRDA:66,6,0,1 +BRDA:66,6,1,0 +BRDA:71,7,0,1 +BRDA:71,7,1,0 +BRDA:76,8,0,1 +BRDA:76,8,1,0 +BRDA:81,9,0,1 +BRDA:81,9,1,0 +BRDA:104,10,0,0 +BRDA:104,10,1,0 +BRDA:109,11,0,0 +BRDA:109,11,1,0 +BRDA:114,12,0,0 +BRDA:114,12,1,0 +BRDA:121,13,0,0 +BRDA:121,13,1,0 +BRDA:131,14,0,0 +BRDA:131,14,1,0 +BRDA:140,15,0,0 +BRDA:140,15,1,0 +BRDA:142,16,0,0 +BRDA:142,16,1,0 +BRDA:144,17,0,0 +BRDA:144,17,1,0 +BRDA:203,18,0,0 +BRDA:203,18,1,0 +BRDA:276,19,0,0 +BRDA:276,19,1,0 +BRDA:276,19,2,0 +BRDA:279,20,0,0 +BRDA:279,20,1,0 +BRDA:280,21,0,0 +BRDA:280,21,1,0 +BRDA:280,21,2,0 +BRDA:281,22,0,0 +BRDA:281,22,1,0 +BRDA:281,22,2,0 +BRDA:301,23,0,0 +BRDA:301,23,1,0 +BRDA:312,24,0,0 +BRDA:312,24,1,0 +BRDA:339,25,0,0 +BRDA:339,25,1,0 +BRDA:345,26,0,0 +BRDA:345,26,1,0 +BRDA:352,27,0,0 +BRDA:352,27,1,0 +BRDA:358,28,0,0 +BRDA:358,28,1,0 +BRDA:365,29,0,0 +BRDA:365,29,1,0 +BRDA:369,30,0,0 +BRDA:369,30,1,0 +BRDA:391,31,0,0 +BRDA:391,31,1,0 +BRDA:392,32,0,0 +BRDA:392,32,1,0 +BRDA:392,32,2,0 +BRDA:392,32,3,0 +BRDA:393,33,0,0 +BRDA:393,33,1,0 +BRDA:393,33,2,0 +BRDA:393,33,3,0 +BRDA:405,34,0,0 +BRDA:405,34,1,0 +BRDA:405,34,2,0 +BRDA:405,34,3,0 +BRDA:405,34,4,0 +BRDA:405,34,5,0 +BRDA:438,35,0,0 +BRDA:438,35,1,0 +BRDA:438,35,2,0 +BRDA:438,35,3,0 +BRDA:438,35,4,0 +BRDA:438,35,5,0 +BRDA:438,35,6,0 +BRDA:438,35,7,0 +BRDA:438,35,8,0 +BRDA:438,35,9,0 +BRDA:493,36,0,0 +BRDA:493,36,1,0 +BRDA:511,37,0,0 +BRDA:511,37,1,0 +BRDA:511,38,0,0 +BRDA:511,38,1,0 +BRDA:523,39,0,0 +BRDA:523,39,1,0 +BRDA:524,40,0,0 +BRDA:524,40,1,0 +BRDA:534,41,0,0 +BRDA:534,41,1,0 +BRDA:536,42,0,0 +BRDA:536,42,1,0 +BRDA:537,43,0,0 +BRDA:537,43,1,0 +BRDA:543,44,0,0 +BRDA:543,44,1,0 +BRDA:568,45,0,0 +BRDA:568,45,1,0 +BRDA:587,46,0,0 +BRDA:587,46,1,0 +BRDA:592,47,0,0 +BRDA:592,47,1,0 +BRDA:597,48,0,0 +BRDA:597,48,1,0 +BRDA:707,49,0,0 +BRDA:707,49,1,0 +BRDA:712,50,0,0 +BRDA:712,50,1,0 +BRDA:716,51,0,0 +BRDA:716,51,1,0 +BRDA:720,52,0,0 +BRDA:720,52,1,0 +BRDA:724,53,0,0 +BRDA:724,53,1,0 +BRDA:772,54,0,0 +BRDA:772,54,1,0 +BRDA:777,55,0,0 +BRDA:777,55,1,0 +BRDA:782,56,0,0 +BRDA:782,56,1,0 +BRDA:787,57,0,0 +BRDA:787,57,1,0 +BRDA:792,58,0,0 +BRDA:792,58,1,0 +BRDA:797,59,0,0 +BRDA:797,59,1,0 +BRDA:802,60,0,0 +BRDA:802,60,1,0 +BRDA:807,61,0,0 +BRDA:807,61,1,0 +BRDA:812,62,0,0 +BRDA:812,62,1,0 +BRDA:817,63,0,0 +BRDA:817,63,1,0 +BRDA:944,64,0,0 +BRDA:944,64,1,0 +BRDA:949,65,0,0 +BRDA:949,65,1,0 +BRDA:954,66,0,0 +BRDA:954,66,1,0 +BRDA:959,67,0,0 +BRDA:959,67,1,0 +BRDA:964,68,0,0 +BRDA:964,68,1,0 +BRDA:982,69,0,0 +BRDA:982,69,1,0 +BRDA:987,70,0,0 +BRDA:987,70,1,0 +BRDA:992,71,0,0 +BRDA:992,71,1,0 +BRDA:997,72,0,0 +BRDA:997,72,1,0 +BRDA:1002,73,0,0 +BRDA:1002,73,1,0 +BRDA:1007,74,0,0 +BRDA:1007,74,1,0 +BRDA:1012,75,0,0 +BRDA:1012,75,1,0 +BRDA:1017,76,0,0 +BRDA:1017,76,1,0 +BRDA:1022,77,0,0 +BRDA:1022,77,1,0 +BRDA:1027,78,0,0 +BRDA:1027,78,1,0 +BRDA:1032,79,0,0 +BRDA:1032,79,1,0 +BRDA:1037,80,0,0 +BRDA:1037,80,1,0 +BRDA:1042,81,0,0 +BRDA:1042,81,1,0 +BRDA:1047,82,0,0 +BRDA:1047,82,1,0 +BRDA:1052,83,0,0 +BRDA:1052,83,1,0 +BRDA:1057,84,0,0 +BRDA:1057,84,1,0 +BRDA:1062,85,0,0 +BRDA:1062,85,1,0 +BRDA:1067,86,0,0 +BRDA:1067,86,1,0 +BRDA:1072,87,0,0 +BRDA:1072,87,1,0 +BRDA:1077,88,0,0 +BRDA:1077,88,1,0 +BRDA:1082,89,0,0 +BRDA:1082,89,1,0 +BRDA:1087,90,0,0 +BRDA:1087,90,1,0 +BRDA:1092,91,0,0 +BRDA:1092,91,1,0 +BRDA:1097,92,0,0 +BRDA:1097,92,1,0 +BRDA:1102,93,0,0 +BRDA:1102,93,1,0 +BRDA:1107,94,0,0 +BRDA:1107,94,1,0 +BRDA:1112,95,0,0 +BRDA:1112,95,1,0 +BRDA:1117,96,0,0 +BRDA:1117,96,1,0 +BRDA:1122,97,0,0 +BRDA:1122,97,1,0 +BRDA:1127,98,0,0 +BRDA:1127,98,1,0 +BRDA:1132,99,0,0 +BRDA:1132,99,1,0 +BRDA:1137,100,0,0 +BRDA:1137,100,1,0 +BRDA:1142,101,0,0 +BRDA:1142,101,1,0 +BRDA:1147,102,0,0 +BRDA:1147,102,1,0 +BRDA:1152,103,0,0 +BRDA:1152,103,1,0 +BRDA:1157,104,0,0 +BRDA:1157,104,1,0 +BRDA:1162,105,0,0 +BRDA:1162,105,1,0 +BRDA:1167,106,0,0 +BRDA:1167,106,1,0 +BRDA:1172,107,0,0 +BRDA:1172,107,1,0 +BRDA:1177,108,0,0 +BRDA:1177,108,1,0 +BRDA:1182,109,0,0 +BRDA:1182,109,1,0 +BRDA:1187,110,0,0 +BRDA:1187,110,1,0 +BRDA:1192,111,0,0 +BRDA:1192,111,1,0 +BRDA:1197,112,0,0 +BRDA:1197,112,1,0 +BRDA:1202,113,0,0 +BRDA:1202,113,1,0 +BRDA:1207,114,0,0 +BRDA:1207,114,1,0 +BRDA:1212,115,0,0 +BRDA:1212,115,1,0 +BRDA:1217,116,0,0 +BRDA:1217,116,1,0 +BRDA:1222,117,0,0 +BRDA:1222,117,1,0 +BRDA:1227,118,0,0 +BRDA:1227,118,1,0 +BRDA:1343,119,0,0 +BRDA:1343,119,1,0 +BRDA:1409,120,0,0 +BRDA:1409,120,1,0 +BRDA:1484,121,0,0 +BRDA:1484,121,1,0 +BRDA:1516,122,0,0 +BRDA:1516,122,1,0 +BRDA:1520,123,0,0 +BRDA:1520,123,1,0 +BRDA:1524,124,0,0 +BRDA:1524,124,1,0 +BRDA:1548,125,0,0 +BRDA:1548,125,1,0 +BRDA:1552,126,0,0 +BRDA:1552,126,1,0 +BRDA:1556,127,0,0 +BRDA:1556,127,1,0 +BRDA:1560,128,0,0 +BRDA:1560,128,1,0 +BRDA:1615,129,0,0 +BRDA:1615,129,1,0 +BRDA:1622,130,0,0 +BRDA:1622,130,1,0 +BRDA:1646,131,0,0 +BRDA:1646,131,1,0 +BRDA:1652,132,0,0 +BRDA:1652,132,1,0 +BRDA:1766,133,0,0 +BRDA:1766,133,1,0 +BRDA:1771,134,0,0 +BRDA:1771,134,1,0 +BRDA:1776,135,0,0 +BRDA:1776,135,1,0 +BRDA:1781,136,0,0 +BRDA:1781,136,1,0 +BRDA:1786,137,0,0 +BRDA:1786,137,1,0 +BRDA:1791,138,0,0 +BRDA:1791,138,1,0 +BRDA:1796,139,0,0 +BRDA:1796,139,1,0 +BRDA:1801,140,0,0 +BRDA:1801,140,1,0 +BRDA:1806,141,0,0 +BRDA:1806,141,1,0 +BRDA:1811,142,0,0 +BRDA:1811,142,1,0 +BRDA:1845,143,0,0 +BRDA:1845,143,1,0 +BRDA:1849,144,0,0 +BRDA:1849,144,1,0 +BRDA:1933,145,0,0 +BRDA:1933,145,1,0 +BRDA:1947,146,0,0 +BRDA:1947,146,1,0 +BRDA:2014,147,0,0 +BRDA:2014,147,1,0 +BRDA:2070,148,0,0 +BRDA:2070,148,1,0 +BRDA:2088,149,0,0 +BRDA:2088,149,1,0 +BRDA:2089,150,0,0 +BRDA:2089,150,1,0 +BRDA:2089,150,2,0 +BRDA:2089,150,3,0 +BRDA:2089,150,4,0 +BRDA:2089,150,5,0 +BRDA:2089,150,6,0 +BRDA:2089,150,7,0 +BRDA:2089,150,8,0 +BRDA:2089,150,9,0 +BRDA:2089,150,10,0 +BRDA:2089,150,11,0 +BRDA:2107,151,0,0 +BRDA:2107,151,1,0 +BRDA:2146,152,0,0 +BRDA:2146,152,1,0 +BRDA:2147,153,0,0 +BRDA:2147,153,1,0 +BRDA:2147,153,2,0 +BRDA:2147,153,3,0 +BRDA:2147,153,4,0 +BRDA:2147,153,5,0 +BRDA:2182,154,0,0 +BRDA:2182,154,1,0 +BRDA:2182,155,0,0 +BRDA:2182,155,1,0 +BRDA:2196,156,0,0 +BRDA:2196,156,1,0 +BRDA:2201,157,0,0 +BRDA:2201,157,1,0 +BRDA:2219,158,0,0 +BRDA:2219,158,1,0 +BRDA:2219,159,0,0 +BRDA:2219,159,1,0 +BRDA:2271,160,0,0 +BRDA:2271,160,1,0 +BRDA:2392,161,0,0 +BRDA:2392,161,1,0 +BRDA:2393,162,0,0 +BRDA:2393,162,1,0 +BRDA:2394,163,0,0 +BRDA:2394,163,1,0 +BRDA:2395,164,0,0 +BRDA:2395,164,1,0 +BRDA:2396,165,0,0 +BRDA:2396,165,1,0 +BRDA:2397,166,0,0 +BRDA:2397,166,1,0 +BRDA:2398,167,0,0 +BRDA:2398,167,1,0 +BRDA:2399,168,0,0 +BRDA:2399,168,1,0 +BRDA:2400,169,0,0 +BRDA:2400,169,1,0 +BRDA:2401,170,0,0 +BRDA:2401,170,1,0 +BRDA:2402,171,0,0 +BRDA:2402,171,1,0 +BRDA:2403,172,0,0 +BRDA:2403,172,1,0 +BRDA:2404,173,0,0 +BRDA:2404,173,1,0 +BRDA:2405,174,0,0 +BRDA:2405,174,1,0 +BRDA:2406,175,0,0 +BRDA:2406,175,1,0 +BRDA:2420,176,0,0 +BRDA:2420,176,1,0 +BRDA:2477,177,0,0 +BRDA:2477,177,1,0 +BRDA:2482,178,0,0 +BRDA:2482,178,1,0 +BRDA:2487,179,0,0 +BRDA:2487,179,1,0 +BRDA:2492,180,0,0 +BRDA:2492,180,1,0 +BRDA:2497,181,0,0 +BRDA:2497,181,1,0 +BRDA:2502,182,0,0 +BRDA:2502,182,1,0 +BRDA:2507,183,0,0 +BRDA:2507,183,1,0 +BRDA:2512,184,0,0 +BRDA:2512,184,1,0 +BRDA:2528,185,0,0 +BRDA:2528,185,1,0 +BRDA:2541,186,0,0 +BRDA:2541,186,1,0 +BRDA:2545,187,0,0 +BRDA:2545,187,1,0 +BRDA:2545,188,0,0 +BRDA:2545,188,1,0 +BRDA:2553,189,0,0 +BRDA:2553,189,1,0 +BRDA:2553,190,0,0 +BRDA:2553,190,1,0 +BRDA:2684,191,0,0 +BRDA:2684,191,1,0 +BRDA:2867,192,0,0 +BRDA:2867,192,1,0 +BRDA:2924,193,0,0 +BRDA:2924,193,1,0 +BRDA:2934,194,0,0 +BRDA:2934,194,1,0 +BRDA:2938,195,0,0 +BRDA:2938,195,1,0 +BRDA:2942,196,0,0 +BRDA:2942,196,1,0 +BRDA:2948,197,0,0 +BRDA:2948,197,1,0 +BRDA:2968,198,0,0 +BRDA:2968,198,1,0 +BRDA:3038,199,0,0 +BRDA:3038,199,1,0 +BRDA:3039,200,0,0 +BRDA:3039,200,1,0 +BRDA:3086,201,0,0 +BRDA:3086,201,1,0 +BRDA:3095,202,0,0 +BRDA:3095,202,1,0 +BRDA:3100,203,0,0 +BRDA:3100,203,1,0 +BRDA:3104,204,0,0 +BRDA:3104,204,1,0 +BRDA:3109,205,0,0 +BRDA:3109,205,1,0 +BRDA:3114,206,0,0 +BRDA:3114,206,1,0 +BRDA:3119,207,0,0 +BRDA:3119,207,1,0 +BRDA:3209,208,0,0 +BRDA:3209,208,1,0 +BRDA:3210,209,0,0 +BRDA:3210,209,1,0 +BRDA:3212,210,0,0 +BRDA:3212,210,1,0 +BRDA:3281,211,0,0 +BRDA:3281,211,1,0 +BRDA:3286,212,0,0 +BRDA:3286,212,1,0 +BRDA:3291,213,0,0 +BRDA:3291,213,1,0 +BRDA:3296,214,0,0 +BRDA:3296,214,1,0 +BRDA:3301,215,0,0 +BRDA:3301,215,1,0 +BRDA:3306,216,0,0 +BRDA:3306,216,1,0 +BRDA:3311,217,0,0 +BRDA:3311,217,1,0 +BRDA:3316,218,0,0 +BRDA:3316,218,1,0 +BRDA:3321,219,0,0 +BRDA:3321,219,1,0 +BRDA:3326,220,0,0 +BRDA:3326,220,1,0 +BRDA:3331,221,0,0 +BRDA:3331,221,1,0 +BRDA:3336,222,0,0 +BRDA:3336,222,1,0 +BRDA:3341,223,0,0 +BRDA:3341,223,1,0 +BRDA:3346,224,0,0 +BRDA:3346,224,1,0 +BRDA:3351,225,0,0 +BRDA:3351,225,1,0 +BRDA:3356,226,0,0 +BRDA:3356,226,1,0 +BRDA:3361,227,0,0 +BRDA:3361,227,1,0 +BRDA:3451,228,0,0 +BRDA:3451,228,1,0 +BRDA:3451,229,0,0 +BRDA:3451,229,1,0 +BRDA:3451,229,2,0 +BRDA:3458,230,0,0 +BRDA:3458,230,1,0 +BRDA:3497,231,0,0 +BRDA:3497,231,1,0 +BRDA:3533,232,0,0 +BRDA:3533,232,1,0 +BRDA:3537,233,0,0 +BRDA:3537,233,1,0 +BRDA:3538,234,0,0 +BRDA:3538,234,1,0 +BRDA:3538,234,2,0 +BRDA:3545,235,0,0 +BRDA:3545,235,1,0 +BRDA:3549,236,0,0 +BRDA:3549,236,1,0 +BRDA:3553,237,0,0 +BRDA:3553,237,1,0 +BRDA:3557,238,0,0 +BRDA:3557,238,1,0 +BRDA:3561,239,0,0 +BRDA:3561,239,1,0 +BRDA:3565,240,0,0 +BRDA:3565,240,1,0 +BRDA:3569,241,0,0 +BRDA:3569,241,1,0 +BRDA:3573,242,0,0 +BRDA:3573,242,1,0 +BRDA:3577,243,0,0 +BRDA:3577,243,1,0 +BRDA:3581,244,0,0 +BRDA:3581,244,1,0 +BRDA:3585,245,0,0 +BRDA:3585,245,1,0 +BRDA:3589,246,0,0 +BRDA:3589,246,1,0 +BRDA:3649,247,0,0 +BRDA:3649,247,1,0 +BRDA:3654,248,0,0 +BRDA:3654,248,1,0 +BRDA:3663,249,0,0 +BRDA:3663,249,1,0 +BRDA:3672,250,0,0 +BRDA:3672,250,1,0 +BRDA:3702,251,0,0 +BRDA:3702,251,1,0 +BRDA:3702,251,2,0 +BRDA:3702,251,3,0 +BRDA:3702,251,4,0 +BRDA:3702,251,5,0 +BRDA:3702,251,6,0 +BRDA:3702,251,7,0 +BRDA:3702,251,8,0 +BRDA:3702,251,9,0 +BRDA:3702,251,10,0 +BRDA:3702,251,11,0 +BRDA:3702,251,12,0 +BRDA:3702,251,13,0 +BRDA:3702,251,14,0 +BRDA:3702,251,15,0 +BRDA:3702,251,16,0 +BRDA:3702,251,17,0 +BRDA:3745,252,0,0 +BRDA:3745,252,1,0 +BRDA:3749,253,0,0 +BRDA:3749,253,1,0 +BRDA:3762,254,0,0 +BRDA:3762,254,1,0 +BRDA:3762,254,2,0 +BRDA:3762,254,3,0 +BRDA:3774,255,0,1 +BRDA:3774,255,1,3 +BRDA:3778,256,0,2 +BRDA:3778,256,1,2 +BRDA:3782,257,0,1 +BRDA:3782,257,1,3 +BRDA:3789,258,0,0 +BRDA:3789,258,1,0 +BRDA:3795,259,0,0 +BRDA:3795,259,1,0 +BRDA:3861,260,0,0 +BRDA:3861,260,1,0 +BRDA:3865,261,0,0 +BRDA:3865,261,1,0 +BRDA:3890,262,0,0 +BRDA:3890,262,1,0 +BRDA:3910,263,0,0 +BRDA:3910,263,1,1 +BRDA:3914,264,0,0 +BRDA:3914,264,1,1 +BRDA:3918,265,0,0 +BRDA:3918,265,1,1 +BRDA:3922,266,0,0 +BRDA:3922,266,1,1 +BRDA:3944,267,0,0 +BRDA:3944,267,1,0 +BRDA:3948,268,0,0 +BRDA:3948,268,1,0 +BRDA:3971,269,0,0 +BRDA:3971,269,1,0 +BRDA:3986,270,0,0 +BRDA:3986,270,1,0 +BRDA:3992,271,0,0 +BRDA:3992,271,1,0 +BRDA:4008,272,0,0 +BRDA:4008,272,1,0 +BRDA:4017,273,0,0 +BRDA:4017,273,1,0 +BRDA:4062,274,0,0 +BRDA:4062,274,1,0 +BRDA:4107,275,0,0 +BRDA:4107,275,1,0 +BRDA:4160,276,0,0 +BRDA:4160,276,1,0 +BRDA:4163,277,0,0 +BRDA:4163,277,1,0 +BRDA:4166,278,0,0 +BRDA:4166,278,1,0 +BRDA:4170,279,0,0 +BRDA:4170,279,1,0 +BRDA:4173,280,0,0 +BRDA:4173,280,1,0 +BRDA:4176,281,0,0 +BRDA:4176,281,1,0 +BRDA:4265,282,0,0 +BRDA:4265,282,1,0 +BRDA:4270,283,0,0 +BRDA:4270,283,1,0 +BRDA:4279,284,0,0 +BRDA:4279,284,1,0 +BRDA:4288,285,0,0 +BRDA:4288,285,1,0 +BRDA:4302,286,0,0 +BRDA:4302,286,1,0 +BRDA:4322,287,0,0 +BRDA:4322,287,1,0 +BRDA:4324,288,0,0 +BRDA:4324,288,1,0 +BRDA:4358,289,0,0 +BRDA:4358,289,1,0 +BRDA:4363,290,0,0 +BRDA:4363,290,1,0 +BRDA:4363,291,0,0 +BRDA:4363,291,1,0 +BRDA:4367,292,0,0 +BRDA:4367,292,1,0 +BRDA:4367,293,0,0 +BRDA:4367,293,1,0 +BRDA:4384,294,0,0 +BRDA:4384,294,1,0 +BRDA:4398,295,0,0 +BRDA:4398,295,1,0 +BRDA:4414,296,0,0 +BRDA:4414,296,1,0 +BRDA:4428,297,0,0 +BRDA:4428,297,1,0 +BRDA:4441,298,0,0 +BRDA:4441,298,1,0 +BRDA:4449,299,0,0 +BRDA:4449,299,1,0 +BRDA:4457,300,0,0 +BRDA:4457,300,1,0 +BRDA:4468,301,0,0 +BRDA:4468,301,1,0 +BRDA:4476,302,0,0 +BRDA:4476,302,1,0 +BRDA:4484,303,0,0 +BRDA:4484,303,1,0 +BRDA:4492,304,0,0 +BRDA:4492,304,1,0 +BRDA:4500,305,0,0 +BRDA:4500,305,1,0 +BRDA:4519,306,0,0 +BRDA:4519,306,1,0 +BRDA:4545,307,0,0 +BRDA:4545,307,1,0 +BRDA:4547,308,0,0 +BRDA:4547,308,1,0 +BRDA:4574,309,0,0 +BRDA:4574,309,1,0 +BRDA:4601,310,0,0 +BRDA:4601,310,1,0 +BRDA:4602,311,0,0 +BRDA:4602,311,1,0 +BRDA:4604,312,0,0 +BRDA:4604,312,1,0 +BRDA:4612,313,0,0 +BRDA:4612,313,1,0 +BRDA:4612,314,0,0 +BRDA:4612,314,1,0 +BRDA:4616,315,0,0 +BRDA:4616,315,1,0 +BRDA:4626,316,0,0 +BRDA:4626,316,1,0 +BRDA:4626,317,0,0 +BRDA:4626,317,1,0 +BRDA:4629,318,0,0 +BRDA:4629,318,1,0 +BRDA:4631,319,0,0 +BRDA:4631,319,1,0 +BRDA:4636,320,0,0 +BRDA:4636,320,1,0 +BRDA:4644,321,0,0 +BRDA:4644,321,1,0 +BRDA:4666,322,0,1 +BRDA:4666,322,1,0 +BRF:697 +BRH:20 +end_of_record diff --git a/gulpfile.js b/gulpfile.js index a4a2aa4..73486b5 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -23,7 +23,7 @@ gulp.task( ); gulp.task('test-prepare', function(){ - return gulp.src(['./build/game-lib.js']) + return gulp.src('./build/game-lib.js') .pipe(plumber()) .pipe(istanbul()) .pipe(istanbul.hookRequire()) @@ -40,7 +40,11 @@ gulp.task( .pipe(sort()) .pipe(plumber()) .pipe(mocha({reporter: 'spec'})) - .pipe(istanbul.writeReports()) + .pipe(istanbul.writeReports({ + dir: './build/coverage', + reporters: [ 'lcov' ], + reportOpts: { dir: './build/coverage' } + })) .pipe(istanbul.enforceThresholds({thresholds:{global:90}})) .on('error', function(error) { From 92ff078277d0e39523615ae5cc0c1981303b5226 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Mon, 24 Oct 2016 15:56:28 +0200 Subject: [PATCH 12/15] test framework stuff --- build/coverage/coverage-final.json | 2 + .../lcov-report/build/game-lib.js.html | 140 ++++++++--------- build/coverage/lcov-report/build/index.html | 36 ++--- build/coverage/lcov-report/index.html | 36 ++--- build/coverage/lcov.info | 84 +++++----- gulpfile.js | 6 +- package.json | 4 +- test/test.GameLib.js | 49 ------ test/test.gameLib.js | 144 ++++++++++++++++++ 9 files changed, 299 insertions(+), 202 deletions(-) create mode 100644 build/coverage/coverage-final.json delete mode 100644 test/test.GameLib.js create mode 100644 test/test.gameLib.js diff --git a/build/coverage/coverage-final.json b/build/coverage/coverage-final.json new file mode 100644 index 0000000..627c006 --- /dev/null +++ b/build/coverage/coverage-final.json @@ -0,0 +1,2 @@ +{ +"/usr/share/gamewheel/game-lib/build/game-lib.js":{"path":"/usr/share/gamewheel/game-lib/build/game-lib.js","s":{"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1,"12":1,"13":0,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":0,"37":1,"38":1,"39":0,"40":1,"41":1,"42":0,"43":1,"44":1,"45":1,"46":1,"47":1,"48":1,"49":0,"50":0,"51":1,"52":1,"53":1,"54":1,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":1,"62":1,"63":1,"64":1,"65":1,"66":1,"67":2,"68":2,"69":2,"70":2,"71":1,"72":2,"73":2,"74":1,"75":0,"76":1,"77":1,"78":0,"79":0,"80":1,"81":0,"82":1,"83":0,"84":1,"85":1,"86":1,"87":1,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":0,"113":0,"114":0,"115":0,"116":0,"117":1,"118":0,"119":0,"120":0,"121":0,"122":1,"123":0,"124":0,"125":0,"126":1,"127":0,"128":0,"129":0,"130":1,"131":0,"132":1,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0,"147":0,"148":0,"149":0,"150":0,"151":0,"152":0,"153":0,"154":0,"155":0,"156":0,"157":0,"158":0,"159":1,"160":0,"161":0,"162":1,"163":0,"164":0,"165":0,"166":0,"167":0,"168":1,"169":0,"170":0,"171":0,"172":0,"173":0,"174":0,"175":0,"176":0,"177":0,"178":0,"179":0,"180":0,"181":0,"182":1,"183":0,"184":0,"185":0,"186":0,"187":0,"188":0,"189":0,"190":0,"191":0,"192":0,"193":0,"194":0,"195":0,"196":1,"197":0,"198":0,"199":0,"200":1,"201":0,"202":1,"203":0,"204":1,"205":0,"206":0,"207":1,"208":0,"209":1,"210":0,"211":0,"212":0,"213":0,"214":0,"215":0,"216":0,"217":0,"218":0,"219":0,"220":0,"221":0,"222":0,"223":0,"224":0,"225":0,"226":0,"227":0,"228":0,"229":0,"230":0,"231":0,"232":0,"233":0,"234":0,"235":0,"236":0,"237":0,"238":0,"239":0,"240":1,"241":0,"242":0,"243":1,"244":0,"245":0,"246":0,"247":0,"248":0,"249":0,"250":0,"251":0,"252":0,"253":1,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"260":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"267":0,"268":0,"269":0,"270":0,"271":0,"272":0,"273":0,"274":0,"275":1,"276":0,"277":0,"278":0,"279":0,"280":0,"281":0,"282":0,"283":0,"284":0,"285":0,"286":0,"287":0,"288":0,"289":0,"290":0,"291":0,"292":0,"293":0,"294":0,"295":0,"296":0,"297":1,"298":0,"299":0,"300":0,"301":0,"302":0,"303":0,"304":0,"305":0,"306":0,"307":0,"308":0,"309":0,"310":0,"311":0,"312":0,"313":1,"314":0,"315":0,"316":0,"317":0,"318":0,"319":0,"320":0,"321":0,"322":0,"323":0,"324":0,"325":0,"326":0,"327":0,"328":0,"329":0,"330":0,"331":0,"332":0,"333":0,"334":0,"335":0,"336":0,"337":0,"338":0,"339":0,"340":0,"341":0,"342":0,"343":0,"344":0,"345":0,"346":0,"347":0,"348":0,"349":1,"350":0,"351":0,"352":0,"353":0,"354":0,"355":0,"356":0,"357":0,"358":0,"359":0,"360":0,"361":0,"362":0,"363":0,"364":0,"365":0,"366":0,"367":0,"368":0,"369":0,"370":0,"371":0,"372":0,"373":0,"374":0,"375":0,"376":0,"377":0,"378":0,"379":0,"380":0,"381":0,"382":0,"383":0,"384":0,"385":0,"386":0,"387":0,"388":0,"389":0,"390":0,"391":0,"392":0,"393":0,"394":0,"395":0,"396":0,"397":0,"398":0,"399":0,"400":0,"401":0,"402":0,"403":0,"404":0,"405":0,"406":0,"407":0,"408":0,"409":0,"410":0,"411":0,"412":0,"413":0,"414":0,"415":0,"416":0,"417":0,"418":0,"419":0,"420":0,"421":0,"422":0,"423":0,"424":0,"425":0,"426":0,"427":0,"428":0,"429":0,"430":0,"431":0,"432":0,"433":0,"434":0,"435":0,"436":0,"437":0,"438":0,"439":0,"440":0,"441":0,"442":0,"443":0,"444":0,"445":0,"446":0,"447":0,"448":0,"449":0,"450":0,"451":0,"452":0,"453":0,"454":0,"455":0,"456":0,"457":0,"458":0,"459":0,"460":0,"461":0,"462":0,"463":0,"464":0,"465":0,"466":0,"467":0,"468":0,"469":0,"470":0,"471":0,"472":0,"473":0,"474":0,"475":0,"476":0,"477":0,"478":0,"479":0,"480":0,"481":0,"482":0,"483":0,"484":0,"485":0,"486":0,"487":0,"488":0,"489":0,"490":0,"491":0,"492":0,"493":0,"494":0,"495":0,"496":0,"497":0,"498":0,"499":0,"500":0,"501":0,"502":0,"503":0,"504":0,"505":0,"506":0,"507":0,"508":0,"509":0,"510":0,"511":0,"512":0,"513":0,"514":0,"515":0,"516":0,"517":1,"518":1,"519":1,"520":1,"521":1,"522":1,"523":1,"524":1,"525":1,"526":1,"527":1,"528":1,"529":1,"530":1,"531":1,"532":1,"533":1,"534":1,"535":1,"536":1,"537":1,"538":1,"539":1,"540":1,"541":1,"542":1,"543":1,"544":1,"545":1,"546":1,"547":1,"548":1,"549":1,"550":1,"551":1,"552":1,"553":1,"554":1,"555":1,"556":1,"557":1,"558":1,"559":1,"560":1,"561":1,"562":1,"563":1,"564":1,"565":1,"566":1,"567":1,"568":1,"569":0,"570":0,"571":0,"572":0,"573":0,"574":0,"575":0,"576":0,"577":0,"578":0,"579":0,"580":0,"581":0,"582":0,"583":0,"584":0,"585":0,"586":0,"587":1,"588":0,"589":0,"590":0,"591":0,"592":0,"593":0,"594":0,"595":1,"596":0,"597":1,"598":0,"599":0,"600":0,"601":0,"602":0,"603":0,"604":0,"605":0,"606":0,"607":1,"608":0,"609":0,"610":0,"611":0,"612":1,"613":0,"614":0,"615":0,"616":0,"617":1,"618":0,"619":0,"620":0,"621":0,"622":1,"623":0,"624":0,"625":0,"626":1,"627":0,"628":0,"629":0,"630":1,"631":0,"632":0,"633":0,"634":1,"635":0,"636":0,"637":0,"638":0,"639":1,"640":0,"641":1,"642":0,"643":0,"644":0,"645":0,"646":0,"647":0,"648":0,"649":0,"650":0,"651":0,"652":0,"653":0,"654":0,"655":0,"656":0,"657":0,"658":0,"659":0,"660":0,"661":1,"662":0,"663":0,"664":0,"665":0,"666":0,"667":0,"668":0,"669":0,"670":0,"671":0,"672":0,"673":0,"674":0,"675":0,"676":0,"677":0,"678":0,"679":0,"680":0,"681":0,"682":0,"683":0,"684":0,"685":0,"686":0,"687":0,"688":0,"689":0,"690":0,"691":0,"692":0,"693":0,"694":0,"695":0,"696":0,"697":0,"698":0,"699":0,"700":0,"701":0,"702":1,"703":1,"704":1,"705":0,"706":0,"707":0,"708":0,"709":0,"710":0,"711":0,"712":0,"713":0,"714":0,"715":0,"716":0,"717":0,"718":0,"719":0,"720":0,"721":0,"722":0,"723":0,"724":0,"725":0,"726":0,"727":0,"728":0,"729":0,"730":0,"731":0,"732":0,"733":0,"734":0,"735":0,"736":0,"737":0,"738":0,"739":0,"740":0,"741":0,"742":0,"743":0,"744":0,"745":0,"746":0,"747":0,"748":0,"749":0,"750":0,"751":0,"752":0,"753":0,"754":0,"755":1,"756":0,"757":0,"758":0,"759":0,"760":0,"761":0,"762":0,"763":0,"764":1,"765":0,"766":0,"767":0,"768":0,"769":0,"770":0,"771":0,"772":0,"773":0,"774":0,"775":0,"776":0,"777":0,"778":0,"779":0,"780":0,"781":0,"782":0,"783":1,"784":1,"785":0,"786":0,"787":0,"788":0,"789":1,"790":0,"791":0,"792":0,"793":0,"794":0,"795":0,"796":0,"797":0,"798":0,"799":0,"800":0,"801":0,"802":0,"803":0,"804":0,"805":0,"806":0,"807":0,"808":0,"809":0,"810":0,"811":0,"812":0,"813":0,"814":0,"815":0,"816":0,"817":0,"818":0,"819":0,"820":0,"821":0,"822":0,"823":0,"824":1,"825":0,"826":0,"827":0,"828":0,"829":0,"830":0,"831":0,"832":0,"833":0,"834":0,"835":0,"836":0,"837":1,"838":0,"839":0,"840":0,"841":0,"842":0,"843":0,"844":1,"845":1,"846":1,"847":0,"848":0,"849":0,"850":0,"851":0,"852":1,"853":0,"854":1,"855":0,"856":1,"857":0,"858":1,"859":0,"860":1,"861":0,"862":1,"863":0,"864":0,"865":0,"866":0,"867":0,"868":0,"869":0,"870":0,"871":0,"872":0,"873":0,"874":0,"875":0,"876":0,"877":0,"878":0,"879":1,"880":0,"881":0,"882":0,"883":0,"884":1,"885":0,"886":0,"887":0,"888":0,"889":0,"890":0,"891":0,"892":0,"893":0,"894":0,"895":0,"896":0,"897":0,"898":0,"899":0,"900":0,"901":0,"902":0,"903":0,"904":0,"905":0,"906":0,"907":0,"908":0,"909":0,"910":0,"911":0,"912":1,"913":0,"914":0,"915":0,"916":0,"917":0,"918":0,"919":0,"920":0,"921":0,"922":0,"923":0,"924":0,"925":0,"926":0,"927":0,"928":0,"929":0,"930":0,"931":0,"932":0,"933":0,"934":0,"935":0,"936":0,"937":0,"938":0,"939":0,"940":0,"941":0,"942":0,"943":0,"944":0,"945":0,"946":0,"947":0,"948":0,"949":0,"950":0,"951":0,"952":0,"953":0,"954":1,"955":0,"956":0,"957":0,"958":0,"959":0,"960":0,"961":0,"962":0,"963":0,"964":0,"965":0,"966":0,"967":0,"968":0,"969":0,"970":0,"971":0,"972":0,"973":0,"974":0,"975":0,"976":0,"977":0,"978":0,"979":0,"980":0,"981":0,"982":0,"983":0,"984":0,"985":0,"986":0,"987":0,"988":0,"989":0,"990":0,"991":0,"992":0,"993":0,"994":0,"995":0,"996":0,"997":0,"998":0,"999":0,"1000":0,"1001":0,"1002":0,"1003":0,"1004":0,"1005":0,"1006":0,"1007":0,"1008":0,"1009":0,"1010":0,"1011":0,"1012":0,"1013":0,"1014":0,"1015":0,"1016":0,"1017":0,"1018":0,"1019":0,"1020":0,"1021":0,"1022":0,"1023":0,"1024":0,"1025":0,"1026":0,"1027":0,"1028":0,"1029":0,"1030":0,"1031":0,"1032":0,"1033":0,"1034":0,"1035":0,"1036":0,"1037":0,"1038":0,"1039":0,"1040":0,"1041":0,"1042":0,"1043":0,"1044":0,"1045":0,"1046":0,"1047":0,"1048":0,"1049":0,"1050":0,"1051":0,"1052":0,"1053":0,"1054":0,"1055":0,"1056":0,"1057":0,"1058":0,"1059":0,"1060":0,"1061":1,"1062":0,"1063":0,"1064":0,"1065":1,"1066":1,"1067":1,"1068":1,"1069":1,"1070":0,"1071":0,"1072":0,"1073":0,"1074":0,"1075":0,"1076":0,"1077":0,"1078":1,"1079":0,"1080":0,"1081":0,"1082":0,"1083":0,"1084":0,"1085":0,"1086":0,"1087":0,"1088":0,"1089":0,"1090":0,"1091":0,"1092":0,"1093":0,"1094":0,"1095":0,"1096":0,"1097":0,"1098":0,"1099":0,"1100":0,"1101":1,"1102":0,"1103":0,"1104":1,"1105":0,"1106":0,"1107":0,"1108":0,"1109":0,"1110":0,"1111":0,"1112":0,"1113":0,"1114":0,"1115":0,"1116":0,"1117":0,"1118":0,"1119":0,"1120":0,"1121":0,"1122":0,"1123":0,"1124":1,"1125":0,"1126":0,"1127":0,"1128":0,"1129":0,"1130":0,"1131":0,"1132":1,"1133":0,"1134":0,"1135":0,"1136":0,"1137":0,"1138":0,"1139":0,"1140":0,"1141":0,"1142":0,"1143":0,"1144":1,"1145":1,"1146":1,"1147":0,"1148":0,"1149":0,"1150":0,"1151":0,"1152":0,"1153":0,"1154":0,"1155":0,"1156":0,"1157":0,"1158":0,"1159":0,"1160":0,"1161":0,"1162":0,"1163":0,"1164":0,"1165":0,"1166":0,"1167":0,"1168":0,"1169":0,"1170":0,"1171":0,"1172":0,"1173":0,"1174":0,"1175":0,"1176":0,"1177":0,"1178":0,"1179":0,"1180":0,"1181":0,"1182":0,"1183":0,"1184":0,"1185":0,"1186":0,"1187":0,"1188":0,"1189":0,"1190":0,"1191":0,"1192":0,"1193":0,"1194":0,"1195":0,"1196":0,"1197":0,"1198":0,"1199":0,"1200":0,"1201":1,"1202":1,"1203":1,"1204":1,"1205":1,"1206":1,"1207":1,"1208":1,"1209":1,"1210":1,"1211":1,"1212":1,"1213":1,"1214":1,"1215":1,"1216":1,"1217":1,"1218":1,"1219":1,"1220":1,"1221":1,"1222":1,"1223":1,"1224":1,"1225":1,"1226":1,"1227":1,"1228":1,"1229":1,"1230":1,"1231":1,"1232":1,"1233":1,"1234":1,"1235":1,"1236":1,"1237":1,"1238":1,"1239":1,"1240":1,"1241":0,"1242":0,"1243":0,"1244":0,"1245":0,"1246":0,"1247":0,"1248":0,"1249":0,"1250":0,"1251":0,"1252":0,"1253":0,"1254":0,"1255":0,"1256":0,"1257":0,"1258":0,"1259":0,"1260":0,"1261":0,"1262":0,"1263":0,"1264":0,"1265":0,"1266":0,"1267":0,"1268":0,"1269":0,"1270":0,"1271":0,"1272":1,"1273":0,"1274":0,"1275":0,"1276":0,"1277":0,"1278":0,"1279":0,"1280":0,"1281":0,"1282":0,"1283":0,"1284":0,"1285":0,"1286":0,"1287":0,"1288":0,"1289":0,"1290":0,"1291":0,"1292":0,"1293":0,"1294":0,"1295":0,"1296":0,"1297":0,"1298":0,"1299":0,"1300":0,"1301":0,"1302":0,"1303":0,"1304":0,"1305":0,"1306":1,"1307":0,"1308":0,"1309":1,"1310":0,"1311":0,"1312":0,"1313":0,"1314":0,"1315":0,"1316":0,"1317":0,"1318":0,"1319":0,"1320":0,"1321":0,"1322":0,"1323":0,"1324":0,"1325":0,"1326":0,"1327":0,"1328":0,"1329":1,"1330":0,"1331":1,"1332":0,"1333":1,"1334":0,"1335":0,"1336":0,"1337":0,"1338":0,"1339":0,"1340":1,"1341":0,"1342":1,"1343":0,"1344":1,"1345":4,"1346":4,"1347":4,"1348":4,"1349":1,"1350":4,"1351":2,"1352":4,"1353":1,"1354":1,"1355":0,"1356":0,"1357":0,"1358":0,"1359":0,"1360":0,"1361":0,"1362":1,"1363":0,"1364":1,"1365":0,"1366":0,"1367":0,"1368":0,"1369":1,"1370":0,"1371":0,"1372":0,"1373":0,"1374":1,"1375":0,"1376":0,"1377":0,"1378":1,"1379":0,"1380":0,"1381":1,"1382":0,"1383":0,"1384":0,"1385":0,"1386":1,"1387":0,"1388":1,"1389":0,"1390":1,"1391":0,"1392":0,"1393":0,"1394":0,"1395":0,"1396":0,"1397":0,"1398":0,"1399":0,"1400":0,"1401":0,"1402":0,"1403":0,"1404":0,"1405":1,"1406":0,"1407":1,"1408":0,"1409":0,"1410":0,"1411":0,"1412":0,"1413":0,"1414":0,"1415":0,"1416":0,"1417":1,"1418":1,"1419":1,"1420":1,"1421":1,"1422":1,"1423":0,"1424":1,"1425":0,"1426":1,"1427":0,"1428":1,"1429":0,"1430":1,"1431":0,"1432":0,"1433":0,"1434":0,"1435":1,"1436":0,"1437":1,"1438":0,"1439":0,"1440":0,"1441":0,"1442":0,"1443":0,"1444":0,"1445":0,"1446":0,"1447":0,"1448":0,"1449":0,"1450":0,"1451":0,"1452":0,"1453":1,"1454":0,"1455":0,"1456":0,"1457":0,"1458":0,"1459":0,"1460":0,"1461":0,"1462":0,"1463":1,"1464":0,"1465":0,"1466":0,"1467":0,"1468":0,"1469":0,"1470":0,"1471":0,"1472":0,"1473":0,"1474":1,"1475":0,"1476":1,"1477":0,"1478":0,"1479":0,"1480":0,"1481":0,"1482":0,"1483":0,"1484":1,"1485":0,"1486":0,"1487":0,"1488":0,"1489":1,"1490":0,"1491":0,"1492":0,"1493":0,"1494":0,"1495":0,"1496":0,"1497":0,"1498":0,"1499":0,"1500":0,"1501":0,"1502":0,"1503":0,"1504":0,"1505":0,"1506":0,"1507":1,"1508":0,"1509":0,"1510":0,"1511":0,"1512":0,"1513":0,"1514":0,"1515":0,"1516":0,"1517":0,"1518":0,"1519":0,"1520":0,"1521":0,"1522":0,"1523":0,"1524":0,"1525":1,"1526":0,"1527":0,"1528":0,"1529":0,"1530":0,"1531":0,"1532":0,"1533":0,"1534":0,"1535":0,"1536":0,"1537":1,"1538":0,"1539":0,"1540":0,"1541":0,"1542":0,"1543":0,"1544":0,"1545":0,"1546":0,"1547":0,"1548":0,"1549":0,"1550":0,"1551":0,"1552":0,"1553":0,"1554":0,"1555":0,"1556":0,"1557":0,"1558":1,"1559":0,"1560":0,"1561":0,"1562":0,"1563":0,"1564":0,"1565":0,"1566":0,"1567":1,"1568":0,"1569":0,"1570":0,"1571":0,"1572":0,"1573":1,"1574":0,"1575":0,"1576":0,"1577":1,"1578":0,"1579":0,"1580":1,"1581":0,"1582":0,"1583":0,"1584":0,"1585":0,"1586":0,"1587":0,"1588":0,"1589":0,"1590":0,"1591":0,"1592":0,"1593":0,"1594":0,"1595":0,"1596":0,"1597":0,"1598":0,"1599":0,"1600":1,"1601":0,"1602":0,"1603":0,"1604":0,"1605":0,"1606":0,"1607":0,"1608":0,"1609":0,"1610":0,"1611":0,"1612":0,"1613":0,"1614":0,"1615":0,"1616":0,"1617":0,"1618":0,"1619":1,"1620":0,"1621":0,"1622":0,"1623":0,"1624":0,"1625":0,"1626":0,"1627":0,"1628":0,"1629":1,"1630":1,"1631":0,"1632":0,"1633":0,"1634":0,"1635":0,"1636":1,"1637":0,"1638":0,"1639":0,"1640":0,"1641":0,"1642":1,"1643":0,"1644":0,"1645":1,"1646":0,"1647":0,"1648":0,"1649":1,"1650":0,"1651":0,"1652":1,"1653":0,"1654":0,"1655":1,"1656":0,"1657":0,"1658":1,"1659":0,"1660":0,"1661":1,"1662":0,"1663":0,"1664":1,"1665":0,"1666":0,"1667":1,"1668":0,"1669":0,"1670":0,"1671":0,"1672":0,"1673":0,"1674":0,"1675":0,"1676":0,"1677":1,"1678":0,"1679":0,"1680":0,"1681":1,"1682":0,"1683":0,"1684":0,"1685":0,"1686":0,"1687":0,"1688":0,"1689":0,"1690":0,"1691":0,"1692":0,"1693":0,"1694":0,"1695":0,"1696":0,"1697":0,"1698":0,"1699":0,"1700":0,"1701":0,"1702":0,"1703":1,"1704":0,"1705":0,"1706":0,"1707":0,"1708":0,"1709":0,"1710":0,"1711":0,"1712":0,"1713":0,"1714":0,"1715":0,"1716":0,"1717":0,"1718":0,"1719":0,"1720":0,"1721":0,"1722":0,"1723":0,"1724":0,"1725":0,"1726":0,"1727":0,"1728":0,"1729":0,"1730":0,"1731":0,"1732":0,"1733":0,"1734":0,"1735":0,"1736":0,"1737":0,"1738":0,"1739":0,"1740":0,"1741":0,"1742":0,"1743":0,"1744":1,"1745":1},"b":{"1":[0,1],"2":[1,0],"3":[0,1],"4":[1,0],"5":[1,0],"6":[1,0],"7":[1,0],"8":[1,0],"9":[1,0],"10":[0,1],"11":[0,1],"12":[0,1],"13":[1,0],"14":[0,1],"15":[1,0],"16":[0,0],"17":[0,0],"18":[0,1],"19":[0,0,0],"20":[0,0],"21":[0,0,0],"22":[0,0,0],"23":[0,0],"24":[0,0],"25":[0,0],"26":[0,0],"27":[0,0],"28":[0,0],"29":[0,0],"30":[0,0],"31":[0,0],"32":[0,0,0,0],"33":[0,0,0,0],"34":[0,0,0,0,0,0],"35":[0,0,0,0,0,0,0,0,0,0],"36":[0,0],"37":[0,0],"38":[0,0],"39":[0,0],"40":[0,0],"41":[0,0],"42":[0,0],"43":[0,0],"44":[0,0],"45":[0,0],"46":[0,0],"47":[0,0],"48":[0,0],"49":[0,0],"50":[0,0],"51":[0,0],"52":[0,0],"53":[0,0],"54":[0,0],"55":[0,0],"56":[0,0],"57":[0,0],"58":[0,0],"59":[0,0],"60":[0,0],"61":[0,0],"62":[0,0],"63":[0,0],"64":[0,0],"65":[0,0],"66":[0,0],"67":[0,0],"68":[0,0],"69":[0,0],"70":[0,0],"71":[0,0],"72":[0,0],"73":[0,0],"74":[0,0],"75":[0,0],"76":[0,0],"77":[0,0],"78":[0,0],"79":[0,0],"80":[0,0],"81":[0,0],"82":[0,0],"83":[0,0],"84":[0,0],"85":[0,0],"86":[0,0],"87":[0,0],"88":[0,0],"89":[0,0],"90":[0,0],"91":[0,0],"92":[0,0],"93":[0,0],"94":[0,0],"95":[0,0],"96":[0,0],"97":[0,0],"98":[0,0],"99":[0,0],"100":[0,0],"101":[0,0],"102":[0,0],"103":[0,0],"104":[0,0],"105":[0,0],"106":[0,0],"107":[0,0],"108":[0,0],"109":[0,0],"110":[0,0],"111":[0,0],"112":[0,0],"113":[0,0],"114":[0,0],"115":[0,0],"116":[0,0],"117":[0,0],"118":[0,0],"119":[0,0],"120":[0,0],"121":[0,0],"122":[0,0],"123":[0,0],"124":[0,0],"125":[0,0],"126":[0,0],"127":[0,0],"128":[0,0],"129":[0,0],"130":[0,0],"131":[0,0],"132":[0,0],"133":[0,0],"134":[0,0],"135":[0,0],"136":[0,0],"137":[0,0],"138":[0,0],"139":[0,0],"140":[0,0],"141":[0,0],"142":[0,0],"143":[0,0],"144":[0,0],"145":[0,0],"146":[0,0],"147":[0,0],"148":[0,0],"149":[0,0],"150":[0,0,0,0,0,0,0,0,0,0,0,0],"151":[0,0],"152":[0,0],"153":[0,0,0,0,0,0],"154":[0,0],"155":[0,0],"156":[0,0],"157":[0,0],"158":[0,0],"159":[0,0],"160":[0,0],"161":[0,0],"162":[0,0],"163":[0,0],"164":[0,0],"165":[0,0],"166":[0,0],"167":[0,0],"168":[0,0],"169":[0,0],"170":[0,0],"171":[0,0],"172":[0,0],"173":[0,0],"174":[0,0],"175":[0,0],"176":[0,0],"177":[0,0],"178":[0,0],"179":[0,0],"180":[0,0],"181":[0,0],"182":[0,0],"183":[0,0],"184":[0,0],"185":[0,0],"186":[0,0],"187":[0,0],"188":[0,0],"189":[0,0],"190":[0,0],"191":[0,0],"192":[0,0],"193":[0,0],"194":[0,0],"195":[0,0],"196":[0,0],"197":[0,0],"198":[0,0],"199":[0,0],"200":[0,0],"201":[0,0],"202":[0,0],"203":[0,0],"204":[0,0],"205":[0,0],"206":[0,0],"207":[0,0],"208":[0,0],"209":[0,0],"210":[0,0],"211":[0,0],"212":[0,0],"213":[0,0],"214":[0,0],"215":[0,0],"216":[0,0],"217":[0,0],"218":[0,0],"219":[0,0],"220":[0,0],"221":[0,0],"222":[0,0],"223":[0,0],"224":[0,0],"225":[0,0],"226":[0,0],"227":[0,0],"228":[0,0],"229":[0,0,0],"230":[0,0],"231":[0,0],"232":[0,0],"233":[0,0],"234":[0,0,0],"235":[0,0],"236":[0,0],"237":[0,0],"238":[0,0],"239":[0,0],"240":[0,0],"241":[0,0],"242":[0,0],"243":[0,0],"244":[0,0],"245":[0,0],"246":[0,0],"247":[0,0],"248":[0,0],"249":[0,0],"250":[0,0],"251":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"252":[0,0],"253":[0,0],"254":[0,0,0,0],"255":[1,3],"256":[2,2],"257":[1,3],"258":[0,0],"259":[0,0],"260":[0,0],"261":[0,0],"262":[0,0],"263":[0,1],"264":[0,1],"265":[0,1],"266":[0,1],"267":[0,0],"268":[0,0],"269":[0,0],"270":[0,0],"271":[0,0],"272":[0,0],"273":[0,0],"274":[0,0],"275":[0,0],"276":[0,0],"277":[0,0],"278":[0,0],"279":[0,0],"280":[0,0],"281":[0,0],"282":[0,0],"283":[0,0],"284":[0,0],"285":[0,0],"286":[0,0],"287":[0,0],"288":[0,0],"289":[0,0],"290":[0,0],"291":[0,0],"292":[0,0],"293":[0,0],"294":[0,0],"295":[0,0],"296":[0,0],"297":[0,0],"298":[0,0],"299":[0,0],"300":[0,0],"301":[0,0],"302":[0,0],"303":[0,0],"304":[0,0],"305":[0,0],"306":[0,0],"307":[0,0],"308":[0,0],"309":[0,0],"310":[0,0],"311":[0,0],"312":[0,0],"313":[0,0],"314":[0,0],"315":[0,0],"316":[0,0],"317":[0,0],"318":[0,0],"319":[0,0],"320":[0,0],"321":[0,0],"322":[1,0]},"f":{"1":0,"2":0,"3":1,"4":1,"5":1,"6":1,"7":2,"8":2,"9":0,"10":1,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":4,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0,"106":0,"107":0,"108":0,"109":0,"110":0,"111":0,"112":1,"113":0,"114":0,"115":0,"116":0,"117":0,"118":0,"119":0,"120":0,"121":0,"122":0,"123":0,"124":0,"125":0,"126":0,"127":0,"128":0,"129":0,"130":0,"131":0,"132":0,"133":0,"134":0,"135":0,"136":0,"137":0,"138":0,"139":0,"140":0,"141":0,"142":0,"143":0,"144":0,"145":0,"146":0},"fnMap":{"1":{"name":"GameLib","line":2,"loc":{"start":{"line":2,"column":4},"end":{"line":2,"column":23}}},"2":{"name":"(anonymous_2)","line":6,"loc":{"start":{"line":6,"column":17},"end":{"line":6,"column":27}}},"3":{"name":"(anonymous_3)","line":14,"loc":{"start":{"line":14,"column":24},"end":{"line":17,"column":2}}},"4":{"name":"(anonymous_4)","line":35,"loc":{"start":{"line":35,"column":18},"end":{"line":46,"column":2}}},"5":{"name":"(anonymous_5)","line":95,"loc":{"start":{"line":95,"column":24},"end":{"line":101,"column":2}}},"6":{"name":"(anonymous_6)","line":129,"loc":{"start":{"line":129,"column":49},"end":{"line":129,"column":60}}},"7":{"name":"(anonymous_7)","line":171,"loc":{"start":{"line":171,"column":19},"end":{"line":171,"column":40}}},"8":{"name":"(anonymous_8)","line":183,"loc":{"start":{"line":183,"column":20},"end":{"line":186,"column":2}}},"9":{"name":"(anonymous_9)","line":195,"loc":{"start":{"line":195,"column":39},"end":{"line":195,"column":50}}},"10":{"name":"(anonymous_10)","line":202,"loc":{"start":{"line":202,"column":47},"end":{"line":202,"column":58}}},"11":{"name":"(anonymous_11)","line":213,"loc":{"start":{"line":213,"column":37},"end":{"line":213,"column":48}}},"12":{"name":"(anonymous_12)","line":221,"loc":{"start":{"line":221,"column":39},"end":{"line":221,"column":50}}},"13":{"name":"(anonymous_13)","line":239,"loc":{"start":{"line":239,"column":25},"end":{"line":243,"column":2}}},"14":{"name":"(anonymous_14)","line":289,"loc":{"start":{"line":289,"column":48},"end":{"line":289,"column":64}}},"15":{"name":"(anonymous_15)","line":300,"loc":{"start":{"line":300,"column":47},"end":{"line":300,"column":63}}},"16":{"name":"(anonymous_16)","line":311,"loc":{"start":{"line":311,"column":45},"end":{"line":311,"column":61}}},"17":{"name":"(anonymous_17)","line":321,"loc":{"start":{"line":321,"column":49},"end":{"line":321,"column":60}}},"18":{"name":"(anonymous_18)","line":329,"loc":{"start":{"line":329,"column":52},"end":{"line":329,"column":72}}},"19":{"name":"(anonymous_19)","line":381,"loc":{"start":{"line":381,"column":42},"end":{"line":381,"column":62}}},"20":{"name":"(anonymous_20)","line":390,"loc":{"start":{"line":390,"column":47},"end":{"line":390,"column":66}}},"21":{"name":"(anonymous_21)","line":404,"loc":{"start":{"line":404,"column":45},"end":{"line":404,"column":64}}},"22":{"name":"(anonymous_22)","line":437,"loc":{"start":{"line":437,"column":43},"end":{"line":437,"column":62}}},"23":{"name":"(anonymous_23)","line":469,"loc":{"start":{"line":469,"column":18},"end":{"line":471,"column":2}}},"24":{"name":"(anonymous_24)","line":477,"loc":{"start":{"line":477,"column":37},"end":{"line":479,"column":2}}},"25":{"name":"(anonymous_25)","line":483,"loc":{"start":{"line":483,"column":44},"end":{"line":485,"column":2}}},"26":{"name":"(anonymous_26)","line":489,"loc":{"start":{"line":489,"column":52},"end":{"line":492,"column":2}}},"27":{"name":"(anonymous_27)","line":497,"loc":{"start":{"line":497,"column":53},"end":{"line":499,"column":2}}},"28":{"name":"(anonymous_28)","line":503,"loc":{"start":{"line":503,"column":43},"end":{"line":505,"column":2}}},"29":{"name":"(anonymous_29)","line":563,"loc":{"start":{"line":563,"column":37},"end":{"line":567,"column":2}}},"30":{"name":"(anonymous_30)","line":582,"loc":{"start":{"line":582,"column":23},"end":{"line":586,"column":2}}},"31":{"name":"(anonymous_31)","line":603,"loc":{"start":{"line":603,"column":66},"end":{"line":607,"column":2}}},"32":{"name":"(anonymous_32)","line":642,"loc":{"start":{"line":642,"column":64},"end":{"line":645,"column":2}}},"33":{"name":"(anonymous_33)","line":648,"loc":{"start":{"line":648,"column":17},"end":{"line":648,"column":29}}},"34":{"name":"(anonymous_34)","line":694,"loc":{"start":{"line":694,"column":19},"end":{"line":700,"column":2}}},"35":{"name":"(anonymous_35)","line":749,"loc":{"start":{"line":749,"column":19},"end":{"line":765,"column":2}}},"36":{"name":"(anonymous_36)","line":883,"loc":{"start":{"line":883,"column":22},"end":{"line":941,"column":2}}},"37":{"name":"(anonymous_37)","line":1335,"loc":{"start":{"line":1335,"column":43},"end":{"line":1335,"column":76}}},"38":{"name":"(anonymous_38)","line":1487,"loc":{"start":{"line":1487,"column":12},"end":{"line":1487,"column":22}}},"39":{"name":"(anonymous_39)","line":1491,"loc":{"start":{"line":1491,"column":12},"end":{"line":1491,"column":27}}},"40":{"name":"(anonymous_40)","line":1509,"loc":{"start":{"line":1509,"column":21},"end":{"line":1513,"column":2}}},"41":{"name":"(anonymous_41)","line":1532,"loc":{"start":{"line":1532,"column":40},"end":{"line":1532,"column":52}}},"42":{"name":"(anonymous_42)","line":1539,"loc":{"start":{"line":1539,"column":21},"end":{"line":1544,"column":2}}},"43":{"name":"(anonymous_43)","line":1565,"loc":{"start":{"line":1565,"column":47},"end":{"line":1565,"column":66}}},"44":{"name":"(anonymous_44)","line":1572,"loc":{"start":{"line":1572,"column":47},"end":{"line":1572,"column":66}}},"45":{"name":"(anonymous_45)","line":1589,"loc":{"start":{"line":1589,"column":47},"end":{"line":1589,"column":66}}},"46":{"name":"(anonymous_46)","line":1596,"loc":{"start":{"line":1596,"column":39},"end":{"line":1596,"column":65}}},"47":{"name":"(anonymous_47)","line":1602,"loc":{"start":{"line":1602,"column":39},"end":{"line":1602,"column":65}}},"48":{"name":"(anonymous_48)","line":1608,"loc":{"start":{"line":1608,"column":39},"end":{"line":1608,"column":65}}},"49":{"name":"(anonymous_49)","line":1614,"loc":{"start":{"line":1614,"column":40},"end":{"line":1614,"column":55}}},"50":{"name":"(anonymous_50)","line":1631,"loc":{"start":{"line":1631,"column":40},"end":{"line":1631,"column":52}}},"51":{"name":"(anonymous_51)","line":1640,"loc":{"start":{"line":1640,"column":38},"end":{"line":1640,"column":70}}},"52":{"name":"(anonymous_52)","line":1737,"loc":{"start":{"line":1737,"column":18},"end":{"line":1758,"column":2}}},"53":{"name":"(anonymous_53)","line":1841,"loc":{"start":{"line":1841,"column":39},"end":{"line":1841,"column":91}}},"54":{"name":"(anonymous_54)","line":1956,"loc":{"start":{"line":1956,"column":42},"end":{"line":1956,"column":62}}},"55":{"name":"(anonymous_55)","line":1974,"loc":{"start":{"line":1974,"column":41},"end":{"line":1974,"column":67}}},"56":{"name":"(anonymous_56)","line":2059,"loc":{"start":{"line":2059,"column":29},"end":{"line":2059,"column":62}}},"57":{"name":"inProcessed","line":2067,"loc":{"start":{"line":2067,"column":4},"end":{"line":2067,"column":46}}},"58":{"name":"neighbourOnEdge","line":2085,"loc":{"start":{"line":2085,"column":4},"end":{"line":2085,"column":59}}},"59":{"name":"(anonymous_59)","line":2217,"loc":{"start":{"line":2217,"column":27},"end":{"line":2217,"column":57}}},"60":{"name":"(anonymous_60)","line":2261,"loc":{"start":{"line":2261,"column":21},"end":{"line":2266,"column":2}}},"61":{"name":"(anonymous_61)","line":2293,"loc":{"start":{"line":2293,"column":24},"end":{"line":2299,"column":2}}},"62":{"name":"(anonymous_62)","line":2311,"loc":{"start":{"line":2311,"column":40},"end":{"line":2311,"column":51}}},"63":{"name":"(anonymous_63)","line":2325,"loc":{"start":{"line":2325,"column":28},"end":{"line":2326,"column":2}}},"64":{"name":"(anonymous_64)","line":2330,"loc":{"start":{"line":2330,"column":51},"end":{"line":2332,"column":2}}},"65":{"name":"(anonymous_65)","line":2342,"loc":{"start":{"line":2342,"column":26},"end":{"line":2343,"column":2}}},"66":{"name":"(anonymous_66)","line":2347,"loc":{"start":{"line":2347,"column":49},"end":{"line":2349,"column":2}}},"67":{"name":"(anonymous_67)","line":2374,"loc":{"start":{"line":2374,"column":23},"end":{"line":2390,"column":2}}},"68":{"name":"(anonymous_68)","line":2415,"loc":{"start":{"line":2415,"column":57},"end":{"line":2415,"column":68}}},"69":{"name":"(anonymous_69)","line":2461,"loc":{"start":{"line":2461,"column":19},"end":{"line":2473,"column":2}}},"70":{"name":"(anonymous_70)","line":2523,"loc":{"start":{"line":2523,"column":40},"end":{"line":2523,"column":66}}},"71":{"name":"(anonymous_71)","line":2539,"loc":{"start":{"line":2539,"column":29},"end":{"line":2539,"column":54}}},"72":{"name":"(anonymous_72)","line":2540,"loc":{"start":{"line":2540,"column":15},"end":{"line":2540,"column":26}}},"73":{"name":"(anonymous_73)","line":2729,"loc":{"start":{"line":2729,"column":33},"end":{"line":2729,"column":82}}},"74":{"name":"(anonymous_74)","line":2882,"loc":{"start":{"line":2882,"column":12},"end":{"line":2882,"column":43}}},"75":{"name":"(anonymous_75)","line":2883,"loc":{"start":{"line":2883,"column":23},"end":{"line":2883,"column":43}}},"76":{"name":"(anonymous_76)","line":2915,"loc":{"start":{"line":2915,"column":16},"end":{"line":2915,"column":31}}},"77":{"name":"(anonymous_77)","line":2922,"loc":{"start":{"line":2922,"column":27},"end":{"line":2922,"column":48}}},"78":{"name":"(anonymous_78)","line":3014,"loc":{"start":{"line":3014,"column":24},"end":{"line":3014,"column":39}}},"79":{"name":"(anonymous_79)","line":3022,"loc":{"start":{"line":3022,"column":27},"end":{"line":3025,"column":2}}},"80":{"name":"(anonymous_80)","line":3037,"loc":{"start":{"line":3037,"column":44},"end":{"line":3037,"column":55}}},"81":{"name":"(anonymous_81)","line":3068,"loc":{"start":{"line":3068,"column":22},"end":{"line":3077,"column":2}}},"82":{"name":"(anonymous_82)","line":3126,"loc":{"start":{"line":3126,"column":20},"end":{"line":3128,"column":2}}},"83":{"name":"(anonymous_83)","line":3133,"loc":{"start":{"line":3133,"column":35},"end":{"line":3135,"column":2}}},"84":{"name":"(anonymous_84)","line":3173,"loc":{"start":{"line":3173,"column":37},"end":{"line":3176,"column":2}}},"85":{"name":"(anonymous_85)","line":3201,"loc":{"start":{"line":3201,"column":28},"end":{"line":3207,"column":2}}},"86":{"name":"(anonymous_86)","line":3255,"loc":{"start":{"line":3255,"column":21},"end":{"line":3276,"column":2}}},"87":{"name":"(anonymous_87)","line":3445,"loc":{"start":{"line":3445,"column":31},"end":{"line":3445,"column":93}}},"88":{"name":"(anonymous_88)","line":3464,"loc":{"start":{"line":3464,"column":12},"end":{"line":3464,"column":30}}},"89":{"name":"(anonymous_89)","line":3493,"loc":{"start":{"line":3493,"column":12},"end":{"line":3493,"column":26}}},"90":{"name":"(anonymous_90)","line":3501,"loc":{"start":{"line":3501,"column":12},"end":{"line":3501,"column":28}}},"91":{"name":"(anonymous_91)","line":3525,"loc":{"start":{"line":3525,"column":32},"end":{"line":3525,"column":86}}},"92":{"name":"(anonymous_92)","line":3607,"loc":{"start":{"line":3607,"column":26},"end":{"line":3610,"column":2}}},"93":{"name":"(anonymous_93)","line":3629,"loc":{"start":{"line":3629,"column":26},"end":{"line":3641,"column":2}}},"94":{"name":"(anonymous_94)","line":3683,"loc":{"start":{"line":3683,"column":42},"end":{"line":3683,"column":52}}},"95":{"name":"(anonymous_95)","line":3700,"loc":{"start":{"line":3700,"column":43},"end":{"line":3700,"column":62}}},"96":{"name":"(anonymous_96)","line":3740,"loc":{"start":{"line":3740,"column":21},"end":{"line":3740,"column":36}}},"97":{"name":"(anonymous_97)","line":3754,"loc":{"start":{"line":3754,"column":36},"end":{"line":3754,"column":47}}},"98":{"name":"(anonymous_98)","line":3761,"loc":{"start":{"line":3761,"column":38},"end":{"line":3761,"column":50}}},"99":{"name":"(anonymous_99)","line":3768,"loc":{"start":{"line":3768,"column":21},"end":{"line":3768,"column":39}}},"100":{"name":"(anonymous_100)","line":3787,"loc":{"start":{"line":3787,"column":40},"end":{"line":3787,"column":53}}},"101":{"name":"(anonymous_101)","line":3802,"loc":{"start":{"line":3802,"column":37},"end":{"line":3802,"column":50}}},"102":{"name":"(anonymous_102)","line":3810,"loc":{"start":{"line":3810,"column":40},"end":{"line":3810,"column":52}}},"103":{"name":"(anonymous_103)","line":3817,"loc":{"start":{"line":3817,"column":31},"end":{"line":3817,"column":61}}},"104":{"name":"(anonymous_104)","line":3828,"loc":{"start":{"line":3828,"column":28},"end":{"line":3828,"column":47}}},"105":{"name":"(anonymous_105)","line":3834,"loc":{"start":{"line":3834,"column":38},"end":{"line":3834,"column":56}}},"106":{"name":"(anonymous_106)","line":3841,"loc":{"start":{"line":3841,"column":41},"end":{"line":3841,"column":54}}},"107":{"name":"(anonymous_107)","line":3848,"loc":{"start":{"line":3848,"column":39},"end":{"line":3848,"column":51}}},"108":{"name":"(anonymous_108)","line":3852,"loc":{"start":{"line":3852,"column":36},"end":{"line":3852,"column":48}}},"109":{"name":"(anonymous_109)","line":3860,"loc":{"start":{"line":3860,"column":40},"end":{"line":3860,"column":53}}},"110":{"name":"(anonymous_110)","line":3880,"loc":{"start":{"line":3880,"column":35},"end":{"line":3880,"column":48}}},"111":{"name":"(anonymous_111)","line":3884,"loc":{"start":{"line":3884,"column":41},"end":{"line":3884,"column":53}}},"112":{"name":"(anonymous_112)","line":3903,"loc":{"start":{"line":3903,"column":21},"end":{"line":3903,"column":42}}},"113":{"name":"(anonymous_113)","line":3927,"loc":{"start":{"line":3927,"column":41},"end":{"line":3927,"column":54}}},"114":{"name":"(anonymous_114)","line":3934,"loc":{"start":{"line":3934,"column":36},"end":{"line":3934,"column":48}}},"115":{"name":"(anonymous_115)","line":3943,"loc":{"start":{"line":3943,"column":40},"end":{"line":3943,"column":53}}},"116":{"name":"(anonymous_116)","line":3964,"loc":{"start":{"line":3964,"column":41},"end":{"line":3964,"column":53}}},"117":{"name":"(anonymous_117)","line":3984,"loc":{"start":{"line":3984,"column":40},"end":{"line":3984,"column":53}}},"118":{"name":"(anonymous_118)","line":4002,"loc":{"start":{"line":4002,"column":28},"end":{"line":4002,"column":40}}},"119":{"name":"(anonymous_119)","line":4006,"loc":{"start":{"line":4006,"column":42},"end":{"line":4006,"column":60}}},"120":{"name":"(anonymous_120)","line":4027,"loc":{"start":{"line":4027,"column":43},"end":{"line":4027,"column":55}}},"121":{"name":"(anonymous_121)","line":4038,"loc":{"start":{"line":4038,"column":56},"end":{"line":4038,"column":73}}},"122":{"name":"(anonymous_122)","line":4083,"loc":{"start":{"line":4083,"column":56},"end":{"line":4083,"column":73}}},"123":{"name":"(anonymous_123)","line":4128,"loc":{"start":{"line":4128,"column":45},"end":{"line":4128,"column":63}}},"124":{"name":"(anonymous_124)","line":4149,"loc":{"start":{"line":4149,"column":48},"end":{"line":4149,"column":60}}},"125":{"name":"(anonymous_125)","line":4188,"loc":{"start":{"line":4188,"column":46},"end":{"line":4188,"column":58}}},"126":{"name":"(anonymous_126)","line":4206,"loc":{"start":{"line":4206,"column":47},"end":{"line":4206,"column":59}}},"127":{"name":"(anonymous_127)","line":4218,"loc":{"start":{"line":4218,"column":47},"end":{"line":4218,"column":59}}},"128":{"name":"(anonymous_128)","line":4233,"loc":{"start":{"line":4233,"column":20},"end":{"line":4236,"column":2}}},"129":{"name":"(anonymous_129)","line":4251,"loc":{"start":{"line":4251,"column":19},"end":{"line":4259,"column":2}}},"130":{"name":"(anonymous_130)","line":4309,"loc":{"start":{"line":4309,"column":49},"end":{"line":4309,"column":60}}},"131":{"name":"(anonymous_131)","line":4347,"loc":{"start":{"line":4347,"column":38},"end":{"line":4352,"column":2}}},"132":{"name":"(anonymous_132)","line":4375,"loc":{"start":{"line":4375,"column":35},"end":{"line":4375,"column":46}}},"133":{"name":"(anonymous_133)","line":4379,"loc":{"start":{"line":4379,"column":48},"end":{"line":4381,"column":2}}},"134":{"name":"(anonymous_134)","line":4393,"loc":{"start":{"line":4393,"column":50},"end":{"line":4395,"column":2}}},"135":{"name":"(anonymous_135)","line":4407,"loc":{"start":{"line":4407,"column":52},"end":{"line":4413,"column":2}}},"136":{"name":"(anonymous_136)","line":4424,"loc":{"start":{"line":4424,"column":54},"end":{"line":4427,"column":2}}},"137":{"name":"(anonymous_137)","line":4437,"loc":{"start":{"line":4437,"column":48},"end":{"line":4440,"column":2}}},"138":{"name":"(anonymous_138)","line":4446,"loc":{"start":{"line":4446,"column":47},"end":{"line":4448,"column":2}}},"139":{"name":"(anonymous_139)","line":4454,"loc":{"start":{"line":4454,"column":44},"end":{"line":4456,"column":2}}},"140":{"name":"(anonymous_140)","line":4462,"loc":{"start":{"line":4462,"column":49},"end":{"line":4467,"column":2}}},"141":{"name":"(anonymous_141)","line":4473,"loc":{"start":{"line":4473,"column":42},"end":{"line":4475,"column":2}}},"142":{"name":"(anonymous_142)","line":4481,"loc":{"start":{"line":4481,"column":40},"end":{"line":4483,"column":2}}},"143":{"name":"(anonymous_143)","line":4489,"loc":{"start":{"line":4489,"column":34},"end":{"line":4491,"column":2}}},"144":{"name":"(anonymous_144)","line":4515,"loc":{"start":{"line":4515,"column":48},"end":{"line":4517,"column":2}}},"145":{"name":"(anonymous_145)","line":4533,"loc":{"start":{"line":4533,"column":55},"end":{"line":4539,"column":2}}},"146":{"name":"(anonymous_146)","line":4592,"loc":{"start":{"line":4592,"column":59},"end":{"line":4599,"column":2}}}},"statementMap":{"1":{"start":{"line":1,"column":0},"end":{"line":3,"column":1}},"2":{"start":{"line":2,"column":4},"end":{"line":2,"column":25}},"3":{"start":{"line":5,"column":0},"end":{"line":7,"column":1}},"4":{"start":{"line":6,"column":4},"end":{"line":6,"column":30}},"5":{"start":{"line":14,"column":0},"end":{"line":20,"column":2}},"6":{"start":{"line":18,"column":4},"end":{"line":18,"column":31}},"7":{"start":{"line":19,"column":4},"end":{"line":19,"column":25}},"8":{"start":{"line":35,"column":0},"end":{"line":85,"column":2}},"9":{"start":{"line":47,"column":4},"end":{"line":47,"column":17}},"10":{"start":{"line":48,"column":4},"end":{"line":48,"column":21}},"11":{"start":{"line":49,"column":4},"end":{"line":49,"column":25}},"12":{"start":{"line":51,"column":4},"end":{"line":53,"column":5}},"13":{"start":{"line":52,"column":8},"end":{"line":52,"column":26}},"14":{"start":{"line":54,"column":4},"end":{"line":54,"column":37}},"15":{"start":{"line":56,"column":4},"end":{"line":58,"column":5}},"16":{"start":{"line":57,"column":8},"end":{"line":57,"column":28}},"17":{"start":{"line":59,"column":4},"end":{"line":59,"column":37}},"18":{"start":{"line":61,"column":4},"end":{"line":63,"column":5}},"19":{"start":{"line":62,"column":8},"end":{"line":62,"column":46}},"20":{"start":{"line":64,"column":4},"end":{"line":64,"column":33}},"21":{"start":{"line":66,"column":4},"end":{"line":68,"column":5}},"22":{"start":{"line":67,"column":8},"end":{"line":67,"column":49}},"23":{"start":{"line":69,"column":4},"end":{"line":69,"column":29}},"24":{"start":{"line":71,"column":4},"end":{"line":73,"column":5}},"25":{"start":{"line":72,"column":8},"end":{"line":72,"column":49}},"26":{"start":{"line":74,"column":4},"end":{"line":74,"column":29}},"27":{"start":{"line":76,"column":4},"end":{"line":78,"column":5}},"28":{"start":{"line":77,"column":8},"end":{"line":77,"column":46}},"29":{"start":{"line":79,"column":4},"end":{"line":79,"column":23}},"30":{"start":{"line":81,"column":4},"end":{"line":83,"column":5}},"31":{"start":{"line":82,"column":8},"end":{"line":82,"column":43}},"32":{"start":{"line":84,"column":4},"end":{"line":84,"column":17}},"33":{"start":{"line":95,"column":0},"end":{"line":124,"column":2}},"34":{"start":{"line":102,"column":4},"end":{"line":102,"column":17}},"35":{"start":{"line":104,"column":4},"end":{"line":106,"column":5}},"36":{"start":{"line":105,"column":8},"end":{"line":105,"column":46}},"37":{"start":{"line":107,"column":4},"end":{"line":107,"column":21}},"38":{"start":{"line":109,"column":4},"end":{"line":111,"column":5}},"39":{"start":{"line":110,"column":8},"end":{"line":110,"column":69}},"40":{"start":{"line":112,"column":4},"end":{"line":112,"column":41}},"41":{"start":{"line":114,"column":4},"end":{"line":116,"column":5}},"42":{"start":{"line":115,"column":8},"end":{"line":115,"column":22}},"43":{"start":{"line":117,"column":4},"end":{"line":117,"column":25}},"44":{"start":{"line":119,"column":4},"end":{"line":119,"column":25}},"45":{"start":{"line":121,"column":4},"end":{"line":123,"column":5}},"46":{"start":{"line":122,"column":8},"end":{"line":122,"column":30}},"47":{"start":{"line":129,"column":0},"end":{"line":154,"column":2}},"48":{"start":{"line":131,"column":4},"end":{"line":134,"column":5}},"49":{"start":{"line":132,"column":8},"end":{"line":132,"column":34}},"50":{"start":{"line":133,"column":8},"end":{"line":133,"column":37}},"51":{"start":{"line":136,"column":4},"end":{"line":136,"column":35}},"52":{"start":{"line":138,"column":4},"end":{"line":138,"column":24}},"53":{"start":{"line":140,"column":4},"end":{"line":149,"column":5}},"54":{"start":{"line":141,"column":8},"end":{"line":141,"column":62}},"55":{"start":{"line":142,"column":11},"end":{"line":149,"column":5}},"56":{"start":{"line":143,"column":8},"end":{"line":143,"column":61}},"57":{"start":{"line":144,"column":11},"end":{"line":149,"column":5}},"58":{"start":{"line":145,"column":8},"end":{"line":145,"column":61}},"59":{"start":{"line":147,"column":8},"end":{"line":147,"column":76}},"60":{"start":{"line":148,"column":8},"end":{"line":148,"column":79}},"61":{"start":{"line":151,"column":4},"end":{"line":151,"column":29}},"62":{"start":{"line":153,"column":4},"end":{"line":153,"column":20}},"63":{"start":{"line":160,"column":0},"end":{"line":160,"column":50}},"64":{"start":{"line":161,"column":0},"end":{"line":161,"column":49}},"65":{"start":{"line":162,"column":0},"end":{"line":162,"column":48}},"66":{"start":{"line":171,"column":0},"end":{"line":176,"column":2}},"67":{"start":{"line":172,"column":4},"end":{"line":172,"column":15}},"68":{"start":{"line":173,"column":4},"end":{"line":173,"column":15}},"69":{"start":{"line":174,"column":4},"end":{"line":174,"column":15}},"70":{"start":{"line":175,"column":4},"end":{"line":175,"column":15}},"71":{"start":{"line":183,"column":0},"end":{"line":189,"column":2}},"72":{"start":{"line":187,"column":4},"end":{"line":187,"column":33}},"73":{"start":{"line":188,"column":4},"end":{"line":188,"column":29}},"74":{"start":{"line":195,"column":0},"end":{"line":197,"column":2}},"75":{"start":{"line":196,"column":4},"end":{"line":196,"column":68}},"76":{"start":{"line":202,"column":0},"end":{"line":207,"column":2}},"77":{"start":{"line":203,"column":4},"end":{"line":206,"column":5}},"78":{"start":{"line":204,"column":8},"end":{"line":204,"column":64}},"79":{"start":{"line":205,"column":8},"end":{"line":205,"column":67}},"80":{"start":{"line":213,"column":0},"end":{"line":215,"column":2}},"81":{"start":{"line":214,"column":4},"end":{"line":214,"column":66}},"82":{"start":{"line":221,"column":0},"end":{"line":223,"column":2}},"83":{"start":{"line":222,"column":4},"end":{"line":222,"column":68}},"84":{"start":{"line":229,"column":0},"end":{"line":229,"column":43}},"85":{"start":{"line":230,"column":0},"end":{"line":230,"column":41}},"86":{"start":{"line":231,"column":0},"end":{"line":231,"column":43}},"87":{"start":{"line":239,"column":0},"end":{"line":283,"column":2}},"88":{"start":{"line":244,"column":4},"end":{"line":244,"column":24}},"89":{"start":{"line":246,"column":4},"end":{"line":246,"column":25}},"90":{"start":{"line":248,"column":4},"end":{"line":248,"column":23}},"91":{"start":{"line":250,"column":4},"end":{"line":250,"column":17}},"92":{"start":{"line":251,"column":4},"end":{"line":251,"column":19}},"93":{"start":{"line":252,"column":4},"end":{"line":252,"column":27}},"94":{"start":{"line":254,"column":4},"end":{"line":254,"column":29}},"95":{"start":{"line":255,"column":4},"end":{"line":255,"column":30}},"96":{"start":{"line":256,"column":4},"end":{"line":256,"column":26}},"97":{"start":{"line":257,"column":4},"end":{"line":257,"column":27}},"98":{"start":{"line":258,"column":4},"end":{"line":258,"column":24}},"99":{"start":{"line":259,"column":4},"end":{"line":259,"column":26}},"100":{"start":{"line":261,"column":4},"end":{"line":261,"column":53}},"101":{"start":{"line":262,"column":4},"end":{"line":262,"column":57}},"102":{"start":{"line":263,"column":4},"end":{"line":263,"column":57}},"103":{"start":{"line":264,"column":4},"end":{"line":264,"column":59}},"104":{"start":{"line":265,"column":4},"end":{"line":265,"column":53}},"105":{"start":{"line":266,"column":4},"end":{"line":266,"column":49}},"106":{"start":{"line":268,"column":4},"end":{"line":268,"column":25}},"107":{"start":{"line":270,"column":4},"end":{"line":270,"column":73}},"108":{"start":{"line":271,"column":4},"end":{"line":271,"column":69}},"109":{"start":{"line":272,"column":4},"end":{"line":272,"column":77}},"110":{"start":{"line":273,"column":4},"end":{"line":273,"column":73}},"111":{"start":{"line":274,"column":4},"end":{"line":274,"column":79}},"112":{"start":{"line":276,"column":4},"end":{"line":276,"column":141}},"113":{"start":{"line":277,"column":4},"end":{"line":277,"column":33}},"114":{"start":{"line":279,"column":4},"end":{"line":282,"column":5}},"115":{"start":{"line":280,"column":8},"end":{"line":280,"column":153}},"116":{"start":{"line":281,"column":8},"end":{"line":281,"column":125}},"117":{"start":{"line":289,"column":0},"end":{"line":294,"column":2}},"118":{"start":{"line":290,"column":4},"end":{"line":290,"column":28}},"119":{"start":{"line":291,"column":4},"end":{"line":291,"column":52}},"120":{"start":{"line":292,"column":4},"end":{"line":292,"column":27}},"121":{"start":{"line":293,"column":4},"end":{"line":293,"column":29}},"122":{"start":{"line":300,"column":0},"end":{"line":305,"column":2}},"123":{"start":{"line":301,"column":4},"end":{"line":304,"column":5}},"124":{"start":{"line":302,"column":8},"end":{"line":302,"column":30}},"125":{"start":{"line":303,"column":8},"end":{"line":303,"column":81}},"126":{"start":{"line":311,"column":0},"end":{"line":316,"column":2}},"127":{"start":{"line":312,"column":4},"end":{"line":315,"column":5}},"128":{"start":{"line":313,"column":8},"end":{"line":313,"column":31}},"129":{"start":{"line":314,"column":8},"end":{"line":314,"column":77}},"130":{"start":{"line":321,"column":0},"end":{"line":323,"column":2}},"131":{"start":{"line":322,"column":4},"end":{"line":322,"column":61}},"132":{"start":{"line":329,"column":0},"end":{"line":374,"column":2}},"133":{"start":{"line":330,"column":4},"end":{"line":330,"column":53}},"134":{"start":{"line":331,"column":4},"end":{"line":331,"column":56}},"135":{"start":{"line":332,"column":4},"end":{"line":332,"column":49}},"136":{"start":{"line":334,"column":4},"end":{"line":334,"column":47}},"137":{"start":{"line":336,"column":4},"end":{"line":336,"column":40}},"138":{"start":{"line":337,"column":4},"end":{"line":337,"column":63}},"139":{"start":{"line":339,"column":4},"end":{"line":350,"column":5}},"140":{"start":{"line":341,"column":8},"end":{"line":341,"column":74}},"141":{"start":{"line":342,"column":8},"end":{"line":342,"column":74}},"142":{"start":{"line":343,"column":8},"end":{"line":343,"column":74}},"143":{"start":{"line":345,"column":11},"end":{"line":350,"column":5}},"144":{"start":{"line":347,"column":8},"end":{"line":347,"column":74}},"145":{"start":{"line":348,"column":8},"end":{"line":348,"column":74}},"146":{"start":{"line":349,"column":8},"end":{"line":349,"column":74}},"147":{"start":{"line":352,"column":4},"end":{"line":363,"column":5}},"148":{"start":{"line":354,"column":8},"end":{"line":354,"column":72}},"149":{"start":{"line":355,"column":8},"end":{"line":355,"column":72}},"150":{"start":{"line":356,"column":8},"end":{"line":356,"column":72}},"151":{"start":{"line":358,"column":11},"end":{"line":363,"column":5}},"152":{"start":{"line":360,"column":8},"end":{"line":360,"column":72}},"153":{"start":{"line":361,"column":8},"end":{"line":361,"column":72}},"154":{"start":{"line":362,"column":8},"end":{"line":362,"column":72}},"155":{"start":{"line":365,"column":4},"end":{"line":373,"column":5}},"156":{"start":{"line":367,"column":8},"end":{"line":367,"column":62}},"157":{"start":{"line":369,"column":11},"end":{"line":373,"column":5}},"158":{"start":{"line":371,"column":8},"end":{"line":371,"column":62}},"159":{"start":{"line":381,"column":0},"end":{"line":384,"column":2}},"160":{"start":{"line":382,"column":4},"end":{"line":382,"column":25}},"161":{"start":{"line":383,"column":4},"end":{"line":383,"column":37}},"162":{"start":{"line":390,"column":0},"end":{"line":398,"column":2}},"163":{"start":{"line":391,"column":4},"end":{"line":397,"column":5}},"164":{"start":{"line":392,"column":8},"end":{"line":392,"column":92}},"165":{"start":{"line":393,"column":8},"end":{"line":393,"column":92}},"166":{"start":{"line":395,"column":8},"end":{"line":395,"column":38}},"167":{"start":{"line":396,"column":8},"end":{"line":396,"column":40}},"168":{"start":{"line":404,"column":0},"end":{"line":431,"column":2}},"169":{"start":{"line":405,"column":4},"end":{"line":430,"column":5}},"170":{"start":{"line":408,"column":12},"end":{"line":408,"column":36}},"171":{"start":{"line":409,"column":12},"end":{"line":409,"column":18}},"172":{"start":{"line":412,"column":12},"end":{"line":412,"column":33}},"173":{"start":{"line":413,"column":12},"end":{"line":413,"column":18}},"174":{"start":{"line":416,"column":12},"end":{"line":416,"column":37}},"175":{"start":{"line":417,"column":12},"end":{"line":417,"column":18}},"176":{"start":{"line":420,"column":12},"end":{"line":420,"column":34}},"177":{"start":{"line":421,"column":12},"end":{"line":421,"column":18}},"178":{"start":{"line":424,"column":12},"end":{"line":424,"column":31}},"179":{"start":{"line":425,"column":12},"end":{"line":425,"column":18}},"180":{"start":{"line":428,"column":12},"end":{"line":428,"column":33}},"181":{"start":{"line":429,"column":12},"end":{"line":429,"column":18}},"182":{"start":{"line":437,"column":0},"end":{"line":468,"column":2}},"183":{"start":{"line":438,"column":4},"end":{"line":467,"column":5}},"184":{"start":{"line":442,"column":12},"end":{"line":442,"column":37}},"185":{"start":{"line":443,"column":12},"end":{"line":443,"column":18}},"186":{"start":{"line":447,"column":12},"end":{"line":447,"column":34}},"187":{"start":{"line":448,"column":12},"end":{"line":448,"column":18}},"188":{"start":{"line":452,"column":12},"end":{"line":452,"column":38}},"189":{"start":{"line":453,"column":12},"end":{"line":453,"column":18}},"190":{"start":{"line":457,"column":12},"end":{"line":457,"column":35}},"191":{"start":{"line":458,"column":12},"end":{"line":458,"column":18}},"192":{"start":{"line":461,"column":12},"end":{"line":461,"column":32}},"193":{"start":{"line":462,"column":12},"end":{"line":462,"column":18}},"194":{"start":{"line":465,"column":12},"end":{"line":465,"column":34}},"195":{"start":{"line":466,"column":12},"end":{"line":466,"column":18}},"196":{"start":{"line":469,"column":0},"end":{"line":475,"column":2}},"197":{"start":{"line":472,"column":4},"end":{"line":472,"column":21}},"198":{"start":{"line":473,"column":4},"end":{"line":473,"column":28}},"199":{"start":{"line":474,"column":4},"end":{"line":474,"column":38}},"200":{"start":{"line":477,"column":0},"end":{"line":481,"column":2}},"201":{"start":{"line":480,"column":4},"end":{"line":480,"column":36}},"202":{"start":{"line":483,"column":0},"end":{"line":487,"column":2}},"203":{"start":{"line":486,"column":4},"end":{"line":486,"column":42}},"204":{"start":{"line":489,"column":0},"end":{"line":495,"column":2}},"205":{"start":{"line":493,"column":4},"end":{"line":493,"column":94}},"206":{"start":{"line":494,"column":4},"end":{"line":494,"column":64}},"207":{"start":{"line":497,"column":0},"end":{"line":501,"column":2}},"208":{"start":{"line":500,"column":4},"end":{"line":500,"column":52}},"209":{"start":{"line":503,"column":0},"end":{"line":561,"column":2}},"210":{"start":{"line":506,"column":4},"end":{"line":560,"column":5}},"211":{"start":{"line":508,"column":8},"end":{"line":508,"column":64}},"212":{"start":{"line":509,"column":8},"end":{"line":509,"column":35}},"213":{"start":{"line":511,"column":8},"end":{"line":558,"column":9}},"214":{"start":{"line":513,"column":12},"end":{"line":557,"column":13}},"215":{"start":{"line":515,"column":16},"end":{"line":515,"column":56}},"216":{"start":{"line":516,"column":16},"end":{"line":516,"column":44}},"217":{"start":{"line":518,"column":16},"end":{"line":556,"column":17}},"218":{"start":{"line":519,"column":20},"end":{"line":519,"column":59}},"219":{"start":{"line":520,"column":20},"end":{"line":520,"column":46}},"220":{"start":{"line":521,"column":20},"end":{"line":521,"column":48}},"221":{"start":{"line":523,"column":20},"end":{"line":555,"column":21}},"222":{"start":{"line":524,"column":24},"end":{"line":554,"column":25}},"223":{"start":{"line":526,"column":28},"end":{"line":526,"column":68}},"224":{"start":{"line":527,"column":28},"end":{"line":527,"column":79}},"225":{"start":{"line":529,"column":28},"end":{"line":529,"column":68}},"226":{"start":{"line":531,"column":28},"end":{"line":531,"column":63}},"227":{"start":{"line":532,"column":28},"end":{"line":532,"column":75}},"228":{"start":{"line":534,"column":28},"end":{"line":550,"column":29}},"229":{"start":{"line":536,"column":32},"end":{"line":549,"column":33}},"230":{"start":{"line":537,"column":36},"end":{"line":541,"column":37}},"231":{"start":{"line":538,"column":40},"end":{"line":538,"column":86}},"232":{"start":{"line":539,"column":40},"end":{"line":539,"column":96}},"233":{"start":{"line":540,"column":40},"end":{"line":540,"column":103}},"234":{"start":{"line":543,"column":36},"end":{"line":548,"column":37}},"235":{"start":{"line":544,"column":40},"end":{"line":544,"column":81}},"236":{"start":{"line":545,"column":40},"end":{"line":545,"column":92}},"237":{"start":{"line":547,"column":40},"end":{"line":547,"column":112}},"238":{"start":{"line":552,"column":28},"end":{"line":552,"column":57}},"239":{"start":{"line":553,"column":28},"end":{"line":553,"column":61}},"240":{"start":{"line":563,"column":0},"end":{"line":574,"column":2}},"241":{"start":{"line":568,"column":4},"end":{"line":568,"column":62}},"242":{"start":{"line":570,"column":4},"end":{"line":573,"column":7}},"243":{"start":{"line":582,"column":0},"end":{"line":601,"column":2}},"244":{"start":{"line":587,"column":4},"end":{"line":589,"column":5}},"245":{"start":{"line":588,"column":8},"end":{"line":588,"column":18}},"246":{"start":{"line":590,"column":4},"end":{"line":590,"column":23}},"247":{"start":{"line":592,"column":4},"end":{"line":594,"column":5}},"248":{"start":{"line":593,"column":8},"end":{"line":593,"column":18}},"249":{"start":{"line":595,"column":4},"end":{"line":595,"column":23}},"250":{"start":{"line":597,"column":4},"end":{"line":599,"column":5}},"251":{"start":{"line":598,"column":8},"end":{"line":598,"column":20}},"252":{"start":{"line":600,"column":4},"end":{"line":600,"column":25}},"253":{"start":{"line":603,"column":0},"end":{"line":639,"column":2}},"254":{"start":{"line":608,"column":4},"end":{"line":608,"column":40}},"255":{"start":{"line":610,"column":4},"end":{"line":610,"column":44}},"256":{"start":{"line":611,"column":4},"end":{"line":611,"column":44}},"257":{"start":{"line":612,"column":4},"end":{"line":612,"column":44}},"258":{"start":{"line":614,"column":4},"end":{"line":614,"column":33}},"259":{"start":{"line":615,"column":4},"end":{"line":634,"column":5}},"260":{"start":{"line":616,"column":8},"end":{"line":633,"column":9}},"261":{"start":{"line":617,"column":12},"end":{"line":632,"column":13}},"262":{"start":{"line":618,"column":16},"end":{"line":618,"column":61}},"263":{"start":{"line":619,"column":16},"end":{"line":619,"column":56}},"264":{"start":{"line":620,"column":16},"end":{"line":620,"column":56}},"265":{"start":{"line":621,"column":16},"end":{"line":621,"column":56}},"266":{"start":{"line":622,"column":16},"end":{"line":622,"column":48}},"267":{"start":{"line":623,"column":16},"end":{"line":623,"column":48}},"268":{"start":{"line":624,"column":16},"end":{"line":624,"column":48}},"269":{"start":{"line":625,"column":16},"end":{"line":629,"column":18}},"270":{"start":{"line":630,"column":16},"end":{"line":630,"column":53}},"271":{"start":{"line":631,"column":16},"end":{"line":631,"column":66}},"272":{"start":{"line":635,"column":4},"end":{"line":635,"column":37}},"273":{"start":{"line":636,"column":4},"end":{"line":636,"column":34}},"274":{"start":{"line":638,"column":4},"end":{"line":638,"column":120}},"275":{"start":{"line":642,"column":0},"end":{"line":684,"column":2}},"276":{"start":{"line":646,"column":4},"end":{"line":646,"column":26}},"277":{"start":{"line":648,"column":4},"end":{"line":681,"column":6}},"278":{"start":{"line":650,"column":8},"end":{"line":650,"column":54}},"279":{"start":{"line":651,"column":8},"end":{"line":651,"column":33}},"280":{"start":{"line":652,"column":8},"end":{"line":652,"column":35}},"281":{"start":{"line":654,"column":8},"end":{"line":654,"column":46}},"282":{"start":{"line":655,"column":8},"end":{"line":655,"column":37}},"283":{"start":{"line":657,"column":8},"end":{"line":657,"column":69}},"284":{"start":{"line":658,"column":8},"end":{"line":658,"column":31}},"285":{"start":{"line":660,"column":8},"end":{"line":660,"column":28}},"286":{"start":{"line":661,"column":8},"end":{"line":663,"column":9}},"287":{"start":{"line":662,"column":12},"end":{"line":662,"column":39}},"288":{"start":{"line":665,"column":8},"end":{"line":665,"column":24}},"289":{"start":{"line":666,"column":8},"end":{"line":667,"column":31}},"290":{"start":{"line":669,"column":8},"end":{"line":675,"column":9}},"291":{"start":{"line":670,"column":12},"end":{"line":670,"column":28}},"292":{"start":{"line":671,"column":12},"end":{"line":674,"column":13}},"293":{"start":{"line":672,"column":16},"end":{"line":672,"column":78}},"294":{"start":{"line":673,"column":16},"end":{"line":673,"column":39}},"295":{"start":{"line":680,"column":8},"end":{"line":680,"column":69}},"296":{"start":{"line":683,"column":4},"end":{"line":683,"column":24}},"297":{"start":{"line":694,"column":0},"end":{"line":729,"column":2}},"298":{"start":{"line":701,"column":4},"end":{"line":701,"column":17}},"299":{"start":{"line":703,"column":4},"end":{"line":703,"column":29}},"300":{"start":{"line":705,"column":4},"end":{"line":705,"column":35}},"301":{"start":{"line":707,"column":4},"end":{"line":709,"column":5}},"302":{"start":{"line":708,"column":8},"end":{"line":708,"column":17}},"303":{"start":{"line":710,"column":4},"end":{"line":710,"column":21}},"304":{"start":{"line":712,"column":4},"end":{"line":727,"column":5}},"305":{"start":{"line":714,"column":8},"end":{"line":714,"column":49}},"306":{"start":{"line":716,"column":8},"end":{"line":718,"column":9}},"307":{"start":{"line":717,"column":12},"end":{"line":717,"column":38}},"308":{"start":{"line":720,"column":8},"end":{"line":722,"column":9}},"309":{"start":{"line":721,"column":12},"end":{"line":721,"column":39}},"310":{"start":{"line":724,"column":8},"end":{"line":726,"column":9}},"311":{"start":{"line":725,"column":12},"end":{"line":725,"column":38}},"312":{"start":{"line":728,"column":4},"end":{"line":728,"column":35}},"313":{"start":{"line":749,"column":0},"end":{"line":821,"column":2}},"314":{"start":{"line":766,"column":4},"end":{"line":766,"column":17}},"315":{"start":{"line":767,"column":4},"end":{"line":767,"column":31}},"316":{"start":{"line":768,"column":4},"end":{"line":768,"column":21}},"317":{"start":{"line":769,"column":4},"end":{"line":769,"column":23}},"318":{"start":{"line":770,"column":4},"end":{"line":770,"column":31}},"319":{"start":{"line":772,"column":4},"end":{"line":774,"column":5}},"320":{"start":{"line":773,"column":8},"end":{"line":773,"column":49}},"321":{"start":{"line":775,"column":4},"end":{"line":775,"column":29}},"322":{"start":{"line":777,"column":4},"end":{"line":779,"column":5}},"323":{"start":{"line":778,"column":8},"end":{"line":778,"column":55}},"324":{"start":{"line":780,"column":4},"end":{"line":780,"column":41}},"325":{"start":{"line":782,"column":4},"end":{"line":784,"column":5}},"326":{"start":{"line":783,"column":8},"end":{"line":783,"column":46}},"327":{"start":{"line":785,"column":4},"end":{"line":785,"column":33}},"328":{"start":{"line":787,"column":4},"end":{"line":789,"column":5}},"329":{"start":{"line":788,"column":8},"end":{"line":788,"column":49}},"330":{"start":{"line":790,"column":4},"end":{"line":790,"column":29}},"331":{"start":{"line":792,"column":4},"end":{"line":794,"column":5}},"332":{"start":{"line":793,"column":8},"end":{"line":793,"column":46}},"333":{"start":{"line":795,"column":4},"end":{"line":795,"column":23}},"334":{"start":{"line":797,"column":4},"end":{"line":799,"column":5}},"335":{"start":{"line":798,"column":8},"end":{"line":798,"column":21}},"336":{"start":{"line":800,"column":4},"end":{"line":800,"column":29}},"337":{"start":{"line":802,"column":4},"end":{"line":804,"column":5}},"338":{"start":{"line":803,"column":8},"end":{"line":803,"column":18}},"339":{"start":{"line":805,"column":4},"end":{"line":805,"column":23}},"340":{"start":{"line":807,"column":4},"end":{"line":809,"column":5}},"341":{"start":{"line":808,"column":8},"end":{"line":808,"column":28}},"342":{"start":{"line":810,"column":4},"end":{"line":810,"column":23}},"343":{"start":{"line":812,"column":4},"end":{"line":814,"column":5}},"344":{"start":{"line":813,"column":8},"end":{"line":813,"column":28}},"345":{"start":{"line":815,"column":4},"end":{"line":815,"column":23}},"346":{"start":{"line":817,"column":4},"end":{"line":819,"column":5}},"347":{"start":{"line":818,"column":8},"end":{"line":818,"column":21}},"348":{"start":{"line":820,"column":4},"end":{"line":820,"column":29}},"349":{"start":{"line":883,"column":0},"end":{"line":1232,"column":2}},"350":{"start":{"line":942,"column":4},"end":{"line":942,"column":17}},"351":{"start":{"line":943,"column":4},"end":{"line":943,"column":21}},"352":{"start":{"line":944,"column":4},"end":{"line":946,"column":5}},"353":{"start":{"line":945,"column":8},"end":{"line":945,"column":62}},"354":{"start":{"line":947,"column":4},"end":{"line":947,"column":37}},"355":{"start":{"line":949,"column":4},"end":{"line":951,"column":5}},"356":{"start":{"line":950,"column":8},"end":{"line":950,"column":22}},"357":{"start":{"line":952,"column":4},"end":{"line":952,"column":27}},"358":{"start":{"line":954,"column":4},"end":{"line":956,"column":5}},"359":{"start":{"line":955,"column":8},"end":{"line":955,"column":51}},"360":{"start":{"line":957,"column":4},"end":{"line":957,"column":21}},"361":{"start":{"line":959,"column":4},"end":{"line":961,"column":5}},"362":{"start":{"line":960,"column":8},"end":{"line":960,"column":28}},"363":{"start":{"line":962,"column":4},"end":{"line":962,"column":35}},"364":{"start":{"line":964,"column":4},"end":{"line":979,"column":5}},"365":{"start":{"line":965,"column":8},"end":{"line":978,"column":10}},"366":{"start":{"line":980,"column":4},"end":{"line":980,"column":21}},"367":{"start":{"line":982,"column":4},"end":{"line":984,"column":5}},"368":{"start":{"line":983,"column":8},"end":{"line":983,"column":64}},"369":{"start":{"line":985,"column":4},"end":{"line":985,"column":29}},"370":{"start":{"line":987,"column":4},"end":{"line":989,"column":5}},"371":{"start":{"line":988,"column":8},"end":{"line":988,"column":30}},"372":{"start":{"line":990,"column":4},"end":{"line":990,"column":47}},"373":{"start":{"line":992,"column":4},"end":{"line":994,"column":5}},"374":{"start":{"line":993,"column":8},"end":{"line":993,"column":27}},"375":{"start":{"line":995,"column":4},"end":{"line":995,"column":41}},"376":{"start":{"line":997,"column":4},"end":{"line":999,"column":5}},"377":{"start":{"line":998,"column":8},"end":{"line":998,"column":48}},"378":{"start":{"line":1000,"column":4},"end":{"line":1000,"column":23}},"379":{"start":{"line":1002,"column":4},"end":{"line":1004,"column":5}},"380":{"start":{"line":1003,"column":8},"end":{"line":1003,"column":52}},"381":{"start":{"line":1005,"column":4},"end":{"line":1005,"column":29}},"382":{"start":{"line":1007,"column":4},"end":{"line":1009,"column":5}},"383":{"start":{"line":1008,"column":8},"end":{"line":1008,"column":30}},"384":{"start":{"line":1010,"column":4},"end":{"line":1010,"column":47}},"385":{"start":{"line":1012,"column":4},"end":{"line":1014,"column":5}},"386":{"start":{"line":1013,"column":8},"end":{"line":1013,"column":62}},"387":{"start":{"line":1015,"column":4},"end":{"line":1015,"column":27}},"388":{"start":{"line":1017,"column":4},"end":{"line":1019,"column":5}},"389":{"start":{"line":1018,"column":8},"end":{"line":1018,"column":23}},"390":{"start":{"line":1020,"column":4},"end":{"line":1020,"column":31}},"391":{"start":{"line":1022,"column":4},"end":{"line":1024,"column":5}},"392":{"start":{"line":1023,"column":8},"end":{"line":1023,"column":25}},"393":{"start":{"line":1025,"column":4},"end":{"line":1025,"column":37}},"394":{"start":{"line":1027,"column":4},"end":{"line":1029,"column":5}},"395":{"start":{"line":1028,"column":8},"end":{"line":1028,"column":31}},"396":{"start":{"line":1030,"column":4},"end":{"line":1030,"column":43}},"397":{"start":{"line":1032,"column":4},"end":{"line":1034,"column":5}},"398":{"start":{"line":1033,"column":8},"end":{"line":1033,"column":19}},"399":{"start":{"line":1035,"column":4},"end":{"line":1035,"column":19}},"400":{"start":{"line":1037,"column":4},"end":{"line":1039,"column":5}},"401":{"start":{"line":1038,"column":8},"end":{"line":1038,"column":26}},"402":{"start":{"line":1040,"column":4},"end":{"line":1040,"column":31}},"403":{"start":{"line":1042,"column":4},"end":{"line":1044,"column":5}},"404":{"start":{"line":1043,"column":8},"end":{"line":1043,"column":31}},"405":{"start":{"line":1045,"column":4},"end":{"line":1045,"column":49}},"406":{"start":{"line":1047,"column":4},"end":{"line":1049,"column":5}},"407":{"start":{"line":1048,"column":8},"end":{"line":1048,"column":35}},"408":{"start":{"line":1050,"column":4},"end":{"line":1050,"column":45}},"409":{"start":{"line":1052,"column":4},"end":{"line":1054,"column":5}},"410":{"start":{"line":1053,"column":8},"end":{"line":1053,"column":36}},"411":{"start":{"line":1055,"column":4},"end":{"line":1055,"column":47}},"412":{"start":{"line":1057,"column":4},"end":{"line":1059,"column":5}},"413":{"start":{"line":1058,"column":8},"end":{"line":1058,"column":58}},"414":{"start":{"line":1060,"column":4},"end":{"line":1060,"column":37}},"415":{"start":{"line":1062,"column":4},"end":{"line":1064,"column":5}},"416":{"start":{"line":1063,"column":8},"end":{"line":1063,"column":25}},"417":{"start":{"line":1065,"column":4},"end":{"line":1065,"column":29}},"418":{"start":{"line":1067,"column":4},"end":{"line":1069,"column":5}},"419":{"start":{"line":1068,"column":8},"end":{"line":1068,"column":29}},"420":{"start":{"line":1070,"column":4},"end":{"line":1070,"column":37}},"421":{"start":{"line":1072,"column":4},"end":{"line":1074,"column":5}},"422":{"start":{"line":1073,"column":8},"end":{"line":1073,"column":29}},"423":{"start":{"line":1075,"column":4},"end":{"line":1075,"column":37}},"424":{"start":{"line":1077,"column":4},"end":{"line":1079,"column":5}},"425":{"start":{"line":1078,"column":8},"end":{"line":1078,"column":21}},"426":{"start":{"line":1080,"column":4},"end":{"line":1080,"column":29}},"427":{"start":{"line":1082,"column":4},"end":{"line":1084,"column":5}},"428":{"start":{"line":1083,"column":8},"end":{"line":1083,"column":22}},"429":{"start":{"line":1085,"column":4},"end":{"line":1085,"column":31}},"430":{"start":{"line":1087,"column":4},"end":{"line":1089,"column":5}},"431":{"start":{"line":1088,"column":8},"end":{"line":1088,"column":26}},"432":{"start":{"line":1090,"column":4},"end":{"line":1090,"column":27}},"433":{"start":{"line":1092,"column":4},"end":{"line":1094,"column":5}},"434":{"start":{"line":1093,"column":8},"end":{"line":1093,"column":27}},"435":{"start":{"line":1095,"column":4},"end":{"line":1095,"column":29}},"436":{"start":{"line":1097,"column":4},"end":{"line":1099,"column":5}},"437":{"start":{"line":1098,"column":8},"end":{"line":1098,"column":21}},"438":{"start":{"line":1100,"column":4},"end":{"line":1100,"column":29}},"439":{"start":{"line":1102,"column":4},"end":{"line":1104,"column":5}},"440":{"start":{"line":1103,"column":8},"end":{"line":1103,"column":21}},"441":{"start":{"line":1105,"column":4},"end":{"line":1105,"column":29}},"442":{"start":{"line":1107,"column":4},"end":{"line":1109,"column":5}},"443":{"start":{"line":1108,"column":8},"end":{"line":1108,"column":60}},"444":{"start":{"line":1110,"column":4},"end":{"line":1110,"column":29}},"445":{"start":{"line":1112,"column":4},"end":{"line":1114,"column":5}},"446":{"start":{"line":1113,"column":8},"end":{"line":1113,"column":61}},"447":{"start":{"line":1115,"column":4},"end":{"line":1115,"column":29}},"448":{"start":{"line":1117,"column":4},"end":{"line":1119,"column":5}},"449":{"start":{"line":1118,"column":8},"end":{"line":1118,"column":71}},"450":{"start":{"line":1120,"column":4},"end":{"line":1120,"column":29}},"451":{"start":{"line":1122,"column":4},"end":{"line":1124,"column":5}},"452":{"start":{"line":1123,"column":8},"end":{"line":1123,"column":62}},"453":{"start":{"line":1125,"column":4},"end":{"line":1125,"column":39}},"454":{"start":{"line":1127,"column":4},"end":{"line":1129,"column":5}},"455":{"start":{"line":1128,"column":8},"end":{"line":1128,"column":25}},"456":{"start":{"line":1130,"column":4},"end":{"line":1130,"column":31}},"457":{"start":{"line":1132,"column":4},"end":{"line":1134,"column":5}},"458":{"start":{"line":1133,"column":8},"end":{"line":1133,"column":62}},"459":{"start":{"line":1135,"column":4},"end":{"line":1135,"column":31}},"460":{"start":{"line":1137,"column":4},"end":{"line":1139,"column":5}},"461":{"start":{"line":1138,"column":8},"end":{"line":1138,"column":26}},"462":{"start":{"line":1140,"column":4},"end":{"line":1140,"column":33}},"463":{"start":{"line":1142,"column":4},"end":{"line":1144,"column":5}},"464":{"start":{"line":1143,"column":8},"end":{"line":1143,"column":30}},"465":{"start":{"line":1145,"column":4},"end":{"line":1145,"column":39}},"466":{"start":{"line":1147,"column":4},"end":{"line":1149,"column":5}},"467":{"start":{"line":1148,"column":8},"end":{"line":1148,"column":32}},"468":{"start":{"line":1150,"column":4},"end":{"line":1150,"column":51}},"469":{"start":{"line":1152,"column":4},"end":{"line":1154,"column":5}},"470":{"start":{"line":1153,"column":8},"end":{"line":1153,"column":31}},"471":{"start":{"line":1155,"column":4},"end":{"line":1155,"column":49}},"472":{"start":{"line":1157,"column":4},"end":{"line":1159,"column":5}},"473":{"start":{"line":1158,"column":8},"end":{"line":1158,"column":22}},"474":{"start":{"line":1160,"column":4},"end":{"line":1160,"column":31}},"475":{"start":{"line":1162,"column":4},"end":{"line":1164,"column":5}},"476":{"start":{"line":1163,"column":8},"end":{"line":1163,"column":28}},"477":{"start":{"line":1165,"column":4},"end":{"line":1165,"column":41}},"478":{"start":{"line":1167,"column":4},"end":{"line":1169,"column":5}},"479":{"start":{"line":1168,"column":8},"end":{"line":1168,"column":28}},"480":{"start":{"line":1170,"column":4},"end":{"line":1170,"column":35}},"481":{"start":{"line":1172,"column":4},"end":{"line":1174,"column":5}},"482":{"start":{"line":1173,"column":8},"end":{"line":1173,"column":23}},"483":{"start":{"line":1175,"column":4},"end":{"line":1175,"column":27}},"484":{"start":{"line":1177,"column":4},"end":{"line":1179,"column":5}},"485":{"start":{"line":1178,"column":8},"end":{"line":1178,"column":56}},"486":{"start":{"line":1180,"column":4},"end":{"line":1180,"column":27}},"487":{"start":{"line":1182,"column":4},"end":{"line":1184,"column":5}},"488":{"start":{"line":1183,"column":8},"end":{"line":1183,"column":22}},"489":{"start":{"line":1185,"column":4},"end":{"line":1185,"column":31}},"490":{"start":{"line":1187,"column":4},"end":{"line":1189,"column":5}},"491":{"start":{"line":1188,"column":8},"end":{"line":1188,"column":24}},"492":{"start":{"line":1190,"column":4},"end":{"line":1190,"column":35}},"493":{"start":{"line":1192,"column":4},"end":{"line":1194,"column":5}},"494":{"start":{"line":1193,"column":8},"end":{"line":1193,"column":30}},"495":{"start":{"line":1195,"column":4},"end":{"line":1195,"column":47}},"496":{"start":{"line":1197,"column":4},"end":{"line":1199,"column":5}},"497":{"start":{"line":1198,"column":8},"end":{"line":1198,"column":29}},"498":{"start":{"line":1200,"column":4},"end":{"line":1200,"column":45}},"499":{"start":{"line":1202,"column":4},"end":{"line":1204,"column":5}},"500":{"start":{"line":1203,"column":8},"end":{"line":1203,"column":24}},"501":{"start":{"line":1205,"column":4},"end":{"line":1205,"column":31}},"502":{"start":{"line":1207,"column":4},"end":{"line":1209,"column":5}},"503":{"start":{"line":1208,"column":8},"end":{"line":1208,"column":24}},"504":{"start":{"line":1210,"column":4},"end":{"line":1210,"column":31}},"505":{"start":{"line":1212,"column":4},"end":{"line":1214,"column":5}},"506":{"start":{"line":1213,"column":8},"end":{"line":1213,"column":22}},"507":{"start":{"line":1215,"column":4},"end":{"line":1215,"column":31}},"508":{"start":{"line":1217,"column":4},"end":{"line":1219,"column":5}},"509":{"start":{"line":1218,"column":8},"end":{"line":1218,"column":36}},"510":{"start":{"line":1220,"column":4},"end":{"line":1220,"column":53}},"511":{"start":{"line":1222,"column":4},"end":{"line":1224,"column":5}},"512":{"start":{"line":1223,"column":8},"end":{"line":1223,"column":27}},"513":{"start":{"line":1225,"column":4},"end":{"line":1225,"column":41}},"514":{"start":{"line":1227,"column":4},"end":{"line":1229,"column":5}},"515":{"start":{"line":1228,"column":8},"end":{"line":1228,"column":30}},"516":{"start":{"line":1230,"column":4},"end":{"line":1230,"column":43}},"517":{"start":{"line":1238,"column":0},"end":{"line":1238,"column":48}},"518":{"start":{"line":1239,"column":0},"end":{"line":1239,"column":43}},"519":{"start":{"line":1240,"column":0},"end":{"line":1240,"column":43}},"520":{"start":{"line":1246,"column":0},"end":{"line":1246,"column":39}},"521":{"start":{"line":1247,"column":0},"end":{"line":1247,"column":41}},"522":{"start":{"line":1248,"column":0},"end":{"line":1248,"column":43}},"523":{"start":{"line":1254,"column":0},"end":{"line":1254,"column":45}},"524":{"start":{"line":1255,"column":0},"end":{"line":1255,"column":47}},"525":{"start":{"line":1256,"column":0},"end":{"line":1256,"column":50}},"526":{"start":{"line":1257,"column":0},"end":{"line":1257,"column":47}},"527":{"start":{"line":1258,"column":0},"end":{"line":1258,"column":45}},"528":{"start":{"line":1264,"column":0},"end":{"line":1264,"column":43}},"529":{"start":{"line":1265,"column":0},"end":{"line":1265,"column":42}},"530":{"start":{"line":1266,"column":0},"end":{"line":1266,"column":48}},"531":{"start":{"line":1267,"column":0},"end":{"line":1267,"column":58}},"532":{"start":{"line":1268,"column":0},"end":{"line":1268,"column":48}},"533":{"start":{"line":1269,"column":0},"end":{"line":1269,"column":58}},"534":{"start":{"line":1270,"column":0},"end":{"line":1270,"column":48}},"535":{"start":{"line":1271,"column":0},"end":{"line":1271,"column":58}},"536":{"start":{"line":1272,"column":0},"end":{"line":1272,"column":48}},"537":{"start":{"line":1273,"column":0},"end":{"line":1273,"column":58}},"538":{"start":{"line":1274,"column":0},"end":{"line":1274,"column":57}},"539":{"start":{"line":1280,"column":0},"end":{"line":1280,"column":44}},"540":{"start":{"line":1281,"column":0},"end":{"line":1281,"column":49}},"541":{"start":{"line":1282,"column":0},"end":{"line":1282,"column":57}},"542":{"start":{"line":1283,"column":0},"end":{"line":1283,"column":44}},"543":{"start":{"line":1284,"column":0},"end":{"line":1284,"column":44}},"544":{"start":{"line":1290,"column":0},"end":{"line":1290,"column":41}},"545":{"start":{"line":1291,"column":0},"end":{"line":1291,"column":42}},"546":{"start":{"line":1292,"column":0},"end":{"line":1292,"column":40}},"547":{"start":{"line":1293,"column":0},"end":{"line":1293,"column":46}},"548":{"start":{"line":1294,"column":0},"end":{"line":1294,"column":41}},"549":{"start":{"line":1295,"column":0},"end":{"line":1295,"column":49}},"550":{"start":{"line":1296,"column":0},"end":{"line":1296,"column":43}},"551":{"start":{"line":1297,"column":0},"end":{"line":1297,"column":45}},"552":{"start":{"line":1303,"column":0},"end":{"line":1303,"column":40}},"553":{"start":{"line":1304,"column":0},"end":{"line":1304,"column":39}},"554":{"start":{"line":1305,"column":0},"end":{"line":1305,"column":41}},"555":{"start":{"line":1311,"column":0},"end":{"line":1311,"column":42}},"556":{"start":{"line":1312,"column":0},"end":{"line":1312,"column":44}},"557":{"start":{"line":1318,"column":0},"end":{"line":1318,"column":61}},"558":{"start":{"line":1319,"column":0},"end":{"line":1319,"column":62}},"559":{"start":{"line":1320,"column":0},"end":{"line":1320,"column":61}},"560":{"start":{"line":1321,"column":0},"end":{"line":1321,"column":61}},"561":{"start":{"line":1322,"column":0},"end":{"line":1322,"column":63}},"562":{"start":{"line":1323,"column":0},"end":{"line":1323,"column":62}},"563":{"start":{"line":1324,"column":0},"end":{"line":1324,"column":61}},"564":{"start":{"line":1325,"column":0},"end":{"line":1325,"column":64}},"565":{"start":{"line":1326,"column":0},"end":{"line":1326,"column":58}},"566":{"start":{"line":1327,"column":0},"end":{"line":1327,"column":58}},"567":{"start":{"line":1328,"column":0},"end":{"line":1328,"column":57}},"568":{"start":{"line":1335,"column":0},"end":{"line":1501,"column":2}},"569":{"start":{"line":1337,"column":4},"end":{"line":1337,"column":31}},"570":{"start":{"line":1339,"column":4},"end":{"line":1339,"column":29}},"571":{"start":{"line":1341,"column":4},"end":{"line":1341,"column":25}},"572":{"start":{"line":1343,"column":4},"end":{"line":1482,"column":5}},"573":{"start":{"line":1345,"column":8},"end":{"line":1394,"column":11}},"574":{"start":{"line":1396,"column":8},"end":{"line":1408,"column":10}},"575":{"start":{"line":1409,"column":11},"end":{"line":1482,"column":5}},"576":{"start":{"line":1411,"column":8},"end":{"line":1465,"column":11}},"577":{"start":{"line":1467,"column":8},"end":{"line":1478,"column":10}},"578":{"start":{"line":1481,"column":8},"end":{"line":1481,"column":137}},"579":{"start":{"line":1484,"column":4},"end":{"line":1498,"column":5}},"580":{"start":{"line":1485,"column":8},"end":{"line":1485,"column":85}},"581":{"start":{"line":1486,"column":8},"end":{"line":1495,"column":9}},"582":{"start":{"line":1488,"column":16},"end":{"line":1488,"column":45}},"583":{"start":{"line":1492,"column":16},"end":{"line":1492,"column":35}},"584":{"start":{"line":1493,"column":16},"end":{"line":1493,"column":36}},"585":{"start":{"line":1497,"column":8},"end":{"line":1497,"column":37}},"586":{"start":{"line":1500,"column":4},"end":{"line":1500,"column":25}},"587":{"start":{"line":1509,"column":0},"end":{"line":1527,"column":2}},"588":{"start":{"line":1514,"column":4},"end":{"line":1514,"column":20}},"589":{"start":{"line":1516,"column":4},"end":{"line":1518,"column":5}},"590":{"start":{"line":1517,"column":8},"end":{"line":1517,"column":28}},"591":{"start":{"line":1520,"column":4},"end":{"line":1522,"column":5}},"592":{"start":{"line":1521,"column":8},"end":{"line":1521,"column":28}},"593":{"start":{"line":1524,"column":4},"end":{"line":1526,"column":5}},"594":{"start":{"line":1525,"column":8},"end":{"line":1525,"column":28}},"595":{"start":{"line":1532,"column":0},"end":{"line":1538,"column":2}},"596":{"start":{"line":1533,"column":4},"end":{"line":1537,"column":6}},"597":{"start":{"line":1539,"column":0},"end":{"line":1563,"column":2}},"598":{"start":{"line":1546,"column":4},"end":{"line":1546,"column":20}},"599":{"start":{"line":1548,"column":4},"end":{"line":1550,"column":5}},"600":{"start":{"line":1549,"column":8},"end":{"line":1549,"column":28}},"601":{"start":{"line":1552,"column":4},"end":{"line":1554,"column":5}},"602":{"start":{"line":1553,"column":8},"end":{"line":1553,"column":28}},"603":{"start":{"line":1556,"column":4},"end":{"line":1558,"column":5}},"604":{"start":{"line":1557,"column":8},"end":{"line":1557,"column":28}},"605":{"start":{"line":1560,"column":4},"end":{"line":1562,"column":5}},"606":{"start":{"line":1561,"column":8},"end":{"line":1561,"column":28}},"607":{"start":{"line":1565,"column":0},"end":{"line":1570,"column":2}},"608":{"start":{"line":1566,"column":4},"end":{"line":1566,"column":20}},"609":{"start":{"line":1567,"column":4},"end":{"line":1567,"column":91}},"610":{"start":{"line":1568,"column":4},"end":{"line":1568,"column":86}},"611":{"start":{"line":1569,"column":4},"end":{"line":1569,"column":16}},"612":{"start":{"line":1572,"column":0},"end":{"line":1587,"column":2}},"613":{"start":{"line":1573,"column":4},"end":{"line":1573,"column":20}},"614":{"start":{"line":1574,"column":4},"end":{"line":1579,"column":6}},"615":{"start":{"line":1580,"column":4},"end":{"line":1585,"column":6}},"616":{"start":{"line":1586,"column":4},"end":{"line":1586,"column":16}},"617":{"start":{"line":1589,"column":0},"end":{"line":1594,"column":2}},"618":{"start":{"line":1590,"column":4},"end":{"line":1590,"column":20}},"619":{"start":{"line":1591,"column":4},"end":{"line":1591,"column":91}},"620":{"start":{"line":1592,"column":4},"end":{"line":1592,"column":86}},"621":{"start":{"line":1593,"column":4},"end":{"line":1593,"column":16}},"622":{"start":{"line":1596,"column":0},"end":{"line":1600,"column":2}},"623":{"start":{"line":1597,"column":4},"end":{"line":1597,"column":20}},"624":{"start":{"line":1598,"column":4},"end":{"line":1598,"column":34}},"625":{"start":{"line":1599,"column":4},"end":{"line":1599,"column":32}},"626":{"start":{"line":1602,"column":0},"end":{"line":1606,"column":2}},"627":{"start":{"line":1603,"column":4},"end":{"line":1603,"column":20}},"628":{"start":{"line":1604,"column":4},"end":{"line":1604,"column":34}},"629":{"start":{"line":1605,"column":4},"end":{"line":1605,"column":32}},"630":{"start":{"line":1608,"column":0},"end":{"line":1612,"column":2}},"631":{"start":{"line":1609,"column":4},"end":{"line":1609,"column":20}},"632":{"start":{"line":1610,"column":4},"end":{"line":1610,"column":34}},"633":{"start":{"line":1611,"column":4},"end":{"line":1611,"column":32}},"634":{"start":{"line":1614,"column":0},"end":{"line":1629,"column":2}},"635":{"start":{"line":1615,"column":4},"end":{"line":1628,"column":5}},"636":{"start":{"line":1616,"column":8},"end":{"line":1621,"column":10}},"637":{"start":{"line":1622,"column":11},"end":{"line":1628,"column":5}},"638":{"start":{"line":1623,"column":8},"end":{"line":1627,"column":10}},"639":{"start":{"line":1631,"column":0},"end":{"line":1638,"column":2}},"640":{"start":{"line":1632,"column":4},"end":{"line":1637,"column":6}},"641":{"start":{"line":1640,"column":0},"end":{"line":1711,"column":2}},"642":{"start":{"line":1642,"column":4},"end":{"line":1642,"column":72}},"643":{"start":{"line":1644,"column":4},"end":{"line":1644,"column":44}},"644":{"start":{"line":1646,"column":4},"end":{"line":1648,"column":5}},"645":{"start":{"line":1647,"column":8},"end":{"line":1647,"column":16}},"646":{"start":{"line":1650,"column":4},"end":{"line":1650,"column":36}},"647":{"start":{"line":1652,"column":4},"end":{"line":1655,"column":5}},"648":{"start":{"line":1653,"column":8},"end":{"line":1653,"column":22}},"649":{"start":{"line":1654,"column":8},"end":{"line":1654,"column":36}},"650":{"start":{"line":1657,"column":4},"end":{"line":1657,"column":23}},"651":{"start":{"line":1659,"column":4},"end":{"line":1659,"column":25}},"652":{"start":{"line":1660,"column":4},"end":{"line":1660,"column":25}},"653":{"start":{"line":1661,"column":4},"end":{"line":1661,"column":25}},"654":{"start":{"line":1663,"column":4},"end":{"line":1663,"column":25}},"655":{"start":{"line":1664,"column":4},"end":{"line":1664,"column":25}},"656":{"start":{"line":1665,"column":4},"end":{"line":1665,"column":25}},"657":{"start":{"line":1667,"column":4},"end":{"line":1667,"column":25}},"658":{"start":{"line":1668,"column":4},"end":{"line":1668,"column":25}},"659":{"start":{"line":1669,"column":4},"end":{"line":1669,"column":25}},"660":{"start":{"line":1671,"column":4},"end":{"line":1671,"column":16}},"661":{"start":{"line":1737,"column":0},"end":{"line":1823,"column":2}},"662":{"start":{"line":1759,"column":4},"end":{"line":1759,"column":17}},"663":{"start":{"line":1760,"column":4},"end":{"line":1760,"column":21}},"664":{"start":{"line":1761,"column":4},"end":{"line":1761,"column":21}},"665":{"start":{"line":1762,"column":4},"end":{"line":1762,"column":29}},"666":{"start":{"line":1763,"column":4},"end":{"line":1763,"column":29}},"667":{"start":{"line":1764,"column":4},"end":{"line":1764,"column":23}},"668":{"start":{"line":1766,"column":4},"end":{"line":1768,"column":5}},"669":{"start":{"line":1767,"column":8},"end":{"line":1767,"column":24}},"670":{"start":{"line":1769,"column":4},"end":{"line":1769,"column":29}},"671":{"start":{"line":1771,"column":4},"end":{"line":1773,"column":5}},"672":{"start":{"line":1772,"column":8},"end":{"line":1772,"column":27}},"673":{"start":{"line":1774,"column":4},"end":{"line":1774,"column":39}},"674":{"start":{"line":1776,"column":4},"end":{"line":1778,"column":5}},"675":{"start":{"line":1777,"column":8},"end":{"line":1777,"column":25}},"676":{"start":{"line":1779,"column":4},"end":{"line":1779,"column":35}},"677":{"start":{"line":1781,"column":4},"end":{"line":1783,"column":5}},"678":{"start":{"line":1782,"column":8},"end":{"line":1782,"column":25}},"679":{"start":{"line":1784,"column":4},"end":{"line":1784,"column":35}},"680":{"start":{"line":1786,"column":4},"end":{"line":1788,"column":5}},"681":{"start":{"line":1787,"column":8},"end":{"line":1787,"column":23}},"682":{"start":{"line":1789,"column":4},"end":{"line":1789,"column":31}},"683":{"start":{"line":1791,"column":4},"end":{"line":1793,"column":5}},"684":{"start":{"line":1792,"column":8},"end":{"line":1792,"column":49}},"685":{"start":{"line":1794,"column":4},"end":{"line":1794,"column":29}},"686":{"start":{"line":1796,"column":4},"end":{"line":1798,"column":5}},"687":{"start":{"line":1797,"column":8},"end":{"line":1797,"column":33}},"688":{"start":{"line":1799,"column":4},"end":{"line":1799,"column":33}},"689":{"start":{"line":1801,"column":4},"end":{"line":1803,"column":5}},"690":{"start":{"line":1802,"column":8},"end":{"line":1802,"column":49}},"691":{"start":{"line":1804,"column":4},"end":{"line":1804,"column":29}},"692":{"start":{"line":1806,"column":4},"end":{"line":1808,"column":5}},"693":{"start":{"line":1807,"column":8},"end":{"line":1807,"column":46}},"694":{"start":{"line":1809,"column":4},"end":{"line":1809,"column":23}},"695":{"start":{"line":1811,"column":4},"end":{"line":1813,"column":5}},"696":{"start":{"line":1812,"column":8},"end":{"line":1812,"column":43}},"697":{"start":{"line":1814,"column":4},"end":{"line":1814,"column":17}},"698":{"start":{"line":1816,"column":4},"end":{"line":1816,"column":27}},"699":{"start":{"line":1818,"column":4},"end":{"line":1818,"column":37}},"700":{"start":{"line":1820,"column":4},"end":{"line":1820,"column":39}},"701":{"start":{"line":1822,"column":4},"end":{"line":1822,"column":24}},"702":{"start":{"line":1830,"column":0},"end":{"line":1830,"column":32}},"703":{"start":{"line":1831,"column":0},"end":{"line":1831,"column":33}},"704":{"start":{"line":1841,"column":0},"end":{"line":1954,"column":2}},"705":{"start":{"line":1843,"column":4},"end":{"line":1843,"column":25}},"706":{"start":{"line":1845,"column":4},"end":{"line":1847,"column":5}},"707":{"start":{"line":1846,"column":8},"end":{"line":1846,"column":70}},"708":{"start":{"line":1849,"column":4},"end":{"line":1945,"column":5}},"709":{"start":{"line":1851,"column":8},"end":{"line":1851,"column":47}},"710":{"start":{"line":1853,"column":8},"end":{"line":1853,"column":50}},"711":{"start":{"line":1855,"column":8},"end":{"line":1855,"column":50}},"712":{"start":{"line":1857,"column":8},"end":{"line":1857,"column":28}},"713":{"start":{"line":1859,"column":8},"end":{"line":1887,"column":9}},"714":{"start":{"line":1861,"column":12},"end":{"line":1861,"column":45}},"715":{"start":{"line":1863,"column":12},"end":{"line":1863,"column":39}},"716":{"start":{"line":1865,"column":12},"end":{"line":1865,"column":51}},"717":{"start":{"line":1866,"column":12},"end":{"line":1866,"column":51}},"718":{"start":{"line":1867,"column":12},"end":{"line":1867,"column":51}},"719":{"start":{"line":1869,"column":12},"end":{"line":1869,"column":51}},"720":{"start":{"line":1870,"column":12},"end":{"line":1870,"column":51}},"721":{"start":{"line":1871,"column":12},"end":{"line":1871,"column":51}},"722":{"start":{"line":1873,"column":12},"end":{"line":1873,"column":55}},"723":{"start":{"line":1874,"column":12},"end":{"line":1874,"column":55}},"724":{"start":{"line":1875,"column":12},"end":{"line":1875,"column":55}},"725":{"start":{"line":1876,"column":12},"end":{"line":1876,"column":55}},"726":{"start":{"line":1878,"column":12},"end":{"line":1878,"column":45}},"727":{"start":{"line":1879,"column":12},"end":{"line":1879,"column":45}},"728":{"start":{"line":1880,"column":12},"end":{"line":1880,"column":45}},"729":{"start":{"line":1882,"column":12},"end":{"line":1882,"column":39}},"730":{"start":{"line":1883,"column":12},"end":{"line":1883,"column":39}},"731":{"start":{"line":1884,"column":12},"end":{"line":1884,"column":39}},"732":{"start":{"line":1886,"column":12},"end":{"line":1886,"column":34}},"733":{"start":{"line":1892,"column":8},"end":{"line":1896,"column":9}},"734":{"start":{"line":1893,"column":12},"end":{"line":1895,"column":13}},"735":{"start":{"line":1894,"column":16},"end":{"line":1894,"column":76}},"736":{"start":{"line":1901,"column":8},"end":{"line":1910,"column":9}},"737":{"start":{"line":1902,"column":12},"end":{"line":1909,"column":14}},"738":{"start":{"line":1915,"column":8},"end":{"line":1924,"column":9}},"739":{"start":{"line":1916,"column":12},"end":{"line":1923,"column":14}},"740":{"start":{"line":1926,"column":8},"end":{"line":1926,"column":77}},"741":{"start":{"line":1928,"column":8},"end":{"line":1928,"column":59}},"742":{"start":{"line":1930,"column":8},"end":{"line":1930,"column":74}},"743":{"start":{"line":1932,"column":8},"end":{"line":1937,"column":9}},"744":{"start":{"line":1933,"column":12},"end":{"line":1936,"column":13}},"745":{"start":{"line":1934,"column":16},"end":{"line":1934,"column":45}},"746":{"start":{"line":1935,"column":16},"end":{"line":1935,"column":22}},"747":{"start":{"line":1939,"column":8},"end":{"line":1939,"column":33}},"748":{"start":{"line":1941,"column":8},"end":{"line":1941,"column":25}},"749":{"start":{"line":1943,"column":8},"end":{"line":1943,"column":85}},"750":{"start":{"line":1944,"column":8},"end":{"line":1944,"column":65}},"751":{"start":{"line":1947,"column":4},"end":{"line":1949,"column":5}},"752":{"start":{"line":1948,"column":8},"end":{"line":1948,"column":86}},"753":{"start":{"line":1951,"column":4},"end":{"line":1951,"column":43}},"754":{"start":{"line":1953,"column":4},"end":{"line":1953,"column":21}},"755":{"start":{"line":1956,"column":0},"end":{"line":1969,"column":2}},"756":{"start":{"line":1958,"column":4},"end":{"line":1966,"column":5}},"757":{"start":{"line":1959,"column":8},"end":{"line":1959,"column":33}},"758":{"start":{"line":1960,"column":8},"end":{"line":1960,"column":42}},"759":{"start":{"line":1961,"column":8},"end":{"line":1961,"column":29}},"760":{"start":{"line":1963,"column":8},"end":{"line":1963,"column":50}},"761":{"start":{"line":1964,"column":8},"end":{"line":1964,"column":64}},"762":{"start":{"line":1965,"column":8},"end":{"line":1965,"column":46}},"763":{"start":{"line":1968,"column":4},"end":{"line":1968,"column":21}},"764":{"start":{"line":1974,"column":0},"end":{"line":2032,"column":2}},"765":{"start":{"line":1976,"column":4},"end":{"line":1976,"column":53}},"766":{"start":{"line":1978,"column":4},"end":{"line":1984,"column":5}},"767":{"start":{"line":1979,"column":8},"end":{"line":1983,"column":11}},"768":{"start":{"line":1986,"column":4},"end":{"line":1986,"column":33}},"769":{"start":{"line":1988,"column":4},"end":{"line":1988,"column":23}},"770":{"start":{"line":1990,"column":4},"end":{"line":2011,"column":5}},"771":{"start":{"line":1992,"column":8},"end":{"line":1992,"column":26}},"772":{"start":{"line":1993,"column":8},"end":{"line":1993,"column":28}},"773":{"start":{"line":1994,"column":8},"end":{"line":1994,"column":28}},"774":{"start":{"line":1996,"column":8},"end":{"line":2010,"column":10}},"775":{"start":{"line":2013,"column":4},"end":{"line":2029,"column":5}},"776":{"start":{"line":2014,"column":8},"end":{"line":2028,"column":9}},"777":{"start":{"line":2022,"column":12},"end":{"line":2022,"column":37}},"778":{"start":{"line":2023,"column":12},"end":{"line":2023,"column":38}},"779":{"start":{"line":2024,"column":12},"end":{"line":2024,"column":46}},"780":{"start":{"line":2025,"column":12},"end":{"line":2025,"column":34}},"781":{"start":{"line":2027,"column":12},"end":{"line":2027,"column":41}},"782":{"start":{"line":2031,"column":4},"end":{"line":2031,"column":21}},"783":{"start":{"line":2059,"column":0},"end":{"line":2207,"column":2}},"784":{"start":{"line":2067,"column":4},"end":{"line":2076,"column":5}},"785":{"start":{"line":2069,"column":8},"end":{"line":2073,"column":9}},"786":{"start":{"line":2070,"column":12},"end":{"line":2072,"column":13}},"787":{"start":{"line":2071,"column":16},"end":{"line":2071,"column":28}},"788":{"start":{"line":2075,"column":8},"end":{"line":2075,"column":21}},"789":{"start":{"line":2085,"column":4},"end":{"line":2119,"column":5}},"790":{"start":{"line":2087,"column":8},"end":{"line":2116,"column":9}},"791":{"start":{"line":2088,"column":12},"end":{"line":2115,"column":13}},"792":{"start":{"line":2097,"column":16},"end":{"line":2105,"column":18}},"793":{"start":{"line":2107,"column":16},"end":{"line":2109,"column":17}},"794":{"start":{"line":2108,"column":20},"end":{"line":2108,"column":29}},"795":{"start":{"line":2111,"column":16},"end":{"line":2114,"column":18}},"796":{"start":{"line":2118,"column":8},"end":{"line":2118,"column":20}},"797":{"start":{"line":2121,"column":4},"end":{"line":2134,"column":6}},"798":{"start":{"line":2136,"column":4},"end":{"line":2136,"column":23}},"799":{"start":{"line":2138,"column":4},"end":{"line":2186,"column":5}},"800":{"start":{"line":2140,"column":8},"end":{"line":2140,"column":43}},"801":{"start":{"line":2146,"column":8},"end":{"line":2161,"column":9}},"802":{"start":{"line":2154,"column":12},"end":{"line":2154,"column":51}},"803":{"start":{"line":2155,"column":12},"end":{"line":2155,"column":64}},"804":{"start":{"line":2156,"column":12},"end":{"line":2156,"column":47}},"805":{"start":{"line":2158,"column":12},"end":{"line":2158,"column":54}},"806":{"start":{"line":2159,"column":12},"end":{"line":2159,"column":68}},"807":{"start":{"line":2160,"column":12},"end":{"line":2160,"column":50}},"808":{"start":{"line":2163,"column":8},"end":{"line":2163,"column":37}},"809":{"start":{"line":2165,"column":8},"end":{"line":2178,"column":10}},"810":{"start":{"line":2180,"column":8},"end":{"line":2185,"column":9}},"811":{"start":{"line":2181,"column":12},"end":{"line":2181,"column":84}},"812":{"start":{"line":2182,"column":12},"end":{"line":2184,"column":13}},"813":{"start":{"line":2183,"column":16},"end":{"line":2183,"column":42}},"814":{"start":{"line":2192,"column":4},"end":{"line":2192,"column":23}},"815":{"start":{"line":2193,"column":4},"end":{"line":2204,"column":5}},"816":{"start":{"line":2194,"column":8},"end":{"line":2194,"column":26}},"817":{"start":{"line":2195,"column":8},"end":{"line":2200,"column":9}},"818":{"start":{"line":2196,"column":12},"end":{"line":2199,"column":13}},"819":{"start":{"line":2197,"column":16},"end":{"line":2197,"column":29}},"820":{"start":{"line":2198,"column":16},"end":{"line":2198,"column":22}},"821":{"start":{"line":2201,"column":8},"end":{"line":2203,"column":9}},"822":{"start":{"line":2202,"column":12},"end":{"line":2202,"column":50}},"823":{"start":{"line":2206,"column":4},"end":{"line":2206,"column":21}},"824":{"start":{"line":2217,"column":0},"end":{"line":2251,"column":2}},"825":{"start":{"line":2219,"column":4},"end":{"line":2221,"column":5}},"826":{"start":{"line":2220,"column":8},"end":{"line":2220,"column":89}},"827":{"start":{"line":2223,"column":4},"end":{"line":2223,"column":22}},"828":{"start":{"line":2225,"column":4},"end":{"line":2225,"column":49}},"829":{"start":{"line":2227,"column":4},"end":{"line":2233,"column":5}},"830":{"start":{"line":2228,"column":8},"end":{"line":2232,"column":11}},"831":{"start":{"line":2235,"column":4},"end":{"line":2235,"column":22}},"832":{"start":{"line":2237,"column":4},"end":{"line":2237,"column":36}},"833":{"start":{"line":2239,"column":4},"end":{"line":2239,"column":36}},"834":{"start":{"line":2241,"column":4},"end":{"line":2248,"column":5}},"835":{"start":{"line":2242,"column":8},"end":{"line":2247,"column":10}},"836":{"start":{"line":2250,"column":4},"end":{"line":2250,"column":20}},"837":{"start":{"line":2261,"column":0},"end":{"line":2275,"column":2}},"838":{"start":{"line":2267,"column":4},"end":{"line":2267,"column":17}},"839":{"start":{"line":2268,"column":4},"end":{"line":2268,"column":21}},"840":{"start":{"line":2269,"column":4},"end":{"line":2269,"column":25}},"841":{"start":{"line":2271,"column":4},"end":{"line":2273,"column":5}},"842":{"start":{"line":2272,"column":8},"end":{"line":2272,"column":20}},"843":{"start":{"line":2274,"column":4},"end":{"line":2274,"column":25}},"844":{"start":{"line":2282,"column":0},"end":{"line":2282,"column":38}},"845":{"start":{"line":2283,"column":0},"end":{"line":2283,"column":35}},"846":{"start":{"line":2293,"column":0},"end":{"line":2305,"column":2}},"847":{"start":{"line":2300,"column":4},"end":{"line":2300,"column":33}},"848":{"start":{"line":2301,"column":4},"end":{"line":2301,"column":33}},"849":{"start":{"line":2302,"column":4},"end":{"line":2302,"column":17}},"850":{"start":{"line":2303,"column":4},"end":{"line":2303,"column":39}},"851":{"start":{"line":2304,"column":4},"end":{"line":2304,"column":31}},"852":{"start":{"line":2311,"column":0},"end":{"line":2319,"column":2}},"853":{"start":{"line":2312,"column":4},"end":{"line":2318,"column":5}},"854":{"start":{"line":2325,"column":0},"end":{"line":2328,"column":2}},"855":{"start":{"line":2327,"column":4},"end":{"line":2327,"column":30}},"856":{"start":{"line":2330,"column":0},"end":{"line":2335,"column":2}},"857":{"start":{"line":2334,"column":4},"end":{"line":2334,"column":41}},"858":{"start":{"line":2342,"column":0},"end":{"line":2345,"column":2}},"859":{"start":{"line":2344,"column":4},"end":{"line":2344,"column":30}},"860":{"start":{"line":2347,"column":0},"end":{"line":2352,"column":2}},"861":{"start":{"line":2351,"column":4},"end":{"line":2351,"column":42}},"862":{"start":{"line":2374,"column":0},"end":{"line":2409,"column":2}},"863":{"start":{"line":2392,"column":4},"end":{"line":2392,"column":57}},"864":{"start":{"line":2393,"column":4},"end":{"line":2393,"column":57}},"865":{"start":{"line":2394,"column":4},"end":{"line":2394,"column":71}},"866":{"start":{"line":2395,"column":4},"end":{"line":2395,"column":71}},"867":{"start":{"line":2396,"column":4},"end":{"line":2396,"column":54}},"868":{"start":{"line":2397,"column":4},"end":{"line":2397,"column":66}},"869":{"start":{"line":2398,"column":4},"end":{"line":2398,"column":84}},"870":{"start":{"line":2399,"column":4},"end":{"line":2399,"column":87}},"871":{"start":{"line":2400,"column":4},"end":{"line":2400,"column":75}},"872":{"start":{"line":2401,"column":4},"end":{"line":2401,"column":89}},"873":{"start":{"line":2402,"column":4},"end":{"line":2402,"column":86}},"874":{"start":{"line":2403,"column":4},"end":{"line":2403,"column":102}},"875":{"start":{"line":2404,"column":4},"end":{"line":2404,"column":99}},"876":{"start":{"line":2405,"column":4},"end":{"line":2405,"column":85}},"877":{"start":{"line":2406,"column":4},"end":{"line":2406,"column":60}},"878":{"start":{"line":2408,"column":4},"end":{"line":2408,"column":60}},"879":{"start":{"line":2415,"column":0},"end":{"line":2444,"column":2}},"880":{"start":{"line":2417,"column":4},"end":{"line":2417,"column":25}},"881":{"start":{"line":2420,"column":4},"end":{"line":2441,"column":5}},"882":{"start":{"line":2421,"column":8},"end":{"line":2439,"column":10}},"883":{"start":{"line":2443,"column":4},"end":{"line":2443,"column":21}},"884":{"start":{"line":2461,"column":0},"end":{"line":2516,"column":2}},"885":{"start":{"line":2474,"column":4},"end":{"line":2474,"column":17}},"886":{"start":{"line":2475,"column":4},"end":{"line":2475,"column":21}},"887":{"start":{"line":2476,"column":4},"end":{"line":2476,"column":21}},"888":{"start":{"line":2477,"column":4},"end":{"line":2479,"column":5}},"889":{"start":{"line":2478,"column":8},"end":{"line":2478,"column":30}},"890":{"start":{"line":2480,"column":4},"end":{"line":2480,"column":25}},"891":{"start":{"line":2482,"column":4},"end":{"line":2484,"column":5}},"892":{"start":{"line":2483,"column":8},"end":{"line":2483,"column":46}},"893":{"start":{"line":2485,"column":4},"end":{"line":2485,"column":33}},"894":{"start":{"line":2487,"column":4},"end":{"line":2489,"column":5}},"895":{"start":{"line":2488,"column":8},"end":{"line":2488,"column":49}},"896":{"start":{"line":2490,"column":4},"end":{"line":2490,"column":29}},"897":{"start":{"line":2492,"column":4},"end":{"line":2494,"column":5}},"898":{"start":{"line":2493,"column":8},"end":{"line":2493,"column":49}},"899":{"start":{"line":2495,"column":4},"end":{"line":2495,"column":29}},"900":{"start":{"line":2497,"column":4},"end":{"line":2499,"column":5}},"901":{"start":{"line":2498,"column":8},"end":{"line":2498,"column":46}},"902":{"start":{"line":2500,"column":4},"end":{"line":2500,"column":23}},"903":{"start":{"line":2502,"column":4},"end":{"line":2504,"column":5}},"904":{"start":{"line":2503,"column":8},"end":{"line":2503,"column":29}},"905":{"start":{"line":2505,"column":4},"end":{"line":2505,"column":39}},"906":{"start":{"line":2507,"column":4},"end":{"line":2509,"column":5}},"907":{"start":{"line":2508,"column":8},"end":{"line":2508,"column":20}},"908":{"start":{"line":2510,"column":4},"end":{"line":2510,"column":25}},"909":{"start":{"line":2512,"column":4},"end":{"line":2514,"column":5}},"910":{"start":{"line":2513,"column":8},"end":{"line":2513,"column":21}},"911":{"start":{"line":2515,"column":4},"end":{"line":2515,"column":27}},"912":{"start":{"line":2523,"column":0},"end":{"line":2720,"column":2}},"913":{"start":{"line":2528,"column":4},"end":{"line":2531,"column":5}},"914":{"start":{"line":2529,"column":8},"end":{"line":2529,"column":68}},"915":{"start":{"line":2530,"column":8},"end":{"line":2530,"column":60}},"916":{"start":{"line":2533,"column":4},"end":{"line":2533,"column":35}},"917":{"start":{"line":2534,"column":4},"end":{"line":2537,"column":6}},"918":{"start":{"line":2539,"column":4},"end":{"line":2717,"column":17}},"919":{"start":{"line":2540,"column":8},"end":{"line":2716,"column":9}},"920":{"start":{"line":2541,"column":12},"end":{"line":2715,"column":13}},"921":{"start":{"line":2543,"column":16},"end":{"line":2543,"column":60}},"922":{"start":{"line":2545,"column":16},"end":{"line":2547,"column":17}},"923":{"start":{"line":2546,"column":20},"end":{"line":2546,"column":83}},"924":{"start":{"line":2549,"column":16},"end":{"line":2549,"column":46}},"925":{"start":{"line":2551,"column":16},"end":{"line":2551,"column":36}},"926":{"start":{"line":2553,"column":16},"end":{"line":2628,"column":17}},"927":{"start":{"line":2555,"column":20},"end":{"line":2627,"column":21}},"928":{"start":{"line":2557,"column":24},"end":{"line":2557,"column":55}},"929":{"start":{"line":2559,"column":24},"end":{"line":2566,"column":26}},"930":{"start":{"line":2568,"column":24},"end":{"line":2568,"column":42}},"931":{"start":{"line":2570,"column":24},"end":{"line":2624,"column":25}},"932":{"start":{"line":2572,"column":28},"end":{"line":2572,"column":58}},"933":{"start":{"line":2574,"column":28},"end":{"line":2574,"column":62}},"934":{"start":{"line":2576,"column":28},"end":{"line":2580,"column":30}},"935":{"start":{"line":2582,"column":28},"end":{"line":2582,"column":54}},"936":{"start":{"line":2584,"column":28},"end":{"line":2590,"column":30}},"937":{"start":{"line":2592,"column":28},"end":{"line":2592,"column":59}},"938":{"start":{"line":2594,"column":28},"end":{"line":2594,"column":46}},"939":{"start":{"line":2596,"column":28},"end":{"line":2607,"column":29}},"940":{"start":{"line":2598,"column":32},"end":{"line":2598,"column":53}},"941":{"start":{"line":2601,"column":32},"end":{"line":2604,"column":34}},"942":{"start":{"line":2606,"column":32},"end":{"line":2606,"column":54}},"943":{"start":{"line":2609,"column":28},"end":{"line":2621,"column":30}},"944":{"start":{"line":2623,"column":28},"end":{"line":2623,"column":51}},"945":{"start":{"line":2626,"column":24},"end":{"line":2626,"column":51}},"946":{"start":{"line":2630,"column":16},"end":{"line":2630,"column":34}},"947":{"start":{"line":2632,"column":16},"end":{"line":2681,"column":17}},"948":{"start":{"line":2634,"column":20},"end":{"line":2634,"column":48}},"949":{"start":{"line":2636,"column":20},"end":{"line":2678,"column":22}},"950":{"start":{"line":2680,"column":20},"end":{"line":2680,"column":43}},"951":{"start":{"line":2683,"column":16},"end":{"line":2712,"column":18}},"952":{"start":{"line":2714,"column":16},"end":{"line":2714,"column":62}},"953":{"start":{"line":2719,"column":4},"end":{"line":2719,"column":15}},"954":{"start":{"line":2729,"column":0},"end":{"line":3017,"column":2}},"955":{"start":{"line":2731,"column":4},"end":{"line":2731,"column":54}},"956":{"start":{"line":2733,"column":4},"end":{"line":2733,"column":34}},"957":{"start":{"line":2735,"column":4},"end":{"line":2735,"column":19}},"958":{"start":{"line":2737,"column":4},"end":{"line":2920,"column":5}},"959":{"start":{"line":2739,"column":8},"end":{"line":2739,"column":42}},"960":{"start":{"line":2741,"column":8},"end":{"line":2741,"column":49}},"961":{"start":{"line":2743,"column":8},"end":{"line":2743,"column":49}},"962":{"start":{"line":2745,"column":8},"end":{"line":2745,"column":37}},"963":{"start":{"line":2747,"column":8},"end":{"line":2747,"column":31}},"964":{"start":{"line":2749,"column":8},"end":{"line":2749,"column":47}},"965":{"start":{"line":2751,"column":8},"end":{"line":2751,"column":39}},"966":{"start":{"line":2756,"column":8},"end":{"line":2764,"column":9}},"967":{"start":{"line":2757,"column":12},"end":{"line":2763,"column":13}},"968":{"start":{"line":2769,"column":8},"end":{"line":2831,"column":9}},"969":{"start":{"line":2771,"column":12},"end":{"line":2786,"column":14}},"970":{"start":{"line":2788,"column":12},"end":{"line":2804,"column":14}},"971":{"start":{"line":2806,"column":12},"end":{"line":2810,"column":14}},"972":{"start":{"line":2812,"column":12},"end":{"line":2828,"column":14}},"973":{"start":{"line":2830,"column":12},"end":{"line":2830,"column":38}},"974":{"start":{"line":2833,"column":8},"end":{"line":2833,"column":36}},"975":{"start":{"line":2838,"column":8},"end":{"line":2861,"column":9}},"976":{"start":{"line":2840,"column":12},"end":{"line":2840,"column":58}},"977":{"start":{"line":2842,"column":12},"end":{"line":2842,"column":44}},"978":{"start":{"line":2844,"column":12},"end":{"line":2860,"column":13}},"979":{"start":{"line":2845,"column":16},"end":{"line":2845,"column":53}},"980":{"start":{"line":2846,"column":16},"end":{"line":2859,"column":18}},"981":{"start":{"line":2867,"column":8},"end":{"line":2870,"column":9}},"982":{"start":{"line":2868,"column":12},"end":{"line":2868,"column":42}},"983":{"start":{"line":2869,"column":12},"end":{"line":2869,"column":44}},"984":{"start":{"line":2872,"column":8},"end":{"line":2872,"column":38}},"985":{"start":{"line":2877,"column":8},"end":{"line":2879,"column":9}},"986":{"start":{"line":2878,"column":12},"end":{"line":2878,"column":79}},"987":{"start":{"line":2881,"column":8},"end":{"line":2917,"column":11}},"988":{"start":{"line":2883,"column":16},"end":{"line":2913,"column":18}},"989":{"start":{"line":2885,"column":20},"end":{"line":2885,"column":74}},"990":{"start":{"line":2890,"column":20},"end":{"line":2890,"column":48}},"991":{"start":{"line":2892,"column":20},"end":{"line":2892,"column":83}},"992":{"start":{"line":2893,"column":20},"end":{"line":2893,"column":47}},"993":{"start":{"line":2895,"column":20},"end":{"line":2895,"column":59}},"994":{"start":{"line":2896,"column":20},"end":{"line":2896,"column":59}},"995":{"start":{"line":2897,"column":20},"end":{"line":2897,"column":59}},"996":{"start":{"line":2899,"column":20},"end":{"line":2899,"column":59}},"997":{"start":{"line":2900,"column":20},"end":{"line":2900,"column":59}},"998":{"start":{"line":2901,"column":20},"end":{"line":2901,"column":59}},"999":{"start":{"line":2903,"column":20},"end":{"line":2903,"column":53}},"1000":{"start":{"line":2904,"column":20},"end":{"line":2904,"column":53}},"1001":{"start":{"line":2905,"column":20},"end":{"line":2905,"column":53}},"1002":{"start":{"line":2907,"column":20},"end":{"line":2907,"column":63}},"1003":{"start":{"line":2908,"column":20},"end":{"line":2908,"column":63}},"1004":{"start":{"line":2909,"column":20},"end":{"line":2909,"column":63}},"1005":{"start":{"line":2910,"column":20},"end":{"line":2910,"column":63}},"1006":{"start":{"line":2912,"column":20},"end":{"line":2912,"column":37}},"1007":{"start":{"line":2916,"column":12},"end":{"line":2916,"column":31}},"1008":{"start":{"line":2919,"column":8},"end":{"line":2919,"column":27}},"1009":{"start":{"line":2922,"column":4},"end":{"line":3016,"column":7}},"1010":{"start":{"line":2923,"column":8},"end":{"line":2923,"column":46}},"1011":{"start":{"line":2924,"column":8},"end":{"line":3013,"column":9}},"1012":{"start":{"line":2926,"column":12},"end":{"line":2926,"column":33}},"1013":{"start":{"line":2928,"column":12},"end":{"line":2974,"column":13}},"1014":{"start":{"line":2930,"column":16},"end":{"line":2930,"column":60}},"1015":{"start":{"line":2932,"column":16},"end":{"line":2932,"column":33}},"1016":{"start":{"line":2934,"column":16},"end":{"line":2936,"column":17}},"1017":{"start":{"line":2935,"column":20},"end":{"line":2935,"column":100}},"1018":{"start":{"line":2938,"column":16},"end":{"line":2940,"column":17}},"1019":{"start":{"line":2939,"column":20},"end":{"line":2939,"column":104}},"1020":{"start":{"line":2942,"column":16},"end":{"line":2946,"column":17}},"1021":{"start":{"line":2943,"column":20},"end":{"line":2943,"column":98}},"1022":{"start":{"line":2944,"column":20},"end":{"line":2944,"column":59}},"1023":{"start":{"line":2945,"column":20},"end":{"line":2945,"column":53}},"1024":{"start":{"line":2948,"column":16},"end":{"line":2954,"column":17}},"1025":{"start":{"line":2949,"column":20},"end":{"line":2949,"column":97}},"1026":{"start":{"line":2950,"column":20},"end":{"line":2950,"column":59}},"1027":{"start":{"line":2951,"column":20},"end":{"line":2951,"column":53}},"1028":{"start":{"line":2952,"column":20},"end":{"line":2952,"column":59}},"1029":{"start":{"line":2953,"column":20},"end":{"line":2953,"column":53}},"1030":{"start":{"line":2956,"column":16},"end":{"line":2956,"column":59}},"1031":{"start":{"line":2957,"column":16},"end":{"line":2957,"column":59}},"1032":{"start":{"line":2958,"column":16},"end":{"line":2958,"column":59}},"1033":{"start":{"line":2960,"column":16},"end":{"line":2960,"column":59}},"1034":{"start":{"line":2961,"column":16},"end":{"line":2961,"column":59}},"1035":{"start":{"line":2962,"column":16},"end":{"line":2962,"column":59}},"1036":{"start":{"line":2968,"column":16},"end":{"line":2973,"column":17}},"1037":{"start":{"line":2969,"column":20},"end":{"line":2969,"column":114}},"1038":{"start":{"line":2971,"column":20},"end":{"line":2971,"column":51}},"1039":{"start":{"line":2972,"column":20},"end":{"line":2972,"column":44}},"1040":{"start":{"line":2976,"column":12},"end":{"line":2976,"column":52}},"1041":{"start":{"line":2978,"column":12},"end":{"line":2978,"column":48}},"1042":{"start":{"line":2980,"column":12},"end":{"line":2980,"column":60}},"1043":{"start":{"line":2981,"column":12},"end":{"line":2981,"column":60}},"1044":{"start":{"line":2982,"column":12},"end":{"line":2982,"column":60}},"1045":{"start":{"line":2984,"column":12},"end":{"line":2984,"column":60}},"1046":{"start":{"line":2985,"column":12},"end":{"line":2985,"column":60}},"1047":{"start":{"line":2986,"column":12},"end":{"line":2986,"column":60}},"1048":{"start":{"line":2988,"column":12},"end":{"line":2988,"column":54}},"1049":{"start":{"line":2989,"column":12},"end":{"line":2989,"column":54}},"1050":{"start":{"line":2990,"column":12},"end":{"line":2990,"column":54}},"1051":{"start":{"line":2992,"column":12},"end":{"line":2992,"column":64}},"1052":{"start":{"line":2993,"column":12},"end":{"line":2993,"column":64}},"1053":{"start":{"line":2994,"column":12},"end":{"line":2994,"column":64}},"1054":{"start":{"line":2995,"column":12},"end":{"line":2995,"column":64}},"1055":{"start":{"line":2997,"column":12},"end":{"line":2999,"column":13}},"1056":{"start":{"line":2998,"column":16},"end":{"line":2998,"column":47}},"1057":{"start":{"line":3001,"column":12},"end":{"line":3003,"column":13}},"1058":{"start":{"line":3002,"column":16},"end":{"line":3002,"column":47}},"1059":{"start":{"line":3005,"column":12},"end":{"line":3012,"column":14}},"1060":{"start":{"line":3015,"column":8},"end":{"line":3015,"column":27}},"1061":{"start":{"line":3022,"column":0},"end":{"line":3029,"column":2}},"1062":{"start":{"line":3026,"column":4},"end":{"line":3026,"column":35}},"1063":{"start":{"line":3027,"column":4},"end":{"line":3027,"column":31}},"1064":{"start":{"line":3028,"column":4},"end":{"line":3028,"column":49}},"1065":{"start":{"line":3031,"column":0},"end":{"line":3031,"column":48}},"1066":{"start":{"line":3032,"column":0},"end":{"line":3032,"column":48}},"1067":{"start":{"line":3033,"column":0},"end":{"line":3033,"column":48}},"1068":{"start":{"line":3034,"column":0},"end":{"line":3034,"column":48}},"1069":{"start":{"line":3037,"column":0},"end":{"line":3054,"column":2}},"1070":{"start":{"line":3038,"column":4},"end":{"line":3053,"column":5}},"1071":{"start":{"line":3039,"column":8},"end":{"line":3052,"column":9}},"1072":{"start":{"line":3040,"column":12},"end":{"line":3046,"column":14}},"1073":{"start":{"line":3047,"column":12},"end":{"line":3047,"column":42}},"1074":{"start":{"line":3048,"column":12},"end":{"line":3048,"column":45}},"1075":{"start":{"line":3049,"column":12},"end":{"line":3049,"column":43}},"1076":{"start":{"line":3050,"column":12},"end":{"line":3050,"column":58}},"1077":{"start":{"line":3051,"column":12},"end":{"line":3051,"column":42}},"1078":{"start":{"line":3068,"column":0},"end":{"line":3123,"column":2}},"1079":{"start":{"line":3078,"column":4},"end":{"line":3078,"column":17}},"1080":{"start":{"line":3080,"column":4},"end":{"line":3080,"column":23}},"1081":{"start":{"line":3086,"column":4},"end":{"line":3088,"column":5}},"1082":{"start":{"line":3087,"column":8},"end":{"line":3087,"column":26}},"1083":{"start":{"line":3089,"column":4},"end":{"line":3089,"column":37}},"1084":{"start":{"line":3095,"column":4},"end":{"line":3097,"column":5}},"1085":{"start":{"line":3096,"column":8},"end":{"line":3096,"column":33}},"1086":{"start":{"line":3098,"column":4},"end":{"line":3098,"column":45}},"1087":{"start":{"line":3100,"column":4},"end":{"line":3102,"column":5}},"1088":{"start":{"line":3101,"column":8},"end":{"line":3101,"column":112}},"1089":{"start":{"line":3104,"column":4},"end":{"line":3106,"column":5}},"1090":{"start":{"line":3105,"column":8},"end":{"line":3105,"column":29}},"1091":{"start":{"line":3107,"column":4},"end":{"line":3107,"column":45}},"1092":{"start":{"line":3109,"column":4},"end":{"line":3111,"column":5}},"1093":{"start":{"line":3110,"column":8},"end":{"line":3110,"column":30}},"1094":{"start":{"line":3112,"column":4},"end":{"line":3112,"column":47}},"1095":{"start":{"line":3114,"column":4},"end":{"line":3116,"column":5}},"1096":{"start":{"line":3115,"column":8},"end":{"line":3115,"column":26}},"1097":{"start":{"line":3117,"column":4},"end":{"line":3117,"column":37}},"1098":{"start":{"line":3119,"column":4},"end":{"line":3121,"column":5}},"1099":{"start":{"line":3120,"column":8},"end":{"line":3120,"column":25}},"1100":{"start":{"line":3122,"column":4},"end":{"line":3122,"column":35}},"1101":{"start":{"line":3126,"column":0},"end":{"line":3131,"column":2}},"1102":{"start":{"line":3129,"column":4},"end":{"line":3129,"column":19}},"1103":{"start":{"line":3130,"column":4},"end":{"line":3130,"column":31}},"1104":{"start":{"line":3133,"column":0},"end":{"line":3171,"column":2}},"1105":{"start":{"line":3136,"column":4},"end":{"line":3136,"column":41}},"1106":{"start":{"line":3137,"column":4},"end":{"line":3137,"column":23}},"1107":{"start":{"line":3138,"column":4},"end":{"line":3138,"column":24}},"1108":{"start":{"line":3139,"column":4},"end":{"line":3139,"column":19}},"1109":{"start":{"line":3140,"column":4},"end":{"line":3140,"column":35}},"1110":{"start":{"line":3141,"column":4},"end":{"line":3141,"column":28}},"1111":{"start":{"line":3143,"column":4},"end":{"line":3143,"column":50}},"1112":{"start":{"line":3146,"column":4},"end":{"line":3146,"column":75}},"1113":{"start":{"line":3147,"column":4},"end":{"line":3147,"column":75}},"1114":{"start":{"line":3148,"column":4},"end":{"line":3148,"column":75}},"1115":{"start":{"line":3149,"column":4},"end":{"line":3149,"column":75}},"1116":{"start":{"line":3150,"column":4},"end":{"line":3150,"column":75}},"1117":{"start":{"line":3151,"column":4},"end":{"line":3151,"column":75}},"1118":{"start":{"line":3154,"column":4},"end":{"line":3156,"column":5}},"1119":{"start":{"line":3155,"column":8},"end":{"line":3155,"column":84}},"1120":{"start":{"line":3159,"column":4},"end":{"line":3159,"column":108}},"1121":{"start":{"line":3160,"column":4},"end":{"line":3160,"column":67}},"1122":{"start":{"line":3161,"column":4},"end":{"line":3161,"column":30}},"1123":{"start":{"line":3166,"column":4},"end":{"line":3170,"column":7}},"1124":{"start":{"line":3173,"column":0},"end":{"line":3190,"column":2}},"1125":{"start":{"line":3177,"column":4},"end":{"line":3177,"column":115}},"1126":{"start":{"line":3179,"column":4},"end":{"line":3179,"column":38}},"1127":{"start":{"line":3181,"column":4},"end":{"line":3181,"column":35}},"1128":{"start":{"line":3183,"column":4},"end":{"line":3183,"column":30}},"1129":{"start":{"line":3185,"column":4},"end":{"line":3185,"column":50}},"1130":{"start":{"line":3187,"column":4},"end":{"line":3187,"column":29}},"1131":{"start":{"line":3189,"column":4},"end":{"line":3189,"column":46}},"1132":{"start":{"line":3201,"column":0},"end":{"line":3222,"column":2}},"1133":{"start":{"line":3208,"column":4},"end":{"line":3208,"column":17}},"1134":{"start":{"line":3209,"column":4},"end":{"line":3217,"column":5}},"1135":{"start":{"line":3210,"column":8},"end":{"line":3216,"column":9}},"1136":{"start":{"line":3211,"column":12},"end":{"line":3211,"column":34}},"1137":{"start":{"line":3212,"column":15},"end":{"line":3216,"column":9}},"1138":{"start":{"line":3213,"column":12},"end":{"line":3213,"column":31}},"1139":{"start":{"line":3215,"column":12},"end":{"line":3215,"column":36}},"1140":{"start":{"line":3218,"column":4},"end":{"line":3218,"column":21}},"1141":{"start":{"line":3219,"column":4},"end":{"line":3219,"column":33}},"1142":{"start":{"line":3220,"column":4},"end":{"line":3220,"column":33}},"1143":{"start":{"line":3221,"column":4},"end":{"line":3221,"column":31}},"1144":{"start":{"line":3228,"column":0},"end":{"line":3228,"column":38}},"1145":{"start":{"line":3229,"column":0},"end":{"line":3229,"column":35}},"1146":{"start":{"line":3255,"column":0},"end":{"line":3365,"column":2}},"1147":{"start":{"line":3277,"column":4},"end":{"line":3277,"column":17}},"1148":{"start":{"line":3278,"column":4},"end":{"line":3278,"column":21}},"1149":{"start":{"line":3279,"column":4},"end":{"line":3279,"column":23}},"1150":{"start":{"line":3281,"column":4},"end":{"line":3283,"column":5}},"1151":{"start":{"line":3282,"column":8},"end":{"line":3282,"column":56}},"1152":{"start":{"line":3284,"column":4},"end":{"line":3284,"column":23}},"1153":{"start":{"line":3286,"column":4},"end":{"line":3288,"column":5}},"1154":{"start":{"line":3287,"column":8},"end":{"line":3287,"column":56}},"1155":{"start":{"line":3289,"column":4},"end":{"line":3289,"column":23}},"1156":{"start":{"line":3291,"column":4},"end":{"line":3293,"column":5}},"1157":{"start":{"line":3292,"column":8},"end":{"line":3292,"column":46}},"1158":{"start":{"line":3294,"column":4},"end":{"line":3294,"column":25}},"1159":{"start":{"line":3296,"column":4},"end":{"line":3298,"column":5}},"1160":{"start":{"line":3297,"column":8},"end":{"line":3297,"column":20}},"1161":{"start":{"line":3299,"column":4},"end":{"line":3299,"column":21}},"1162":{"start":{"line":3301,"column":4},"end":{"line":3303,"column":5}},"1163":{"start":{"line":3302,"column":8},"end":{"line":3302,"column":53}},"1164":{"start":{"line":3304,"column":4},"end":{"line":3304,"column":25}},"1165":{"start":{"line":3306,"column":4},"end":{"line":3308,"column":5}},"1166":{"start":{"line":3307,"column":8},"end":{"line":3307,"column":53}},"1167":{"start":{"line":3309,"column":4},"end":{"line":3309,"column":27}},"1168":{"start":{"line":3311,"column":4},"end":{"line":3313,"column":5}},"1169":{"start":{"line":3312,"column":8},"end":{"line":3312,"column":58}},"1170":{"start":{"line":3314,"column":4},"end":{"line":3314,"column":31}},"1171":{"start":{"line":3316,"column":4},"end":{"line":3318,"column":5}},"1172":{"start":{"line":3317,"column":8},"end":{"line":3317,"column":72}},"1173":{"start":{"line":3319,"column":4},"end":{"line":3319,"column":31}},"1174":{"start":{"line":3321,"column":4},"end":{"line":3323,"column":5}},"1175":{"start":{"line":3322,"column":8},"end":{"line":3322,"column":60}},"1176":{"start":{"line":3324,"column":4},"end":{"line":3324,"column":35}},"1177":{"start":{"line":3326,"column":4},"end":{"line":3328,"column":5}},"1178":{"start":{"line":3327,"column":8},"end":{"line":3327,"column":23}},"1179":{"start":{"line":3329,"column":4},"end":{"line":3329,"column":33}},"1180":{"start":{"line":3331,"column":4},"end":{"line":3333,"column":5}},"1181":{"start":{"line":3332,"column":8},"end":{"line":3332,"column":46}},"1182":{"start":{"line":3334,"column":4},"end":{"line":3334,"column":25}},"1183":{"start":{"line":3336,"column":4},"end":{"line":3338,"column":5}},"1184":{"start":{"line":3337,"column":8},"end":{"line":3337,"column":31}},"1185":{"start":{"line":3339,"column":4},"end":{"line":3339,"column":43}},"1186":{"start":{"line":3341,"column":4},"end":{"line":3343,"column":5}},"1187":{"start":{"line":3342,"column":8},"end":{"line":3342,"column":21}},"1188":{"start":{"line":3344,"column":4},"end":{"line":3344,"column":23}},"1189":{"start":{"line":3346,"column":4},"end":{"line":3348,"column":5}},"1190":{"start":{"line":3347,"column":8},"end":{"line":3347,"column":21}},"1191":{"start":{"line":3349,"column":4},"end":{"line":3349,"column":27}},"1192":{"start":{"line":3351,"column":4},"end":{"line":3353,"column":5}},"1193":{"start":{"line":3352,"column":8},"end":{"line":3352,"column":28}},"1194":{"start":{"line":3354,"column":4},"end":{"line":3354,"column":43}},"1195":{"start":{"line":3356,"column":4},"end":{"line":3358,"column":5}},"1196":{"start":{"line":3357,"column":8},"end":{"line":3357,"column":33}},"1197":{"start":{"line":3359,"column":4},"end":{"line":3359,"column":45}},"1198":{"start":{"line":3361,"column":4},"end":{"line":3363,"column":5}},"1199":{"start":{"line":3362,"column":8},"end":{"line":3362,"column":59}},"1200":{"start":{"line":3364,"column":4},"end":{"line":3364,"column":29}},"1201":{"start":{"line":3371,"column":0},"end":{"line":3371,"column":44}},"1202":{"start":{"line":3372,"column":0},"end":{"line":3372,"column":42}},"1203":{"start":{"line":3373,"column":0},"end":{"line":3373,"column":43}},"1204":{"start":{"line":3374,"column":0},"end":{"line":3374,"column":48}},"1205":{"start":{"line":3375,"column":0},"end":{"line":3375,"column":54}},"1206":{"start":{"line":3376,"column":0},"end":{"line":3376,"column":44}},"1207":{"start":{"line":3382,"column":0},"end":{"line":3382,"column":41}},"1208":{"start":{"line":3383,"column":0},"end":{"line":3383,"column":54}},"1209":{"start":{"line":3384,"column":0},"end":{"line":3384,"column":54}},"1210":{"start":{"line":3385,"column":0},"end":{"line":3385,"column":66}},"1211":{"start":{"line":3386,"column":0},"end":{"line":3386,"column":66}},"1212":{"start":{"line":3387,"column":0},"end":{"line":3387,"column":59}},"1213":{"start":{"line":3388,"column":0},"end":{"line":3388,"column":57}},"1214":{"start":{"line":3389,"column":0},"end":{"line":3389,"column":57}},"1215":{"start":{"line":3395,"column":0},"end":{"line":3395,"column":47}},"1216":{"start":{"line":3396,"column":0},"end":{"line":3396,"column":54}},"1217":{"start":{"line":3397,"column":0},"end":{"line":3397,"column":56}},"1218":{"start":{"line":3403,"column":0},"end":{"line":3403,"column":46}},"1219":{"start":{"line":3404,"column":0},"end":{"line":3404,"column":61}},"1220":{"start":{"line":3405,"column":0},"end":{"line":3405,"column":60}},"1221":{"start":{"line":3406,"column":0},"end":{"line":3406,"column":45}},"1222":{"start":{"line":3407,"column":0},"end":{"line":3407,"column":60}},"1223":{"start":{"line":3408,"column":0},"end":{"line":3408,"column":59}},"1224":{"start":{"line":3414,"column":0},"end":{"line":3414,"column":45}},"1225":{"start":{"line":3415,"column":0},"end":{"line":3415,"column":36}},"1226":{"start":{"line":3416,"column":0},"end":{"line":3416,"column":37}},"1227":{"start":{"line":3417,"column":0},"end":{"line":3417,"column":46}},"1228":{"start":{"line":3418,"column":0},"end":{"line":3418,"column":35}},"1229":{"start":{"line":3419,"column":0},"end":{"line":3419,"column":44}},"1230":{"start":{"line":3420,"column":0},"end":{"line":3420,"column":37}},"1231":{"start":{"line":3421,"column":0},"end":{"line":3421,"column":42}},"1232":{"start":{"line":3427,"column":0},"end":{"line":3427,"column":47}},"1233":{"start":{"line":3428,"column":0},"end":{"line":3428,"column":45}},"1234":{"start":{"line":3429,"column":0},"end":{"line":3429,"column":46}},"1235":{"start":{"line":3430,"column":0},"end":{"line":3430,"column":45}},"1236":{"start":{"line":3431,"column":0},"end":{"line":3431,"column":48}},"1237":{"start":{"line":3432,"column":0},"end":{"line":3432,"column":46}},"1238":{"start":{"line":3433,"column":0},"end":{"line":3433,"column":47}},"1239":{"start":{"line":3434,"column":0},"end":{"line":3434,"column":45}},"1240":{"start":{"line":3445,"column":0},"end":{"line":3515,"column":2}},"1241":{"start":{"line":3447,"column":4},"end":{"line":3447,"column":27}},"1242":{"start":{"line":3449,"column":4},"end":{"line":3449,"column":25}},"1243":{"start":{"line":3451,"column":4},"end":{"line":3456,"column":5}},"1244":{"start":{"line":3455,"column":8},"end":{"line":3455,"column":98}},"1245":{"start":{"line":3458,"column":4},"end":{"line":3512,"column":5}},"1246":{"start":{"line":3460,"column":8},"end":{"line":3460,"column":44}},"1247":{"start":{"line":3462,"column":8},"end":{"line":3508,"column":10}},"1248":{"start":{"line":3468,"column":16},"end":{"line":3468,"column":62}},"1249":{"start":{"line":3469,"column":16},"end":{"line":3469,"column":79}},"1250":{"start":{"line":3470,"column":16},"end":{"line":3470,"column":91}},"1251":{"start":{"line":3471,"column":16},"end":{"line":3471,"column":87}},"1252":{"start":{"line":3472,"column":16},"end":{"line":3472,"column":81}},"1253":{"start":{"line":3476,"column":16},"end":{"line":3476,"column":101}},"1254":{"start":{"line":3477,"column":16},"end":{"line":3477,"column":89}},"1255":{"start":{"line":3478,"column":16},"end":{"line":3478,"column":89}},"1256":{"start":{"line":3479,"column":16},"end":{"line":3479,"column":85}},"1257":{"start":{"line":3480,"column":16},"end":{"line":3480,"column":85}},"1258":{"start":{"line":3481,"column":16},"end":{"line":3484,"column":18}},"1259":{"start":{"line":3485,"column":16},"end":{"line":3485,"column":103}},"1260":{"start":{"line":3486,"column":16},"end":{"line":3486,"column":93}},"1261":{"start":{"line":3487,"column":16},"end":{"line":3487,"column":81}},"1262":{"start":{"line":3488,"column":16},"end":{"line":3488,"column":81}},"1263":{"start":{"line":3489,"column":16},"end":{"line":3489,"column":101}},"1264":{"start":{"line":3490,"column":16},"end":{"line":3490,"column":49}},"1265":{"start":{"line":3491,"column":16},"end":{"line":3491,"column":32}},"1266":{"start":{"line":3497,"column":16},"end":{"line":3499,"column":17}},"1267":{"start":{"line":3498,"column":20},"end":{"line":3498,"column":116}},"1268":{"start":{"line":3505,"column":16},"end":{"line":3505,"column":95}},"1269":{"start":{"line":3506,"column":16},"end":{"line":3506,"column":32}},"1270":{"start":{"line":3511,"column":8},"end":{"line":3511,"column":24}},"1271":{"start":{"line":3514,"column":4},"end":{"line":3514,"column":21}},"1272":{"start":{"line":3525,"column":0},"end":{"line":3599,"column":2}},"1273":{"start":{"line":3527,"column":4},"end":{"line":3527,"column":25}},"1274":{"start":{"line":3529,"column":4},"end":{"line":3596,"column":5}},"1275":{"start":{"line":3531,"column":8},"end":{"line":3531,"column":34}},"1276":{"start":{"line":3533,"column":8},"end":{"line":3595,"column":9}},"1277":{"start":{"line":3535,"column":12},"end":{"line":3535,"column":59}},"1278":{"start":{"line":3537,"column":12},"end":{"line":3594,"column":13}},"1279":{"start":{"line":3543,"column":16},"end":{"line":3543,"column":36}},"1280":{"start":{"line":3545,"column":16},"end":{"line":3547,"column":17}},"1281":{"start":{"line":3546,"column":20},"end":{"line":3546,"column":42}},"1282":{"start":{"line":3549,"column":16},"end":{"line":3551,"column":17}},"1283":{"start":{"line":3550,"column":20},"end":{"line":3550,"column":39}},"1284":{"start":{"line":3553,"column":16},"end":{"line":3555,"column":17}},"1285":{"start":{"line":3554,"column":20},"end":{"line":3554,"column":41}},"1286":{"start":{"line":3557,"column":16},"end":{"line":3559,"column":17}},"1287":{"start":{"line":3558,"column":20},"end":{"line":3558,"column":49}},"1288":{"start":{"line":3561,"column":16},"end":{"line":3563,"column":17}},"1289":{"start":{"line":3562,"column":20},"end":{"line":3562,"column":45}},"1290":{"start":{"line":3565,"column":16},"end":{"line":3567,"column":17}},"1291":{"start":{"line":3566,"column":20},"end":{"line":3566,"column":40}},"1292":{"start":{"line":3569,"column":16},"end":{"line":3571,"column":17}},"1293":{"start":{"line":3570,"column":20},"end":{"line":3570,"column":42}},"1294":{"start":{"line":3573,"column":16},"end":{"line":3575,"column":17}},"1295":{"start":{"line":3574,"column":20},"end":{"line":3574,"column":45}},"1296":{"start":{"line":3577,"column":16},"end":{"line":3579,"column":17}},"1297":{"start":{"line":3578,"column":20},"end":{"line":3578,"column":37}},"1298":{"start":{"line":3581,"column":16},"end":{"line":3583,"column":17}},"1299":{"start":{"line":3582,"column":20},"end":{"line":3582,"column":46}},"1300":{"start":{"line":3585,"column":16},"end":{"line":3587,"column":17}},"1301":{"start":{"line":3586,"column":20},"end":{"line":3586,"column":46}},"1302":{"start":{"line":3589,"column":16},"end":{"line":3591,"column":17}},"1303":{"start":{"line":3590,"column":20},"end":{"line":3590,"column":66}},"1304":{"start":{"line":3593,"column":16},"end":{"line":3593,"column":99}},"1305":{"start":{"line":3598,"column":4},"end":{"line":3598,"column":23}},"1306":{"start":{"line":3607,"column":0},"end":{"line":3613,"column":2}},"1307":{"start":{"line":3611,"column":4},"end":{"line":3611,"column":29}},"1308":{"start":{"line":3612,"column":4},"end":{"line":3612,"column":21}},"1309":{"start":{"line":3629,"column":0},"end":{"line":3677,"column":2}},"1310":{"start":{"line":3642,"column":4},"end":{"line":3642,"column":17}},"1311":{"start":{"line":3643,"column":4},"end":{"line":3643,"column":17}},"1312":{"start":{"line":3644,"column":4},"end":{"line":3644,"column":17}},"1313":{"start":{"line":3645,"column":4},"end":{"line":3645,"column":39}},"1314":{"start":{"line":3646,"column":4},"end":{"line":3646,"column":21}},"1315":{"start":{"line":3647,"column":4},"end":{"line":3647,"column":21}},"1316":{"start":{"line":3648,"column":4},"end":{"line":3648,"column":21}},"1317":{"start":{"line":3649,"column":4},"end":{"line":3651,"column":5}},"1318":{"start":{"line":3650,"column":8},"end":{"line":3650,"column":61}},"1319":{"start":{"line":3652,"column":4},"end":{"line":3652,"column":23}},"1320":{"start":{"line":3654,"column":4},"end":{"line":3660,"column":5}},"1321":{"start":{"line":3655,"column":8},"end":{"line":3659,"column":10}},"1322":{"start":{"line":3661,"column":4},"end":{"line":3661,"column":37}},"1323":{"start":{"line":3663,"column":4},"end":{"line":3669,"column":5}},"1324":{"start":{"line":3664,"column":8},"end":{"line":3668,"column":9}},"1325":{"start":{"line":3670,"column":4},"end":{"line":3670,"column":39}},"1326":{"start":{"line":3672,"column":4},"end":{"line":3674,"column":5}},"1327":{"start":{"line":3673,"column":8},"end":{"line":3673,"column":43}},"1328":{"start":{"line":3676,"column":4},"end":{"line":3676,"column":25}},"1329":{"start":{"line":3683,"column":0},"end":{"line":3693,"column":2}},"1330":{"start":{"line":3684,"column":4},"end":{"line":3692,"column":6}},"1331":{"start":{"line":3700,"column":0},"end":{"line":3737,"column":2}},"1332":{"start":{"line":3701,"column":4},"end":{"line":3736,"column":7}},"1333":{"start":{"line":3740,"column":0},"end":{"line":3752,"column":2}},"1334":{"start":{"line":3742,"column":4},"end":{"line":3742,"column":15}},"1335":{"start":{"line":3743,"column":4},"end":{"line":3743,"column":15}},"1336":{"start":{"line":3745,"column":4},"end":{"line":3747,"column":5}},"1337":{"start":{"line":3746,"column":8},"end":{"line":3746,"column":19}},"1338":{"start":{"line":3749,"column":4},"end":{"line":3751,"column":5}},"1339":{"start":{"line":3750,"column":8},"end":{"line":3750,"column":19}},"1340":{"start":{"line":3754,"column":0},"end":{"line":3759,"column":2}},"1341":{"start":{"line":3755,"column":4},"end":{"line":3758,"column":6}},"1342":{"start":{"line":3761,"column":0},"end":{"line":3766,"column":2}},"1343":{"start":{"line":3762,"column":4},"end":{"line":3765,"column":22}},"1344":{"start":{"line":3768,"column":0},"end":{"line":3785,"column":2}},"1345":{"start":{"line":3770,"column":4},"end":{"line":3770,"column":15}},"1346":{"start":{"line":3771,"column":4},"end":{"line":3771,"column":15}},"1347":{"start":{"line":3772,"column":4},"end":{"line":3772,"column":15}},"1348":{"start":{"line":3774,"column":4},"end":{"line":3776,"column":5}},"1349":{"start":{"line":3775,"column":8},"end":{"line":3775,"column":19}},"1350":{"start":{"line":3778,"column":4},"end":{"line":3780,"column":5}},"1351":{"start":{"line":3779,"column":8},"end":{"line":3779,"column":19}},"1352":{"start":{"line":3782,"column":4},"end":{"line":3784,"column":5}},"1353":{"start":{"line":3783,"column":8},"end":{"line":3783,"column":19}},"1354":{"start":{"line":3787,"column":0},"end":{"line":3800,"column":2}},"1355":{"start":{"line":3789,"column":4},"end":{"line":3793,"column":5}},"1356":{"start":{"line":3790,"column":8},"end":{"line":3790,"column":22}},"1357":{"start":{"line":3791,"column":8},"end":{"line":3791,"column":22}},"1358":{"start":{"line":3792,"column":8},"end":{"line":3792,"column":22}},"1359":{"start":{"line":3795,"column":4},"end":{"line":3797,"column":5}},"1360":{"start":{"line":3796,"column":8},"end":{"line":3796,"column":77}},"1361":{"start":{"line":3799,"column":4},"end":{"line":3799,"column":16}},"1362":{"start":{"line":3802,"column":0},"end":{"line":3808,"column":2}},"1363":{"start":{"line":3803,"column":4},"end":{"line":3807,"column":6}},"1364":{"start":{"line":3810,"column":0},"end":{"line":3815,"column":2}},"1365":{"start":{"line":3811,"column":4},"end":{"line":3811,"column":17}},"1366":{"start":{"line":3812,"column":4},"end":{"line":3812,"column":17}},"1367":{"start":{"line":3813,"column":4},"end":{"line":3813,"column":17}},"1368":{"start":{"line":3814,"column":4},"end":{"line":3814,"column":16}},"1369":{"start":{"line":3817,"column":0},"end":{"line":3826,"column":2}},"1370":{"start":{"line":3819,"column":4},"end":{"line":3819,"column":52}},"1371":{"start":{"line":3821,"column":4},"end":{"line":3821,"column":22}},"1372":{"start":{"line":3823,"column":4},"end":{"line":3823,"column":53}},"1373":{"start":{"line":3825,"column":4},"end":{"line":3825,"column":25}},"1374":{"start":{"line":3828,"column":0},"end":{"line":3832,"column":2}},"1375":{"start":{"line":3829,"column":4},"end":{"line":3829,"column":22}},"1376":{"start":{"line":3830,"column":4},"end":{"line":3830,"column":22}},"1377":{"start":{"line":3831,"column":4},"end":{"line":3831,"column":48}},"1378":{"start":{"line":3834,"column":0},"end":{"line":3839,"column":2}},"1379":{"start":{"line":3836,"column":4},"end":{"line":3836,"column":63}},"1380":{"start":{"line":3838,"column":4},"end":{"line":3838,"column":32}},"1381":{"start":{"line":3841,"column":0},"end":{"line":3846,"column":2}},"1382":{"start":{"line":3842,"column":4},"end":{"line":3842,"column":18}},"1383":{"start":{"line":3843,"column":4},"end":{"line":3843,"column":18}},"1384":{"start":{"line":3844,"column":4},"end":{"line":3844,"column":18}},"1385":{"start":{"line":3845,"column":4},"end":{"line":3845,"column":16}},"1386":{"start":{"line":3848,"column":0},"end":{"line":3850,"column":2}},"1387":{"start":{"line":3849,"column":4},"end":{"line":3849,"column":63}},"1388":{"start":{"line":3852,"column":0},"end":{"line":3858,"column":2}},"1389":{"start":{"line":3853,"column":4},"end":{"line":3857,"column":6}},"1390":{"start":{"line":3860,"column":0},"end":{"line":3877,"column":2}},"1391":{"start":{"line":3861,"column":4},"end":{"line":3875,"column":5}},"1392":{"start":{"line":3862,"column":8},"end":{"line":3862,"column":22}},"1393":{"start":{"line":3863,"column":8},"end":{"line":3863,"column":22}},"1394":{"start":{"line":3864,"column":8},"end":{"line":3864,"column":22}},"1395":{"start":{"line":3865,"column":11},"end":{"line":3875,"column":5}},"1396":{"start":{"line":3866,"column":8},"end":{"line":3866,"column":83}},"1397":{"start":{"line":3867,"column":8},"end":{"line":3867,"column":83}},"1398":{"start":{"line":3868,"column":8},"end":{"line":3868,"column":83}},"1399":{"start":{"line":3869,"column":8},"end":{"line":3869,"column":19}},"1400":{"start":{"line":3870,"column":8},"end":{"line":3870,"column":19}},"1401":{"start":{"line":3871,"column":8},"end":{"line":3871,"column":19}},"1402":{"start":{"line":3873,"column":8},"end":{"line":3873,"column":70}},"1403":{"start":{"line":3874,"column":8},"end":{"line":3874,"column":43}},"1404":{"start":{"line":3876,"column":4},"end":{"line":3876,"column":16}},"1405":{"start":{"line":3880,"column":0},"end":{"line":3882,"column":2}},"1406":{"start":{"line":3881,"column":4},"end":{"line":3881,"column":60}},"1407":{"start":{"line":3884,"column":0},"end":{"line":3901,"column":2}},"1408":{"start":{"line":3886,"column":4},"end":{"line":3886,"column":27}},"1409":{"start":{"line":3888,"column":4},"end":{"line":3888,"column":28}},"1410":{"start":{"line":3890,"column":4},"end":{"line":3892,"column":5}},"1411":{"start":{"line":3891,"column":8},"end":{"line":3891,"column":20}},"1412":{"start":{"line":3894,"column":4},"end":{"line":3894,"column":38}},"1413":{"start":{"line":3896,"column":4},"end":{"line":3896,"column":24}},"1414":{"start":{"line":3897,"column":4},"end":{"line":3897,"column":24}},"1415":{"start":{"line":3898,"column":4},"end":{"line":3898,"column":24}},"1416":{"start":{"line":3900,"column":4},"end":{"line":3900,"column":16}},"1417":{"start":{"line":3903,"column":0},"end":{"line":3925,"column":2}},"1418":{"start":{"line":3905,"column":4},"end":{"line":3905,"column":15}},"1419":{"start":{"line":3906,"column":4},"end":{"line":3906,"column":15}},"1420":{"start":{"line":3907,"column":4},"end":{"line":3907,"column":15}},"1421":{"start":{"line":3908,"column":4},"end":{"line":3908,"column":15}},"1422":{"start":{"line":3910,"column":4},"end":{"line":3912,"column":5}},"1423":{"start":{"line":3911,"column":8},"end":{"line":3911,"column":19}},"1424":{"start":{"line":3914,"column":4},"end":{"line":3916,"column":5}},"1425":{"start":{"line":3915,"column":8},"end":{"line":3915,"column":19}},"1426":{"start":{"line":3918,"column":4},"end":{"line":3920,"column":5}},"1427":{"start":{"line":3919,"column":8},"end":{"line":3919,"column":19}},"1428":{"start":{"line":3922,"column":4},"end":{"line":3924,"column":5}},"1429":{"start":{"line":3923,"column":8},"end":{"line":3923,"column":19}},"1430":{"start":{"line":3927,"column":0},"end":{"line":3932,"column":2}},"1431":{"start":{"line":3928,"column":4},"end":{"line":3928,"column":18}},"1432":{"start":{"line":3929,"column":4},"end":{"line":3929,"column":18}},"1433":{"start":{"line":3930,"column":4},"end":{"line":3930,"column":18}},"1434":{"start":{"line":3931,"column":4},"end":{"line":3931,"column":16}},"1435":{"start":{"line":3934,"column":0},"end":{"line":3941,"column":2}},"1436":{"start":{"line":3935,"column":4},"end":{"line":3940,"column":6}},"1437":{"start":{"line":3943,"column":0},"end":{"line":3961,"column":2}},"1438":{"start":{"line":3944,"column":4},"end":{"line":3960,"column":5}},"1439":{"start":{"line":3945,"column":8},"end":{"line":3945,"column":22}},"1440":{"start":{"line":3946,"column":8},"end":{"line":3946,"column":22}},"1441":{"start":{"line":3947,"column":8},"end":{"line":3947,"column":22}},"1442":{"start":{"line":3948,"column":11},"end":{"line":3960,"column":5}},"1443":{"start":{"line":3949,"column":8},"end":{"line":3949,"column":106}},"1444":{"start":{"line":3950,"column":8},"end":{"line":3950,"column":106}},"1445":{"start":{"line":3951,"column":8},"end":{"line":3951,"column":106}},"1446":{"start":{"line":3952,"column":8},"end":{"line":3952,"column":106}},"1447":{"start":{"line":3953,"column":8},"end":{"line":3953,"column":19}},"1448":{"start":{"line":3954,"column":8},"end":{"line":3954,"column":19}},"1449":{"start":{"line":3955,"column":8},"end":{"line":3955,"column":19}},"1450":{"start":{"line":3956,"column":8},"end":{"line":3956,"column":19}},"1451":{"start":{"line":3958,"column":8},"end":{"line":3958,"column":70}},"1452":{"start":{"line":3959,"column":8},"end":{"line":3959,"column":43}},"1453":{"start":{"line":3964,"column":0},"end":{"line":3982,"column":2}},"1454":{"start":{"line":3967,"column":4},"end":{"line":3967,"column":27}},"1455":{"start":{"line":3969,"column":4},"end":{"line":3969,"column":65}},"1456":{"start":{"line":3971,"column":4},"end":{"line":3973,"column":5}},"1457":{"start":{"line":3972,"column":8},"end":{"line":3972,"column":20}},"1458":{"start":{"line":3975,"column":4},"end":{"line":3975,"column":38}},"1459":{"start":{"line":3977,"column":4},"end":{"line":3977,"column":24}},"1460":{"start":{"line":3978,"column":4},"end":{"line":3978,"column":24}},"1461":{"start":{"line":3979,"column":4},"end":{"line":3979,"column":24}},"1462":{"start":{"line":3981,"column":4},"end":{"line":3981,"column":16}},"1463":{"start":{"line":3984,"column":0},"end":{"line":4000,"column":2}},"1464":{"start":{"line":3986,"column":4},"end":{"line":3990,"column":5}},"1465":{"start":{"line":3987,"column":8},"end":{"line":3987,"column":22}},"1466":{"start":{"line":3988,"column":8},"end":{"line":3988,"column":22}},"1467":{"start":{"line":3989,"column":8},"end":{"line":3989,"column":22}},"1468":{"start":{"line":3992,"column":4},"end":{"line":3997,"column":5}},"1469":{"start":{"line":3993,"column":8},"end":{"line":3993,"column":22}},"1470":{"start":{"line":3994,"column":8},"end":{"line":3994,"column":22}},"1471":{"start":{"line":3995,"column":8},"end":{"line":3995,"column":22}},"1472":{"start":{"line":3996,"column":8},"end":{"line":3996,"column":22}},"1473":{"start":{"line":3999,"column":4},"end":{"line":3999,"column":16}},"1474":{"start":{"line":4002,"column":0},"end":{"line":4004,"column":2}},"1475":{"start":{"line":4003,"column":4},"end":{"line":4003,"column":22}},"1476":{"start":{"line":4006,"column":0},"end":{"line":4025,"column":2}},"1477":{"start":{"line":4008,"column":4},"end":{"line":4015,"column":5}},"1478":{"start":{"line":4009,"column":8},"end":{"line":4014,"column":9}},"1479":{"start":{"line":4017,"column":4},"end":{"line":4020,"column":5}},"1480":{"start":{"line":4018,"column":8},"end":{"line":4018,"column":59}},"1481":{"start":{"line":4019,"column":8},"end":{"line":4019,"column":62}},"1482":{"start":{"line":4022,"column":4},"end":{"line":4022,"column":30}},"1483":{"start":{"line":4024,"column":4},"end":{"line":4024,"column":16}},"1484":{"start":{"line":4027,"column":0},"end":{"line":4036,"column":2}},"1485":{"start":{"line":4029,"column":4},"end":{"line":4029,"column":21}},"1486":{"start":{"line":4031,"column":4},"end":{"line":4033,"column":5}},"1487":{"start":{"line":4032,"column":8},"end":{"line":4032,"column":45}},"1488":{"start":{"line":4035,"column":4},"end":{"line":4035,"column":19}},"1489":{"start":{"line":4038,"column":0},"end":{"line":4081,"column":2}},"1490":{"start":{"line":4042,"column":4},"end":{"line":4042,"column":23}},"1491":{"start":{"line":4044,"column":4},"end":{"line":4044,"column":74}},"1492":{"start":{"line":4046,"column":4},"end":{"line":4046,"column":25}},"1493":{"start":{"line":4048,"column":4},"end":{"line":4048,"column":36}},"1494":{"start":{"line":4050,"column":4},"end":{"line":4050,"column":25}},"1495":{"start":{"line":4052,"column":4},"end":{"line":4067,"column":5}},"1496":{"start":{"line":4054,"column":8},"end":{"line":4054,"column":21}},"1497":{"start":{"line":4056,"column":8},"end":{"line":4058,"column":9}},"1498":{"start":{"line":4057,"column":12},"end":{"line":4057,"column":72}},"1499":{"start":{"line":4060,"column":8},"end":{"line":4060,"column":41}},"1500":{"start":{"line":4062,"column":8},"end":{"line":4066,"column":9}},"1501":{"start":{"line":4064,"column":12},"end":{"line":4064,"column":39}},"1502":{"start":{"line":4065,"column":12},"end":{"line":4065,"column":46}},"1503":{"start":{"line":4069,"column":4},"end":{"line":4069,"column":33}},"1504":{"start":{"line":4073,"column":4},"end":{"line":4073,"column":83}},"1505":{"start":{"line":4075,"column":4},"end":{"line":4077,"column":5}},"1506":{"start":{"line":4076,"column":8},"end":{"line":4076,"column":70}},"1507":{"start":{"line":4083,"column":0},"end":{"line":4125,"column":2}},"1508":{"start":{"line":4087,"column":4},"end":{"line":4087,"column":23}},"1509":{"start":{"line":4089,"column":4},"end":{"line":4089,"column":74}},"1510":{"start":{"line":4091,"column":4},"end":{"line":4091,"column":25}},"1511":{"start":{"line":4093,"column":4},"end":{"line":4093,"column":36}},"1512":{"start":{"line":4095,"column":4},"end":{"line":4095,"column":25}},"1513":{"start":{"line":4097,"column":4},"end":{"line":4111,"column":5}},"1514":{"start":{"line":4099,"column":8},"end":{"line":4099,"column":21}},"1515":{"start":{"line":4101,"column":8},"end":{"line":4103,"column":9}},"1516":{"start":{"line":4102,"column":12},"end":{"line":4102,"column":72}},"1517":{"start":{"line":4105,"column":8},"end":{"line":4105,"column":41}},"1518":{"start":{"line":4107,"column":8},"end":{"line":4110,"column":9}},"1519":{"start":{"line":4108,"column":12},"end":{"line":4108,"column":39}},"1520":{"start":{"line":4109,"column":12},"end":{"line":4109,"column":46}},"1521":{"start":{"line":4113,"column":4},"end":{"line":4113,"column":33}},"1522":{"start":{"line":4117,"column":4},"end":{"line":4117,"column":83}},"1523":{"start":{"line":4119,"column":4},"end":{"line":4121,"column":5}},"1524":{"start":{"line":4120,"column":8},"end":{"line":4120,"column":70}},"1525":{"start":{"line":4128,"column":0},"end":{"line":4147,"column":2}},"1526":{"start":{"line":4130,"column":4},"end":{"line":4130,"column":36}},"1527":{"start":{"line":4132,"column":4},"end":{"line":4132,"column":63}},"1528":{"start":{"line":4134,"column":4},"end":{"line":4134,"column":75}},"1529":{"start":{"line":4136,"column":4},"end":{"line":4136,"column":62}},"1530":{"start":{"line":4137,"column":4},"end":{"line":4137,"column":62}},"1531":{"start":{"line":4138,"column":4},"end":{"line":4138,"column":62}},"1532":{"start":{"line":4140,"column":4},"end":{"line":4140,"column":77}},"1533":{"start":{"line":4142,"column":4},"end":{"line":4146,"column":5}},"1534":{"start":{"line":4143,"column":8},"end":{"line":4143,"column":85}},"1535":{"start":{"line":4144,"column":8},"end":{"line":4144,"column":65}},"1536":{"start":{"line":4145,"column":8},"end":{"line":4145,"column":85}},"1537":{"start":{"line":4149,"column":0},"end":{"line":4186,"column":2}},"1538":{"start":{"line":4151,"column":4},"end":{"line":4151,"column":33}},"1539":{"start":{"line":4152,"column":4},"end":{"line":4152,"column":33}},"1540":{"start":{"line":4153,"column":4},"end":{"line":4153,"column":33}},"1541":{"start":{"line":4155,"column":4},"end":{"line":4155,"column":33}},"1542":{"start":{"line":4156,"column":4},"end":{"line":4156,"column":33}},"1543":{"start":{"line":4157,"column":4},"end":{"line":4157,"column":33}},"1544":{"start":{"line":4159,"column":4},"end":{"line":4179,"column":5}},"1545":{"start":{"line":4160,"column":8},"end":{"line":4162,"column":9}},"1546":{"start":{"line":4161,"column":12},"end":{"line":4161,"column":37}},"1547":{"start":{"line":4163,"column":8},"end":{"line":4165,"column":9}},"1548":{"start":{"line":4164,"column":12},"end":{"line":4164,"column":37}},"1549":{"start":{"line":4166,"column":8},"end":{"line":4168,"column":9}},"1550":{"start":{"line":4167,"column":12},"end":{"line":4167,"column":37}},"1551":{"start":{"line":4170,"column":8},"end":{"line":4172,"column":9}},"1552":{"start":{"line":4171,"column":12},"end":{"line":4171,"column":37}},"1553":{"start":{"line":4173,"column":8},"end":{"line":4175,"column":9}},"1554":{"start":{"line":4174,"column":12},"end":{"line":4174,"column":37}},"1555":{"start":{"line":4176,"column":8},"end":{"line":4178,"column":9}},"1556":{"start":{"line":4177,"column":12},"end":{"line":4177,"column":37}},"1557":{"start":{"line":4181,"column":4},"end":{"line":4185,"column":5}},"1558":{"start":{"line":4188,"column":0},"end":{"line":4204,"column":2}},"1559":{"start":{"line":4189,"column":4},"end":{"line":4189,"column":21}},"1560":{"start":{"line":4190,"column":4},"end":{"line":4190,"column":21}},"1561":{"start":{"line":4191,"column":4},"end":{"line":4191,"column":21}},"1562":{"start":{"line":4193,"column":4},"end":{"line":4197,"column":5}},"1563":{"start":{"line":4194,"column":8},"end":{"line":4194,"column":38}},"1564":{"start":{"line":4195,"column":8},"end":{"line":4195,"column":38}},"1565":{"start":{"line":4196,"column":8},"end":{"line":4196,"column":38}},"1566":{"start":{"line":4199,"column":4},"end":{"line":4203,"column":6}},"1567":{"start":{"line":4206,"column":0},"end":{"line":4215,"column":2}},"1568":{"start":{"line":4208,"column":4},"end":{"line":4212,"column":5}},"1569":{"start":{"line":4209,"column":8},"end":{"line":4209,"column":32}},"1570":{"start":{"line":4210,"column":8},"end":{"line":4210,"column":32}},"1571":{"start":{"line":4211,"column":8},"end":{"line":4211,"column":32}},"1572":{"start":{"line":4214,"column":4},"end":{"line":4214,"column":16}},"1573":{"start":{"line":4218,"column":0},"end":{"line":4225,"column":2}},"1574":{"start":{"line":4220,"column":4},"end":{"line":4220,"column":55}},"1575":{"start":{"line":4222,"column":4},"end":{"line":4224,"column":5}},"1576":{"start":{"line":4223,"column":8},"end":{"line":4223,"column":54}},"1577":{"start":{"line":4233,"column":0},"end":{"line":4239,"column":2}},"1578":{"start":{"line":4237,"column":4},"end":{"line":4237,"column":29}},"1579":{"start":{"line":4238,"column":4},"end":{"line":4238,"column":35}},"1580":{"start":{"line":4251,"column":0},"end":{"line":4306,"column":2}},"1581":{"start":{"line":4261,"column":4},"end":{"line":4261,"column":17}},"1582":{"start":{"line":4263,"column":4},"end":{"line":4263,"column":21}},"1583":{"start":{"line":4265,"column":4},"end":{"line":4267,"column":5}},"1584":{"start":{"line":4266,"column":8},"end":{"line":4266,"column":54}},"1585":{"start":{"line":4268,"column":4},"end":{"line":4268,"column":27}},"1586":{"start":{"line":4270,"column":4},"end":{"line":4276,"column":5}},"1587":{"start":{"line":4271,"column":8},"end":{"line":4275,"column":10}},"1588":{"start":{"line":4277,"column":4},"end":{"line":4277,"column":33}},"1589":{"start":{"line":4279,"column":4},"end":{"line":4285,"column":5}},"1590":{"start":{"line":4280,"column":8},"end":{"line":4284,"column":10}},"1591":{"start":{"line":4286,"column":4},"end":{"line":4286,"column":25}},"1592":{"start":{"line":4288,"column":4},"end":{"line":4290,"column":5}},"1593":{"start":{"line":4289,"column":8},"end":{"line":4289,"column":25}},"1594":{"start":{"line":4291,"column":4},"end":{"line":4291,"column":35}},"1595":{"start":{"line":4293,"column":4},"end":{"line":4293,"column":23}},"1596":{"start":{"line":4295,"column":4},"end":{"line":4295,"column":30}},"1597":{"start":{"line":4302,"column":4},"end":{"line":4305,"column":5}},"1598":{"start":{"line":4303,"column":8},"end":{"line":4303,"column":29}},"1599":{"start":{"line":4304,"column":8},"end":{"line":4304,"column":56}},"1600":{"start":{"line":4309,"column":0},"end":{"line":4345,"column":2}},"1601":{"start":{"line":4311,"column":4},"end":{"line":4311,"column":35}},"1602":{"start":{"line":4313,"column":4},"end":{"line":4313,"column":55}},"1603":{"start":{"line":4315,"column":4},"end":{"line":4315,"column":32}},"1604":{"start":{"line":4318,"column":4},"end":{"line":4318,"column":46}},"1605":{"start":{"line":4320,"column":4},"end":{"line":4320,"column":28}},"1606":{"start":{"line":4322,"column":4},"end":{"line":4327,"column":5}},"1607":{"start":{"line":4323,"column":8},"end":{"line":4323,"column":62}},"1608":{"start":{"line":4324,"column":11},"end":{"line":4327,"column":5}},"1609":{"start":{"line":4325,"column":8},"end":{"line":4325,"column":59}},"1610":{"start":{"line":4326,"column":8},"end":{"line":4326,"column":57}},"1611":{"start":{"line":4329,"column":4},"end":{"line":4329,"column":38}},"1612":{"start":{"line":4331,"column":4},"end":{"line":4331,"column":43}},"1613":{"start":{"line":4332,"column":4},"end":{"line":4332,"column":43}},"1614":{"start":{"line":4333,"column":4},"end":{"line":4333,"column":43}},"1615":{"start":{"line":4335,"column":4},"end":{"line":4340,"column":5}},"1616":{"start":{"line":4337,"column":8},"end":{"line":4337,"column":68}},"1617":{"start":{"line":4342,"column":4},"end":{"line":4342,"column":33}},"1618":{"start":{"line":4344,"column":4},"end":{"line":4344,"column":23}},"1619":{"start":{"line":4347,"column":0},"end":{"line":4373,"column":2}},"1620":{"start":{"line":4353,"column":4},"end":{"line":4353,"column":24}},"1621":{"start":{"line":4358,"column":4},"end":{"line":4372,"column":5}},"1622":{"start":{"line":4360,"column":8},"end":{"line":4360,"column":27}},"1623":{"start":{"line":4361,"column":8},"end":{"line":4361,"column":32}},"1624":{"start":{"line":4363,"column":8},"end":{"line":4365,"column":9}},"1625":{"start":{"line":4364,"column":12},"end":{"line":4364,"column":81}},"1626":{"start":{"line":4367,"column":8},"end":{"line":4369,"column":9}},"1627":{"start":{"line":4368,"column":12},"end":{"line":4368,"column":122}},"1628":{"start":{"line":4371,"column":8},"end":{"line":4371,"column":80}},"1629":{"start":{"line":4375,"column":0},"end":{"line":4377,"column":2}},"1630":{"start":{"line":4379,"column":0},"end":{"line":4391,"column":2}},"1631":{"start":{"line":4382,"column":4},"end":{"line":4382,"column":61}},"1632":{"start":{"line":4384,"column":4},"end":{"line":4390,"column":5}},"1633":{"start":{"line":4385,"column":8},"end":{"line":4387,"column":11}},"1634":{"start":{"line":4388,"column":8},"end":{"line":4388,"column":45}},"1635":{"start":{"line":4389,"column":8},"end":{"line":4389,"column":28}},"1636":{"start":{"line":4393,"column":0},"end":{"line":4405,"column":2}},"1637":{"start":{"line":4396,"column":4},"end":{"line":4396,"column":65}},"1638":{"start":{"line":4398,"column":4},"end":{"line":4404,"column":5}},"1639":{"start":{"line":4399,"column":8},"end":{"line":4401,"column":11}},"1640":{"start":{"line":4402,"column":8},"end":{"line":4402,"column":47}},"1641":{"start":{"line":4403,"column":8},"end":{"line":4403,"column":30}},"1642":{"start":{"line":4407,"column":0},"end":{"line":4422,"column":2}},"1643":{"start":{"line":4414,"column":4},"end":{"line":4421,"column":5}},"1644":{"start":{"line":4415,"column":8},"end":{"line":4420,"column":11}},"1645":{"start":{"line":4424,"column":0},"end":{"line":4433,"column":2}},"1646":{"start":{"line":4428,"column":4},"end":{"line":4432,"column":5}},"1647":{"start":{"line":4429,"column":8},"end":{"line":4429,"column":48}},"1648":{"start":{"line":4431,"column":8},"end":{"line":4431,"column":59}},"1649":{"start":{"line":4437,"column":0},"end":{"line":4444,"column":2}},"1650":{"start":{"line":4441,"column":4},"end":{"line":4443,"column":5}},"1651":{"start":{"line":4442,"column":8},"end":{"line":4442,"column":135}},"1652":{"start":{"line":4446,"column":0},"end":{"line":4452,"column":2}},"1653":{"start":{"line":4449,"column":4},"end":{"line":4451,"column":5}},"1654":{"start":{"line":4450,"column":8},"end":{"line":4450,"column":122}},"1655":{"start":{"line":4454,"column":0},"end":{"line":4460,"column":2}},"1656":{"start":{"line":4457,"column":4},"end":{"line":4459,"column":5}},"1657":{"start":{"line":4458,"column":8},"end":{"line":4458,"column":192}},"1658":{"start":{"line":4462,"column":0},"end":{"line":4471,"column":2}},"1659":{"start":{"line":4468,"column":4},"end":{"line":4470,"column":5}},"1660":{"start":{"line":4469,"column":8},"end":{"line":4469,"column":164}},"1661":{"start":{"line":4473,"column":0},"end":{"line":4479,"column":2}},"1662":{"start":{"line":4476,"column":4},"end":{"line":4478,"column":5}},"1663":{"start":{"line":4477,"column":8},"end":{"line":4477,"column":55}},"1664":{"start":{"line":4481,"column":0},"end":{"line":4487,"column":2}},"1665":{"start":{"line":4484,"column":4},"end":{"line":4486,"column":5}},"1666":{"start":{"line":4485,"column":8},"end":{"line":4485,"column":59}},"1667":{"start":{"line":4489,"column":0},"end":{"line":4513,"column":2}},"1668":{"start":{"line":4492,"column":4},"end":{"line":4512,"column":5}},"1669":{"start":{"line":4498,"column":8},"end":{"line":4498,"column":43}},"1670":{"start":{"line":4500,"column":8},"end":{"line":4505,"column":9}},"1671":{"start":{"line":4502,"column":12},"end":{"line":4502,"column":44}},"1672":{"start":{"line":4503,"column":12},"end":{"line":4503,"column":36}},"1673":{"start":{"line":4504,"column":12},"end":{"line":4504,"column":19}},"1674":{"start":{"line":4507,"column":8},"end":{"line":4507,"column":56}},"1675":{"start":{"line":4509,"column":8},"end":{"line":4509,"column":59}},"1676":{"start":{"line":4511,"column":8},"end":{"line":4511,"column":32}},"1677":{"start":{"line":4515,"column":0},"end":{"line":4531,"column":2}},"1678":{"start":{"line":4519,"column":4},"end":{"line":4529,"column":5}},"1679":{"start":{"line":4521,"column":8},"end":{"line":4524,"column":10}},"1680":{"start":{"line":4528,"column":8},"end":{"line":4528,"column":20}},"1681":{"start":{"line":4533,"column":0},"end":{"line":4590,"column":2}},"1682":{"start":{"line":4540,"column":4},"end":{"line":4540,"column":45}},"1683":{"start":{"line":4541,"column":4},"end":{"line":4549,"column":6}},"1684":{"start":{"line":4551,"column":4},"end":{"line":4551,"column":58}},"1685":{"start":{"line":4553,"column":4},"end":{"line":4555,"column":5}},"1686":{"start":{"line":4554,"column":8},"end":{"line":4554,"column":129}},"1687":{"start":{"line":4557,"column":4},"end":{"line":4583,"column":5}},"1688":{"start":{"line":4558,"column":8},"end":{"line":4558,"column":37}},"1689":{"start":{"line":4559,"column":8},"end":{"line":4559,"column":41}},"1690":{"start":{"line":4560,"column":8},"end":{"line":4560,"column":41}},"1691":{"start":{"line":4562,"column":8},"end":{"line":4562,"column":62}},"1692":{"start":{"line":4567,"column":8},"end":{"line":4571,"column":29}},"1693":{"start":{"line":4573,"column":8},"end":{"line":4573,"column":26}},"1694":{"start":{"line":4574,"column":8},"end":{"line":4579,"column":9}},"1695":{"start":{"line":4575,"column":12},"end":{"line":4575,"column":56}},"1696":{"start":{"line":4576,"column":12},"end":{"line":4576,"column":51}},"1697":{"start":{"line":4581,"column":8},"end":{"line":4581,"column":162}},"1698":{"start":{"line":4582,"column":8},"end":{"line":4582,"column":40}},"1699":{"start":{"line":4585,"column":4},"end":{"line":4585,"column":41}},"1700":{"start":{"line":4586,"column":4},"end":{"line":4586,"column":41}},"1701":{"start":{"line":4587,"column":4},"end":{"line":4587,"column":41}},"1702":{"start":{"line":4589,"column":4},"end":{"line":4589,"column":30}},"1703":{"start":{"line":4592,"column":0},"end":{"line":4664,"column":2}},"1704":{"start":{"line":4600,"column":4},"end":{"line":4600,"column":27}},"1705":{"start":{"line":4601,"column":4},"end":{"line":4601,"column":53}},"1706":{"start":{"line":4602,"column":4},"end":{"line":4602,"column":51}},"1707":{"start":{"line":4603,"column":4},"end":{"line":4603,"column":56}},"1708":{"start":{"line":4604,"column":4},"end":{"line":4604,"column":108}},"1709":{"start":{"line":4606,"column":4},"end":{"line":4606,"column":19}},"1710":{"start":{"line":4608,"column":4},"end":{"line":4608,"column":22}},"1711":{"start":{"line":4609,"column":4},"end":{"line":4609,"column":22}},"1712":{"start":{"line":4611,"column":4},"end":{"line":4663,"column":5}},"1713":{"start":{"line":4612,"column":8},"end":{"line":4647,"column":9}},"1714":{"start":{"line":4614,"column":12},"end":{"line":4614,"column":28}},"1715":{"start":{"line":4616,"column":12},"end":{"line":4633,"column":13}},"1716":{"start":{"line":4618,"column":16},"end":{"line":4618,"column":84}},"1717":{"start":{"line":4619,"column":16},"end":{"line":4619,"column":122}},"1718":{"start":{"line":4620,"column":16},"end":{"line":4620,"column":39}},"1719":{"start":{"line":4621,"column":16},"end":{"line":4621,"column":42}},"1720":{"start":{"line":4622,"column":16},"end":{"line":4622,"column":40}},"1721":{"start":{"line":4623,"column":16},"end":{"line":4623,"column":55}},"1722":{"start":{"line":4624,"column":16},"end":{"line":4624,"column":39}},"1723":{"start":{"line":4626,"column":16},"end":{"line":4626,"column":115}},"1724":{"start":{"line":4627,"column":16},"end":{"line":4627,"column":41}},"1725":{"start":{"line":4629,"column":19},"end":{"line":4633,"column":13}},"1726":{"start":{"line":4631,"column":19},"end":{"line":4633,"column":13}},"1727":{"start":{"line":4635,"column":12},"end":{"line":4638,"column":15}},"1728":{"start":{"line":4640,"column":12},"end":{"line":4640,"column":26}},"1729":{"start":{"line":4641,"column":12},"end":{"line":4641,"column":26}},"1730":{"start":{"line":4642,"column":12},"end":{"line":4642,"column":31}},"1731":{"start":{"line":4644,"column":12},"end":{"line":4646,"column":13}},"1732":{"start":{"line":4645,"column":16},"end":{"line":4645,"column":29}},"1733":{"start":{"line":4649,"column":8},"end":{"line":4649,"column":47}},"1734":{"start":{"line":4650,"column":8},"end":{"line":4650,"column":39}},"1735":{"start":{"line":4651,"column":8},"end":{"line":4651,"column":39}},"1736":{"start":{"line":4652,"column":8},"end":{"line":4652,"column":39}},"1737":{"start":{"line":4654,"column":8},"end":{"line":4654,"column":53}},"1738":{"start":{"line":4655,"column":8},"end":{"line":4655,"column":53}},"1739":{"start":{"line":4656,"column":8},"end":{"line":4656,"column":53}},"1740":{"start":{"line":4658,"column":8},"end":{"line":4658,"column":40}},"1741":{"start":{"line":4659,"column":8},"end":{"line":4659,"column":40}},"1742":{"start":{"line":4660,"column":8},"end":{"line":4660,"column":40}},"1743":{"start":{"line":4662,"column":8},"end":{"line":4662,"column":25}},"1744":{"start":{"line":4666,"column":0},"end":{"line":4668,"column":1}},"1745":{"start":{"line":4667,"column":4},"end":{"line":4667,"column":29}}},"branchMap":{"1":{"line":1,"type":"if","locations":[{"start":{"line":1,"column":0},"end":{"line":1,"column":0}},{"start":{"line":1,"column":0},"end":{"line":1,"column":0}}]},"2":{"line":5,"type":"if","locations":[{"start":{"line":5,"column":0},"end":{"line":5,"column":0}},{"start":{"line":5,"column":0},"end":{"line":5,"column":0}}]},"3":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":4},"end":{"line":51,"column":4}},{"start":{"line":51,"column":4},"end":{"line":51,"column":4}}]},"4":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":4},"end":{"line":56,"column":4}},{"start":{"line":56,"column":4},"end":{"line":56,"column":4}}]},"5":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":4},"end":{"line":61,"column":4}},{"start":{"line":61,"column":4},"end":{"line":61,"column":4}}]},"6":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":4},"end":{"line":66,"column":4}},{"start":{"line":66,"column":4},"end":{"line":66,"column":4}}]},"7":{"line":71,"type":"if","locations":[{"start":{"line":71,"column":4},"end":{"line":71,"column":4}},{"start":{"line":71,"column":4},"end":{"line":71,"column":4}}]},"8":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":4},"end":{"line":76,"column":4}},{"start":{"line":76,"column":4},"end":{"line":76,"column":4}}]},"9":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":4},"end":{"line":81,"column":4}},{"start":{"line":81,"column":4},"end":{"line":81,"column":4}}]},"10":{"line":104,"type":"if","locations":[{"start":{"line":104,"column":4},"end":{"line":104,"column":4}},{"start":{"line":104,"column":4},"end":{"line":104,"column":4}}]},"11":{"line":109,"type":"if","locations":[{"start":{"line":109,"column":4},"end":{"line":109,"column":4}},{"start":{"line":109,"column":4},"end":{"line":109,"column":4}}]},"12":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":4},"end":{"line":114,"column":4}},{"start":{"line":114,"column":4},"end":{"line":114,"column":4}}]},"13":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":4},"end":{"line":121,"column":4}},{"start":{"line":121,"column":4},"end":{"line":121,"column":4}}]},"14":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":4},"end":{"line":131,"column":4}},{"start":{"line":131,"column":4},"end":{"line":131,"column":4}}]},"15":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":4},"end":{"line":140,"column":4}},{"start":{"line":140,"column":4},"end":{"line":140,"column":4}}]},"16":{"line":142,"type":"if","locations":[{"start":{"line":142,"column":11},"end":{"line":142,"column":11}},{"start":{"line":142,"column":11},"end":{"line":142,"column":11}}]},"17":{"line":144,"type":"if","locations":[{"start":{"line":144,"column":11},"end":{"line":144,"column":11}},{"start":{"line":144,"column":11},"end":{"line":144,"column":11}}]},"18":{"line":203,"type":"if","locations":[{"start":{"line":203,"column":4},"end":{"line":203,"column":4}},{"start":{"line":203,"column":4},"end":{"line":203,"column":4}}]},"19":{"line":276,"type":"binary-expr","locations":[{"start":{"line":276,"column":27},"end":{"line":276,"column":59}},{"start":{"line":276,"column":63},"end":{"line":276,"column":98}},{"start":{"line":276,"column":102},"end":{"line":276,"column":140}}]},"20":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":4},"end":{"line":279,"column":4}},{"start":{"line":279,"column":4},"end":{"line":279,"column":4}}]},"21":{"line":280,"type":"binary-expr","locations":[{"start":{"line":280,"column":42},"end":{"line":280,"column":73}},{"start":{"line":280,"column":77},"end":{"line":280,"column":111}},{"start":{"line":280,"column":115},"end":{"line":280,"column":152}}]},"22":{"line":281,"type":"binary-expr","locations":[{"start":{"line":281,"column":35},"end":{"line":281,"column":59}},{"start":{"line":281,"column":63},"end":{"line":281,"column":90}},{"start":{"line":281,"column":94},"end":{"line":281,"column":124}}]},"23":{"line":301,"type":"if","locations":[{"start":{"line":301,"column":4},"end":{"line":301,"column":4}},{"start":{"line":301,"column":4},"end":{"line":301,"column":4}}]},"24":{"line":312,"type":"if","locations":[{"start":{"line":312,"column":4},"end":{"line":312,"column":4}},{"start":{"line":312,"column":4},"end":{"line":312,"column":4}}]},"25":{"line":339,"type":"if","locations":[{"start":{"line":339,"column":4},"end":{"line":339,"column":4}},{"start":{"line":339,"column":4},"end":{"line":339,"column":4}}]},"26":{"line":345,"type":"if","locations":[{"start":{"line":345,"column":11},"end":{"line":345,"column":11}},{"start":{"line":345,"column":11},"end":{"line":345,"column":11}}]},"27":{"line":352,"type":"if","locations":[{"start":{"line":352,"column":4},"end":{"line":352,"column":4}},{"start":{"line":352,"column":4},"end":{"line":352,"column":4}}]},"28":{"line":358,"type":"if","locations":[{"start":{"line":358,"column":11},"end":{"line":358,"column":11}},{"start":{"line":358,"column":11},"end":{"line":358,"column":11}}]},"29":{"line":365,"type":"if","locations":[{"start":{"line":365,"column":4},"end":{"line":365,"column":4}},{"start":{"line":365,"column":4},"end":{"line":365,"column":4}}]},"30":{"line":369,"type":"if","locations":[{"start":{"line":369,"column":11},"end":{"line":369,"column":11}},{"start":{"line":369,"column":11},"end":{"line":369,"column":11}}]},"31":{"line":391,"type":"if","locations":[{"start":{"line":391,"column":4},"end":{"line":391,"column":4}},{"start":{"line":391,"column":4},"end":{"line":391,"column":4}}]},"32":{"line":392,"type":"binary-expr","locations":[{"start":{"line":392,"column":24},"end":{"line":392,"column":39}},{"start":{"line":392,"column":43},"end":{"line":392,"column":61}},{"start":{"line":392,"column":65},"end":{"line":392,"column":86}},{"start":{"line":392,"column":90},"end":{"line":392,"column":91}}]},"33":{"line":393,"type":"binary-expr","locations":[{"start":{"line":393,"column":24},"end":{"line":393,"column":39}},{"start":{"line":393,"column":43},"end":{"line":393,"column":61}},{"start":{"line":393,"column":65},"end":{"line":393,"column":86}},{"start":{"line":393,"column":90},"end":{"line":393,"column":91}}]},"34":{"line":405,"type":"switch","locations":[{"start":{"line":407,"column":8},"end":{"line":409,"column":18}},{"start":{"line":411,"column":8},"end":{"line":413,"column":18}},{"start":{"line":415,"column":8},"end":{"line":417,"column":18}},{"start":{"line":419,"column":8},"end":{"line":421,"column":18}},{"start":{"line":423,"column":8},"end":{"line":425,"column":18}},{"start":{"line":427,"column":8},"end":{"line":429,"column":18}}]},"35":{"line":438,"type":"switch","locations":[{"start":{"line":440,"column":8},"end":{"line":440,"column":16}},{"start":{"line":441,"column":8},"end":{"line":443,"column":18}},{"start":{"line":445,"column":8},"end":{"line":445,"column":16}},{"start":{"line":446,"column":8},"end":{"line":448,"column":18}},{"start":{"line":450,"column":8},"end":{"line":450,"column":16}},{"start":{"line":451,"column":8},"end":{"line":453,"column":18}},{"start":{"line":455,"column":8},"end":{"line":455,"column":16}},{"start":{"line":456,"column":8},"end":{"line":458,"column":18}},{"start":{"line":460,"column":8},"end":{"line":462,"column":18}},{"start":{"line":464,"column":8},"end":{"line":466,"column":18}}]},"36":{"line":493,"type":"binary-expr","locations":[{"start":{"line":493,"column":47},"end":{"line":493,"column":87}},{"start":{"line":493,"column":91},"end":{"line":493,"column":93}}]},"37":{"line":511,"type":"if","locations":[{"start":{"line":511,"column":8},"end":{"line":511,"column":8}},{"start":{"line":511,"column":8},"end":{"line":511,"column":8}}]},"38":{"line":511,"type":"binary-expr","locations":[{"start":{"line":511,"column":11},"end":{"line":511,"column":16}},{"start":{"line":511,"column":20},"end":{"line":511,"column":37}}]},"39":{"line":523,"type":"if","locations":[{"start":{"line":523,"column":20},"end":{"line":523,"column":20}},{"start":{"line":523,"column":20},"end":{"line":523,"column":20}}]},"40":{"line":524,"type":"if","locations":[{"start":{"line":524,"column":24},"end":{"line":524,"column":24}},{"start":{"line":524,"column":24},"end":{"line":524,"column":24}}]},"41":{"line":534,"type":"if","locations":[{"start":{"line":534,"column":28},"end":{"line":534,"column":28}},{"start":{"line":534,"column":28},"end":{"line":534,"column":28}}]},"42":{"line":536,"type":"if","locations":[{"start":{"line":536,"column":32},"end":{"line":536,"column":32}},{"start":{"line":536,"column":32},"end":{"line":536,"column":32}}]},"43":{"line":537,"type":"if","locations":[{"start":{"line":537,"column":36},"end":{"line":537,"column":36}},{"start":{"line":537,"column":36},"end":{"line":537,"column":36}}]},"44":{"line":543,"type":"if","locations":[{"start":{"line":543,"column":36},"end":{"line":543,"column":36}},{"start":{"line":543,"column":36},"end":{"line":543,"column":36}}]},"45":{"line":568,"type":"binary-expr","locations":[{"start":{"line":568,"column":31},"end":{"line":568,"column":55}},{"start":{"line":568,"column":59},"end":{"line":568,"column":61}}]},"46":{"line":587,"type":"if","locations":[{"start":{"line":587,"column":4},"end":{"line":587,"column":4}},{"start":{"line":587,"column":4},"end":{"line":587,"column":4}}]},"47":{"line":592,"type":"if","locations":[{"start":{"line":592,"column":4},"end":{"line":592,"column":4}},{"start":{"line":592,"column":4},"end":{"line":592,"column":4}}]},"48":{"line":597,"type":"if","locations":[{"start":{"line":597,"column":4},"end":{"line":597,"column":4}},{"start":{"line":597,"column":4},"end":{"line":597,"column":4}}]},"49":{"line":707,"type":"if","locations":[{"start":{"line":707,"column":4},"end":{"line":707,"column":4}},{"start":{"line":707,"column":4},"end":{"line":707,"column":4}}]},"50":{"line":712,"type":"if","locations":[{"start":{"line":712,"column":4},"end":{"line":712,"column":4}},{"start":{"line":712,"column":4},"end":{"line":712,"column":4}}]},"51":{"line":716,"type":"if","locations":[{"start":{"line":716,"column":8},"end":{"line":716,"column":8}},{"start":{"line":716,"column":8},"end":{"line":716,"column":8}}]},"52":{"line":720,"type":"if","locations":[{"start":{"line":720,"column":8},"end":{"line":720,"column":8}},{"start":{"line":720,"column":8},"end":{"line":720,"column":8}}]},"53":{"line":724,"type":"if","locations":[{"start":{"line":724,"column":8},"end":{"line":724,"column":8}},{"start":{"line":724,"column":8},"end":{"line":724,"column":8}}]},"54":{"line":772,"type":"if","locations":[{"start":{"line":772,"column":4},"end":{"line":772,"column":4}},{"start":{"line":772,"column":4},"end":{"line":772,"column":4}}]},"55":{"line":777,"type":"if","locations":[{"start":{"line":777,"column":4},"end":{"line":777,"column":4}},{"start":{"line":777,"column":4},"end":{"line":777,"column":4}}]},"56":{"line":782,"type":"if","locations":[{"start":{"line":782,"column":4},"end":{"line":782,"column":4}},{"start":{"line":782,"column":4},"end":{"line":782,"column":4}}]},"57":{"line":787,"type":"if","locations":[{"start":{"line":787,"column":4},"end":{"line":787,"column":4}},{"start":{"line":787,"column":4},"end":{"line":787,"column":4}}]},"58":{"line":792,"type":"if","locations":[{"start":{"line":792,"column":4},"end":{"line":792,"column":4}},{"start":{"line":792,"column":4},"end":{"line":792,"column":4}}]},"59":{"line":797,"type":"if","locations":[{"start":{"line":797,"column":4},"end":{"line":797,"column":4}},{"start":{"line":797,"column":4},"end":{"line":797,"column":4}}]},"60":{"line":802,"type":"if","locations":[{"start":{"line":802,"column":4},"end":{"line":802,"column":4}},{"start":{"line":802,"column":4},"end":{"line":802,"column":4}}]},"61":{"line":807,"type":"if","locations":[{"start":{"line":807,"column":4},"end":{"line":807,"column":4}},{"start":{"line":807,"column":4},"end":{"line":807,"column":4}}]},"62":{"line":812,"type":"if","locations":[{"start":{"line":812,"column":4},"end":{"line":812,"column":4}},{"start":{"line":812,"column":4},"end":{"line":812,"column":4}}]},"63":{"line":817,"type":"if","locations":[{"start":{"line":817,"column":4},"end":{"line":817,"column":4}},{"start":{"line":817,"column":4},"end":{"line":817,"column":4}}]},"64":{"line":944,"type":"if","locations":[{"start":{"line":944,"column":4},"end":{"line":944,"column":4}},{"start":{"line":944,"column":4},"end":{"line":944,"column":4}}]},"65":{"line":949,"type":"if","locations":[{"start":{"line":949,"column":4},"end":{"line":949,"column":4}},{"start":{"line":949,"column":4},"end":{"line":949,"column":4}}]},"66":{"line":954,"type":"if","locations":[{"start":{"line":954,"column":4},"end":{"line":954,"column":4}},{"start":{"line":954,"column":4},"end":{"line":954,"column":4}}]},"67":{"line":959,"type":"if","locations":[{"start":{"line":959,"column":4},"end":{"line":959,"column":4}},{"start":{"line":959,"column":4},"end":{"line":959,"column":4}}]},"68":{"line":964,"type":"if","locations":[{"start":{"line":964,"column":4},"end":{"line":964,"column":4}},{"start":{"line":964,"column":4},"end":{"line":964,"column":4}}]},"69":{"line":982,"type":"if","locations":[{"start":{"line":982,"column":4},"end":{"line":982,"column":4}},{"start":{"line":982,"column":4},"end":{"line":982,"column":4}}]},"70":{"line":987,"type":"if","locations":[{"start":{"line":987,"column":4},"end":{"line":987,"column":4}},{"start":{"line":987,"column":4},"end":{"line":987,"column":4}}]},"71":{"line":992,"type":"if","locations":[{"start":{"line":992,"column":4},"end":{"line":992,"column":4}},{"start":{"line":992,"column":4},"end":{"line":992,"column":4}}]},"72":{"line":997,"type":"if","locations":[{"start":{"line":997,"column":4},"end":{"line":997,"column":4}},{"start":{"line":997,"column":4},"end":{"line":997,"column":4}}]},"73":{"line":1002,"type":"if","locations":[{"start":{"line":1002,"column":4},"end":{"line":1002,"column":4}},{"start":{"line":1002,"column":4},"end":{"line":1002,"column":4}}]},"74":{"line":1007,"type":"if","locations":[{"start":{"line":1007,"column":4},"end":{"line":1007,"column":4}},{"start":{"line":1007,"column":4},"end":{"line":1007,"column":4}}]},"75":{"line":1012,"type":"if","locations":[{"start":{"line":1012,"column":4},"end":{"line":1012,"column":4}},{"start":{"line":1012,"column":4},"end":{"line":1012,"column":4}}]},"76":{"line":1017,"type":"if","locations":[{"start":{"line":1017,"column":4},"end":{"line":1017,"column":4}},{"start":{"line":1017,"column":4},"end":{"line":1017,"column":4}}]},"77":{"line":1022,"type":"if","locations":[{"start":{"line":1022,"column":4},"end":{"line":1022,"column":4}},{"start":{"line":1022,"column":4},"end":{"line":1022,"column":4}}]},"78":{"line":1027,"type":"if","locations":[{"start":{"line":1027,"column":4},"end":{"line":1027,"column":4}},{"start":{"line":1027,"column":4},"end":{"line":1027,"column":4}}]},"79":{"line":1032,"type":"if","locations":[{"start":{"line":1032,"column":4},"end":{"line":1032,"column":4}},{"start":{"line":1032,"column":4},"end":{"line":1032,"column":4}}]},"80":{"line":1037,"type":"if","locations":[{"start":{"line":1037,"column":4},"end":{"line":1037,"column":4}},{"start":{"line":1037,"column":4},"end":{"line":1037,"column":4}}]},"81":{"line":1042,"type":"if","locations":[{"start":{"line":1042,"column":4},"end":{"line":1042,"column":4}},{"start":{"line":1042,"column":4},"end":{"line":1042,"column":4}}]},"82":{"line":1047,"type":"if","locations":[{"start":{"line":1047,"column":4},"end":{"line":1047,"column":4}},{"start":{"line":1047,"column":4},"end":{"line":1047,"column":4}}]},"83":{"line":1052,"type":"if","locations":[{"start":{"line":1052,"column":4},"end":{"line":1052,"column":4}},{"start":{"line":1052,"column":4},"end":{"line":1052,"column":4}}]},"84":{"line":1057,"type":"if","locations":[{"start":{"line":1057,"column":4},"end":{"line":1057,"column":4}},{"start":{"line":1057,"column":4},"end":{"line":1057,"column":4}}]},"85":{"line":1062,"type":"if","locations":[{"start":{"line":1062,"column":4},"end":{"line":1062,"column":4}},{"start":{"line":1062,"column":4},"end":{"line":1062,"column":4}}]},"86":{"line":1067,"type":"if","locations":[{"start":{"line":1067,"column":4},"end":{"line":1067,"column":4}},{"start":{"line":1067,"column":4},"end":{"line":1067,"column":4}}]},"87":{"line":1072,"type":"if","locations":[{"start":{"line":1072,"column":4},"end":{"line":1072,"column":4}},{"start":{"line":1072,"column":4},"end":{"line":1072,"column":4}}]},"88":{"line":1077,"type":"if","locations":[{"start":{"line":1077,"column":4},"end":{"line":1077,"column":4}},{"start":{"line":1077,"column":4},"end":{"line":1077,"column":4}}]},"89":{"line":1082,"type":"if","locations":[{"start":{"line":1082,"column":4},"end":{"line":1082,"column":4}},{"start":{"line":1082,"column":4},"end":{"line":1082,"column":4}}]},"90":{"line":1087,"type":"if","locations":[{"start":{"line":1087,"column":4},"end":{"line":1087,"column":4}},{"start":{"line":1087,"column":4},"end":{"line":1087,"column":4}}]},"91":{"line":1092,"type":"if","locations":[{"start":{"line":1092,"column":4},"end":{"line":1092,"column":4}},{"start":{"line":1092,"column":4},"end":{"line":1092,"column":4}}]},"92":{"line":1097,"type":"if","locations":[{"start":{"line":1097,"column":4},"end":{"line":1097,"column":4}},{"start":{"line":1097,"column":4},"end":{"line":1097,"column":4}}]},"93":{"line":1102,"type":"if","locations":[{"start":{"line":1102,"column":4},"end":{"line":1102,"column":4}},{"start":{"line":1102,"column":4},"end":{"line":1102,"column":4}}]},"94":{"line":1107,"type":"if","locations":[{"start":{"line":1107,"column":4},"end":{"line":1107,"column":4}},{"start":{"line":1107,"column":4},"end":{"line":1107,"column":4}}]},"95":{"line":1112,"type":"if","locations":[{"start":{"line":1112,"column":4},"end":{"line":1112,"column":4}},{"start":{"line":1112,"column":4},"end":{"line":1112,"column":4}}]},"96":{"line":1117,"type":"if","locations":[{"start":{"line":1117,"column":4},"end":{"line":1117,"column":4}},{"start":{"line":1117,"column":4},"end":{"line":1117,"column":4}}]},"97":{"line":1122,"type":"if","locations":[{"start":{"line":1122,"column":4},"end":{"line":1122,"column":4}},{"start":{"line":1122,"column":4},"end":{"line":1122,"column":4}}]},"98":{"line":1127,"type":"if","locations":[{"start":{"line":1127,"column":4},"end":{"line":1127,"column":4}},{"start":{"line":1127,"column":4},"end":{"line":1127,"column":4}}]},"99":{"line":1132,"type":"if","locations":[{"start":{"line":1132,"column":4},"end":{"line":1132,"column":4}},{"start":{"line":1132,"column":4},"end":{"line":1132,"column":4}}]},"100":{"line":1137,"type":"if","locations":[{"start":{"line":1137,"column":4},"end":{"line":1137,"column":4}},{"start":{"line":1137,"column":4},"end":{"line":1137,"column":4}}]},"101":{"line":1142,"type":"if","locations":[{"start":{"line":1142,"column":4},"end":{"line":1142,"column":4}},{"start":{"line":1142,"column":4},"end":{"line":1142,"column":4}}]},"102":{"line":1147,"type":"if","locations":[{"start":{"line":1147,"column":4},"end":{"line":1147,"column":4}},{"start":{"line":1147,"column":4},"end":{"line":1147,"column":4}}]},"103":{"line":1152,"type":"if","locations":[{"start":{"line":1152,"column":4},"end":{"line":1152,"column":4}},{"start":{"line":1152,"column":4},"end":{"line":1152,"column":4}}]},"104":{"line":1157,"type":"if","locations":[{"start":{"line":1157,"column":4},"end":{"line":1157,"column":4}},{"start":{"line":1157,"column":4},"end":{"line":1157,"column":4}}]},"105":{"line":1162,"type":"if","locations":[{"start":{"line":1162,"column":4},"end":{"line":1162,"column":4}},{"start":{"line":1162,"column":4},"end":{"line":1162,"column":4}}]},"106":{"line":1167,"type":"if","locations":[{"start":{"line":1167,"column":4},"end":{"line":1167,"column":4}},{"start":{"line":1167,"column":4},"end":{"line":1167,"column":4}}]},"107":{"line":1172,"type":"if","locations":[{"start":{"line":1172,"column":4},"end":{"line":1172,"column":4}},{"start":{"line":1172,"column":4},"end":{"line":1172,"column":4}}]},"108":{"line":1177,"type":"if","locations":[{"start":{"line":1177,"column":4},"end":{"line":1177,"column":4}},{"start":{"line":1177,"column":4},"end":{"line":1177,"column":4}}]},"109":{"line":1182,"type":"if","locations":[{"start":{"line":1182,"column":4},"end":{"line":1182,"column":4}},{"start":{"line":1182,"column":4},"end":{"line":1182,"column":4}}]},"110":{"line":1187,"type":"if","locations":[{"start":{"line":1187,"column":4},"end":{"line":1187,"column":4}},{"start":{"line":1187,"column":4},"end":{"line":1187,"column":4}}]},"111":{"line":1192,"type":"if","locations":[{"start":{"line":1192,"column":4},"end":{"line":1192,"column":4}},{"start":{"line":1192,"column":4},"end":{"line":1192,"column":4}}]},"112":{"line":1197,"type":"if","locations":[{"start":{"line":1197,"column":4},"end":{"line":1197,"column":4}},{"start":{"line":1197,"column":4},"end":{"line":1197,"column":4}}]},"113":{"line":1202,"type":"if","locations":[{"start":{"line":1202,"column":4},"end":{"line":1202,"column":4}},{"start":{"line":1202,"column":4},"end":{"line":1202,"column":4}}]},"114":{"line":1207,"type":"if","locations":[{"start":{"line":1207,"column":4},"end":{"line":1207,"column":4}},{"start":{"line":1207,"column":4},"end":{"line":1207,"column":4}}]},"115":{"line":1212,"type":"if","locations":[{"start":{"line":1212,"column":4},"end":{"line":1212,"column":4}},{"start":{"line":1212,"column":4},"end":{"line":1212,"column":4}}]},"116":{"line":1217,"type":"if","locations":[{"start":{"line":1217,"column":4},"end":{"line":1217,"column":4}},{"start":{"line":1217,"column":4},"end":{"line":1217,"column":4}}]},"117":{"line":1222,"type":"if","locations":[{"start":{"line":1222,"column":4},"end":{"line":1222,"column":4}},{"start":{"line":1222,"column":4},"end":{"line":1222,"column":4}}]},"118":{"line":1227,"type":"if","locations":[{"start":{"line":1227,"column":4},"end":{"line":1227,"column":4}},{"start":{"line":1227,"column":4},"end":{"line":1227,"column":4}}]},"119":{"line":1343,"type":"if","locations":[{"start":{"line":1343,"column":4},"end":{"line":1343,"column":4}},{"start":{"line":1343,"column":4},"end":{"line":1343,"column":4}}]},"120":{"line":1409,"type":"if","locations":[{"start":{"line":1409,"column":11},"end":{"line":1409,"column":11}},{"start":{"line":1409,"column":11},"end":{"line":1409,"column":11}}]},"121":{"line":1484,"type":"if","locations":[{"start":{"line":1484,"column":4},"end":{"line":1484,"column":4}},{"start":{"line":1484,"column":4},"end":{"line":1484,"column":4}}]},"122":{"line":1516,"type":"if","locations":[{"start":{"line":1516,"column":4},"end":{"line":1516,"column":4}},{"start":{"line":1516,"column":4},"end":{"line":1516,"column":4}}]},"123":{"line":1520,"type":"if","locations":[{"start":{"line":1520,"column":4},"end":{"line":1520,"column":4}},{"start":{"line":1520,"column":4},"end":{"line":1520,"column":4}}]},"124":{"line":1524,"type":"if","locations":[{"start":{"line":1524,"column":4},"end":{"line":1524,"column":4}},{"start":{"line":1524,"column":4},"end":{"line":1524,"column":4}}]},"125":{"line":1548,"type":"if","locations":[{"start":{"line":1548,"column":4},"end":{"line":1548,"column":4}},{"start":{"line":1548,"column":4},"end":{"line":1548,"column":4}}]},"126":{"line":1552,"type":"if","locations":[{"start":{"line":1552,"column":4},"end":{"line":1552,"column":4}},{"start":{"line":1552,"column":4},"end":{"line":1552,"column":4}}]},"127":{"line":1556,"type":"if","locations":[{"start":{"line":1556,"column":4},"end":{"line":1556,"column":4}},{"start":{"line":1556,"column":4},"end":{"line":1556,"column":4}}]},"128":{"line":1560,"type":"if","locations":[{"start":{"line":1560,"column":4},"end":{"line":1560,"column":4}},{"start":{"line":1560,"column":4},"end":{"line":1560,"column":4}}]},"129":{"line":1615,"type":"if","locations":[{"start":{"line":1615,"column":4},"end":{"line":1615,"column":4}},{"start":{"line":1615,"column":4},"end":{"line":1615,"column":4}}]},"130":{"line":1622,"type":"if","locations":[{"start":{"line":1622,"column":11},"end":{"line":1622,"column":11}},{"start":{"line":1622,"column":11},"end":{"line":1622,"column":11}}]},"131":{"line":1646,"type":"if","locations":[{"start":{"line":1646,"column":4},"end":{"line":1646,"column":4}},{"start":{"line":1646,"column":4},"end":{"line":1646,"column":4}}]},"132":{"line":1652,"type":"if","locations":[{"start":{"line":1652,"column":4},"end":{"line":1652,"column":4}},{"start":{"line":1652,"column":4},"end":{"line":1652,"column":4}}]},"133":{"line":1766,"type":"if","locations":[{"start":{"line":1766,"column":4},"end":{"line":1766,"column":4}},{"start":{"line":1766,"column":4},"end":{"line":1766,"column":4}}]},"134":{"line":1771,"type":"if","locations":[{"start":{"line":1771,"column":4},"end":{"line":1771,"column":4}},{"start":{"line":1771,"column":4},"end":{"line":1771,"column":4}}]},"135":{"line":1776,"type":"if","locations":[{"start":{"line":1776,"column":4},"end":{"line":1776,"column":4}},{"start":{"line":1776,"column":4},"end":{"line":1776,"column":4}}]},"136":{"line":1781,"type":"if","locations":[{"start":{"line":1781,"column":4},"end":{"line":1781,"column":4}},{"start":{"line":1781,"column":4},"end":{"line":1781,"column":4}}]},"137":{"line":1786,"type":"if","locations":[{"start":{"line":1786,"column":4},"end":{"line":1786,"column":4}},{"start":{"line":1786,"column":4},"end":{"line":1786,"column":4}}]},"138":{"line":1791,"type":"if","locations":[{"start":{"line":1791,"column":4},"end":{"line":1791,"column":4}},{"start":{"line":1791,"column":4},"end":{"line":1791,"column":4}}]},"139":{"line":1796,"type":"if","locations":[{"start":{"line":1796,"column":4},"end":{"line":1796,"column":4}},{"start":{"line":1796,"column":4},"end":{"line":1796,"column":4}}]},"140":{"line":1801,"type":"if","locations":[{"start":{"line":1801,"column":4},"end":{"line":1801,"column":4}},{"start":{"line":1801,"column":4},"end":{"line":1801,"column":4}}]},"141":{"line":1806,"type":"if","locations":[{"start":{"line":1806,"column":4},"end":{"line":1806,"column":4}},{"start":{"line":1806,"column":4},"end":{"line":1806,"column":4}}]},"142":{"line":1811,"type":"if","locations":[{"start":{"line":1811,"column":4},"end":{"line":1811,"column":4}},{"start":{"line":1811,"column":4},"end":{"line":1811,"column":4}}]},"143":{"line":1845,"type":"if","locations":[{"start":{"line":1845,"column":4},"end":{"line":1845,"column":4}},{"start":{"line":1845,"column":4},"end":{"line":1845,"column":4}}]},"144":{"line":1849,"type":"if","locations":[{"start":{"line":1849,"column":4},"end":{"line":1849,"column":4}},{"start":{"line":1849,"column":4},"end":{"line":1849,"column":4}}]},"145":{"line":1933,"type":"if","locations":[{"start":{"line":1933,"column":12},"end":{"line":1933,"column":12}},{"start":{"line":1933,"column":12},"end":{"line":1933,"column":12}}]},"146":{"line":1947,"type":"if","locations":[{"start":{"line":1947,"column":4},"end":{"line":1947,"column":4}},{"start":{"line":1947,"column":4},"end":{"line":1947,"column":4}}]},"147":{"line":2014,"type":"if","locations":[{"start":{"line":2014,"column":8},"end":{"line":2014,"column":8}},{"start":{"line":2014,"column":8},"end":{"line":2014,"column":8}}]},"148":{"line":2070,"type":"if","locations":[{"start":{"line":2070,"column":12},"end":{"line":2070,"column":12}},{"start":{"line":2070,"column":12},"end":{"line":2070,"column":12}}]},"149":{"line":2088,"type":"if","locations":[{"start":{"line":2088,"column":12},"end":{"line":2088,"column":12}},{"start":{"line":2088,"column":12},"end":{"line":2088,"column":12}}]},"150":{"line":2089,"type":"binary-expr","locations":[{"start":{"line":2089,"column":17},"end":{"line":2089,"column":38}},{"start":{"line":2089,"column":42},"end":{"line":2089,"column":63}},{"start":{"line":2090,"column":17},"end":{"line":2090,"column":38}},{"start":{"line":2090,"column":42},"end":{"line":2090,"column":63}},{"start":{"line":2091,"column":17},"end":{"line":2091,"column":38}},{"start":{"line":2091,"column":42},"end":{"line":2091,"column":63}},{"start":{"line":2092,"column":17},"end":{"line":2092,"column":38}},{"start":{"line":2092,"column":42},"end":{"line":2092,"column":63}},{"start":{"line":2093,"column":17},"end":{"line":2093,"column":38}},{"start":{"line":2093,"column":42},"end":{"line":2093,"column":63}},{"start":{"line":2094,"column":17},"end":{"line":2094,"column":38}},{"start":{"line":2094,"column":42},"end":{"line":2094,"column":63}}]},"151":{"line":2107,"type":"if","locations":[{"start":{"line":2107,"column":16},"end":{"line":2107,"column":16}},{"start":{"line":2107,"column":16},"end":{"line":2107,"column":16}}]},"152":{"line":2146,"type":"if","locations":[{"start":{"line":2146,"column":8},"end":{"line":2146,"column":8}},{"start":{"line":2146,"column":8},"end":{"line":2146,"column":8}}]},"153":{"line":2147,"type":"binary-expr","locations":[{"start":{"line":2147,"column":13},"end":{"line":2147,"column":60}},{"start":{"line":2148,"column":12},"end":{"line":2148,"column":59}},{"start":{"line":2149,"column":13},"end":{"line":2149,"column":60}},{"start":{"line":2150,"column":12},"end":{"line":2150,"column":59}},{"start":{"line":2151,"column":13},"end":{"line":2151,"column":60}},{"start":{"line":2152,"column":12},"end":{"line":2152,"column":59}}]},"154":{"line":2182,"type":"if","locations":[{"start":{"line":2182,"column":12},"end":{"line":2182,"column":12}},{"start":{"line":2182,"column":12},"end":{"line":2182,"column":12}}]},"155":{"line":2182,"type":"binary-expr","locations":[{"start":{"line":2182,"column":16},"end":{"line":2182,"column":25}},{"start":{"line":2182,"column":29},"end":{"line":2182,"column":72}}]},"156":{"line":2196,"type":"if","locations":[{"start":{"line":2196,"column":12},"end":{"line":2196,"column":12}},{"start":{"line":2196,"column":12},"end":{"line":2196,"column":12}}]},"157":{"line":2201,"type":"if","locations":[{"start":{"line":2201,"column":8},"end":{"line":2201,"column":8}},{"start":{"line":2201,"column":8},"end":{"line":2201,"column":8}}]},"158":{"line":2219,"type":"if","locations":[{"start":{"line":2219,"column":4},"end":{"line":2219,"column":4}},{"start":{"line":2219,"column":4},"end":{"line":2219,"column":4}}]},"159":{"line":2219,"type":"binary-expr","locations":[{"start":{"line":2219,"column":8},"end":{"line":2219,"column":38}},{"start":{"line":2219,"column":42},"end":{"line":2219,"column":68}}]},"160":{"line":2271,"type":"if","locations":[{"start":{"line":2271,"column":4},"end":{"line":2271,"column":4}},{"start":{"line":2271,"column":4},"end":{"line":2271,"column":4}}]},"161":{"line":2392,"type":"binary-expr","locations":[{"start":{"line":2392,"column":20},"end":{"line":2392,"column":28}},{"start":{"line":2392,"column":32},"end":{"line":2392,"column":56}}]},"162":{"line":2393,"type":"binary-expr","locations":[{"start":{"line":2393,"column":20},"end":{"line":2393,"column":28}},{"start":{"line":2393,"column":32},"end":{"line":2393,"column":56}}]},"163":{"line":2394,"type":"binary-expr","locations":[{"start":{"line":2394,"column":27},"end":{"line":2394,"column":42}},{"start":{"line":2394,"column":46},"end":{"line":2394,"column":70}}]},"164":{"line":2395,"type":"binary-expr","locations":[{"start":{"line":2395,"column":22},"end":{"line":2395,"column":32}},{"start":{"line":2395,"column":36},"end":{"line":2395,"column":70}}]},"165":{"line":2396,"type":"cond-expr","locations":[{"start":{"line":2396,"column":45},"end":{"line":2396,"column":46}},{"start":{"line":2396,"column":49},"end":{"line":2396,"column":53}}]},"166":{"line":2397,"type":"cond-expr","locations":[{"start":{"line":2397,"column":53},"end":{"line":2397,"column":54}},{"start":{"line":2397,"column":57},"end":{"line":2397,"column":65}}]},"167":{"line":2398,"type":"cond-expr","locations":[{"start":{"line":2398,"column":63},"end":{"line":2398,"column":67}},{"start":{"line":2398,"column":70},"end":{"line":2398,"column":83}}]},"168":{"line":2399,"type":"cond-expr","locations":[{"start":{"line":2399,"column":65},"end":{"line":2399,"column":69}},{"start":{"line":2399,"column":72},"end":{"line":2399,"column":86}}]},"169":{"line":2400,"type":"cond-expr","locations":[{"start":{"line":2400,"column":57},"end":{"line":2400,"column":61}},{"start":{"line":2400,"column":64},"end":{"line":2400,"column":74}}]},"170":{"line":2401,"type":"cond-expr","locations":[{"start":{"line":2401,"column":67},"end":{"line":2401,"column":70}},{"start":{"line":2401,"column":73},"end":{"line":2401,"column":88}}]},"171":{"line":2402,"type":"cond-expr","locations":[{"start":{"line":2402,"column":65},"end":{"line":2402,"column":68}},{"start":{"line":2402,"column":71},"end":{"line":2402,"column":85}}]},"172":{"line":2403,"type":"cond-expr","locations":[{"start":{"line":2403,"column":77},"end":{"line":2403,"column":78}},{"start":{"line":2403,"column":81},"end":{"line":2403,"column":101}}]},"173":{"line":2404,"type":"cond-expr","locations":[{"start":{"line":2404,"column":75},"end":{"line":2404,"column":76}},{"start":{"line":2404,"column":79},"end":{"line":2404,"column":98}}]},"174":{"line":2405,"type":"cond-expr","locations":[{"start":{"line":2405,"column":63},"end":{"line":2405,"column":68}},{"start":{"line":2405,"column":71},"end":{"line":2405,"column":84}}]},"175":{"line":2406,"type":"cond-expr","locations":[{"start":{"line":2406,"column":47},"end":{"line":2406,"column":51}},{"start":{"line":2406,"column":54},"end":{"line":2406,"column":59}}]},"176":{"line":2420,"type":"if","locations":[{"start":{"line":2420,"column":4},"end":{"line":2420,"column":4}},{"start":{"line":2420,"column":4},"end":{"line":2420,"column":4}}]},"177":{"line":2477,"type":"if","locations":[{"start":{"line":2477,"column":4},"end":{"line":2477,"column":4}},{"start":{"line":2477,"column":4},"end":{"line":2477,"column":4}}]},"178":{"line":2482,"type":"if","locations":[{"start":{"line":2482,"column":4},"end":{"line":2482,"column":4}},{"start":{"line":2482,"column":4},"end":{"line":2482,"column":4}}]},"179":{"line":2487,"type":"if","locations":[{"start":{"line":2487,"column":4},"end":{"line":2487,"column":4}},{"start":{"line":2487,"column":4},"end":{"line":2487,"column":4}}]},"180":{"line":2492,"type":"if","locations":[{"start":{"line":2492,"column":4},"end":{"line":2492,"column":4}},{"start":{"line":2492,"column":4},"end":{"line":2492,"column":4}}]},"181":{"line":2497,"type":"if","locations":[{"start":{"line":2497,"column":4},"end":{"line":2497,"column":4}},{"start":{"line":2497,"column":4},"end":{"line":2497,"column":4}}]},"182":{"line":2502,"type":"if","locations":[{"start":{"line":2502,"column":4},"end":{"line":2502,"column":4}},{"start":{"line":2502,"column":4},"end":{"line":2502,"column":4}}]},"183":{"line":2507,"type":"if","locations":[{"start":{"line":2507,"column":4},"end":{"line":2507,"column":4}},{"start":{"line":2507,"column":4},"end":{"line":2507,"column":4}}]},"184":{"line":2512,"type":"if","locations":[{"start":{"line":2512,"column":4},"end":{"line":2512,"column":4}},{"start":{"line":2512,"column":4},"end":{"line":2512,"column":4}}]},"185":{"line":2528,"type":"if","locations":[{"start":{"line":2528,"column":4},"end":{"line":2528,"column":4}},{"start":{"line":2528,"column":4},"end":{"line":2528,"column":4}}]},"186":{"line":2541,"type":"if","locations":[{"start":{"line":2541,"column":12},"end":{"line":2541,"column":12}},{"start":{"line":2541,"column":12},"end":{"line":2541,"column":12}}]},"187":{"line":2545,"type":"if","locations":[{"start":{"line":2545,"column":16},"end":{"line":2545,"column":16}},{"start":{"line":2545,"column":16},"end":{"line":2545,"column":16}}]},"188":{"line":2545,"type":"binary-expr","locations":[{"start":{"line":2545,"column":20},"end":{"line":2545,"column":35}},{"start":{"line":2545,"column":39},"end":{"line":2545,"column":65}}]},"189":{"line":2553,"type":"if","locations":[{"start":{"line":2553,"column":16},"end":{"line":2553,"column":16}},{"start":{"line":2553,"column":16},"end":{"line":2553,"column":16}}]},"190":{"line":2553,"type":"binary-expr","locations":[{"start":{"line":2553,"column":20},"end":{"line":2553,"column":33}},{"start":{"line":2553,"column":37},"end":{"line":2553,"column":61}}]},"191":{"line":2684,"type":"binary-expr","locations":[{"start":{"line":2684,"column":20},"end":{"line":2684,"column":29}},{"start":{"line":2684,"column":33},"end":{"line":2684,"column":41}}]},"192":{"line":2867,"type":"if","locations":[{"start":{"line":2867,"column":8},"end":{"line":2867,"column":8}},{"start":{"line":2867,"column":8},"end":{"line":2867,"column":8}}]},"193":{"line":2924,"type":"if","locations":[{"start":{"line":2924,"column":8},"end":{"line":2924,"column":8}},{"start":{"line":2924,"column":8},"end":{"line":2924,"column":8}}]},"194":{"line":2934,"type":"if","locations":[{"start":{"line":2934,"column":16},"end":{"line":2934,"column":16}},{"start":{"line":2934,"column":16},"end":{"line":2934,"column":16}}]},"195":{"line":2938,"type":"if","locations":[{"start":{"line":2938,"column":16},"end":{"line":2938,"column":16}},{"start":{"line":2938,"column":16},"end":{"line":2938,"column":16}}]},"196":{"line":2942,"type":"if","locations":[{"start":{"line":2942,"column":16},"end":{"line":2942,"column":16}},{"start":{"line":2942,"column":16},"end":{"line":2942,"column":16}}]},"197":{"line":2948,"type":"if","locations":[{"start":{"line":2948,"column":16},"end":{"line":2948,"column":16}},{"start":{"line":2948,"column":16},"end":{"line":2948,"column":16}}]},"198":{"line":2968,"type":"if","locations":[{"start":{"line":2968,"column":16},"end":{"line":2968,"column":16}},{"start":{"line":2968,"column":16},"end":{"line":2968,"column":16}}]},"199":{"line":3038,"type":"if","locations":[{"start":{"line":3038,"column":4},"end":{"line":3038,"column":4}},{"start":{"line":3038,"column":4},"end":{"line":3038,"column":4}}]},"200":{"line":3039,"type":"if","locations":[{"start":{"line":3039,"column":8},"end":{"line":3039,"column":8}},{"start":{"line":3039,"column":8},"end":{"line":3039,"column":8}}]},"201":{"line":3086,"type":"if","locations":[{"start":{"line":3086,"column":4},"end":{"line":3086,"column":4}},{"start":{"line":3086,"column":4},"end":{"line":3086,"column":4}}]},"202":{"line":3095,"type":"if","locations":[{"start":{"line":3095,"column":4},"end":{"line":3095,"column":4}},{"start":{"line":3095,"column":4},"end":{"line":3095,"column":4}}]},"203":{"line":3100,"type":"if","locations":[{"start":{"line":3100,"column":4},"end":{"line":3100,"column":4}},{"start":{"line":3100,"column":4},"end":{"line":3100,"column":4}}]},"204":{"line":3104,"type":"if","locations":[{"start":{"line":3104,"column":4},"end":{"line":3104,"column":4}},{"start":{"line":3104,"column":4},"end":{"line":3104,"column":4}}]},"205":{"line":3109,"type":"if","locations":[{"start":{"line":3109,"column":4},"end":{"line":3109,"column":4}},{"start":{"line":3109,"column":4},"end":{"line":3109,"column":4}}]},"206":{"line":3114,"type":"if","locations":[{"start":{"line":3114,"column":4},"end":{"line":3114,"column":4}},{"start":{"line":3114,"column":4},"end":{"line":3114,"column":4}}]},"207":{"line":3119,"type":"if","locations":[{"start":{"line":3119,"column":4},"end":{"line":3119,"column":4}},{"start":{"line":3119,"column":4},"end":{"line":3119,"column":4}}]},"208":{"line":3209,"type":"if","locations":[{"start":{"line":3209,"column":4},"end":{"line":3209,"column":4}},{"start":{"line":3209,"column":4},"end":{"line":3209,"column":4}}]},"209":{"line":3210,"type":"if","locations":[{"start":{"line":3210,"column":8},"end":{"line":3210,"column":8}},{"start":{"line":3210,"column":8},"end":{"line":3210,"column":8}}]},"210":{"line":3212,"type":"if","locations":[{"start":{"line":3212,"column":15},"end":{"line":3212,"column":15}},{"start":{"line":3212,"column":15},"end":{"line":3212,"column":15}}]},"211":{"line":3281,"type":"if","locations":[{"start":{"line":3281,"column":4},"end":{"line":3281,"column":4}},{"start":{"line":3281,"column":4},"end":{"line":3281,"column":4}}]},"212":{"line":3286,"type":"if","locations":[{"start":{"line":3286,"column":4},"end":{"line":3286,"column":4}},{"start":{"line":3286,"column":4},"end":{"line":3286,"column":4}}]},"213":{"line":3291,"type":"if","locations":[{"start":{"line":3291,"column":4},"end":{"line":3291,"column":4}},{"start":{"line":3291,"column":4},"end":{"line":3291,"column":4}}]},"214":{"line":3296,"type":"if","locations":[{"start":{"line":3296,"column":4},"end":{"line":3296,"column":4}},{"start":{"line":3296,"column":4},"end":{"line":3296,"column":4}}]},"215":{"line":3301,"type":"if","locations":[{"start":{"line":3301,"column":4},"end":{"line":3301,"column":4}},{"start":{"line":3301,"column":4},"end":{"line":3301,"column":4}}]},"216":{"line":3306,"type":"if","locations":[{"start":{"line":3306,"column":4},"end":{"line":3306,"column":4}},{"start":{"line":3306,"column":4},"end":{"line":3306,"column":4}}]},"217":{"line":3311,"type":"if","locations":[{"start":{"line":3311,"column":4},"end":{"line":3311,"column":4}},{"start":{"line":3311,"column":4},"end":{"line":3311,"column":4}}]},"218":{"line":3316,"type":"if","locations":[{"start":{"line":3316,"column":4},"end":{"line":3316,"column":4}},{"start":{"line":3316,"column":4},"end":{"line":3316,"column":4}}]},"219":{"line":3321,"type":"if","locations":[{"start":{"line":3321,"column":4},"end":{"line":3321,"column":4}},{"start":{"line":3321,"column":4},"end":{"line":3321,"column":4}}]},"220":{"line":3326,"type":"if","locations":[{"start":{"line":3326,"column":4},"end":{"line":3326,"column":4}},{"start":{"line":3326,"column":4},"end":{"line":3326,"column":4}}]},"221":{"line":3331,"type":"if","locations":[{"start":{"line":3331,"column":4},"end":{"line":3331,"column":4}},{"start":{"line":3331,"column":4},"end":{"line":3331,"column":4}}]},"222":{"line":3336,"type":"if","locations":[{"start":{"line":3336,"column":4},"end":{"line":3336,"column":4}},{"start":{"line":3336,"column":4},"end":{"line":3336,"column":4}}]},"223":{"line":3341,"type":"if","locations":[{"start":{"line":3341,"column":4},"end":{"line":3341,"column":4}},{"start":{"line":3341,"column":4},"end":{"line":3341,"column":4}}]},"224":{"line":3346,"type":"if","locations":[{"start":{"line":3346,"column":4},"end":{"line":3346,"column":4}},{"start":{"line":3346,"column":4},"end":{"line":3346,"column":4}}]},"225":{"line":3351,"type":"if","locations":[{"start":{"line":3351,"column":4},"end":{"line":3351,"column":4}},{"start":{"line":3351,"column":4},"end":{"line":3351,"column":4}}]},"226":{"line":3356,"type":"if","locations":[{"start":{"line":3356,"column":4},"end":{"line":3356,"column":4}},{"start":{"line":3356,"column":4},"end":{"line":3356,"column":4}}]},"227":{"line":3361,"type":"if","locations":[{"start":{"line":3361,"column":4},"end":{"line":3361,"column":4}},{"start":{"line":3361,"column":4},"end":{"line":3361,"column":4}}]},"228":{"line":3451,"type":"if","locations":[{"start":{"line":3451,"column":4},"end":{"line":3451,"column":4}},{"start":{"line":3451,"column":4},"end":{"line":3451,"column":4}}]},"229":{"line":3451,"type":"binary-expr","locations":[{"start":{"line":3451,"column":8},"end":{"line":3451,"column":22}},{"start":{"line":3451,"column":26},"end":{"line":3451,"column":46}},{"start":{"line":3451,"column":50},"end":{"line":3451,"column":79}}]},"230":{"line":3458,"type":"if","locations":[{"start":{"line":3458,"column":4},"end":{"line":3458,"column":4}},{"start":{"line":3458,"column":4},"end":{"line":3458,"column":4}}]},"231":{"line":3497,"type":"if","locations":[{"start":{"line":3497,"column":16},"end":{"line":3497,"column":16}},{"start":{"line":3497,"column":16},"end":{"line":3497,"column":16}}]},"232":{"line":3533,"type":"if","locations":[{"start":{"line":3533,"column":8},"end":{"line":3533,"column":8}},{"start":{"line":3533,"column":8},"end":{"line":3533,"column":8}}]},"233":{"line":3537,"type":"if","locations":[{"start":{"line":3537,"column":12},"end":{"line":3537,"column":12}},{"start":{"line":3537,"column":12},"end":{"line":3537,"column":12}}]},"234":{"line":3538,"type":"binary-expr","locations":[{"start":{"line":3538,"column":16},"end":{"line":3538,"column":30}},{"start":{"line":3539,"column":16},"end":{"line":3539,"column":36}},{"start":{"line":3540,"column":16},"end":{"line":3540,"column":45}}]},"235":{"line":3545,"type":"if","locations":[{"start":{"line":3545,"column":16},"end":{"line":3545,"column":16}},{"start":{"line":3545,"column":16},"end":{"line":3545,"column":16}}]},"236":{"line":3549,"type":"if","locations":[{"start":{"line":3549,"column":16},"end":{"line":3549,"column":16}},{"start":{"line":3549,"column":16},"end":{"line":3549,"column":16}}]},"237":{"line":3553,"type":"if","locations":[{"start":{"line":3553,"column":16},"end":{"line":3553,"column":16}},{"start":{"line":3553,"column":16},"end":{"line":3553,"column":16}}]},"238":{"line":3557,"type":"if","locations":[{"start":{"line":3557,"column":16},"end":{"line":3557,"column":16}},{"start":{"line":3557,"column":16},"end":{"line":3557,"column":16}}]},"239":{"line":3561,"type":"if","locations":[{"start":{"line":3561,"column":16},"end":{"line":3561,"column":16}},{"start":{"line":3561,"column":16},"end":{"line":3561,"column":16}}]},"240":{"line":3565,"type":"if","locations":[{"start":{"line":3565,"column":16},"end":{"line":3565,"column":16}},{"start":{"line":3565,"column":16},"end":{"line":3565,"column":16}}]},"241":{"line":3569,"type":"if","locations":[{"start":{"line":3569,"column":16},"end":{"line":3569,"column":16}},{"start":{"line":3569,"column":16},"end":{"line":3569,"column":16}}]},"242":{"line":3573,"type":"if","locations":[{"start":{"line":3573,"column":16},"end":{"line":3573,"column":16}},{"start":{"line":3573,"column":16},"end":{"line":3573,"column":16}}]},"243":{"line":3577,"type":"if","locations":[{"start":{"line":3577,"column":16},"end":{"line":3577,"column":16}},{"start":{"line":3577,"column":16},"end":{"line":3577,"column":16}}]},"244":{"line":3581,"type":"if","locations":[{"start":{"line":3581,"column":16},"end":{"line":3581,"column":16}},{"start":{"line":3581,"column":16},"end":{"line":3581,"column":16}}]},"245":{"line":3585,"type":"if","locations":[{"start":{"line":3585,"column":16},"end":{"line":3585,"column":16}},{"start":{"line":3585,"column":16},"end":{"line":3585,"column":16}}]},"246":{"line":3589,"type":"if","locations":[{"start":{"line":3589,"column":16},"end":{"line":3589,"column":16}},{"start":{"line":3589,"column":16},"end":{"line":3589,"column":16}}]},"247":{"line":3649,"type":"if","locations":[{"start":{"line":3649,"column":4},"end":{"line":3649,"column":4}},{"start":{"line":3649,"column":4},"end":{"line":3649,"column":4}}]},"248":{"line":3654,"type":"if","locations":[{"start":{"line":3654,"column":4},"end":{"line":3654,"column":4}},{"start":{"line":3654,"column":4},"end":{"line":3654,"column":4}}]},"249":{"line":3663,"type":"if","locations":[{"start":{"line":3663,"column":4},"end":{"line":3663,"column":4}},{"start":{"line":3663,"column":4},"end":{"line":3663,"column":4}}]},"250":{"line":3672,"type":"if","locations":[{"start":{"line":3672,"column":4},"end":{"line":3672,"column":4}},{"start":{"line":3672,"column":4},"end":{"line":3672,"column":4}}]},"251":{"line":3702,"type":"binary-expr","locations":[{"start":{"line":3703,"column":9},"end":{"line":3703,"column":31}},{"start":{"line":3704,"column":9},"end":{"line":3704,"column":31}},{"start":{"line":3705,"column":9},"end":{"line":3705,"column":31}},{"start":{"line":3709,"column":9},"end":{"line":3709,"column":31}},{"start":{"line":3710,"column":9},"end":{"line":3710,"column":31}},{"start":{"line":3711,"column":9},"end":{"line":3711,"column":31}},{"start":{"line":3715,"column":9},"end":{"line":3715,"column":31}},{"start":{"line":3716,"column":9},"end":{"line":3716,"column":31}},{"start":{"line":3717,"column":9},"end":{"line":3717,"column":31}},{"start":{"line":3721,"column":9},"end":{"line":3721,"column":31}},{"start":{"line":3722,"column":9},"end":{"line":3722,"column":31}},{"start":{"line":3723,"column":9},"end":{"line":3723,"column":31}},{"start":{"line":3727,"column":9},"end":{"line":3727,"column":31}},{"start":{"line":3728,"column":9},"end":{"line":3728,"column":31}},{"start":{"line":3729,"column":9},"end":{"line":3729,"column":31}},{"start":{"line":3733,"column":9},"end":{"line":3733,"column":31}},{"start":{"line":3734,"column":9},"end":{"line":3734,"column":31}},{"start":{"line":3735,"column":9},"end":{"line":3735,"column":31}}]},"252":{"line":3745,"type":"if","locations":[{"start":{"line":3745,"column":4},"end":{"line":3745,"column":4}},{"start":{"line":3745,"column":4},"end":{"line":3745,"column":4}}]},"253":{"line":3749,"type":"if","locations":[{"start":{"line":3749,"column":4},"end":{"line":3749,"column":4}},{"start":{"line":3749,"column":4},"end":{"line":3749,"column":4}}]},"254":{"line":3762,"type":"binary-expr","locations":[{"start":{"line":3762,"column":16},"end":{"line":3762,"column":29}},{"start":{"line":3763,"column":5},"end":{"line":3763,"column":18}},{"start":{"line":3764,"column":6},"end":{"line":3764,"column":19}},{"start":{"line":3765,"column":5},"end":{"line":3765,"column":18}}]},"255":{"line":3774,"type":"if","locations":[{"start":{"line":3774,"column":4},"end":{"line":3774,"column":4}},{"start":{"line":3774,"column":4},"end":{"line":3774,"column":4}}]},"256":{"line":3778,"type":"if","locations":[{"start":{"line":3778,"column":4},"end":{"line":3778,"column":4}},{"start":{"line":3778,"column":4},"end":{"line":3778,"column":4}}]},"257":{"line":3782,"type":"if","locations":[{"start":{"line":3782,"column":4},"end":{"line":3782,"column":4}},{"start":{"line":3782,"column":4},"end":{"line":3782,"column":4}}]},"258":{"line":3789,"type":"if","locations":[{"start":{"line":3789,"column":4},"end":{"line":3789,"column":4}},{"start":{"line":3789,"column":4},"end":{"line":3789,"column":4}}]},"259":{"line":3795,"type":"if","locations":[{"start":{"line":3795,"column":4},"end":{"line":3795,"column":4}},{"start":{"line":3795,"column":4},"end":{"line":3795,"column":4}}]},"260":{"line":3861,"type":"if","locations":[{"start":{"line":3861,"column":4},"end":{"line":3861,"column":4}},{"start":{"line":3861,"column":4},"end":{"line":3861,"column":4}}]},"261":{"line":3865,"type":"if","locations":[{"start":{"line":3865,"column":11},"end":{"line":3865,"column":11}},{"start":{"line":3865,"column":11},"end":{"line":3865,"column":11}}]},"262":{"line":3890,"type":"if","locations":[{"start":{"line":3890,"column":4},"end":{"line":3890,"column":4}},{"start":{"line":3890,"column":4},"end":{"line":3890,"column":4}}]},"263":{"line":3910,"type":"if","locations":[{"start":{"line":3910,"column":4},"end":{"line":3910,"column":4}},{"start":{"line":3910,"column":4},"end":{"line":3910,"column":4}}]},"264":{"line":3914,"type":"if","locations":[{"start":{"line":3914,"column":4},"end":{"line":3914,"column":4}},{"start":{"line":3914,"column":4},"end":{"line":3914,"column":4}}]},"265":{"line":3918,"type":"if","locations":[{"start":{"line":3918,"column":4},"end":{"line":3918,"column":4}},{"start":{"line":3918,"column":4},"end":{"line":3918,"column":4}}]},"266":{"line":3922,"type":"if","locations":[{"start":{"line":3922,"column":4},"end":{"line":3922,"column":4}},{"start":{"line":3922,"column":4},"end":{"line":3922,"column":4}}]},"267":{"line":3944,"type":"if","locations":[{"start":{"line":3944,"column":4},"end":{"line":3944,"column":4}},{"start":{"line":3944,"column":4},"end":{"line":3944,"column":4}}]},"268":{"line":3948,"type":"if","locations":[{"start":{"line":3948,"column":11},"end":{"line":3948,"column":11}},{"start":{"line":3948,"column":11},"end":{"line":3948,"column":11}}]},"269":{"line":3971,"type":"if","locations":[{"start":{"line":3971,"column":4},"end":{"line":3971,"column":4}},{"start":{"line":3971,"column":4},"end":{"line":3971,"column":4}}]},"270":{"line":3986,"type":"if","locations":[{"start":{"line":3986,"column":4},"end":{"line":3986,"column":4}},{"start":{"line":3986,"column":4},"end":{"line":3986,"column":4}}]},"271":{"line":3992,"type":"if","locations":[{"start":{"line":3992,"column":4},"end":{"line":3992,"column":4}},{"start":{"line":3992,"column":4},"end":{"line":3992,"column":4}}]},"272":{"line":4008,"type":"if","locations":[{"start":{"line":4008,"column":4},"end":{"line":4008,"column":4}},{"start":{"line":4008,"column":4},"end":{"line":4008,"column":4}}]},"273":{"line":4017,"type":"if","locations":[{"start":{"line":4017,"column":4},"end":{"line":4017,"column":4}},{"start":{"line":4017,"column":4},"end":{"line":4017,"column":4}}]},"274":{"line":4062,"type":"if","locations":[{"start":{"line":4062,"column":8},"end":{"line":4062,"column":8}},{"start":{"line":4062,"column":8},"end":{"line":4062,"column":8}}]},"275":{"line":4107,"type":"if","locations":[{"start":{"line":4107,"column":8},"end":{"line":4107,"column":8}},{"start":{"line":4107,"column":8},"end":{"line":4107,"column":8}}]},"276":{"line":4160,"type":"if","locations":[{"start":{"line":4160,"column":8},"end":{"line":4160,"column":8}},{"start":{"line":4160,"column":8},"end":{"line":4160,"column":8}}]},"277":{"line":4163,"type":"if","locations":[{"start":{"line":4163,"column":8},"end":{"line":4163,"column":8}},{"start":{"line":4163,"column":8},"end":{"line":4163,"column":8}}]},"278":{"line":4166,"type":"if","locations":[{"start":{"line":4166,"column":8},"end":{"line":4166,"column":8}},{"start":{"line":4166,"column":8},"end":{"line":4166,"column":8}}]},"279":{"line":4170,"type":"if","locations":[{"start":{"line":4170,"column":8},"end":{"line":4170,"column":8}},{"start":{"line":4170,"column":8},"end":{"line":4170,"column":8}}]},"280":{"line":4173,"type":"if","locations":[{"start":{"line":4173,"column":8},"end":{"line":4173,"column":8}},{"start":{"line":4173,"column":8},"end":{"line":4173,"column":8}}]},"281":{"line":4176,"type":"if","locations":[{"start":{"line":4176,"column":8},"end":{"line":4176,"column":8}},{"start":{"line":4176,"column":8},"end":{"line":4176,"column":8}}]},"282":{"line":4265,"type":"if","locations":[{"start":{"line":4265,"column":4},"end":{"line":4265,"column":4}},{"start":{"line":4265,"column":4},"end":{"line":4265,"column":4}}]},"283":{"line":4270,"type":"if","locations":[{"start":{"line":4270,"column":4},"end":{"line":4270,"column":4}},{"start":{"line":4270,"column":4},"end":{"line":4270,"column":4}}]},"284":{"line":4279,"type":"if","locations":[{"start":{"line":4279,"column":4},"end":{"line":4279,"column":4}},{"start":{"line":4279,"column":4},"end":{"line":4279,"column":4}}]},"285":{"line":4288,"type":"if","locations":[{"start":{"line":4288,"column":4},"end":{"line":4288,"column":4}},{"start":{"line":4288,"column":4},"end":{"line":4288,"column":4}}]},"286":{"line":4302,"type":"if","locations":[{"start":{"line":4302,"column":4},"end":{"line":4302,"column":4}},{"start":{"line":4302,"column":4},"end":{"line":4302,"column":4}}]},"287":{"line":4322,"type":"if","locations":[{"start":{"line":4322,"column":4},"end":{"line":4322,"column":4}},{"start":{"line":4322,"column":4},"end":{"line":4322,"column":4}}]},"288":{"line":4324,"type":"if","locations":[{"start":{"line":4324,"column":11},"end":{"line":4324,"column":11}},{"start":{"line":4324,"column":11},"end":{"line":4324,"column":11}}]},"289":{"line":4358,"type":"if","locations":[{"start":{"line":4358,"column":4},"end":{"line":4358,"column":4}},{"start":{"line":4358,"column":4},"end":{"line":4358,"column":4}}]},"290":{"line":4363,"type":"if","locations":[{"start":{"line":4363,"column":8},"end":{"line":4363,"column":8}},{"start":{"line":4363,"column":8},"end":{"line":4363,"column":8}}]},"291":{"line":4363,"type":"binary-expr","locations":[{"start":{"line":4363,"column":11},"end":{"line":4363,"column":25}},{"start":{"line":4363,"column":29},"end":{"line":4363,"column":58}}]},"292":{"line":4367,"type":"if","locations":[{"start":{"line":4367,"column":8},"end":{"line":4367,"column":8}},{"start":{"line":4367,"column":8},"end":{"line":4367,"column":8}}]},"293":{"line":4367,"type":"binary-expr","locations":[{"start":{"line":4367,"column":11},"end":{"line":4367,"column":30}},{"start":{"line":4367,"column":34},"end":{"line":4367,"column":68}}]},"294":{"line":4384,"type":"if","locations":[{"start":{"line":4384,"column":4},"end":{"line":4384,"column":4}},{"start":{"line":4384,"column":4},"end":{"line":4384,"column":4}}]},"295":{"line":4398,"type":"if","locations":[{"start":{"line":4398,"column":4},"end":{"line":4398,"column":4}},{"start":{"line":4398,"column":4},"end":{"line":4398,"column":4}}]},"296":{"line":4414,"type":"if","locations":[{"start":{"line":4414,"column":4},"end":{"line":4414,"column":4}},{"start":{"line":4414,"column":4},"end":{"line":4414,"column":4}}]},"297":{"line":4428,"type":"if","locations":[{"start":{"line":4428,"column":4},"end":{"line":4428,"column":4}},{"start":{"line":4428,"column":4},"end":{"line":4428,"column":4}}]},"298":{"line":4441,"type":"if","locations":[{"start":{"line":4441,"column":4},"end":{"line":4441,"column":4}},{"start":{"line":4441,"column":4},"end":{"line":4441,"column":4}}]},"299":{"line":4449,"type":"if","locations":[{"start":{"line":4449,"column":4},"end":{"line":4449,"column":4}},{"start":{"line":4449,"column":4},"end":{"line":4449,"column":4}}]},"300":{"line":4457,"type":"if","locations":[{"start":{"line":4457,"column":4},"end":{"line":4457,"column":4}},{"start":{"line":4457,"column":4},"end":{"line":4457,"column":4}}]},"301":{"line":4468,"type":"if","locations":[{"start":{"line":4468,"column":4},"end":{"line":4468,"column":4}},{"start":{"line":4468,"column":4},"end":{"line":4468,"column":4}}]},"302":{"line":4476,"type":"if","locations":[{"start":{"line":4476,"column":4},"end":{"line":4476,"column":4}},{"start":{"line":4476,"column":4},"end":{"line":4476,"column":4}}]},"303":{"line":4484,"type":"if","locations":[{"start":{"line":4484,"column":4},"end":{"line":4484,"column":4}},{"start":{"line":4484,"column":4},"end":{"line":4484,"column":4}}]},"304":{"line":4492,"type":"if","locations":[{"start":{"line":4492,"column":4},"end":{"line":4492,"column":4}},{"start":{"line":4492,"column":4},"end":{"line":4492,"column":4}}]},"305":{"line":4500,"type":"if","locations":[{"start":{"line":4500,"column":8},"end":{"line":4500,"column":8}},{"start":{"line":4500,"column":8},"end":{"line":4500,"column":8}}]},"306":{"line":4519,"type":"if","locations":[{"start":{"line":4519,"column":4},"end":{"line":4519,"column":4}},{"start":{"line":4519,"column":4},"end":{"line":4519,"column":4}}]},"307":{"line":4545,"type":"cond-expr","locations":[{"start":{"line":4545,"column":36},"end":{"line":4545,"column":50}},{"start":{"line":4545,"column":53},"end":{"line":4545,"column":61}}]},"308":{"line":4547,"type":"cond-expr","locations":[{"start":{"line":4547,"column":31},"end":{"line":4547,"column":38}},{"start":{"line":4547,"column":41},"end":{"line":4547,"column":44}}]},"309":{"line":4574,"type":"if","locations":[{"start":{"line":4574,"column":8},"end":{"line":4574,"column":8}},{"start":{"line":4574,"column":8},"end":{"line":4574,"column":8}}]},"310":{"line":4601,"type":"binary-expr","locations":[{"start":{"line":4601,"column":29},"end":{"line":4601,"column":47}},{"start":{"line":4601,"column":51},"end":{"line":4601,"column":52}}]},"311":{"line":4602,"type":"binary-expr","locations":[{"start":{"line":4602,"column":27},"end":{"line":4602,"column":45}},{"start":{"line":4602,"column":49},"end":{"line":4602,"column":50}}]},"312":{"line":4604,"type":"cond-expr","locations":[{"start":{"line":4604,"column":53},"end":{"line":4604,"column":90}},{"start":{"line":4604,"column":94},"end":{"line":4604,"column":107}}]},"313":{"line":4612,"type":"if","locations":[{"start":{"line":4612,"column":8},"end":{"line":4612,"column":8}},{"start":{"line":4612,"column":8},"end":{"line":4612,"column":8}}]},"314":{"line":4612,"type":"binary-expr","locations":[{"start":{"line":4612,"column":11},"end":{"line":4612,"column":43}},{"start":{"line":4612,"column":47},"end":{"line":4612,"column":65}}]},"315":{"line":4616,"type":"if","locations":[{"start":{"line":4616,"column":12},"end":{"line":4616,"column":12}},{"start":{"line":4616,"column":12},"end":{"line":4616,"column":12}}]},"316":{"line":4626,"type":"cond-expr","locations":[{"start":{"line":4626,"column":67},"end":{"line":4626,"column":71}},{"start":{"line":4626,"column":74},"end":{"line":4626,"column":75}}]},"317":{"line":4626,"type":"cond-expr","locations":[{"start":{"line":4626,"column":98},"end":{"line":4626,"column":106}},{"start":{"line":4626,"column":109},"end":{"line":4626,"column":111}}]},"318":{"line":4629,"type":"if","locations":[{"start":{"line":4629,"column":19},"end":{"line":4629,"column":19}},{"start":{"line":4629,"column":19},"end":{"line":4629,"column":19}}]},"319":{"line":4631,"type":"if","locations":[{"start":{"line":4631,"column":19},"end":{"line":4631,"column":19}},{"start":{"line":4631,"column":19},"end":{"line":4631,"column":19}}]},"320":{"line":4636,"type":"cond-expr","locations":[{"start":{"line":4636,"column":57},"end":{"line":4636,"column":61}},{"start":{"line":4636,"column":64},"end":{"line":4636,"column":73}}]},"321":{"line":4644,"type":"if","locations":[{"start":{"line":4644,"column":12},"end":{"line":4644,"column":12}},{"start":{"line":4644,"column":12},"end":{"line":4644,"column":12}}]},"322":{"line":4666,"type":"if","locations":[{"start":{"line":4666,"column":0},"end":{"line":4666,"column":0}},{"start":{"line":4666,"column":0},"end":{"line":4666,"column":0}}]}},"l":{"1":1,"2":1,"5":1,"6":1,"14":1,"18":1,"19":1,"35":1,"47":1,"48":1,"49":1,"51":1,"52":0,"54":1,"56":1,"57":1,"59":1,"61":1,"62":1,"64":1,"66":1,"67":1,"69":1,"71":1,"72":1,"74":1,"76":1,"77":1,"79":1,"81":1,"82":1,"84":1,"95":1,"102":1,"104":1,"105":0,"107":1,"109":1,"110":0,"112":1,"114":1,"115":0,"117":1,"119":1,"121":1,"122":1,"129":1,"131":1,"132":0,"133":0,"136":1,"138":1,"140":1,"141":1,"142":0,"143":0,"144":0,"145":0,"147":0,"148":0,"151":1,"153":1,"160":1,"161":1,"162":1,"171":1,"172":2,"173":2,"174":2,"175":2,"183":1,"187":2,"188":2,"195":1,"196":0,"202":1,"203":1,"204":0,"205":0,"213":1,"214":0,"221":1,"222":0,"229":1,"230":1,"231":1,"239":1,"244":0,"246":0,"248":0,"250":0,"251":0,"252":0,"254":0,"255":0,"256":0,"257":0,"258":0,"259":0,"261":0,"262":0,"263":0,"264":0,"265":0,"266":0,"268":0,"270":0,"271":0,"272":0,"273":0,"274":0,"276":0,"277":0,"279":0,"280":0,"281":0,"289":1,"290":0,"291":0,"292":0,"293":0,"300":1,"301":0,"302":0,"303":0,"311":1,"312":0,"313":0,"314":0,"321":1,"322":0,"329":1,"330":0,"331":0,"332":0,"334":0,"336":0,"337":0,"339":0,"341":0,"342":0,"343":0,"345":0,"347":0,"348":0,"349":0,"352":0,"354":0,"355":0,"356":0,"358":0,"360":0,"361":0,"362":0,"365":0,"367":0,"369":0,"371":0,"381":1,"382":0,"383":0,"390":1,"391":0,"392":0,"393":0,"395":0,"396":0,"404":1,"405":0,"408":0,"409":0,"412":0,"413":0,"416":0,"417":0,"420":0,"421":0,"424":0,"425":0,"428":0,"429":0,"437":1,"438":0,"442":0,"443":0,"447":0,"448":0,"452":0,"453":0,"457":0,"458":0,"461":0,"462":0,"465":0,"466":0,"469":1,"472":0,"473":0,"474":0,"477":1,"480":0,"483":1,"486":0,"489":1,"493":0,"494":0,"497":1,"500":0,"503":1,"506":0,"508":0,"509":0,"511":0,"513":0,"515":0,"516":0,"518":0,"519":0,"520":0,"521":0,"523":0,"524":0,"526":0,"527":0,"529":0,"531":0,"532":0,"534":0,"536":0,"537":0,"538":0,"539":0,"540":0,"543":0,"544":0,"545":0,"547":0,"552":0,"553":0,"563":1,"568":0,"570":0,"582":1,"587":0,"588":0,"590":0,"592":0,"593":0,"595":0,"597":0,"598":0,"600":0,"603":1,"608":0,"610":0,"611":0,"612":0,"614":0,"615":0,"616":0,"617":0,"618":0,"619":0,"620":0,"621":0,"622":0,"623":0,"624":0,"625":0,"630":0,"631":0,"635":0,"636":0,"638":0,"642":1,"646":0,"648":0,"650":0,"651":0,"652":0,"654":0,"655":0,"657":0,"658":0,"660":0,"661":0,"662":0,"665":0,"666":0,"669":0,"670":0,"671":0,"672":0,"673":0,"680":0,"683":0,"694":1,"701":0,"703":0,"705":0,"707":0,"708":0,"710":0,"712":0,"714":0,"716":0,"717":0,"720":0,"721":0,"724":0,"725":0,"728":0,"749":1,"766":0,"767":0,"768":0,"769":0,"770":0,"772":0,"773":0,"775":0,"777":0,"778":0,"780":0,"782":0,"783":0,"785":0,"787":0,"788":0,"790":0,"792":0,"793":0,"795":0,"797":0,"798":0,"800":0,"802":0,"803":0,"805":0,"807":0,"808":0,"810":0,"812":0,"813":0,"815":0,"817":0,"818":0,"820":0,"883":1,"942":0,"943":0,"944":0,"945":0,"947":0,"949":0,"950":0,"952":0,"954":0,"955":0,"957":0,"959":0,"960":0,"962":0,"964":0,"965":0,"980":0,"982":0,"983":0,"985":0,"987":0,"988":0,"990":0,"992":0,"993":0,"995":0,"997":0,"998":0,"1000":0,"1002":0,"1003":0,"1005":0,"1007":0,"1008":0,"1010":0,"1012":0,"1013":0,"1015":0,"1017":0,"1018":0,"1020":0,"1022":0,"1023":0,"1025":0,"1027":0,"1028":0,"1030":0,"1032":0,"1033":0,"1035":0,"1037":0,"1038":0,"1040":0,"1042":0,"1043":0,"1045":0,"1047":0,"1048":0,"1050":0,"1052":0,"1053":0,"1055":0,"1057":0,"1058":0,"1060":0,"1062":0,"1063":0,"1065":0,"1067":0,"1068":0,"1070":0,"1072":0,"1073":0,"1075":0,"1077":0,"1078":0,"1080":0,"1082":0,"1083":0,"1085":0,"1087":0,"1088":0,"1090":0,"1092":0,"1093":0,"1095":0,"1097":0,"1098":0,"1100":0,"1102":0,"1103":0,"1105":0,"1107":0,"1108":0,"1110":0,"1112":0,"1113":0,"1115":0,"1117":0,"1118":0,"1120":0,"1122":0,"1123":0,"1125":0,"1127":0,"1128":0,"1130":0,"1132":0,"1133":0,"1135":0,"1137":0,"1138":0,"1140":0,"1142":0,"1143":0,"1145":0,"1147":0,"1148":0,"1150":0,"1152":0,"1153":0,"1155":0,"1157":0,"1158":0,"1160":0,"1162":0,"1163":0,"1165":0,"1167":0,"1168":0,"1170":0,"1172":0,"1173":0,"1175":0,"1177":0,"1178":0,"1180":0,"1182":0,"1183":0,"1185":0,"1187":0,"1188":0,"1190":0,"1192":0,"1193":0,"1195":0,"1197":0,"1198":0,"1200":0,"1202":0,"1203":0,"1205":0,"1207":0,"1208":0,"1210":0,"1212":0,"1213":0,"1215":0,"1217":0,"1218":0,"1220":0,"1222":0,"1223":0,"1225":0,"1227":0,"1228":0,"1230":0,"1238":1,"1239":1,"1240":1,"1246":1,"1247":1,"1248":1,"1254":1,"1255":1,"1256":1,"1257":1,"1258":1,"1264":1,"1265":1,"1266":1,"1267":1,"1268":1,"1269":1,"1270":1,"1271":1,"1272":1,"1273":1,"1274":1,"1280":1,"1281":1,"1282":1,"1283":1,"1284":1,"1290":1,"1291":1,"1292":1,"1293":1,"1294":1,"1295":1,"1296":1,"1297":1,"1303":1,"1304":1,"1305":1,"1311":1,"1312":1,"1318":1,"1319":1,"1320":1,"1321":1,"1322":1,"1323":1,"1324":1,"1325":1,"1326":1,"1327":1,"1328":1,"1335":1,"1337":0,"1339":0,"1341":0,"1343":0,"1345":0,"1396":0,"1409":0,"1411":0,"1467":0,"1481":0,"1484":0,"1485":0,"1486":0,"1488":0,"1492":0,"1493":0,"1497":0,"1500":0,"1509":1,"1514":0,"1516":0,"1517":0,"1520":0,"1521":0,"1524":0,"1525":0,"1532":1,"1533":0,"1539":1,"1546":0,"1548":0,"1549":0,"1552":0,"1553":0,"1556":0,"1557":0,"1560":0,"1561":0,"1565":1,"1566":0,"1567":0,"1568":0,"1569":0,"1572":1,"1573":0,"1574":0,"1580":0,"1586":0,"1589":1,"1590":0,"1591":0,"1592":0,"1593":0,"1596":1,"1597":0,"1598":0,"1599":0,"1602":1,"1603":0,"1604":0,"1605":0,"1608":1,"1609":0,"1610":0,"1611":0,"1614":1,"1615":0,"1616":0,"1622":0,"1623":0,"1631":1,"1632":0,"1640":1,"1642":0,"1644":0,"1646":0,"1647":0,"1650":0,"1652":0,"1653":0,"1654":0,"1657":0,"1659":0,"1660":0,"1661":0,"1663":0,"1664":0,"1665":0,"1667":0,"1668":0,"1669":0,"1671":0,"1737":1,"1759":0,"1760":0,"1761":0,"1762":0,"1763":0,"1764":0,"1766":0,"1767":0,"1769":0,"1771":0,"1772":0,"1774":0,"1776":0,"1777":0,"1779":0,"1781":0,"1782":0,"1784":0,"1786":0,"1787":0,"1789":0,"1791":0,"1792":0,"1794":0,"1796":0,"1797":0,"1799":0,"1801":0,"1802":0,"1804":0,"1806":0,"1807":0,"1809":0,"1811":0,"1812":0,"1814":0,"1816":0,"1818":0,"1820":0,"1822":0,"1830":1,"1831":1,"1841":1,"1843":0,"1845":0,"1846":0,"1849":0,"1851":0,"1853":0,"1855":0,"1857":0,"1859":0,"1861":0,"1863":0,"1865":0,"1866":0,"1867":0,"1869":0,"1870":0,"1871":0,"1873":0,"1874":0,"1875":0,"1876":0,"1878":0,"1879":0,"1880":0,"1882":0,"1883":0,"1884":0,"1886":0,"1892":0,"1893":0,"1894":0,"1901":0,"1902":0,"1915":0,"1916":0,"1926":0,"1928":0,"1930":0,"1932":0,"1933":0,"1934":0,"1935":0,"1939":0,"1941":0,"1943":0,"1944":0,"1947":0,"1948":0,"1951":0,"1953":0,"1956":1,"1958":0,"1959":0,"1960":0,"1961":0,"1963":0,"1964":0,"1965":0,"1968":0,"1974":1,"1976":0,"1978":0,"1979":0,"1986":0,"1988":0,"1990":0,"1992":0,"1993":0,"1994":0,"1996":0,"2013":0,"2014":0,"2022":0,"2023":0,"2024":0,"2025":0,"2027":0,"2031":0,"2059":1,"2067":1,"2069":0,"2070":0,"2071":0,"2075":0,"2085":1,"2087":0,"2088":0,"2097":0,"2107":0,"2108":0,"2111":0,"2118":0,"2121":0,"2136":0,"2138":0,"2140":0,"2146":0,"2154":0,"2155":0,"2156":0,"2158":0,"2159":0,"2160":0,"2163":0,"2165":0,"2180":0,"2181":0,"2182":0,"2183":0,"2192":0,"2193":0,"2194":0,"2195":0,"2196":0,"2197":0,"2198":0,"2201":0,"2202":0,"2206":0,"2217":1,"2219":0,"2220":0,"2223":0,"2225":0,"2227":0,"2228":0,"2235":0,"2237":0,"2239":0,"2241":0,"2242":0,"2250":0,"2261":1,"2267":0,"2268":0,"2269":0,"2271":0,"2272":0,"2274":0,"2282":1,"2283":1,"2293":1,"2300":0,"2301":0,"2302":0,"2303":0,"2304":0,"2311":1,"2312":0,"2325":1,"2327":0,"2330":1,"2334":0,"2342":1,"2344":0,"2347":1,"2351":0,"2374":1,"2392":0,"2393":0,"2394":0,"2395":0,"2396":0,"2397":0,"2398":0,"2399":0,"2400":0,"2401":0,"2402":0,"2403":0,"2404":0,"2405":0,"2406":0,"2408":0,"2415":1,"2417":0,"2420":0,"2421":0,"2443":0,"2461":1,"2474":0,"2475":0,"2476":0,"2477":0,"2478":0,"2480":0,"2482":0,"2483":0,"2485":0,"2487":0,"2488":0,"2490":0,"2492":0,"2493":0,"2495":0,"2497":0,"2498":0,"2500":0,"2502":0,"2503":0,"2505":0,"2507":0,"2508":0,"2510":0,"2512":0,"2513":0,"2515":0,"2523":1,"2528":0,"2529":0,"2530":0,"2533":0,"2534":0,"2539":0,"2540":0,"2541":0,"2543":0,"2545":0,"2546":0,"2549":0,"2551":0,"2553":0,"2555":0,"2557":0,"2559":0,"2568":0,"2570":0,"2572":0,"2574":0,"2576":0,"2582":0,"2584":0,"2592":0,"2594":0,"2596":0,"2598":0,"2601":0,"2606":0,"2609":0,"2623":0,"2626":0,"2630":0,"2632":0,"2634":0,"2636":0,"2680":0,"2683":0,"2714":0,"2719":0,"2729":1,"2731":0,"2733":0,"2735":0,"2737":0,"2739":0,"2741":0,"2743":0,"2745":0,"2747":0,"2749":0,"2751":0,"2756":0,"2757":0,"2769":0,"2771":0,"2788":0,"2806":0,"2812":0,"2830":0,"2833":0,"2838":0,"2840":0,"2842":0,"2844":0,"2845":0,"2846":0,"2867":0,"2868":0,"2869":0,"2872":0,"2877":0,"2878":0,"2881":0,"2883":0,"2885":0,"2890":0,"2892":0,"2893":0,"2895":0,"2896":0,"2897":0,"2899":0,"2900":0,"2901":0,"2903":0,"2904":0,"2905":0,"2907":0,"2908":0,"2909":0,"2910":0,"2912":0,"2916":0,"2919":0,"2922":0,"2923":0,"2924":0,"2926":0,"2928":0,"2930":0,"2932":0,"2934":0,"2935":0,"2938":0,"2939":0,"2942":0,"2943":0,"2944":0,"2945":0,"2948":0,"2949":0,"2950":0,"2951":0,"2952":0,"2953":0,"2956":0,"2957":0,"2958":0,"2960":0,"2961":0,"2962":0,"2968":0,"2969":0,"2971":0,"2972":0,"2976":0,"2978":0,"2980":0,"2981":0,"2982":0,"2984":0,"2985":0,"2986":0,"2988":0,"2989":0,"2990":0,"2992":0,"2993":0,"2994":0,"2995":0,"2997":0,"2998":0,"3001":0,"3002":0,"3005":0,"3015":0,"3022":1,"3026":0,"3027":0,"3028":0,"3031":1,"3032":1,"3033":1,"3034":1,"3037":1,"3038":0,"3039":0,"3040":0,"3047":0,"3048":0,"3049":0,"3050":0,"3051":0,"3068":1,"3078":0,"3080":0,"3086":0,"3087":0,"3089":0,"3095":0,"3096":0,"3098":0,"3100":0,"3101":0,"3104":0,"3105":0,"3107":0,"3109":0,"3110":0,"3112":0,"3114":0,"3115":0,"3117":0,"3119":0,"3120":0,"3122":0,"3126":1,"3129":0,"3130":0,"3133":1,"3136":0,"3137":0,"3138":0,"3139":0,"3140":0,"3141":0,"3143":0,"3146":0,"3147":0,"3148":0,"3149":0,"3150":0,"3151":0,"3154":0,"3155":0,"3159":0,"3160":0,"3161":0,"3166":0,"3173":1,"3177":0,"3179":0,"3181":0,"3183":0,"3185":0,"3187":0,"3189":0,"3201":1,"3208":0,"3209":0,"3210":0,"3211":0,"3212":0,"3213":0,"3215":0,"3218":0,"3219":0,"3220":0,"3221":0,"3228":1,"3229":1,"3255":1,"3277":0,"3278":0,"3279":0,"3281":0,"3282":0,"3284":0,"3286":0,"3287":0,"3289":0,"3291":0,"3292":0,"3294":0,"3296":0,"3297":0,"3299":0,"3301":0,"3302":0,"3304":0,"3306":0,"3307":0,"3309":0,"3311":0,"3312":0,"3314":0,"3316":0,"3317":0,"3319":0,"3321":0,"3322":0,"3324":0,"3326":0,"3327":0,"3329":0,"3331":0,"3332":0,"3334":0,"3336":0,"3337":0,"3339":0,"3341":0,"3342":0,"3344":0,"3346":0,"3347":0,"3349":0,"3351":0,"3352":0,"3354":0,"3356":0,"3357":0,"3359":0,"3361":0,"3362":0,"3364":0,"3371":1,"3372":1,"3373":1,"3374":1,"3375":1,"3376":1,"3382":1,"3383":1,"3384":1,"3385":1,"3386":1,"3387":1,"3388":1,"3389":1,"3395":1,"3396":1,"3397":1,"3403":1,"3404":1,"3405":1,"3406":1,"3407":1,"3408":1,"3414":1,"3415":1,"3416":1,"3417":1,"3418":1,"3419":1,"3420":1,"3421":1,"3427":1,"3428":1,"3429":1,"3430":1,"3431":1,"3432":1,"3433":1,"3434":1,"3445":1,"3447":0,"3449":0,"3451":0,"3455":0,"3458":0,"3460":0,"3462":0,"3468":0,"3469":0,"3470":0,"3471":0,"3472":0,"3476":0,"3477":0,"3478":0,"3479":0,"3480":0,"3481":0,"3485":0,"3486":0,"3487":0,"3488":0,"3489":0,"3490":0,"3491":0,"3497":0,"3498":0,"3505":0,"3506":0,"3511":0,"3514":0,"3525":1,"3527":0,"3529":0,"3531":0,"3533":0,"3535":0,"3537":0,"3543":0,"3545":0,"3546":0,"3549":0,"3550":0,"3553":0,"3554":0,"3557":0,"3558":0,"3561":0,"3562":0,"3565":0,"3566":0,"3569":0,"3570":0,"3573":0,"3574":0,"3577":0,"3578":0,"3581":0,"3582":0,"3585":0,"3586":0,"3589":0,"3590":0,"3593":0,"3598":0,"3607":1,"3611":0,"3612":0,"3629":1,"3642":0,"3643":0,"3644":0,"3645":0,"3646":0,"3647":0,"3648":0,"3649":0,"3650":0,"3652":0,"3654":0,"3655":0,"3661":0,"3663":0,"3664":0,"3670":0,"3672":0,"3673":0,"3676":0,"3683":1,"3684":0,"3700":1,"3701":0,"3740":1,"3742":0,"3743":0,"3745":0,"3746":0,"3749":0,"3750":0,"3754":1,"3755":0,"3761":1,"3762":0,"3768":1,"3770":4,"3771":4,"3772":4,"3774":4,"3775":1,"3778":4,"3779":2,"3782":4,"3783":1,"3787":1,"3789":0,"3790":0,"3791":0,"3792":0,"3795":0,"3796":0,"3799":0,"3802":1,"3803":0,"3810":1,"3811":0,"3812":0,"3813":0,"3814":0,"3817":1,"3819":0,"3821":0,"3823":0,"3825":0,"3828":1,"3829":0,"3830":0,"3831":0,"3834":1,"3836":0,"3838":0,"3841":1,"3842":0,"3843":0,"3844":0,"3845":0,"3848":1,"3849":0,"3852":1,"3853":0,"3860":1,"3861":0,"3862":0,"3863":0,"3864":0,"3865":0,"3866":0,"3867":0,"3868":0,"3869":0,"3870":0,"3871":0,"3873":0,"3874":0,"3876":0,"3880":1,"3881":0,"3884":1,"3886":0,"3888":0,"3890":0,"3891":0,"3894":0,"3896":0,"3897":0,"3898":0,"3900":0,"3903":1,"3905":1,"3906":1,"3907":1,"3908":1,"3910":1,"3911":0,"3914":1,"3915":0,"3918":1,"3919":0,"3922":1,"3923":0,"3927":1,"3928":0,"3929":0,"3930":0,"3931":0,"3934":1,"3935":0,"3943":1,"3944":0,"3945":0,"3946":0,"3947":0,"3948":0,"3949":0,"3950":0,"3951":0,"3952":0,"3953":0,"3954":0,"3955":0,"3956":0,"3958":0,"3959":0,"3964":1,"3967":0,"3969":0,"3971":0,"3972":0,"3975":0,"3977":0,"3978":0,"3979":0,"3981":0,"3984":1,"3986":0,"3987":0,"3988":0,"3989":0,"3992":0,"3993":0,"3994":0,"3995":0,"3996":0,"3999":0,"4002":1,"4003":0,"4006":1,"4008":0,"4009":0,"4017":0,"4018":0,"4019":0,"4022":0,"4024":0,"4027":1,"4029":0,"4031":0,"4032":0,"4035":0,"4038":1,"4042":0,"4044":0,"4046":0,"4048":0,"4050":0,"4052":0,"4054":0,"4056":0,"4057":0,"4060":0,"4062":0,"4064":0,"4065":0,"4069":0,"4073":0,"4075":0,"4076":0,"4083":1,"4087":0,"4089":0,"4091":0,"4093":0,"4095":0,"4097":0,"4099":0,"4101":0,"4102":0,"4105":0,"4107":0,"4108":0,"4109":0,"4113":0,"4117":0,"4119":0,"4120":0,"4128":1,"4130":0,"4132":0,"4134":0,"4136":0,"4137":0,"4138":0,"4140":0,"4142":0,"4143":0,"4144":0,"4145":0,"4149":1,"4151":0,"4152":0,"4153":0,"4155":0,"4156":0,"4157":0,"4159":0,"4160":0,"4161":0,"4163":0,"4164":0,"4166":0,"4167":0,"4170":0,"4171":0,"4173":0,"4174":0,"4176":0,"4177":0,"4181":0,"4188":1,"4189":0,"4190":0,"4191":0,"4193":0,"4194":0,"4195":0,"4196":0,"4199":0,"4206":1,"4208":0,"4209":0,"4210":0,"4211":0,"4214":0,"4218":1,"4220":0,"4222":0,"4223":0,"4233":1,"4237":0,"4238":0,"4251":1,"4261":0,"4263":0,"4265":0,"4266":0,"4268":0,"4270":0,"4271":0,"4277":0,"4279":0,"4280":0,"4286":0,"4288":0,"4289":0,"4291":0,"4293":0,"4295":0,"4302":0,"4303":0,"4304":0,"4309":1,"4311":0,"4313":0,"4315":0,"4318":0,"4320":0,"4322":0,"4323":0,"4324":0,"4325":0,"4326":0,"4329":0,"4331":0,"4332":0,"4333":0,"4335":0,"4337":0,"4342":0,"4344":0,"4347":1,"4353":0,"4358":0,"4360":0,"4361":0,"4363":0,"4364":0,"4367":0,"4368":0,"4371":0,"4375":1,"4379":1,"4382":0,"4384":0,"4385":0,"4388":0,"4389":0,"4393":1,"4396":0,"4398":0,"4399":0,"4402":0,"4403":0,"4407":1,"4414":0,"4415":0,"4424":1,"4428":0,"4429":0,"4431":0,"4437":1,"4441":0,"4442":0,"4446":1,"4449":0,"4450":0,"4454":1,"4457":0,"4458":0,"4462":1,"4468":0,"4469":0,"4473":1,"4476":0,"4477":0,"4481":1,"4484":0,"4485":0,"4489":1,"4492":0,"4498":0,"4500":0,"4502":0,"4503":0,"4504":0,"4507":0,"4509":0,"4511":0,"4515":1,"4519":0,"4521":0,"4528":0,"4533":1,"4540":0,"4541":0,"4551":0,"4553":0,"4554":0,"4557":0,"4558":0,"4559":0,"4560":0,"4562":0,"4567":0,"4573":0,"4574":0,"4575":0,"4576":0,"4581":0,"4582":0,"4585":0,"4586":0,"4587":0,"4589":0,"4592":1,"4600":0,"4601":0,"4602":0,"4603":0,"4604":0,"4606":0,"4608":0,"4609":0,"4611":0,"4612":0,"4614":0,"4616":0,"4618":0,"4619":0,"4620":0,"4621":0,"4622":0,"4623":0,"4624":0,"4626":0,"4627":0,"4629":0,"4631":0,"4635":0,"4640":0,"4641":0,"4642":0,"4644":0,"4645":0,"4649":0,"4650":0,"4651":0,"4652":0,"4654":0,"4655":0,"4656":0,"4658":0,"4659":0,"4660":0,"4662":0,"4666":1,"4667":1}}} diff --git a/build/coverage/lcov-report/build/game-lib.js.html b/build/coverage/lcov-report/build/game-lib.js.html index a69c4c0..86c8b5c 100644 --- a/build/coverage/lcov-report/build/game-lib.js.html +++ b/build/coverage/lcov-report/build/game-lib.js.html @@ -20,24 +20,24 @@
- 16.22% + 17.71% Statements - 283/1745 + 309/1745
- 2.87% + 3.87% Branches - 20/697 + 27/697
- 2.05% + 6.16% Functions - 3/146 + 9/146
- 16.22% + 17.71% Lines - 283/1745 + 309/1745
@@ -4727,8 +4727,8 @@       -  -  +1× +1×       @@ -4811,27 +4811,27 @@       +1× +  +1×     -  +1× +  +1×     +1× +  +1×     -  -  +1×   -  +1×   -  -  -  -  -  -  -  -  -  +1× +1×       @@ -4840,17 +4840,17 @@   1×   -  +1×         -  +1×   -  +1×   -  -  +1× +1×       @@ -4860,9 +4860,9 @@       -  +1×   -  +1×       @@ -4881,10 +4881,10 @@     1× -  -  -  -  +2× +2× +2× +2×       @@ -4896,8 +4896,8 @@       -  -  +2× +2×       @@ -4912,7 +4912,7 @@     1× -  +1×       @@ -9390,12 +9390,12 @@ * @param weight float * @constructor */ -GameLib.D3.BoneWeight = function( +GameLib.D3.BoneWeight = function( boneIndex, weight ) { - this.boneIndex = boneIndex; - this.weight = weight; + this.boneIndex = boneIndex; + this.weight = weight; }; /** * Bone Superset @@ -9471,53 +9471,53 @@ GameLib.D3.Bone = function( * @param createInstance Boolean * @constructor */ -GameLib.D3.Broadphase = function( +GameLib.D3.Broadphase = function( id, name, broadphaseType, engine, createInstance ) { - this.id = id; + this.id = id;   - if (typeof name == 'undefined') { + Iif (typeof name == 'undefined') { name = 'broadphase-' + broadphaseType; } - this.name = name; + this.name = name;   - if (typeof broadphaseType == 'undefined') { + Iif (typeof broadphaseType == 'undefined') { broadphaseType = GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE; } - this.broadphaseType = broadphaseType; + this.broadphaseType = broadphaseType;   - if (typeof engine == 'undefined') { + Iif (typeof engine == 'undefined') { engine = null; } - this.engine = engine; + this.engine = engine;   - this.instance = null; + this.instance = null;   - if (createInstance) { - this.createInstance(); + Eif (createInstance) { + this.createInstance(); } };   /** * Creates a custom Broadphase instance based on the engine type */ -GameLib.D3.Broadphase.prototype.createInstance = function() { +GameLib.D3.Broadphase.prototype.createInstance = function() {   - if (!(this.engine instanceof GameLib.D3.Engine)) { + Iif (!(this.engine instanceof GameLib.D3.Engine)) { console.warn('No Engine'); throw new Error('No Engine'); }   - this.engine.isNotCannonThrow(); + this.engine.isNotCannonThrow();   - var instance = null; + var instance = null;   - if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { - instance = new this.engine.instance.NaiveBroadphase(); + Eif (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE) { + instance = new this.engine.instance.NaiveBroadphase(); } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID) { instance = new this.engine.instance.GridBroadphase(); } else if (this.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP) { @@ -9527,9 +9527,9 @@ GameLib.D3.Broadphase.prototype.createInstance = throw new Error('Unsupported broadphase type: ' + this.broadphaseType); }   - this.instance = instance; + this.instance = instance;   - return instance; + return instance; };   /** @@ -9547,11 +9547,11 @@ GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP = 0x3; * @param a * @constructor */ -GameLib.D3.Color = function(r, g, b, a) { - this.r = r; - this.g = g; - this.b = b; - this.a = a; +GameLib.D3.Color = function(r, g, b, a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; }; /** * Engine Superset @@ -9559,12 +9559,12 @@ GameLib.D3.Color = function * @param instance {CANNON | Ammo | Goblin} * @constructor */ -GameLib.D3.Engine = function( +GameLib.D3.Engine = function( engineType, instance ) { - this.engineType = engineType; - this.instance = instance; + this.engineType = engineType; + this.instance = instance; };   /** @@ -9578,8 +9578,8 @@ GameLib.D3.Engine.prototype.isCannon = function() { - if (this.engineType != GameLib.D3.Engine.ENGINE_TYPE_CANNON) { +GameLib.D3.Engine.prototype.isNotCannonThrow = function() { + Iif (this.engineType != GameLib.D3.Engine.ENGINE_TYPE_CANNON) { console.warn('Only CANNON supported for this function'); throw new Error('Only CANNON supported for this function'); } @@ -14050,7 +14050,7 @@ GameLib.D3.World.prototype.GenerateTriangleCollisionMesh = istanbul at Tue Oct 18 2016 13:47:58 GMT+0200 (CEST) + generated by istanbul at Tue Oct 18 2016 15:35:01 GMT+0200 (CEST) diff --git a/build/coverage/lcov-report/build/index.html b/build/coverage/lcov-report/build/index.html index 6395199..dcb7484 100644 --- a/build/coverage/lcov-report/build/index.html +++ b/build/coverage/lcov-report/build/index.html @@ -20,24 +20,24 @@
- 16.22% + 17.71% Statements - 283/1745 + 309/1745
- 2.87% + 3.87% Branches - 20/697 + 27/697
- 2.05% + 6.16% Functions - 3/146 + 9/146
- 16.22% + 17.71% Lines - 283/1745 + 309/1745
@@ -60,15 +60,15 @@ game-lib.js -
- 16.22% - 283/1745 - 2.87% - 20/697 - 2.05% - 3/146 - 16.22% - 283/1745 +
+ 17.71% + 309/1745 + 3.87% + 27/697 + 6.16% + 9/146 + 17.71% + 309/1745 @@ -77,7 +77,7 @@ diff --git a/build/coverage/lcov-report/index.html b/build/coverage/lcov-report/index.html index c262352..44b2a4c 100644 --- a/build/coverage/lcov-report/index.html +++ b/build/coverage/lcov-report/index.html @@ -20,24 +20,24 @@
- 16.22% + 17.71% Statements - 283/1745 + 309/1745
- 2.87% + 3.87% Branches - 20/697 + 27/697
- 2.05% + 6.16% Functions - 3/146 + 9/146
- 16.22% + 17.71% Lines - 283/1745 + 309/1745
@@ -60,15 +60,15 @@ build/ -
- 16.22% - 283/1745 - 2.87% - 20/697 - 2.05% - 3/146 - 16.22% - 283/1745 +
+ 17.71% + 309/1745 + 3.87% + 27/697 + 6.16% + 9/146 + 17.71% + 309/1745 @@ -77,7 +77,7 @@ diff --git a/build/coverage/lcov.info b/build/coverage/lcov.info index ad94920..59ef6c1 100644 --- a/build/coverage/lcov.info +++ b/build/coverage/lcov.info @@ -147,17 +147,17 @@ FN:4515,(anonymous_144) FN:4533,(anonymous_145) FN:4592,(anonymous_146) FNF:146 -FNH:3 +FNH:9 FNDA:0,GameLib FNDA:0,(anonymous_2) -FNDA:0,(anonymous_3) +FNDA:1,(anonymous_3) FNDA:1,(anonymous_4) -FNDA:0,(anonymous_5) -FNDA:0,(anonymous_6) -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) +FNDA:1,(anonymous_5) +FNDA:1,(anonymous_6) +FNDA:2,(anonymous_7) +FNDA:2,(anonymous_8) FNDA:0,(anonymous_9) -FNDA:0,(anonymous_10) +FNDA:1,(anonymous_10) FNDA:0,(anonymous_11) FNDA:0,(anonymous_12) FNDA:0,(anonymous_13) @@ -299,8 +299,8 @@ DA:2,1 DA:5,1 DA:6,1 DA:14,1 -DA:18,0 -DA:19,0 +DA:18,1 +DA:19,1 DA:35,1 DA:47,1 DA:48,1 @@ -327,50 +327,50 @@ DA:81,1 DA:82,1 DA:84,1 DA:95,1 -DA:102,0 -DA:104,0 +DA:102,1 +DA:104,1 DA:105,0 -DA:107,0 -DA:109,0 +DA:107,1 +DA:109,1 DA:110,0 -DA:112,0 -DA:114,0 +DA:112,1 +DA:114,1 DA:115,0 -DA:117,0 -DA:119,0 -DA:121,0 -DA:122,0 +DA:117,1 +DA:119,1 +DA:121,1 +DA:122,1 DA:129,1 -DA:131,0 +DA:131,1 DA:132,0 DA:133,0 -DA:136,0 -DA:138,0 -DA:140,0 -DA:141,0 +DA:136,1 +DA:138,1 +DA:140,1 +DA:141,1 DA:142,0 DA:143,0 DA:144,0 DA:145,0 DA:147,0 DA:148,0 -DA:151,0 -DA:153,0 +DA:151,1 +DA:153,1 DA:160,1 DA:161,1 DA:162,1 DA:171,1 -DA:172,0 -DA:173,0 -DA:174,0 -DA:175,0 +DA:172,2 +DA:173,2 +DA:174,2 +DA:175,2 DA:183,1 -DA:187,0 -DA:188,0 +DA:187,2 +DA:188,2 DA:195,1 DA:196,0 DA:202,1 -DA:203,0 +DA:203,1 DA:204,0 DA:205,0 DA:213,1 @@ -2040,7 +2040,7 @@ DA:4662,0 DA:4666,1 DA:4667,1 LF:1745 -LH:283 +LH:309 BRDA:1,1,0,0 BRDA:1,1,1,1 BRDA:5,2,0,1 @@ -2060,23 +2060,23 @@ BRDA:76,8,1,0 BRDA:81,9,0,1 BRDA:81,9,1,0 BRDA:104,10,0,0 -BRDA:104,10,1,0 +BRDA:104,10,1,1 BRDA:109,11,0,0 -BRDA:109,11,1,0 +BRDA:109,11,1,1 BRDA:114,12,0,0 -BRDA:114,12,1,0 -BRDA:121,13,0,0 +BRDA:114,12,1,1 +BRDA:121,13,0,1 BRDA:121,13,1,0 BRDA:131,14,0,0 -BRDA:131,14,1,0 -BRDA:140,15,0,0 +BRDA:131,14,1,1 +BRDA:140,15,0,1 BRDA:140,15,1,0 BRDA:142,16,0,0 BRDA:142,16,1,0 BRDA:144,17,0,0 BRDA:144,17,1,0 BRDA:203,18,0,0 -BRDA:203,18,1,0 +BRDA:203,18,1,1 BRDA:276,19,0,0 BRDA:276,19,1,0 BRDA:276,19,2,0 @@ -2739,5 +2739,5 @@ BRDA:4644,321,1,0 BRDA:4666,322,0,1 BRDA:4666,322,1,0 BRF:697 -BRH:20 +BRH:27 end_of_record diff --git a/gulpfile.js b/gulpfile.js index 73486b5..5e268bf 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -41,11 +41,9 @@ gulp.task( .pipe(plumber()) .pipe(mocha({reporter: 'spec'})) .pipe(istanbul.writeReports({ - dir: './build/coverage', - reporters: [ 'lcov' ], - reportOpts: { dir: './build/coverage' } + dir: './build/coverage' })) - .pipe(istanbul.enforceThresholds({thresholds:{global:90}})) + .pipe(istanbul.enforceThresholds({thresholds:{global:1}})) .on('error', function(error) { console.log('plugin error occurred' + error); diff --git a/package.json b/package.json index 3430faf..275e7df 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,12 @@ "description": "Gamewheel Game Library", "version": "0.0.1", "dependencies": { + "cannon": "^0.6.2", "gulp": "^3.9.1", "gulp-concat": "^2.6.0", "gulp-minify": "0.0.14", - "gulp-sort": "^2.0.0" + "gulp-sort": "^2.0.0", + "three": "^0.81.2" }, "repository": "https://github.com/ToywheelDev/game-lib.git", "license": "UNLICENSED", diff --git a/test/test.GameLib.js b/test/test.GameLib.js deleted file mode 100644 index af1d51d..0000000 --- a/test/test.GameLib.js +++ /dev/null @@ -1,49 +0,0 @@ -var chai = require('chai'), - sinon = require("sinon"), - sinonChai = require("sinon-chai"), - config = require('../config.js'), - assert = chai.assert, - GameLib = require('../build/game-lib'); - -chai.use(sinonChai); - -describe('Bone', function(){ - - this.timeout(0); - - before(function(){ - - }); - - after(function(){ - - }); - - beforeEach(function(done) { - done(); - }); - - afterEach(function(done){ - done(); - }); - - it('Should create a Bone object', function (done) { - - var bone = new GameLib.D3.Bone( - null, - 1, - 'test bone 1', - [2, 3, 4] - ); - - assert(bone.position instanceof GameLib.D3.Vector3); - assert(bone.rotation instanceof GameLib.D3.Vector3); - assert(bone.scale instanceof GameLib.D3.Vector3); - assert(bone.up instanceof GameLib.D3.Vector3); - assert(bone.quaternion instanceof GameLib.D3.Vector4); - assert(bone.parentBoneId == null); - assert.deepEqual(bone.childBoneIds, [2,3,4]); - - done(); - }); -}); \ No newline at end of file diff --git a/test/test.gameLib.js b/test/test.gameLib.js new file mode 100644 index 0000000..a3e4abf --- /dev/null +++ b/test/test.gameLib.js @@ -0,0 +1,144 @@ +var chai = require('chai'), + sinon = require("sinon"), + sinonChai = require("sinon-chai"), + config = require('../config.js'), + assert = chai.assert, + GameLib = require('../build/game-lib'), + CANNON = require('cannon'), + THREE = require('three'); + +chai.use(sinonChai); + +describe('GameLib object creation', function(){ + + this.timeout(0); + + before(function(){ + + }); + + after(function(){ + + }); + + beforeEach(function(done) { + done(); + }); + + afterEach(function(done){ + done(); + }); + + it('Should create a Bone object', function (done) { + + var bone = new GameLib.D3.Bone( + null, + 1, + 'test bone 1', + [2, 3, 4] + ); + + assert(bone.position instanceof GameLib.D3.Vector3); + assert(bone.rotation instanceof GameLib.D3.Vector3); + assert(bone.scale instanceof GameLib.D3.Vector3); + assert(bone.up instanceof GameLib.D3.Vector3); + assert(bone.quaternion instanceof GameLib.D3.Vector4); + assert(bone.parentBoneId == null); + assert.deepEqual(bone.childBoneIds, [2,3,4]); + + done(); + }); + + it('Should create a BoneWeight object', function (done) { + + var boneWeight = new GameLib.D3.BoneWeight( + 1, + 0.5 + ); + + assert(boneWeight.boneIndex == 1); + assert(boneWeight.weight == 0.5); + + done(); + }); + + it('Should create a Broadphase object', function (done) { + + var engine = new GameLib.D3.Engine( + GameLib.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + + assert(engine.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON); + assert(engine.instance instanceof Object); + + var broadphase = new GameLib.D3.Broadphase( + null, + 'broad-phase', + GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE, + engine, + true + ); + + assert(broadphase.id == null); + assert(broadphase.instance instanceof CANNON.NaiveBroadphase); + assert(broadphase.engine instanceof GameLib.D3.Engine); + assert(broadphase.name == 'broad-phase'); + assert(broadphase.broadphaseType == GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE); + + done(); + }); + + it('Should create a Color object', function (done) { + + var color = new GameLib.D3.Color( + 0.1, + 0.2, + 0.3, + 0.4 + ); + + assert(color.r == 0.1); + assert(color.g == 0.2); + assert(color.b == 0.3); + assert(color.a == 0.4); + + done(); + }); + + it('Should create a Color object', function (done) { + + var color = new GameLib.D3.Color( + 0.1, + 0.2, + 0.3, + 0.4 + ); + + assert(color.r == 0.1); + assert(color.g == 0.2); + assert(color.b == 0.3); + assert(color.a == 0.4); + + done(); + }); + + + it('Should create an Engine object', function (done) { + + var engine = new GameLib.D3.Engine( + GameLib.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + + assert(engine.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON); + assert(engine.instance instanceof Object); + + done(); + }); + + it('Should create a FlyControls object', function (done) { + console.log("Cannot test FlyControls server side"); + done(); + }); +}); \ No newline at end of file From 39258d2afe30efc6239a4f0af612f8c6bdb08fbf Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Tue, 25 Oct 2016 17:57:32 +0200 Subject: [PATCH 13/15] modular refactoring --- build/game-lib-min.js | 4 +- build/game-lib.js | 663 +++++++++++++++++++++++---------------- gulpfile.js | 16 +- package.json | 1 + src/game-lib-graphics.js | 37 +++ src/game-lib-material.js | 232 +++++++------- src/game-lib-mesh.js | 27 +- src/game-lib-scene.js | 230 ++++++++------ src/game-lib-texture.js | 137 +++++--- 9 files changed, 813 insertions(+), 534 deletions(-) create mode 100644 src/game-lib-graphics.js diff --git a/build/game-lib-min.js b/build/game-lib-min.js index afdab8c..39f3cfc 100644 --- a/build/game-lib-min.js +++ b/build/game-lib-min.js @@ -1,2 +1,2 @@ -function GameLib(){}"undefined"==typeof GameLib.D3&&(GameLib.D3=function(){}),GameLib.D3.BoneWeight=function(e,t){this.boneIndex=e,this.weight=t},GameLib.D3.Bone=function(e,t,i,n,s,o,a,r,h,l){this.id=e,this.name=i,this.boneId=t,"undefined"==typeof n&&(n=[]),this.childBoneIds=n,"undefined"==typeof s&&(s=null),this.parentBoneId=s,"undefined"==typeof o&&(o=new GameLib.D3.Vector4),this.quaternion=o,"undefined"==typeof a&&(a=new GameLib.D3.Vector3(0,0,0)),this.position=a,"undefined"==typeof r&&(r=new GameLib.D3.Vector3(0,0,0)),this.rotation=r,"undefined"==typeof h&&(h=new GameLib.D3.Vector3(1,1,1)),this.scale=h,"undefined"==typeof l&&(l=new GameLib.D3.Vector3(0,1,0)),this.up=l},GameLib.D3.Broadphase=function(e,t,i,n,s){this.id=e,"undefined"==typeof t&&(t="broadphase-"+i),this.name=t,"undefined"==typeof i&&(i=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=i,"undefined"==typeof n&&(n=null),this.engine=n,this.instance=null,s&&this.createInstance()},GameLib.D3.Broadphase.prototype.createInstance=function(){if(!(this.engine instanceof GameLib.D3.Engine))throw console.warn("No Engine"),new Error("No Engine");this.engine.isNotCannonThrow();var e=null;if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)e=new this.engine.instance.NaiveBroadphase;else if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)e=new this.engine.instance.GridBroadphase;else{if(this.broadphaseType!=GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);e=new this.engine.instance.SAPBroardphase}return this.instance=e,e},GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Color=function(e,t,i,n){this.r=e,this.g=t,this.b=i,this.a=n},GameLib.D3.Engine=function(e,t){this.engineType=e,this.instance=t},GameLib.D3.Engine.prototype.isCannon=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_CANNON},GameLib.D3.Engine.prototype.isNotCannonThrow=function(){if(this.engineType!=GameLib.D3.Engine.ENGINE_TYPE_CANNON)throw console.warn("Only CANNON supported for this function"),new Error("Only CANNON supported for this function")},GameLib.D3.Engine.prototype.isAmmo=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_AMMO},GameLib.D3.Engine.prototype.isGoblin=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_GOBLIN},GameLib.D3.Engine.ENGINE_TYPE_CANNON=1,GameLib.D3.Engine.ENGINE_TYPE_AMMO=2,GameLib.D3.Engine.ENGINE_TYPE_GOBLIN=3,GameLib.D3.FlyControls=function(e,t,i){this.flySpeed=100,this.canvas=i,this.THREE=t,this.yaw=0,this.pitch=0,this.canRotate=!1,this.moveForward=!1,this.moveBackward=!1,this.moveLeft=!1,this.moveRight=!1,this.moveUp=!1,this.moveDown=!1,this.mouseUpCallback=this.onMouseUp.bind(this),this.mouseDownCallback=this.onMouseDown.bind(this),this.mouseMoveCallback=this.onMouseMove.bind(this),this.mouseWheelCallback=this.onMouseWheel.bind(this),this.keyDownCallback=this.onKeyDown.bind(this),this.keyUpCallback=this.onKeyUp.bind(this),this.camera=e,this.canvas.addEventListener("keydown",this.keyDownCallback,!1),this.canvas.addEventListener("keyup",this.keyUpCallback,!1),this.canvas.addEventListener("mousedown",this.mouseDownCallback,!1),this.canvas.addEventListener("mouseup",this.mouseUpCallback,!1),this.canvas.addEventListener("mousewheel",this.mouseWheelCallback,!1),this.havePointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.element=document.body,this.havePointerLock&&(this.element.requestPointerLock=this.element.requestPointerLock||this.element.mozRequestPointerLock||this.element.webkitRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock)},GameLib.D3.FlyControls.prototype.onMouseWheel=function(e){this.moveForward=!0,this.applyTranslation(.001*e.wheelDelta),e.preventDefault(),this.moveForward=!1},GameLib.D3.FlyControls.prototype.onMouseDown=function(e){1==e.button&&(this.canRotate=!0,this.canvas.addEventListener("mousemove",this.mouseMoveCallback,!1))},GameLib.D3.FlyControls.prototype.onMouseUp=function(e){1==e.button&&(this.canRotate=!1,this.canvas.removeEventListener("mousemove",this.mouseMoveCallback))},GameLib.D3.FlyControls.prototype.applyRotation=function(){this.camera.rotation.set(this.pitch,this.yaw,0,"YXZ")},GameLib.D3.FlyControls.prototype.applyTranslation=function(e){var t=new this.THREE.Vector3(0,0,-1),i=new this.THREE.Euler(0,0,0,"YXZ");i.set(this.pitch,this.yaw,0,"YXZ"),t=t.applyEuler(i);var n=t.normalize(),s=n.cross(new this.THREE.Vector3(0,1,0));this.moveForward?(this.camera.position.x+=n.x*(e*this.flySpeed),this.camera.position.y+=n.y*(e*this.flySpeed),this.camera.position.z+=n.z*(e*this.flySpeed)):this.moveBackward&&(this.camera.position.x-=n.x*(e*this.flySpeed),this.camera.position.y-=n.y*(e*this.flySpeed),this.camera.position.z-=n.z*(e*this.flySpeed)),this.moveLeft?(this.camera.position.x-=s.x*(e*this.flySpeed),this.camera.position.y-=s.y*(e*this.flySpeed),this.camera.position.z-=s.z*(e*this.flySpeed)):this.moveRight&&(this.camera.position.x+=s.x*(e*this.flySpeed),this.camera.position.y+=s.y*(e*this.flySpeed),this.camera.position.z+=s.z*(e*this.flySpeed)),this.moveUp?this.camera.position.y+=e*this.flySpeed:this.moveDown&&(this.camera.position.y-=e*this.flySpeed)},GameLib.D3.FlyControls.prototype.update=function(e){this.applyRotation(),this.applyTranslation(e)},GameLib.D3.FlyControls.prototype.onMouseMove=function(e){if(this.canRotate){var t=e.movementX||e.mozMovementX||e.webkitMovementX||0,i=e.movementY||e.mozMovementY||e.webkitMovementY||0;this.yaw-=.002*t,this.pitch-=.002*i}},GameLib.D3.FlyControls.prototype.onKeyDown=function(e){switch(e.keyCode){case 87:this.moveForward=!0;break;case 65:this.moveLeft=!0;break;case 83:this.moveBackward=!0;break;case 68:this.moveRight=!0;break;case 104:this.moveUp=!0;break;case 98:this.moveDown=!0}},GameLib.D3.FlyControls.prototype.onKeyUp=function(e){switch(e.keyCode){case 38:case 87:this.moveForward=!1;break;case 37:case 65:this.moveLeft=!1;break;case 40:case 83:this.moveBackward=!1;break;case 39:case 68:this.moveRight=!1;break;case 104:this.moveUp=!1;break;case 98:this.moveDown=!1}},GameLib.D3.Game=function(){this.scenes={},this.physicsWorlds=[],this.sceneToPhysicsWorldsMap={}},GameLib.D3.Game.prototype.AddScene=function(e){this.scenes[e.name]=e},GameLib.D3.Game.prototype.AddPhysicsWorld=function(e){this.physicsWorlds.push(e)},GameLib.D3.Game.prototype.LinkPhysicsWorldToScene=function(e,t){this.sceneToPhysicsWorldsMap[t.name]=this.sceneToPhysicsWorldsMap[t.name]||[],this.sceneToPhysicsWorldsMap[t.name].push(e)},GameLib.D3.Game.prototype.GetPhysicsWorldsForScene=function(e){return this.sceneToPhysicsWorldsMap[e.name]},GameLib.D3.Game.prototype.ProcessPhysics=function(e){for(var t in this.sceneToPhysicsWorldsMap){var i=this.sceneToPhysicsWorldsMap[t],n=this.scenes[t];if(n&&i)for(var s=0,o=i.length;s0){var o=this.loadMaps(e,s,n);Q.all(o).then(function(){i.resolve(n)}).catch(function(e){console.log(e),i.reject(e)})}else i.resolve(n);return i.promise},GameLib.D3.Matrix3=function(e,t,i){this.identity(),e&&(this.rows[0]=e),t&&(this.rows[1]=t),i&&(this.rows[2]=i)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,t,i,n){this.identity(),e&&(this.rows[0]=e),t&&(this.rows[1]=t),i&&(this.rows[2]=i),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,t){return this.identity(),this.rotationMatrixX(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.rotateY=function(e,t){return this.identity(),this.rotationMatrixY(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,t){return this.identity(),this.rotationMatrixZ(e),this.multiply(t)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,t,i){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(t).normalize();0===s.squared()&&(s.z=1);var o=i.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=i.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,t,i,n,s,o,a,r,h,l,c,p,m,d,y,u,f,b,L,v){this.id=e,this.path=t,this.name=i,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof l&&(l=[]),this.skinWeights=l,"undefined"==typeof c&&(c=[]),this.materials=c,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(1,1,1)),this.scale=y,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(0,1,0)),this.up=u,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.prototype.createThreeMesh=function(e,t,i){var n=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(n=new this.THREE.Mesh(t,i)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var s=e.skeleton.bones,o=e.skinIndices,a=e.skinWeights,r=[],h=0;h0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var l=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],c=0;c9||console.log("The vertices are not in the right length : "+e.length);for(var i=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var a=0;a0},GameLib.D3.Vector3.normal=function(e,t,i){var n=t.copy(),s=i.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,t){var i=GameLib.D3.Matrix4.lookAt(this,e,t);this.multiply(i)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var t=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,i=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=t,this.y=i,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z};GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,t=this.squared();if(to&&(o=h.x,n=t*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixY(n),c=0;co&&(o=h.y,n=t*e)}this.vectors=s;for(var l=(new GameLib.D3.Matrix4).rotationMatrixX(n),c=0;cn&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-t),Math.abs(s-i))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,t=0,i=0,n=0;n0){var r=GameLib.D3.Texture.loadMaps(e,a,o,i,t,n);Q.all(r).then(function(){s.resolve(o)}).catch(function(e){console.log(e),s.reject(e)})}else s.resolve(o);return s.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,c,l,p,m,d,u,y,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof c&&(c=[]),this.skinWeights=c,"undefined"==typeof l&&(l=[]),this.materials=l,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(1,1,1)),this.scale=u,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(0,1,0)),this.up=y,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.Mesh.createInstanceMesh=function(e,i,t,n){var s=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(s=new n.instance.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var o=e.skeleton.bones,a=e.skinIndices,r=e.skinWeights,h=[],c=0;c0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var c=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],l=0;l9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var h=0;h0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixY(n),l=0;lo&&(o=h.y,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixX(n),l=0;ln&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n 0) { - var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial); + var textureMaps = GameLib.D3.Texture.loadMaps( + gameLibMaterial, + blenderMaps, + instanceMaterial, + graphics, + uploadPath, + progressCallback + ); Q.all(textureMaps).then( function(){ - defer.resolve(threeMaterial); + defer.resolve(instanceMaterial); } ).catch( function(error){ @@ -1494,7 +1545,7 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) { } ) } else { - defer.resolve(threeMaterial); + defer.resolve(instanceMaterial); } return defer.promise; @@ -1833,17 +1884,18 @@ GameLib.D3.Mesh.TYPE_SKINNED = 1; /** * Creates a THREE Mesh from GameLib.D3.Mesh - * @param gameLibMesh - * @param threeGeometry - * @param threeMaterial + * @param gameLibMesh GameLib.D3.Mesh + * @param instanceGeometry + * @param instanceMaterial + * @param graphics * @returns {*} */ -GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) { +GameLib.D3.Mesh.createInstanceMesh = function(gameLibMesh, instanceGeometry, instanceMaterial, graphics) { var threeMesh = null; if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) { - threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial); + threeMesh = new graphics.instance.Mesh(instanceGeometry, instanceMaterial); } if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) { @@ -1858,7 +1910,7 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre for (var bi = 0; bi < bones.length; bi++) { - var bone = new this.THREE.Bone(); + var bone = new graphics.instance.Bone(); bone.name = bones[bi].name; @@ -1899,8 +1951,8 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre * Setup bones (indexes) */ for (var si = 0; si < skinIndices.length; si++) { - threeGeometry.skinIndices.push( - new this.THREE.Vector4( + instanceGeometry.skinIndices.push( + new graphics.instance.Vector4( skinIndices[si].x, skinIndices[si].y, skinIndices[si].z, @@ -1913,8 +1965,8 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre * Setup bones (weights) */ for (var sw = 0; sw < skinWeights.length; sw++) { - threeGeometry.skinWeights.push( - new this.THREE.Vector4( + instanceGeometry.skinWeights.push( + new graphics.instance.Vector4( skinWeights[sw].x, skinWeights[sw].y, skinWeights[sw].z, @@ -1923,9 +1975,9 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre ); } - threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial); + threeMesh = new graphics.instance.SkinnedMesh(instanceGeometry, instanceMaterial); - var skeleton = new this.THREE.Skeleton(threeBones); + var skeleton = new graphics.instance.Skeleton(threeBones); skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture; @@ -1940,7 +1992,7 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre threeMesh.pose(); - threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh); + threeMesh.skeleton.skeletonHelper = new graphics.instance.SkeletonHelper(threeMesh); threeMesh.skeleton.skeletonHelper.material.linewidth = 5; } @@ -2444,6 +2496,10 @@ GameLib.D3.RigidBody.prototype.createRigidBodyInstance = function() { }; +if (typeof require != 'undefined') { + var Q = require('q'); +} + /** * Scenes are objects putting meshes into 'world space' * @param id @@ -2456,6 +2512,7 @@ GameLib.D3.RigidBody.prototype.createRigidBodyInstance = function() { * @param scale * @param parentSceneId * @param lights + * @param physics GameLib.D3.Physics * @constructor */ GameLib.D3.Scene = function( @@ -2517,10 +2574,21 @@ GameLib.D3.Scene = function( /** * Loads a scene directly from the API - * @param sceneName + * @param gameLibScene GameLib.D3.Scene * @param onLoaded callback + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback callback + * @param apiUrl */ -GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { +GameLib.D3.Scene.loadSceneFromApi = function( + gameLibScene, + onLoaded, + graphics, + uploadPath, + progressCallback, + apiUrl +) { /** * First check if this is a client or server side request @@ -2533,10 +2601,10 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { var xhr = new XMLHttpRequest(); xhr.open( 'GET', - this.apiUrl + '/scene/load' + scene.path + '/' + scene.name + apiUrl + '/scene/load' + gameLibScene.path + '/' + gameLibScene.name ); - xhr.onreadystatechange = function(xhr, gameLibD3) { + xhr.onreadystatechange = function(xhr) { return function() { if (xhr.readyState == 4) { @@ -2556,12 +2624,19 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { var physics = scene.physics[p]; + var engine = null; + + if (physics.engine.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON) { + engine = new GameLib.D3.Engine( + GameLib.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + } + var physics3d = new GameLib.D3.Physics( physics.id, physics.name, - physics.engineType, - gameLibD3.CANNON, - null, + engine, null ); @@ -2678,7 +2753,7 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { ); lights3d.push(light3d); - }; + } var scene3d = new GameLib.D3.Scene( scene._id || scene.id, @@ -2711,27 +2786,41 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { physics3ds ); - gameLibD3.loadScene(scene3d, onLoaded, false); + GameLib.D3.Scene.loadScene( + scene3d, + onLoaded, + false, + graphics, + uploadPath, + progressCallback + ); } } - }(xhr, this); + }(xhr); xhr.send(); }; - /** - * Loads a GameLib.D3.Scene object into a ThreeJS Scene object + * Loads a GameLib.D3.Scene object into a Graphics Instance Scene object * @param gameLibScene GameLib.D3.Scene * @param onLoaded callback when all meshes have loaded * @param computeNormals set to true to compute new face and vertex normals during load + * @param graphics GameLib.D3.Graphics + * @param uploadPath + * @param progressCallback */ -GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) { +GameLib.D3.Scene.loadScene = function( + gameLibScene, + onLoaded, + computeNormals, + graphics, + uploadPath, + progressCallback +) { console.log("loading scene " + gameLibScene.name); - this.path = gameLibScene.path; - var meshQ = []; for (var m = 0; m < gameLibScene.meshes.length; m++) { @@ -2740,7 +2829,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals console.log("loading mesh " + mesh.name); - var geometry = new this.THREE.Geometry(); + var geometry = new graphics.instance.Geometry(); var vertices = mesh.vertices; @@ -2755,7 +2844,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ for (var v = 0; v < vertices.length; v++) { geometry.vertices.push( - new this.THREE.Vector3( + new graphics.instance.Vector3( vertices[v].position.x, vertices[v].position.y, vertices[v].position.z @@ -2768,16 +2857,16 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ for (var f = 0; f < faces.length; f++) { - var face = new this.THREE.Face3( + var face = new graphics.instance.Face3( faces[f].v0, faces[f].v1, faces[f].v2, - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].normal.x, faces[f].normal.y, faces[f].normal.z ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].color.r, faces[f].color.g, faces[f].color.b @@ -2786,41 +2875,41 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals ); face.vertexColors = [ - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[0].r, faces[f].vertexColors[0].g, faces[f].vertexColors[0].b ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[1].r, faces[f].vertexColors[1].g, faces[f].vertexColors[1].b ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[2].r, faces[f].vertexColors[2].g, faces[f].vertexColors[2].b ) ]; - face.normal = new this.THREE.Vector3( + face.normal = new graphics.instance.Vector3( faces[f].normal.x, faces[f].normal.y, faces[f].normal.z ); face.vertexNormals = [ - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[0].x, faces[f].vertexNormals[0].y, faces[f].vertexNormals[0].z ), - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[1].x, faces[f].vertexNormals[1].y, faces[f].vertexNormals[1].z ), - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[2].x, faces[f].vertexNormals[2].y, faces[f].vertexNormals[2].z @@ -2844,15 +2933,15 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) { geometry.faceVertexUvs[fm][fuv] = []; geometry.faceVertexUvs[fm][fuv].push( - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][0].x, faceMaterialVertexUvs[fuv][0].y ), - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][1].x, faceMaterialVertexUvs[fuv][1].y ), - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][2].x, faceMaterialVertexUvs[fuv][2].y ) @@ -2869,17 +2958,24 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals geometry.computeVertexNormals(); } - var threeMaterialLoaders = []; + var instanceMaterialLoaders = []; /** * Setup materials */ for (var mi = 0; mi < materials.length; mi++) { - threeMaterialLoaders.push(this.createThreeMaterial(materials[mi])); + instanceMaterialLoaders.push( + GameLib.D3.Material.createInstanceMaterial( + materials[mi], + graphics, + uploadPath, + progressCallback + ) + ); } - var result = this.Q.all(threeMaterialLoaders).then( - function(gl3d, mesh, geometry) { + var result = Q.all(instanceMaterialLoaders).then( + function(mesh, geometry) { return function(materials) { console.log("loaded material : " + materials[0].name); @@ -2889,7 +2985,12 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ var material = materials[0]; - var threeMesh = gl3d.createThreeMesh(mesh, geometry, material); + var threeMesh = GameLib.D3.Mesh.createInstanceMesh( + mesh, + geometry, + material, + graphics + ); threeMesh.name = mesh.name; threeMesh.position.x = mesh.position.x; @@ -2911,7 +3012,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals return threeMesh; }; - }(this, mesh, geometry) + }(mesh, geometry) ).catch(function(error){ console.log(error); }); @@ -2919,101 +3020,100 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals meshQ.push(result); } - this.Q.all(meshQ).then(function(threeMeshes){ + Q.all(meshQ).then( + function(instanceMeshes){ console.log("all meshes have loaded"); if (typeof onLoaded != 'undefined') { - var threeLights = []; + var instanceLights = []; for (var sli = 0; sli < gameLibScene.lights.length; sli++) { - var blenderLight = gameLibScene.lights[sli]; + var gameLibLight = gameLibScene.lights[sli]; var light = null; - if (blenderLight.lightType == 'AmbientLight') { - light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity); + if (gameLibLight.lightType == 'AmbientLight') { + light = new graphics.instance.AmbientLight(gameLibLight.color, gameLibLight.intensity); } - if (blenderLight.lightType == 'DirectionalLight') { - light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity); + if (gameLibLight.lightType == 'DirectionalLight') { + light = new graphics.instance.DirectionalLight(gameLibLight.color, gameLibLight.intensity); } - if (blenderLight.lightType == 'PointLight') { - light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.decay = blenderLight.decay; + if (gameLibLight.lightType == 'PointLight') { + light = new graphics.instance.PointLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.decay = gameLibLight.decay; } - if (blenderLight.lightType == 'SpotLight') { - light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.angle = blenderLight.angle; - light.penumbra = blenderLight.penumbra; - light.decay = blenderLight.decay; + if (gameLibLight.lightType == 'SpotLight') { + light = new graphics.instance.SpotLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.angle = gameLibLight.angle; + light.penumbra = gameLibLight.penumbra; + light.decay = gameLibLight.decay; } - light.position.x = blenderLight.position.x; - light.position.y = blenderLight.position.y; - light.position.z = blenderLight.position.z; + light.position.x = gameLibLight.position.x; + light.position.y = gameLibLight.position.y; + light.position.z = gameLibLight.position.z; - light.rotation.x = blenderLight.rotation.x; - light.rotation.y = blenderLight.rotation.y; - light.rotation.z = blenderLight.rotation.z; - - // light.scale.x = blenderLight.scale.x; - // light.scale.y = blenderLight.scale.y; - // light.scale.z = blenderLight.scale.z; + light.rotation.x = gameLibLight.rotation.x; + light.rotation.y = gameLibLight.rotation.y; + light.rotation.z = gameLibLight.rotation.z; if (light == null) { - console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported'); + console.warn('Does not support lights of type :' + gameLibLight.lightType + ', not imported'); } else { - light.name = blenderLight.name; - threeLights.push(light); + light.name = gameLibLight.name; + instanceLights.push(light); } } - var threeScene = new this.THREE.Scene(); + var instanceScene = new graphics.instance.Scene(); - threeScene.name = gameLibScene.name; + instanceScene.name = gameLibScene.name; - threeScene.position.x = gameLibScene.position.x; - threeScene.position.y = gameLibScene.position.y; - threeScene.position.z = gameLibScene.position.z; + instanceScene.position.x = gameLibScene.position.x; + instanceScene.position.y = gameLibScene.position.y; + instanceScene.position.z = gameLibScene.position.z; - threeScene.rotation.x = gameLibScene.rotation.x; - threeScene.rotation.y = gameLibScene.rotation.y; - threeScene.rotation.z = gameLibScene.rotation.z; + instanceScene.rotation.x = gameLibScene.rotation.x; + instanceScene.rotation.y = gameLibScene.rotation.y; + instanceScene.rotation.z = gameLibScene.rotation.z; - threeScene.scale.x = gameLibScene.scale.x; - threeScene.scale.y = gameLibScene.scale.y; - threeScene.scale.z = gameLibScene.scale.z; + instanceScene.scale.x = gameLibScene.scale.x; + instanceScene.scale.y = gameLibScene.scale.y; + instanceScene.scale.z = gameLibScene.scale.z; - threeScene.quaternion.x = gameLibScene.quaternion.x; - threeScene.quaternion.y = gameLibScene.quaternion.y; - threeScene.quaternion.z = gameLibScene.quaternion.z; - threeScene.quaternion.w = gameLibScene.quaternion.w; + instanceScene.quaternion.x = gameLibScene.quaternion.x; + instanceScene.quaternion.y = gameLibScene.quaternion.y; + instanceScene.quaternion.z = gameLibScene.quaternion.z; + instanceScene.quaternion.w = gameLibScene.quaternion.w; - for (var m = 0; m < threeMeshes.length; m++) { - threeScene.add(threeMeshes[m]); + for (var m = 0; m < instanceMeshes.length; m++) { + instanceScene.add(instanceMeshes[m]); } - for (var l = 0; l < threeLights.length; l++) { - threeScene.add(threeLights[l]); + for (var l = 0; l < instanceLights.length; l++) { + instanceScene.add(instanceLights[l]); } onLoaded( gameLibScene, { - scene: threeScene, - lights: threeLights, - meshes: threeMeshes + scene: instanceScene, + lights: instanceLights, + meshes: instanceMeshes } ); } - }.bind(this)).catch(function(error){ - console.log(error); - }); + }.catch( + function(error){ + console.log(error); + } + )); }; /** * Physics Shape Superset @@ -3228,6 +3328,10 @@ GameLib.D3.Physics.Solver = function( GameLib.D3.Physics.SPLIT_SOLVER = 0x1; GameLib.D3.Physics.GS_SOLVER = 0x2; +if (typeof require != 'undefined') { + var Q = require('q'); +} + /** * Texture Superset * @param id @@ -3433,69 +3537,79 @@ GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004; GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. - - /** * Defers loading of an image and resolves once image is loaded - * @param gameLibTexture - * @param threeMaterial - * @param threeMaterialMapType + * @param gameLibTexture GameLib.D3.Texture + * @param instanceMaterial + * @param instanceMaterialMapType + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback * @returns {Promise} */ -GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) { +GameLib.D3.Texture.loadMap = function( + gameLibTexture, + instanceMaterial, + instanceMaterialMapType, + graphics, + uploadPath, + progressCallback +) { - var q = this.Q.defer(); + var defer = Q.defer(); var imagePath = null; + + var textureLoader = new graphics.instance.TextureLoader(); if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { /** * Else, load from upload source */ - imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; + imagePath = uploadPath + '/' + gameLibTexture.image.filename; } if (imagePath) { - this.textureLoader.crossOrigin = ''; + textureLoader.crossOrigin = ''; - this.textureLoader.load( + textureLoader.load( imagePath, function(texture) { /** * onLoad */ - threeMaterial[threeMaterialMapType] = texture; - threeMaterial[threeMaterialMapType].name = gameLibTexture.name; - threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy; - threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding; - threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY; + instanceMaterial[instanceMaterialMapType] = texture; + instanceMaterial[instanceMaterialMapType].name = gameLibTexture.name; + instanceMaterial[instanceMaterialMapType].anisotropy = gameLibTexture.anisotropy; + instanceMaterial[instanceMaterialMapType].encoding = gameLibTexture.encoding; + instanceMaterial[instanceMaterialMapType].flipY = gameLibTexture.flipY; /** * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes */ - threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; - threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter; - threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter; - threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping; - threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps; - threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2( + instanceMaterial[instanceMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; + instanceMaterial[instanceMaterialMapType].magFilter = gameLibTexture.magFilter; + instanceMaterial[instanceMaterialMapType].minFilter = gameLibTexture.minFilter; + instanceMaterial[instanceMaterialMapType].mapping = gameLibTexture.mapping; + instanceMaterial[instanceMaterialMapType].mipmaps = gameLibTexture.mipmaps; + instanceMaterial[instanceMaterialMapType].offset = new graphics.instance.Vector2( gameLibTexture.offset.x, gameLibTexture.offset.y ); - threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; - threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType; - threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS; - threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT; - threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; - threeMaterial.needsUpdate = true; - q.resolve(true); + instanceMaterial[instanceMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; + instanceMaterial[instanceMaterialMapType].textureType = gameLibTexture.textureType; + instanceMaterial[instanceMaterialMapType].wrapS = gameLibTexture.wrapS; + instanceMaterial[instanceMaterialMapType].wrapT = gameLibTexture.wrapT; + instanceMaterial[instanceMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; + instanceMaterial.needsUpdate = true; + defer.resolve(true); }, function(xhr) { /** * onProgress */ - if (this.editor) { - this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success'); + if (progressCallback) { + progressCallback(Math.round(xhr.loaded / xhr.total * 100)); } }, function(error) { @@ -3503,26 +3617,36 @@ GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMate * onError */ console.log("an error occurred while trying to load the image : " + imagePath); - q.resolve(null); + defer.resolve(null); } ); } else { - q.resolve(null); + defer.resolve(null); } - return q.promise; + return defer.promise; }; /** * Returns an array of image loading Promises - * @param blenderMaterial + * @param gameLibMaterial * @param blenderMaps - * @param threeMaterial + * @param instanceMaterial + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback * @returns Q[] */ -GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) { +GameLib.D3.Texture.loadMaps = function( + gameLibMaterial, + blenderMaps, + instanceMaterial, + graphics, + uploadPath, + progressCallback +) { var textureMaps = []; @@ -3530,9 +3654,9 @@ GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMate var map = blenderMaps[ti]; - if (blenderMaterial.maps.hasOwnProperty(map)) { + if (gameLibMaterial.maps.hasOwnProperty(map)) { - var blenderTexture = blenderMaterial.maps[map]; + var blenderTexture = gameLibMaterial.maps[map]; if ( blenderTexture && @@ -3540,57 +3664,66 @@ GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMate blenderTexture.image.filename ) { - var threeMap = null; + var instanceMap = null; if (map == 'alpha') { - threeMap = 'alhpaMap'; + instanceMap = 'alhpaMap'; } if (map == 'ao') { - threeMap = 'aoMap'; + instanceMap = 'aoMap'; } if (map == 'bump') { - threeMap = 'bumpMap'; + instanceMap = 'bumpMap'; } if (map == 'displacement') { - threeMap = 'displacementMap'; + instanceMap = 'displacementMap'; } if (map == 'emissive') { - threeMap = 'emissiveMap'; + instanceMap = 'emissiveMap'; } if (map == 'environment') { - threeMap = 'envMap'; + instanceMap = 'envMap'; } if (map == 'light') { - threeMap = 'lightMap'; + instanceMap = 'lightMap'; } if (map == 'specular') { - threeMap = 'specularMap'; + instanceMap = 'specularMap'; } if (map == 'diffuse') { - threeMap = 'map'; + instanceMap = 'map'; } if (map == 'roughness') { - threeMap = 'roughnessMap'; + instanceMap = 'roughnessMap'; } if (map == 'metalness') { - threeMap = 'metalnessMap'; + instanceMap = 'metalnessMap'; } - if (threeMap == null) { + if (instanceMap == null) { console.warn("unsupported map type : " + map); } - textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap)); + textureMaps.push( + GameLib.D3.Texture.loadMap( + gameLibMaterial.maps[map], + instanceMaterial, + instanceMap, + graphics, + uploadPath, + progressCallback + ) + ); } } } diff --git a/gulpfile.js b/gulpfile.js index 5e268bf..3e4b80c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -5,6 +5,7 @@ var minify = require('gulp-minify'); var plumber = require('gulp-plumber'); var istanbul = require('gulp-istanbul'); var mocha = require('gulp-mocha'); +var watch = require('gulp-watch'); gulp.task( 'build', @@ -59,6 +60,17 @@ gulp.task( gulp.task( 'default', - ['build'], - function() {} + [ + 'build' + ], + function() { + return watch([ + 'src/*.js' + ], + function() { + gulp.start([ + 'build' + ]); + }) + } ); \ No newline at end of file diff --git a/package.json b/package.json index 275e7df..a94a06b 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "gulp-istanbul": "^1.1.1", "gulp-mocha": "^3.0.1", "gulp-plumber": "^1.1.0", + "gulp-watch": "^4.3.10", "sinon": "^1.17.6", "sinon-chai": "^2.8.0" } diff --git a/src/game-lib-graphics.js b/src/game-lib-graphics.js new file mode 100644 index 0000000..7ffb678 --- /dev/null +++ b/src/game-lib-graphics.js @@ -0,0 +1,37 @@ +/** + * Graphics Superset + * @param graphicsType + * @param instance {THREE} + * @constructor + */ +GameLib.D3.Graphics = function( + graphicsType, + instance +) { + this.graphicsType = graphicsType; + this.instance = instance; +}; + +/** + * True if THREE physics + * @returns {boolean} + */ +GameLib.D3.Graphics.prototype.isThree = function() { + return (this.graphicsType == GameLib.D3.Graphics.GRAPHICS_TYPE_THREE) +}; + +/** + * Logs a warning and throws an error if not cannon + */ +GameLib.D3.Graphics.prototype.isNotThreeThrow = function() { + if (this.graphicsType != GameLib.D3.Graphics.GRAPHICS_TYPE_THREE) { + console.warn('Only THREE supported for this function'); + throw new Error('Only THREE supported for this function'); + } +}; + +/** + * Physics GameLib.D3.Graphics Types + * @type {number} + */ +GameLib.D3.Graphics.GRAPHICS_TYPE_THREE = 0x1; \ No newline at end of file diff --git a/src/game-lib-material.js b/src/game-lib-material.js index 1bfe4a5..131fe54 100644 --- a/src/game-lib-material.js +++ b/src/game-lib-material.js @@ -507,69 +507,76 @@ GameLib.D3.Material.TYPE_SPRITE = "SpriteMaterial"; GameLib.D3.Material.TYPE_MULTI_MATERIAL= "MultiMaterial"; /** - * Creates a THREE.Material from a GameLib.D3.Material - * @param blenderMaterial GameLib.D3.Material - * @param THREE THREE.js + * Creates an instance Material from a GameLib.D3.Material + * @param gameLibMaterial GameLib.D3.Material + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback */ -GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) { +GameLib.D3.Material.createInstanceMaterial = function( + gameLibMaterial, + graphics, + uploadPath, + progressCallback +) { var defer = this.Q.defer(); - var threeMaterial = null; + var instanceMaterial = null; var blenderMaps = []; - if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { + if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_STANDARD) { - threeMaterial = new THREE.MeshStandardMaterial({ - name: blenderMaterial.name, - opacity: blenderMaterial.opacity, - transparent: blenderMaterial.transparent, - blending: blenderMaterial.blending, - blendSrc: blenderMaterial.blendSrc, - blendDst: blenderMaterial.blendDst, - blendEquation: blenderMaterial.blendEquation, - depthTest: blenderMaterial.depthTest, - depthFunc: blenderMaterial.depthFunc, - depthWrite: blenderMaterial.depthWrite, - polygonOffset: blenderMaterial.polygonOffset, - polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, - polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, - alphaTest: blenderMaterial.alphaTest, - clippingPlanes: blenderMaterial.clippingPlanes, - clipShadows: blenderMaterial.clipShadows, - overdraw: blenderMaterial.overdraw, - visible: blenderMaterial.visible, - side: blenderMaterial.side, - color: new THREE.Color( - blenderMaterial.color.r, - blenderMaterial.color.g, - blenderMaterial.color.b + instanceMaterial = new graphics.instance.MeshStandardMaterial({ + name: gameLibMaterial.name, + opacity: gameLibMaterial.opacity, + transparent: gameLibMaterial.transparent, + blending: gameLibMaterial.blending, + blendSrc: gameLibMaterial.blendSrc, + blendDst: gameLibMaterial.blendDst, + blendEquation: gameLibMaterial.blendEquation, + depthTest: gameLibMaterial.depthTest, + depthFunc: gameLibMaterial.depthFunc, + depthWrite: gameLibMaterial.depthWrite, + polygonOffset: gameLibMaterial.polygonOffset, + polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor, + polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits, + alphaTest: gameLibMaterial.alphaTest, + clippingPlanes: gameLibMaterial.clippingPlanes, + clipShadows: gameLibMaterial.clipShadows, + overdraw: gameLibMaterial.overdraw, + visible: gameLibMaterial.visible, + side: gameLibMaterial.side, + color: new graphics.instance.Color( + gameLibMaterial.color.r, + gameLibMaterial.color.g, + gameLibMaterial.color.b ), - roughness: blenderMaterial.roughness, - metalness: blenderMaterial.metalness, - lightMapIntensity: blenderMaterial.lightMapIntensity, - aoMapIntensity: blenderMaterial.aoMapIntensity, - emissive: new THREE.Color( - blenderMaterial.emissive.r, - blenderMaterial.emissive.g, - blenderMaterial.emissive.b + roughness: gameLibMaterial.roughness, + metalness: gameLibMaterial.metalness, + lightMapIntensity: gameLibMaterial.lightMapIntensity, + aoMapIntensity: gameLibMaterial.aoMapIntensity, + emissive: new graphics.instance.Color( + gameLibMaterial.emissive.r, + gameLibMaterial.emissive.g, + gameLibMaterial.emissive.b ), - emissiveIntensity: blenderMaterial.emissiveIntensity, - bumpScale: blenderMaterial.bumpScale, - normalScale: blenderMaterial.normalScale, - displacementScale: blenderMaterial.displacementScale, - refractionRatio: blenderMaterial.refractionRatio, - fog: blenderMaterial.fog, - shading: blenderMaterial.shading, - wireframe: blenderMaterial.wireframe, - wireframeLinewidth: blenderMaterial.wireframeLineWidth, - wireframeLinecap: blenderMaterial.wireframeLineCap, - wireframeLinejoin: blenderMaterial.wireframeLineJoin, - vertexColors: blenderMaterial.vertexColors, - skinning: blenderMaterial.skinning, - morphTargets: blenderMaterial.morphTargets, - morphNormals: blenderMaterial.morphNormals + emissiveIntensity: gameLibMaterial.emissiveIntensity, + bumpScale: gameLibMaterial.bumpScale, + normalScale: gameLibMaterial.normalScale, + displacementScale: gameLibMaterial.displacementScale, + refractionRatio: gameLibMaterial.refractionRatio, + fog: gameLibMaterial.fog, + shading: gameLibMaterial.shading, + wireframe: gameLibMaterial.wireframe, + wireframeLinewidth: gameLibMaterial.wireframeLineWidth, + wireframeLinecap: gameLibMaterial.wireframeLineCap, + wireframeLinejoin: gameLibMaterial.wireframeLineJoin, + vertexColors: gameLibMaterial.vertexColors, + skinning: gameLibMaterial.skinning, + morphTargets: gameLibMaterial.morphTargets, + morphNormals: gameLibMaterial.morphNormals }); blenderMaps.push( @@ -585,62 +592,62 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) { 'alpha', 'environment' ); - } else if (blenderMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { + } else if (gameLibMaterial.materialType == GameLib.D3.Material.TYPE_MESH_PHONG) { - threeMaterial = new THREE.MeshPhongMaterial({ - name: blenderMaterial.name, - opacity: blenderMaterial.opacity, - transparent: blenderMaterial.transparent, - blending: blenderMaterial.blending, - blendSrc: blenderMaterial.blendSrc, - blendDst: blenderMaterial.blendDst, - blendEquation: blenderMaterial.blendEquation, - depthTest: blenderMaterial.depthTest, - depthFunc: blenderMaterial.depthFunc, - depthWrite: blenderMaterial.depthWrite, - polygonOffset: blenderMaterial.polygonOffset, - polygonOffsetFactor: blenderMaterial.polygonOffsetFactor, - polygonOffsetUnits: blenderMaterial.polygonOffsetUnits, - alphaTest: blenderMaterial.alphaTest, - clippingPlanes: blenderMaterial.clippingPlanes, - clipShadows: blenderMaterial.clipShadows, - overdraw: blenderMaterial.overdraw, - visible: blenderMaterial.visible, - side: blenderMaterial.side, - color: new THREE.Color( - blenderMaterial.color.r, - blenderMaterial.color.g, - blenderMaterial.color.b + instanceMaterial = new graphics.instance.MeshPhongMaterial({ + name: gameLibMaterial.name, + opacity: gameLibMaterial.opacity, + transparent: gameLibMaterial.transparent, + blending: gameLibMaterial.blending, + blendSrc: gameLibMaterial.blendSrc, + blendDst: gameLibMaterial.blendDst, + blendEquation: gameLibMaterial.blendEquation, + depthTest: gameLibMaterial.depthTest, + depthFunc: gameLibMaterial.depthFunc, + depthWrite: gameLibMaterial.depthWrite, + polygonOffset: gameLibMaterial.polygonOffset, + polygonOffsetFactor: gameLibMaterial.polygonOffsetFactor, + polygonOffsetUnits: gameLibMaterial.polygonOffsetUnits, + alphaTest: gameLibMaterial.alphaTest, + clippingPlanes: gameLibMaterial.clippingPlanes, + clipShadows: gameLibMaterial.clipShadows, + overdraw: gameLibMaterial.overdraw, + visible: gameLibMaterial.visible, + side: gameLibMaterial.side, + color: new graphics.instance.Color( + gameLibMaterial.color.r, + gameLibMaterial.color.g, + gameLibMaterial.color.b ), - specular: new THREE.Color( - blenderMaterial.specular.r, - blenderMaterial.specular.g, - blenderMaterial.specular.b + specular: new graphics.instance.Color( + gameLibMaterial.specular.r, + gameLibMaterial.specular.g, + gameLibMaterial.specular.b ), - shininess: blenderMaterial.shininess, - lightMapIntensity: blenderMaterial.lightMapIntensity, - aoMapIntensity: blenderMaterial.aoMapIntensity, - emissive: new THREE.Color( - blenderMaterial.emissive.r, - blenderMaterial.emissive.g, - blenderMaterial.emissive.b + shininess: gameLibMaterial.shininess, + lightMapIntensity: gameLibMaterial.lightMapIntensity, + aoMapIntensity: gameLibMaterial.aoMapIntensity, + emissive: new graphics.instance.Color( + gameLibMaterial.emissive.r, + gameLibMaterial.emissive.g, + gameLibMaterial.emissive.b ), - emissiveIntensity: blenderMaterial.emissiveIntensity, - bumpScale: blenderMaterial.bumpScale, - normalScale: blenderMaterial.normalScale, - displacementScale: blenderMaterial.displacementScale, - combine: blenderMaterial.combine, - refractionRatio: blenderMaterial.refractionRatio, - fog: blenderMaterial.fog, - shading: blenderMaterial.shading, - wireframe: blenderMaterial.wireframe, - wireframeLinewidth: blenderMaterial.wireframeLineWidth, - wireframeLinecap: blenderMaterial.wireframeLineCap, - wireframeLinejoin: blenderMaterial.wireframeLineJoin, - vertexColors: blenderMaterial.vertexColors, - skinning: blenderMaterial.skinning, - morphTargets: blenderMaterial.morphTargets, - morphNormals: blenderMaterial.morphNormals + emissiveIntensity: gameLibMaterial.emissiveIntensity, + bumpScale: gameLibMaterial.bumpScale, + normalScale: gameLibMaterial.normalScale, + displacementScale: gameLibMaterial.displacementScale, + combine: gameLibMaterial.combine, + refractionRatio: gameLibMaterial.refractionRatio, + fog: gameLibMaterial.fog, + shading: gameLibMaterial.shading, + wireframe: gameLibMaterial.wireframe, + wireframeLinewidth: gameLibMaterial.wireframeLineWidth, + wireframeLinecap: gameLibMaterial.wireframeLineCap, + wireframeLinejoin: gameLibMaterial.wireframeLineJoin, + vertexColors: gameLibMaterial.vertexColors, + skinning: gameLibMaterial.skinning, + morphTargets: gameLibMaterial.morphTargets, + morphNormals: gameLibMaterial.morphNormals }); blenderMaps.push( @@ -657,14 +664,21 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) { ); } else { - console.log("material type is not implemented yet: " + blenderMaterial.materialType + " - material indexes could be screwed up"); + console.log("material type is not implemented yet: " + gameLibMaterial.materialType + " - material indexes could be screwed up"); } if (blenderMaps.length > 0) { - var textureMaps = this.loadMaps(blenderMaterial, blenderMaps, threeMaterial); + var textureMaps = GameLib.D3.Texture.loadMaps( + gameLibMaterial, + blenderMaps, + instanceMaterial, + graphics, + uploadPath, + progressCallback + ); Q.all(textureMaps).then( function(){ - defer.resolve(threeMaterial); + defer.resolve(instanceMaterial); } ).catch( function(error){ @@ -673,7 +687,7 @@ GameLib.D3.prototype.createThreeMaterial = function(blenderMaterial, THREE) { } ) } else { - defer.resolve(threeMaterial); + defer.resolve(instanceMaterial); } return defer.promise; diff --git a/src/game-lib-mesh.js b/src/game-lib-mesh.js index a557188..883edff 100644 --- a/src/game-lib-mesh.js +++ b/src/game-lib-mesh.js @@ -121,17 +121,18 @@ GameLib.D3.Mesh.TYPE_SKINNED = 1; /** * Creates a THREE Mesh from GameLib.D3.Mesh - * @param gameLibMesh - * @param threeGeometry - * @param threeMaterial + * @param gameLibMesh GameLib.D3.Mesh + * @param instanceGeometry + * @param instanceMaterial + * @param graphics * @returns {*} */ -GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, threeMaterial) { +GameLib.D3.Mesh.createInstanceMesh = function(gameLibMesh, instanceGeometry, instanceMaterial, graphics) { var threeMesh = null; if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_NORMAL) { - threeMesh = new this.THREE.Mesh(threeGeometry, threeMaterial); + threeMesh = new graphics.instance.Mesh(instanceGeometry, instanceMaterial); } if (gameLibMesh.meshType == GameLib.D3.Mesh.TYPE_SKINNED) { @@ -146,7 +147,7 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre for (var bi = 0; bi < bones.length; bi++) { - var bone = new this.THREE.Bone(); + var bone = new graphics.instance.Bone(); bone.name = bones[bi].name; @@ -187,8 +188,8 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre * Setup bones (indexes) */ for (var si = 0; si < skinIndices.length; si++) { - threeGeometry.skinIndices.push( - new this.THREE.Vector4( + instanceGeometry.skinIndices.push( + new graphics.instance.Vector4( skinIndices[si].x, skinIndices[si].y, skinIndices[si].z, @@ -201,8 +202,8 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre * Setup bones (weights) */ for (var sw = 0; sw < skinWeights.length; sw++) { - threeGeometry.skinWeights.push( - new this.THREE.Vector4( + instanceGeometry.skinWeights.push( + new graphics.instance.Vector4( skinWeights[sw].x, skinWeights[sw].y, skinWeights[sw].z, @@ -211,9 +212,9 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre ); } - threeMesh = new this.THREE.SkinnedMesh(threeGeometry, threeMaterial); + threeMesh = new graphics.instance.SkinnedMesh(instanceGeometry, instanceMaterial); - var skeleton = new this.THREE.Skeleton(threeBones); + var skeleton = new graphics.instance.Skeleton(threeBones); skeleton.useVertexTexture = gameLibMesh.skeleton.useVertexTexture; @@ -228,7 +229,7 @@ GameLib.D3.prototype.createThreeMesh = function(gameLibMesh, threeGeometry, thre threeMesh.pose(); - threeMesh.skeleton.skeletonHelper = new this.THREE.SkeletonHelper(threeMesh); + threeMesh.skeleton.skeletonHelper = new graphics.instance.SkeletonHelper(threeMesh); threeMesh.skeleton.skeletonHelper.material.linewidth = 5; } diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index b036a30..fc7b261 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -1,3 +1,7 @@ +if (typeof require != 'undefined') { + var Q = require('q'); +} + /** * Scenes are objects putting meshes into 'world space' * @param id @@ -10,6 +14,7 @@ * @param scale * @param parentSceneId * @param lights + * @param physics GameLib.D3.Physics * @constructor */ GameLib.D3.Scene = function( @@ -71,10 +76,21 @@ GameLib.D3.Scene = function( /** * Loads a scene directly from the API - * @param sceneName + * @param gameLibScene GameLib.D3.Scene * @param onLoaded callback + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback callback + * @param apiUrl */ -GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { +GameLib.D3.Scene.loadSceneFromApi = function( + gameLibScene, + onLoaded, + graphics, + uploadPath, + progressCallback, + apiUrl +) { /** * First check if this is a client or server side request @@ -87,10 +103,10 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { var xhr = new XMLHttpRequest(); xhr.open( 'GET', - this.apiUrl + '/scene/load' + scene.path + '/' + scene.name + apiUrl + '/scene/load' + gameLibScene.path + '/' + gameLibScene.name ); - xhr.onreadystatechange = function(xhr, gameLibD3) { + xhr.onreadystatechange = function(xhr) { return function() { if (xhr.readyState == 4) { @@ -110,12 +126,19 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { var physics = scene.physics[p]; + var engine = null; + + if (physics.engine.engineType == GameLib.D3.Engine.ENGINE_TYPE_CANNON) { + engine = new GameLib.D3.Engine( + GameLib.D3.Engine.ENGINE_TYPE_CANNON, + CANNON + ); + } + var physics3d = new GameLib.D3.Physics( physics.id, physics.name, - physics.engineType, - gameLibD3.CANNON, - null, + engine, null ); @@ -232,7 +255,7 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { ); lights3d.push(light3d); - }; + } var scene3d = new GameLib.D3.Scene( scene._id || scene.id, @@ -265,27 +288,41 @@ GameLib.D3.prototype.loadSceneFromApi = function(scene, onLoaded) { physics3ds ); - gameLibD3.loadScene(scene3d, onLoaded, false); + GameLib.D3.Scene.loadScene( + scene3d, + onLoaded, + false, + graphics, + uploadPath, + progressCallback + ); } } - }(xhr, this); + }(xhr); xhr.send(); }; - /** - * Loads a GameLib.D3.Scene object into a ThreeJS Scene object + * Loads a GameLib.D3.Scene object into a Graphics Instance Scene object * @param gameLibScene GameLib.D3.Scene * @param onLoaded callback when all meshes have loaded * @param computeNormals set to true to compute new face and vertex normals during load + * @param graphics GameLib.D3.Graphics + * @param uploadPath + * @param progressCallback */ -GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals) { +GameLib.D3.Scene.loadScene = function( + gameLibScene, + onLoaded, + computeNormals, + graphics, + uploadPath, + progressCallback +) { console.log("loading scene " + gameLibScene.name); - this.path = gameLibScene.path; - var meshQ = []; for (var m = 0; m < gameLibScene.meshes.length; m++) { @@ -294,7 +331,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals console.log("loading mesh " + mesh.name); - var geometry = new this.THREE.Geometry(); + var geometry = new graphics.instance.Geometry(); var vertices = mesh.vertices; @@ -309,7 +346,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ for (var v = 0; v < vertices.length; v++) { geometry.vertices.push( - new this.THREE.Vector3( + new graphics.instance.Vector3( vertices[v].position.x, vertices[v].position.y, vertices[v].position.z @@ -322,16 +359,16 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ for (var f = 0; f < faces.length; f++) { - var face = new this.THREE.Face3( + var face = new graphics.instance.Face3( faces[f].v0, faces[f].v1, faces[f].v2, - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].normal.x, faces[f].normal.y, faces[f].normal.z ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].color.r, faces[f].color.g, faces[f].color.b @@ -340,41 +377,41 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals ); face.vertexColors = [ - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[0].r, faces[f].vertexColors[0].g, faces[f].vertexColors[0].b ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[1].r, faces[f].vertexColors[1].g, faces[f].vertexColors[1].b ), - new this.THREE.Color( + new graphics.instance.Color( faces[f].vertexColors[2].r, faces[f].vertexColors[2].g, faces[f].vertexColors[2].b ) ]; - face.normal = new this.THREE.Vector3( + face.normal = new graphics.instance.Vector3( faces[f].normal.x, faces[f].normal.y, faces[f].normal.z ); face.vertexNormals = [ - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[0].x, faces[f].vertexNormals[0].y, faces[f].vertexNormals[0].z ), - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[1].x, faces[f].vertexNormals[1].y, faces[f].vertexNormals[1].z ), - new this.THREE.Vector3( + new graphics.instance.Vector3( faces[f].vertexNormals[2].x, faces[f].vertexNormals[2].y, faces[f].vertexNormals[2].z @@ -398,15 +435,15 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals for (var fuv = 0; fuv < faceMaterialVertexUvs.length; fuv++) { geometry.faceVertexUvs[fm][fuv] = []; geometry.faceVertexUvs[fm][fuv].push( - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][0].x, faceMaterialVertexUvs[fuv][0].y ), - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][1].x, faceMaterialVertexUvs[fuv][1].y ), - new this.THREE.Vector2( + new graphics.instance.Vector2( faceMaterialVertexUvs[fuv][2].x, faceMaterialVertexUvs[fuv][2].y ) @@ -423,17 +460,24 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals geometry.computeVertexNormals(); } - var threeMaterialLoaders = []; + var instanceMaterialLoaders = []; /** * Setup materials */ for (var mi = 0; mi < materials.length; mi++) { - threeMaterialLoaders.push(this.createThreeMaterial(materials[mi])); + instanceMaterialLoaders.push( + GameLib.D3.Material.createInstanceMaterial( + materials[mi], + graphics, + uploadPath, + progressCallback + ) + ); } - var result = this.Q.all(threeMaterialLoaders).then( - function(gl3d, mesh, geometry) { + var result = Q.all(instanceMaterialLoaders).then( + function(mesh, geometry) { return function(materials) { console.log("loaded material : " + materials[0].name); @@ -443,7 +487,12 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals */ var material = materials[0]; - var threeMesh = gl3d.createThreeMesh(mesh, geometry, material); + var threeMesh = GameLib.D3.Mesh.createInstanceMesh( + mesh, + geometry, + material, + graphics + ); threeMesh.name = mesh.name; threeMesh.position.x = mesh.position.x; @@ -465,7 +514,7 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals return threeMesh; }; - }(this, mesh, geometry) + }(mesh, geometry) ).catch(function(error){ console.log(error); }); @@ -473,99 +522,98 @@ GameLib.D3.prototype.loadScene = function(gameLibScene, onLoaded, computeNormals meshQ.push(result); } - this.Q.all(meshQ).then(function(threeMeshes){ + Q.all(meshQ).then( + function(instanceMeshes){ console.log("all meshes have loaded"); if (typeof onLoaded != 'undefined') { - var threeLights = []; + var instanceLights = []; for (var sli = 0; sli < gameLibScene.lights.length; sli++) { - var blenderLight = gameLibScene.lights[sli]; + var gameLibLight = gameLibScene.lights[sli]; var light = null; - if (blenderLight.lightType == 'AmbientLight') { - light = new this.THREE.AmbientLight(blenderLight.color, blenderLight.intensity); + if (gameLibLight.lightType == 'AmbientLight') { + light = new graphics.instance.AmbientLight(gameLibLight.color, gameLibLight.intensity); } - if (blenderLight.lightType == 'DirectionalLight') { - light = new this.THREE.DirectionalLight(blenderLight.color, blenderLight.intensity); + if (gameLibLight.lightType == 'DirectionalLight') { + light = new graphics.instance.DirectionalLight(gameLibLight.color, gameLibLight.intensity); } - if (blenderLight.lightType == 'PointLight') { - light = new this.THREE.PointLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.decay = blenderLight.decay; + if (gameLibLight.lightType == 'PointLight') { + light = new graphics.instance.PointLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.decay = gameLibLight.decay; } - if (blenderLight.lightType == 'SpotLight') { - light = new this.THREE.SpotLight(blenderLight.color, blenderLight.intensity); - light.distance = blenderLight.distance; - light.angle = blenderLight.angle; - light.penumbra = blenderLight.penumbra; - light.decay = blenderLight.decay; + if (gameLibLight.lightType == 'SpotLight') { + light = new graphics.instance.SpotLight(gameLibLight.color, gameLibLight.intensity); + light.distance = gameLibLight.distance; + light.angle = gameLibLight.angle; + light.penumbra = gameLibLight.penumbra; + light.decay = gameLibLight.decay; } - light.position.x = blenderLight.position.x; - light.position.y = blenderLight.position.y; - light.position.z = blenderLight.position.z; + light.position.x = gameLibLight.position.x; + light.position.y = gameLibLight.position.y; + light.position.z = gameLibLight.position.z; - light.rotation.x = blenderLight.rotation.x; - light.rotation.y = blenderLight.rotation.y; - light.rotation.z = blenderLight.rotation.z; - - // light.scale.x = blenderLight.scale.x; - // light.scale.y = blenderLight.scale.y; - // light.scale.z = blenderLight.scale.z; + light.rotation.x = gameLibLight.rotation.x; + light.rotation.y = gameLibLight.rotation.y; + light.rotation.z = gameLibLight.rotation.z; if (light == null) { - console.warn('Does not support lights of type :' + blenderLight.lightType + ', not imported'); + console.warn('Does not support lights of type :' + gameLibLight.lightType + ', not imported'); } else { - light.name = blenderLight.name; - threeLights.push(light); + light.name = gameLibLight.name; + instanceLights.push(light); } } - var threeScene = new this.THREE.Scene(); + var instanceScene = new graphics.instance.Scene(); - threeScene.name = gameLibScene.name; + instanceScene.name = gameLibScene.name; - threeScene.position.x = gameLibScene.position.x; - threeScene.position.y = gameLibScene.position.y; - threeScene.position.z = gameLibScene.position.z; + instanceScene.position.x = gameLibScene.position.x; + instanceScene.position.y = gameLibScene.position.y; + instanceScene.position.z = gameLibScene.position.z; - threeScene.rotation.x = gameLibScene.rotation.x; - threeScene.rotation.y = gameLibScene.rotation.y; - threeScene.rotation.z = gameLibScene.rotation.z; + instanceScene.rotation.x = gameLibScene.rotation.x; + instanceScene.rotation.y = gameLibScene.rotation.y; + instanceScene.rotation.z = gameLibScene.rotation.z; - threeScene.scale.x = gameLibScene.scale.x; - threeScene.scale.y = gameLibScene.scale.y; - threeScene.scale.z = gameLibScene.scale.z; + instanceScene.scale.x = gameLibScene.scale.x; + instanceScene.scale.y = gameLibScene.scale.y; + instanceScene.scale.z = gameLibScene.scale.z; - threeScene.quaternion.x = gameLibScene.quaternion.x; - threeScene.quaternion.y = gameLibScene.quaternion.y; - threeScene.quaternion.z = gameLibScene.quaternion.z; - threeScene.quaternion.w = gameLibScene.quaternion.w; + instanceScene.quaternion.x = gameLibScene.quaternion.x; + instanceScene.quaternion.y = gameLibScene.quaternion.y; + instanceScene.quaternion.z = gameLibScene.quaternion.z; + instanceScene.quaternion.w = gameLibScene.quaternion.w; - for (var m = 0; m < threeMeshes.length; m++) { - threeScene.add(threeMeshes[m]); + for (var m = 0; m < instanceMeshes.length; m++) { + instanceScene.add(instanceMeshes[m]); } - for (var l = 0; l < threeLights.length; l++) { - threeScene.add(threeLights[l]); + for (var l = 0; l < instanceLights.length; l++) { + instanceScene.add(instanceLights[l]); } onLoaded( gameLibScene, { - scene: threeScene, - lights: threeLights, - meshes: threeMeshes + scene: instanceScene, + lights: instanceLights, + meshes: instanceMeshes } ); } - }.bind(this)).catch(function(error){ - console.log(error); - }); + }.catch( + function(error){ + console.log(error); + } + )); }; \ No newline at end of file diff --git a/src/game-lib-texture.js b/src/game-lib-texture.js index 9c85869..ff78af4 100644 --- a/src/game-lib-texture.js +++ b/src/game-lib-texture.js @@ -1,3 +1,7 @@ +if (typeof require != 'undefined') { + var Q = require('q'); +} + /** * Texture Superset * @param id @@ -203,69 +207,79 @@ GameLib.D3.Texture.TYPE_RGBM7_ENCODING = 3004; GameLib.D3.Texture.TYPE_RGBM16_ENCODING = 3005; GameLib.D3.Texture.TYPE_RGBD_ENCODING = 3006; // MAXRANGE IS 256. - - /** * Defers loading of an image and resolves once image is loaded - * @param gameLibTexture - * @param threeMaterial - * @param threeMaterialMapType + * @param gameLibTexture GameLib.D3.Texture + * @param instanceMaterial + * @param instanceMaterialMapType + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback * @returns {Promise} */ -GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMaterialMapType) { +GameLib.D3.Texture.loadMap = function( + gameLibTexture, + instanceMaterial, + instanceMaterialMapType, + graphics, + uploadPath, + progressCallback +) { - var q = this.Q.defer(); + var defer = Q.defer(); var imagePath = null; + + var textureLoader = new graphics.instance.TextureLoader(); if (gameLibTexture && gameLibTexture.image && gameLibTexture.image.filename) { /** * Else, load from upload source */ - imagePath = this.editorUrl + '/uploads' + this.path + '/' + gameLibTexture.image.filename; + imagePath = uploadPath + '/' + gameLibTexture.image.filename; } if (imagePath) { - this.textureLoader.crossOrigin = ''; + textureLoader.crossOrigin = ''; - this.textureLoader.load( + textureLoader.load( imagePath, function(texture) { /** * onLoad */ - threeMaterial[threeMaterialMapType] = texture; - threeMaterial[threeMaterialMapType].name = gameLibTexture.name; - threeMaterial[threeMaterialMapType].anisotropy = gameLibTexture.anisotropy; - threeMaterial[threeMaterialMapType].encoding = gameLibTexture.encoding; - threeMaterial[threeMaterialMapType].flipY = gameLibTexture.flipY; + instanceMaterial[instanceMaterialMapType] = texture; + instanceMaterial[instanceMaterialMapType].name = gameLibTexture.name; + instanceMaterial[instanceMaterialMapType].anisotropy = gameLibTexture.anisotropy; + instanceMaterial[instanceMaterialMapType].encoding = gameLibTexture.encoding; + instanceMaterial[instanceMaterialMapType].flipY = gameLibTexture.flipY; /** * We don't restore the format since this changing from OS to OS and breaks the implementation sometimes */ - threeMaterial[threeMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; - threeMaterial[threeMaterialMapType].magFilter = gameLibTexture.magFilter; - threeMaterial[threeMaterialMapType].minFilter = gameLibTexture.minFilter; - threeMaterial[threeMaterialMapType].mapping = gameLibTexture.mapping; - threeMaterial[threeMaterialMapType].mipmaps = gameLibTexture.mipmaps; - threeMaterial[threeMaterialMapType].offset = new this.THREE.Vector2( + instanceMaterial[instanceMaterialMapType].generateMipmaps = gameLibTexture.generateMipmaps; + instanceMaterial[instanceMaterialMapType].magFilter = gameLibTexture.magFilter; + instanceMaterial[instanceMaterialMapType].minFilter = gameLibTexture.minFilter; + instanceMaterial[instanceMaterialMapType].mapping = gameLibTexture.mapping; + instanceMaterial[instanceMaterialMapType].mipmaps = gameLibTexture.mipmaps; + instanceMaterial[instanceMaterialMapType].offset = new graphics.instance.Vector2( gameLibTexture.offset.x, gameLibTexture.offset.y ); - threeMaterial[threeMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; - threeMaterial[threeMaterialMapType].textureType = gameLibTexture.textureType; - threeMaterial[threeMaterialMapType].wrapS = gameLibTexture.wrapS; - threeMaterial[threeMaterialMapType].wrapT = gameLibTexture.wrapT; - threeMaterial[threeMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; - threeMaterial.needsUpdate = true; - q.resolve(true); + instanceMaterial[instanceMaterialMapType].premultiplyAlpha = gameLibTexture.premultiplyAlpha; + instanceMaterial[instanceMaterialMapType].textureType = gameLibTexture.textureType; + instanceMaterial[instanceMaterialMapType].wrapS = gameLibTexture.wrapS; + instanceMaterial[instanceMaterialMapType].wrapT = gameLibTexture.wrapT; + instanceMaterial[instanceMaterialMapType].unpackAlignment = gameLibTexture.unpackAlignment; + instanceMaterial.needsUpdate = true; + defer.resolve(true); }, function(xhr) { /** * onProgress */ - if (this.editor) { - this.editor.setServerStatus(Math.round(xhr.loaded / xhr.total * 100) + '% complete', 'success'); + if (progressCallback) { + progressCallback(Math.round(xhr.loaded / xhr.total * 100)); } }, function(error) { @@ -273,26 +287,36 @@ GameLib.D3.prototype.loadMap = function(gameLibTexture, threeMaterial, threeMate * onError */ console.log("an error occurred while trying to load the image : " + imagePath); - q.resolve(null); + defer.resolve(null); } ); } else { - q.resolve(null); + defer.resolve(null); } - return q.promise; + return defer.promise; }; /** * Returns an array of image loading Promises - * @param blenderMaterial + * @param gameLibMaterial * @param blenderMaps - * @param threeMaterial + * @param instanceMaterial + * @param graphics GameLib.D3.Graphics + * @param uploadPath String + * @param progressCallback * @returns Q[] */ -GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMaterial) { +GameLib.D3.Texture.loadMaps = function( + gameLibMaterial, + blenderMaps, + instanceMaterial, + graphics, + uploadPath, + progressCallback +) { var textureMaps = []; @@ -300,9 +324,9 @@ GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMate var map = blenderMaps[ti]; - if (blenderMaterial.maps.hasOwnProperty(map)) { + if (gameLibMaterial.maps.hasOwnProperty(map)) { - var blenderTexture = blenderMaterial.maps[map]; + var blenderTexture = gameLibMaterial.maps[map]; if ( blenderTexture && @@ -310,57 +334,66 @@ GameLib.D3.prototype.loadMaps = function(blenderMaterial, blenderMaps, threeMate blenderTexture.image.filename ) { - var threeMap = null; + var instanceMap = null; if (map == 'alpha') { - threeMap = 'alhpaMap'; + instanceMap = 'alhpaMap'; } if (map == 'ao') { - threeMap = 'aoMap'; + instanceMap = 'aoMap'; } if (map == 'bump') { - threeMap = 'bumpMap'; + instanceMap = 'bumpMap'; } if (map == 'displacement') { - threeMap = 'displacementMap'; + instanceMap = 'displacementMap'; } if (map == 'emissive') { - threeMap = 'emissiveMap'; + instanceMap = 'emissiveMap'; } if (map == 'environment') { - threeMap = 'envMap'; + instanceMap = 'envMap'; } if (map == 'light') { - threeMap = 'lightMap'; + instanceMap = 'lightMap'; } if (map == 'specular') { - threeMap = 'specularMap'; + instanceMap = 'specularMap'; } if (map == 'diffuse') { - threeMap = 'map'; + instanceMap = 'map'; } if (map == 'roughness') { - threeMap = 'roughnessMap'; + instanceMap = 'roughnessMap'; } if (map == 'metalness') { - threeMap = 'metalnessMap'; + instanceMap = 'metalnessMap'; } - if (threeMap == null) { + if (instanceMap == null) { console.warn("unsupported map type : " + map); } - textureMaps.push(this.loadMap(blenderMaterial.maps[map], threeMaterial, threeMap)); + textureMaps.push( + GameLib.D3.Texture.loadMap( + gameLibMaterial.maps[map], + instanceMaterial, + instanceMap, + graphics, + uploadPath, + progressCallback + ) + ); } } } From 7e8e3155bdfecec58433ea20f42b880715c63e46 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Wed, 26 Oct 2016 16:13:18 +0200 Subject: [PATCH 14/15] fixes from integration tests --- build/game-lib-min.js | 4 +-- build/game-lib.js | 55 +++++++++++++++++++++------------------- src/game-lib-a.js | 9 +++++++ src/game-lib-material.js | 8 +++--- src/game-lib-scene.js | 22 ++++++++-------- src/game-lib-texture.js | 16 +++++------- 6 files changed, 60 insertions(+), 54 deletions(-) diff --git a/build/game-lib-min.js b/build/game-lib-min.js index 39f3cfc..4f3ec0e 100644 --- a/build/game-lib-min.js +++ b/build/game-lib-min.js @@ -1,2 +1,2 @@ -function GameLib(){}if("undefined"==typeof GameLib.D3&&(GameLib.D3=function(){}),GameLib.D3.BoneWeight=function(e,i){this.boneIndex=e,this.weight=i},GameLib.D3.Bone=function(e,i,t,n,s,o,a,r,h,c){this.id=e,this.name=t,this.boneId=i,"undefined"==typeof n&&(n=[]),this.childBoneIds=n,"undefined"==typeof s&&(s=null),this.parentBoneId=s,"undefined"==typeof o&&(o=new GameLib.D3.Vector4),this.quaternion=o,"undefined"==typeof a&&(a=new GameLib.D3.Vector3(0,0,0)),this.position=a,"undefined"==typeof r&&(r=new GameLib.D3.Vector3(0,0,0)),this.rotation=r,"undefined"==typeof h&&(h=new GameLib.D3.Vector3(1,1,1)),this.scale=h,"undefined"==typeof c&&(c=new GameLib.D3.Vector3(0,1,0)),this.up=c},GameLib.D3.Broadphase=function(e,i,t,n,s){this.id=e,"undefined"==typeof i&&(i="broadphase-"+t),this.name=i,"undefined"==typeof t&&(t=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=t,"undefined"==typeof n&&(n=null),this.engine=n,this.instance=null,s&&this.createInstance()},GameLib.D3.Broadphase.prototype.createInstance=function(){if(!(this.engine instanceof GameLib.D3.Engine))throw console.warn("No Engine"),new Error("No Engine");this.engine.isNotCannonThrow();var e=null;if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)e=new this.engine.instance.NaiveBroadphase;else if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)e=new this.engine.instance.GridBroadphase;else{if(this.broadphaseType!=GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);e=new this.engine.instance.SAPBroardphase}return this.instance=e,e},GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Color=function(e,i,t,n){this.r=e,this.g=i,this.b=t,this.a=n},GameLib.D3.Engine=function(e,i){this.engineType=e,this.instance=i},GameLib.D3.Engine.prototype.isCannon=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_CANNON},GameLib.D3.Engine.prototype.isNotCannonThrow=function(){if(this.engineType!=GameLib.D3.Engine.ENGINE_TYPE_CANNON)throw console.warn("Only CANNON supported for this function"),new Error("Only CANNON supported for this function")},GameLib.D3.Engine.prototype.isAmmo=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_AMMO},GameLib.D3.Engine.prototype.isGoblin=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_GOBLIN},GameLib.D3.Engine.ENGINE_TYPE_CANNON=1,GameLib.D3.Engine.ENGINE_TYPE_AMMO=2,GameLib.D3.Engine.ENGINE_TYPE_GOBLIN=3,GameLib.D3.FlyControls=function(e,i,t){this.flySpeed=100,this.canvas=t,this.THREE=i,this.yaw=0,this.pitch=0,this.canRotate=!1,this.moveForward=!1,this.moveBackward=!1,this.moveLeft=!1,this.moveRight=!1,this.moveUp=!1,this.moveDown=!1,this.mouseUpCallback=this.onMouseUp.bind(this),this.mouseDownCallback=this.onMouseDown.bind(this),this.mouseMoveCallback=this.onMouseMove.bind(this),this.mouseWheelCallback=this.onMouseWheel.bind(this),this.keyDownCallback=this.onKeyDown.bind(this),this.keyUpCallback=this.onKeyUp.bind(this),this.camera=e,this.canvas.addEventListener("keydown",this.keyDownCallback,!1),this.canvas.addEventListener("keyup",this.keyUpCallback,!1),this.canvas.addEventListener("mousedown",this.mouseDownCallback,!1),this.canvas.addEventListener("mouseup",this.mouseUpCallback,!1),this.canvas.addEventListener("mousewheel",this.mouseWheelCallback,!1),this.havePointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.element=document.body,this.havePointerLock&&(this.element.requestPointerLock=this.element.requestPointerLock||this.element.mozRequestPointerLock||this.element.webkitRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock)},GameLib.D3.FlyControls.prototype.onMouseWheel=function(e){this.moveForward=!0,this.applyTranslation(.001*e.wheelDelta),e.preventDefault(),this.moveForward=!1},GameLib.D3.FlyControls.prototype.onMouseDown=function(e){1==e.button&&(this.canRotate=!0,this.canvas.addEventListener("mousemove",this.mouseMoveCallback,!1))},GameLib.D3.FlyControls.prototype.onMouseUp=function(e){1==e.button&&(this.canRotate=!1,this.canvas.removeEventListener("mousemove",this.mouseMoveCallback))},GameLib.D3.FlyControls.prototype.applyRotation=function(){this.camera.rotation.set(this.pitch,this.yaw,0,"YXZ")},GameLib.D3.FlyControls.prototype.applyTranslation=function(e){var i=new this.THREE.Vector3(0,0,-1),t=new this.THREE.Euler(0,0,0,"YXZ");t.set(this.pitch,this.yaw,0,"YXZ"),i=i.applyEuler(t);var n=i.normalize(),s=n.cross(new this.THREE.Vector3(0,1,0));this.moveForward?(this.camera.position.x+=n.x*(e*this.flySpeed),this.camera.position.y+=n.y*(e*this.flySpeed),this.camera.position.z+=n.z*(e*this.flySpeed)):this.moveBackward&&(this.camera.position.x-=n.x*(e*this.flySpeed),this.camera.position.y-=n.y*(e*this.flySpeed),this.camera.position.z-=n.z*(e*this.flySpeed)),this.moveLeft?(this.camera.position.x-=s.x*(e*this.flySpeed),this.camera.position.y-=s.y*(e*this.flySpeed),this.camera.position.z-=s.z*(e*this.flySpeed)):this.moveRight&&(this.camera.position.x+=s.x*(e*this.flySpeed),this.camera.position.y+=s.y*(e*this.flySpeed),this.camera.position.z+=s.z*(e*this.flySpeed)),this.moveUp?this.camera.position.y+=e*this.flySpeed:this.moveDown&&(this.camera.position.y-=e*this.flySpeed)},GameLib.D3.FlyControls.prototype.update=function(e){this.applyRotation(),this.applyTranslation(e)},GameLib.D3.FlyControls.prototype.onMouseMove=function(e){if(this.canRotate){var i=e.movementX||e.mozMovementX||e.webkitMovementX||0,t=e.movementY||e.mozMovementY||e.webkitMovementY||0;this.yaw-=.002*i,this.pitch-=.002*t}},GameLib.D3.FlyControls.prototype.onKeyDown=function(e){switch(e.keyCode){case 87:this.moveForward=!0;break;case 65:this.moveLeft=!0;break;case 83:this.moveBackward=!0;break;case 68:this.moveRight=!0;break;case 104:this.moveUp=!0;break;case 98:this.moveDown=!0}},GameLib.D3.FlyControls.prototype.onKeyUp=function(e){switch(e.keyCode){case 38:case 87:this.moveForward=!1;break;case 37:case 65:this.moveLeft=!1;break;case 40:case 83:this.moveBackward=!1;break;case 39:case 68:this.moveRight=!1;break;case 104:this.moveUp=!1;break;case 98:this.moveDown=!1}},GameLib.D3.Game=function(){this.scenes={},this.physicsWorlds=[],this.sceneToPhysicsWorldsMap={}},GameLib.D3.Game.prototype.AddScene=function(e){this.scenes[e.name]=e},GameLib.D3.Game.prototype.AddPhysicsWorld=function(e){this.physicsWorlds.push(e)},GameLib.D3.Game.prototype.LinkPhysicsWorldToScene=function(e,i){this.sceneToPhysicsWorldsMap[i.name]=this.sceneToPhysicsWorldsMap[i.name]||[],this.sceneToPhysicsWorldsMap[i.name].push(e)},GameLib.D3.Game.prototype.GetPhysicsWorldsForScene=function(e){return this.sceneToPhysicsWorldsMap[e.name]},GameLib.D3.Game.prototype.ProcessPhysics=function(e){for(var i in this.sceneToPhysicsWorldsMap){var t=this.sceneToPhysicsWorldsMap[i],n=this.scenes[i];if(n&&t)for(var s=0,o=t.length;s0){var r=GameLib.D3.Texture.loadMaps(e,a,o,i,t,n);Q.all(r).then(function(){s.resolve(o)}).catch(function(e){console.log(e),s.reject(e)})}else s.resolve(o);return s.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,c,l,p,m,d,u,y,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof c&&(c=[]),this.skinWeights=c,"undefined"==typeof l&&(l=[]),this.materials=l,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(1,1,1)),this.scale=u,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(0,1,0)),this.up=y,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.Mesh.createInstanceMesh=function(e,i,t,n){var s=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(s=new n.instance.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var o=e.skeleton.bones,a=e.skinIndices,r=e.skinWeights,h=[],c=0;c0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var c=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],l=0;l9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var h=0;h0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)},GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixY(n),l=0;lo&&(o=h.y,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixX(n),l=0;ln&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n0){var r=GameLib.D3.Texture.loadMaps(e,a,o,i,t,n);Q.all(r).then(function(){s.resolve(o)}).catch(function(e){console.log(e),s.reject(e)})}else s.resolve(o);return s.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,c,l,p,m,d,u,y,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof c&&(c=[]),this.skinWeights=c,"undefined"==typeof l&&(l=[]),this.materials=l,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(1,1,1)),this.scale=u,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(0,1,0)),this.up=y,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.Mesh.createInstanceMesh=function(e,i,t,n){var s=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(s=new n.instance.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var o=e.skeleton.bones,a=e.skinIndices,r=e.skinWeights,h=[],c=0;c0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var c=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],l=0;l9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var h=0;h0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z};GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)};GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixY(n),l=0;lo&&(o=h.y,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixX(n),l=0;ln&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n Date: Thu, 27 Oct 2016 18:47:02 +0200 Subject: [PATCH 15/15] integration test fixes --- build/game-lib-min.js | 2 +- build/game-lib.js | 20 +++++++++++++------- src/game-lib-rigid-body.js | 16 +++++++++------- src/game-lib-scene.js | 4 ++++ 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/build/game-lib-min.js b/build/game-lib-min.js index 4f3ec0e..64b2d72 100644 --- a/build/game-lib-min.js +++ b/build/game-lib-min.js @@ -1,2 +1,2 @@ -function GameLib(){}if("undefined"==typeof GameLib.D3&&(GameLib.D3=function(){}),"undefined"==typeof Q){if("undefined"==typeof require)throw console.warn("You need the Q promise library for the GameLib.D3"),new Error("You need the Q promise library for the GameLib.D3");var Q=require("q")}GameLib.D3.BoneWeight=function(e,i){this.boneIndex=e,this.weight=i},GameLib.D3.Bone=function(e,i,t,n,s,o,a,r,h,c){this.id=e,this.name=t,this.boneId=i,"undefined"==typeof n&&(n=[]),this.childBoneIds=n,"undefined"==typeof s&&(s=null),this.parentBoneId=s,"undefined"==typeof o&&(o=new GameLib.D3.Vector4),this.quaternion=o,"undefined"==typeof a&&(a=new GameLib.D3.Vector3(0,0,0)),this.position=a,"undefined"==typeof r&&(r=new GameLib.D3.Vector3(0,0,0)),this.rotation=r,"undefined"==typeof h&&(h=new GameLib.D3.Vector3(1,1,1)),this.scale=h,"undefined"==typeof c&&(c=new GameLib.D3.Vector3(0,1,0)),this.up=c},GameLib.D3.Broadphase=function(e,i,t,n,s){this.id=e,"undefined"==typeof i&&(i="broadphase-"+t),this.name=i,"undefined"==typeof t&&(t=GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE),this.broadphaseType=t,"undefined"==typeof n&&(n=null),this.engine=n,this.instance=null,s&&this.createInstance()},GameLib.D3.Broadphase.prototype.createInstance=function(){if(!(this.engine instanceof GameLib.D3.Engine))throw console.warn("No Engine"),new Error("No Engine");this.engine.isNotCannonThrow();var e=null;if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE)e=new this.engine.instance.NaiveBroadphase;else if(this.broadphaseType==GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID)e=new this.engine.instance.GridBroadphase;else{if(this.broadphaseType!=GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP)throw console.warn("Unsupported broadphase type: "+this.broadphaseType),new Error("Unsupported broadphase type: "+this.broadphaseType);e=new this.engine.instance.SAPBroardphase}return this.instance=e,e},GameLib.D3.Broadphase.BROADPHASE_TYPE_NAIVE=1,GameLib.D3.Broadphase.BROADPHASE_TYPE_GRID=2,GameLib.D3.Broadphase.BROADPHASE_TYPE_SAP=3,GameLib.D3.Color=function(e,i,t,n){this.r=e,this.g=i,this.b=t,this.a=n},GameLib.D3.Engine=function(e,i){this.engineType=e,this.instance=i},GameLib.D3.Engine.prototype.isCannon=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_CANNON},GameLib.D3.Engine.prototype.isNotCannonThrow=function(){if(this.engineType!=GameLib.D3.Engine.ENGINE_TYPE_CANNON)throw console.warn("Only CANNON supported for this function"),new Error("Only CANNON supported for this function")},GameLib.D3.Engine.prototype.isAmmo=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_AMMO},GameLib.D3.Engine.prototype.isGoblin=function(){return this.engineType==GameLib.D3.Engine.ENGINE_TYPE_GOBLIN},GameLib.D3.Engine.ENGINE_TYPE_CANNON=1,GameLib.D3.Engine.ENGINE_TYPE_AMMO=2,GameLib.D3.Engine.ENGINE_TYPE_GOBLIN=3,GameLib.D3.FlyControls=function(e,i,t){this.flySpeed=100,this.canvas=t,this.THREE=i,this.yaw=0,this.pitch=0,this.canRotate=!1,this.moveForward=!1,this.moveBackward=!1,this.moveLeft=!1,this.moveRight=!1,this.moveUp=!1,this.moveDown=!1,this.mouseUpCallback=this.onMouseUp.bind(this),this.mouseDownCallback=this.onMouseDown.bind(this),this.mouseMoveCallback=this.onMouseMove.bind(this),this.mouseWheelCallback=this.onMouseWheel.bind(this),this.keyDownCallback=this.onKeyDown.bind(this),this.keyUpCallback=this.onKeyUp.bind(this),this.camera=e,this.canvas.addEventListener("keydown",this.keyDownCallback,!1),this.canvas.addEventListener("keyup",this.keyUpCallback,!1),this.canvas.addEventListener("mousedown",this.mouseDownCallback,!1),this.canvas.addEventListener("mouseup",this.mouseUpCallback,!1),this.canvas.addEventListener("mousewheel",this.mouseWheelCallback,!1),this.havePointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.element=document.body,this.havePointerLock&&(this.element.requestPointerLock=this.element.requestPointerLock||this.element.mozRequestPointerLock||this.element.webkitRequestPointerLock,document.exitPointerLock=document.exitPointerLock||document.mozExitPointerLock||document.webkitExitPointerLock)},GameLib.D3.FlyControls.prototype.onMouseWheel=function(e){this.moveForward=!0,this.applyTranslation(.001*e.wheelDelta),e.preventDefault(),this.moveForward=!1},GameLib.D3.FlyControls.prototype.onMouseDown=function(e){1==e.button&&(this.canRotate=!0,this.canvas.addEventListener("mousemove",this.mouseMoveCallback,!1))},GameLib.D3.FlyControls.prototype.onMouseUp=function(e){1==e.button&&(this.canRotate=!1,this.canvas.removeEventListener("mousemove",this.mouseMoveCallback))},GameLib.D3.FlyControls.prototype.applyRotation=function(){this.camera.rotation.set(this.pitch,this.yaw,0,"YXZ")},GameLib.D3.FlyControls.prototype.applyTranslation=function(e){var i=new this.THREE.Vector3(0,0,-1),t=new this.THREE.Euler(0,0,0,"YXZ");t.set(this.pitch,this.yaw,0,"YXZ"),i=i.applyEuler(t);var n=i.normalize(),s=n.cross(new this.THREE.Vector3(0,1,0));this.moveForward?(this.camera.position.x+=n.x*(e*this.flySpeed),this.camera.position.y+=n.y*(e*this.flySpeed),this.camera.position.z+=n.z*(e*this.flySpeed)):this.moveBackward&&(this.camera.position.x-=n.x*(e*this.flySpeed),this.camera.position.y-=n.y*(e*this.flySpeed),this.camera.position.z-=n.z*(e*this.flySpeed)),this.moveLeft?(this.camera.position.x-=s.x*(e*this.flySpeed),this.camera.position.y-=s.y*(e*this.flySpeed),this.camera.position.z-=s.z*(e*this.flySpeed)):this.moveRight&&(this.camera.position.x+=s.x*(e*this.flySpeed),this.camera.position.y+=s.y*(e*this.flySpeed),this.camera.position.z+=s.z*(e*this.flySpeed)),this.moveUp?this.camera.position.y+=e*this.flySpeed:this.moveDown&&(this.camera.position.y-=e*this.flySpeed)},GameLib.D3.FlyControls.prototype.update=function(e){this.applyRotation(),this.applyTranslation(e)},GameLib.D3.FlyControls.prototype.onMouseMove=function(e){if(this.canRotate){var i=e.movementX||e.mozMovementX||e.webkitMovementX||0,t=e.movementY||e.mozMovementY||e.webkitMovementY||0;this.yaw-=.002*i,this.pitch-=.002*t}},GameLib.D3.FlyControls.prototype.onKeyDown=function(e){switch(e.keyCode){case 87:this.moveForward=!0;break;case 65:this.moveLeft=!0;break;case 83:this.moveBackward=!0;break;case 68:this.moveRight=!0;break;case 104:this.moveUp=!0;break;case 98:this.moveDown=!0}},GameLib.D3.FlyControls.prototype.onKeyUp=function(e){switch(e.keyCode){case 38:case 87:this.moveForward=!1;break;case 37:case 65:this.moveLeft=!1;break;case 40:case 83:this.moveBackward=!1;break;case 39:case 68:this.moveRight=!1;break;case 104:this.moveUp=!1;break;case 98:this.moveDown=!1}},GameLib.D3.Game=function(){this.scenes={},this.physicsWorlds=[],this.sceneToPhysicsWorldsMap={}},GameLib.D3.Game.prototype.AddScene=function(e){this.scenes[e.name]=e},GameLib.D3.Game.prototype.AddPhysicsWorld=function(e){this.physicsWorlds.push(e)},GameLib.D3.Game.prototype.LinkPhysicsWorldToScene=function(e,i){this.sceneToPhysicsWorldsMap[i.name]=this.sceneToPhysicsWorldsMap[i.name]||[],this.sceneToPhysicsWorldsMap[i.name].push(e)},GameLib.D3.Game.prototype.GetPhysicsWorldsForScene=function(e){return this.sceneToPhysicsWorldsMap[e.name]},GameLib.D3.Game.prototype.ProcessPhysics=function(e){for(var i in this.sceneToPhysicsWorldsMap){var t=this.sceneToPhysicsWorldsMap[i],n=this.scenes[i];if(n&&t)for(var s=0,o=t.length;s0){var r=GameLib.D3.Texture.loadMaps(e,a,o,i,t,n);Q.all(r).then(function(){s.resolve(o)}).catch(function(e){console.log(e),s.reject(e)})}else s.resolve(o);return s.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,c,l,p,m,d,u,y,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof c&&(c=[]),this.skinWeights=c,"undefined"==typeof l&&(l=[]),this.materials=l,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(1,1,1)),this.scale=u,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(0,1,0)),this.up=y,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.Mesh.createInstanceMesh=function(e,i,t,n){var s=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(s=new n.instance.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var o=e.skeleton.bones,a=e.skinIndices,r=e.skinWeights,h=[],c=0;c0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var c=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],l=0;l9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var h=0;h0){var r=GameLib.D3.Texture.loadMaps(e,a,o,i,t,n);Q.all(r).then(function(){s.resolve(o)}).catch(function(e){console.log(e),s.reject(e)})}else s.resolve(o);return s.promise},GameLib.D3.Matrix3=function(e,i,t){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t)},GameLib.D3.Matrix3.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0),new GameLib.D3.Vector4(0,1,0),new GameLib.D3.Vector4(0,0,1)]},GameLib.D3.Matrix4=function(e,i,t,n){this.identity(),e&&(this.rows[0]=e),i&&(this.rows[1]=i),t&&(this.rows[2]=t),n&&(this.rows[3]=n)},GameLib.D3.Matrix4.prototype.rotationMatrixX=function(e){return this.identity(),this.rows[1]=new GameLib.D3.Vector4(0,Math.cos(e),-1*Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(0,Math.sin(e),Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixY=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),0,Math.sin(e),0),this.rows[2]=new GameLib.D3.Vector4(-1*Math.sin(e),0,Math.cos(e),0),this},GameLib.D3.Matrix4.prototype.rotationMatrixZ=function(e){return this.identity(),this.rows[0]=new GameLib.D3.Vector4(Math.cos(e),-1*Math.sin(e),0,0),this.rows[1]=new GameLib.D3.Vector4(Math.sin(e),Math.cos(e),0,0),this},GameLib.D3.Matrix4.prototype.rotateX=function(e,i){return this.identity(),this.rotationMatrixX(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateY=function(e,i){return this.identity(),this.rotationMatrixY(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.rotateZ=function(e,i){return this.identity(),this.rotationMatrixZ(e),this.multiply(i)},GameLib.D3.Matrix4.prototype.multiply=function(e){return e instanceof GameLib.D3.Vector4?new GameLib.D3.Vector4(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z+this.rows[0].w*e.w,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z+this.rows[1].w*e.w,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z+this.rows[2].w*e.w,this.rows[3].x*e.x+this.rows[3].y*e.y+this.rows[3].z*e.z+this.rows[3].w*e.w):e instanceof GameLib.D3.Vector3?new GameLib.D3.Vector3(this.rows[0].x*e.x+this.rows[0].y*e.y+this.rows[0].z*e.z,this.rows[1].x*e.x+this.rows[1].y*e.y+this.rows[1].z*e.z,this.rows[2].x*e.x+this.rows[2].y*e.y+this.rows[2].z*e.z):void 0},GameLib.D3.Matrix4.prototype.identity=function(){this.rows=[new GameLib.D3.Vector4(1,0,0,0),new GameLib.D3.Vector4(0,1,0,0),new GameLib.D3.Vector4(0,0,1,0),new GameLib.D3.Vector4(0,0,0,1)]},GameLib.D3.Matrix4.prototype.lookAt=function(e,i,t){var n=new GameLib.D3.Vector3(e.x,e.y,e.z),s=n.subtract(i).normalize();0===s.squared()&&(s.z=1);var o=t.cross(s).normalize();0===o.squared()&&(s.x+=1e-4,o=t.cross(s).normalize());var a=s.cross(o);return this.rows[0].x=o.x,this.rows[0].y=o.y,this.rows[0].z=o.z,this.rows[1].x=a.x,this.rows[1].y=a.y,this.rows[1].z=a.z,this.rows[2].x=s.x,this.rows[2].y=s.y,this.rows[2].z=s.z,this},GameLib.D3.Mesh=function(e,i,t,n,s,o,a,r,h,c,l,p,m,d,u,y,f,b,L,v){this.id=e,this.path=i,this.name=t,this.meshType=n,this.vertices=s,this.faces=o,"undefined"==typeof a&&(a=null),this.skeleton=a,"undefined"==typeof r&&(r=[]),this.faceVertexUvs=r,"undefined"==typeof h&&(h=[]),this.skinIndices=h,"undefined"==typeof c&&(c=[]),this.skinWeights=c,"undefined"==typeof l&&(l=[]),this.materials=l,"undefined"==typeof p&&(p=new GameLib.D3.Vector3(0,0,0)),this.position=p,"undefined"==typeof m&&new GameLib.D3.Vector4,this.quaternion=m,"undefined"==typeof d&&(d=new GameLib.D3.Vector3(0,0,0)),this.rotation=d,"undefined"==typeof u&&(u=new GameLib.D3.Vector3(1,1,1)),this.scale=u,"undefined"==typeof y&&(y=new GameLib.D3.Vector3(0,1,0)),this.up=y,this.physics=f,this.parentMeshId=b,this.parentSceneId=L,this.rawData=null},GameLib.D3.Mesh.TYPE_NORMAL=0,GameLib.D3.Mesh.TYPE_SKINNED=1,GameLib.D3.Mesh.createInstanceMesh=function(e,i,t,n){var s=null;if(e.meshType==GameLib.D3.Mesh.TYPE_NORMAL&&(s=new n.instance.Mesh(i,t)),e.meshType==GameLib.D3.Mesh.TYPE_SKINNED){for(var o=e.skeleton.bones,a=e.skinIndices,r=e.skinWeights,h=[],c=0;c0;){var a=s.pop();if(a.triangle.v0==a.edge.x&&a.triangle.v1==a.edge.y||a.triangle.v1==a.edge.x&&a.triangle.v2==a.edge.y||a.triangle.v2==a.edge.x&&a.triangle.v0==a.edge.y){var r=a.triangle.v1;a.triangle.v1=a.triangle.v2,a.triangle.v2=r;var h=a.triangle.v1uv;a.triangle.v1uv=a.triangle.v2uv,a.triangle.v2uv=h}o.push(a);for(var c=[new GameLib.D3.Vector2(a.triangle.v0,a.triangle.v1),new GameLib.D3.Vector2(a.triangle.v1,a.triangle.v2),new GameLib.D3.Vector2(a.triangle.v2,a.triangle.v0)],l=0;l9||console.log("The vertices are not in the right length : "+e.length);for(var t=[],n=new GameLib.D3.Vector4.Points,s=0;s0)for(var h=0;h0},GameLib.D3.Vector3.normal=function(e,i,t){var n=i.copy(),s=t.copy();return n.subtract(e).cross(s.subtract(e))},GameLib.D3.Vector3.prototype.lookAt=function(e,i){var t=GameLib.D3.Matrix4.lookAt(this,e,i);this.multiply(t)},GameLib.D3.Vector3.prototype.translate=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this},GameLib.D3.Vector3.prototype.squared=function(){return this.x*this.x+this.y*this.y+this.z*this.z};GameLib.D3.Vector3.prototype.copy=function(){return new GameLib.D3.Vector3(this.x,this.y,this.z)};GameLib.D3.Vector3.prototype.multiply=function(e){if(e instanceof GameLib.D3.Vector3)this.x*=e.x,this.y*=e.y,this.z*=e.z;else{if(!(e instanceof GameLib.D3.Matrix4))throw console.log("functionality not implemented - please do this"),new Error("not implemented");var i=e.rows[0].x*this.x+e.rows[0].y*this.y+e.rows[0].z*this.z,t=e.rows[1].x*this.x+e.rows[1].y*this.y+e.rows[1].z*this.z,n=e.rows[2].x*this.x+e.rows[2].y*this.y+e.rows[2].z*this.z;this.x=i,this.y=t,this.z=n}return this},GameLib.D3.Vector3.prototype.dot=function(e){return this.x*e.x+this.y*e.y+this.z*e.z},GameLib.D3.Vector3.prototype.normalize=function(){var e=1e-6,i=this.squared();if(io&&(o=h.x,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixY(n),l=0;lo&&(o=h.y,n=i*e)}this.vectors=s;for(var c=(new GameLib.D3.Matrix4).rotationMatrixX(n),l=0;ln&&(n=this.vectors[a].x),this.vectors[a].y>s&&(s=this.vectors[a].y),this.vectors[a].z>o&&(o=this.vectors[a].z);return new GameLib.D3.Vector3(Math.abs(n-e),Math.abs(s-i),Math.abs(s-t))},GameLib.D3.Vector4.Points.prototype.average=function(){for(var e=0,i=0,t=0,n=0;n