From 683607d7bf4015f1b04ec4864589b3c8cdc932fc Mon Sep 17 00:00:00 2001 From: Theunis Johannes Botha Date: Sat, 1 Oct 2016 01:10:02 +0200 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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;