diff --git a/src/game-lib-a-api-component.js b/src/game-lib-a-api-component.js index 848fd5f..67d3a84 100644 --- a/src/game-lib-a-api-component.js +++ b/src/game-lib-a-api-component.js @@ -4,13 +4,15 @@ * @param linkedObjects * @param loaded (indicates whether the linked Objects for this component has been loaded) * @param parentEntity + * @param selected * @constructor */ GameLib.API.Component = function( componentType, linkedObjects, loaded, - parentEntity + parentEntity, + selected ) { this.componentType = componentType; @@ -28,6 +30,11 @@ GameLib.API.Component = function( parentEntity = null; } this.parentEntity = parentEntity; + + if (GameLib.Utils.UndefinedOrNull(selected)) { + selected = false; + } + this.selected = selected; }; /** diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 11cf412..154fc70 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -5,28 +5,31 @@ * @param linkedObjects * @param loaded * @param parentEntity + * @param selected */ GameLib.Component = function( - componentType, - linkedObjects, - loaded, - parentEntity + componentType, + linkedObjects, + loaded, + parentEntity, + selected ) { - GameLib.API.Component.call( - this, - componentType, - linkedObjects, - loaded, - parentEntity - ); + GameLib.API.Component.call( + this, + componentType, + linkedObjects, + loaded, + parentEntity, + selected + ); - this.idToObject = {}; + this.idToObject = {}; - //this.parentObjects = []; - - this.build = true; + //this.parentObjects = []; - //this.linkedObjects.parentEntity = GameLib.Entity; + this.build = true; + + //this.linkedObjects.parentEntity = GameLib.Entity; }; GameLib.Component.prototype = Object.create(GameLib.API.Component.prototype); @@ -60,42 +63,44 @@ GameLib.Component.COMPONENT_TEXTURE = 0x1a; GameLib.Component.COMPONENT_ENTITY_MANAGER = 0x1b; GameLib.Component.COMPONENT_DOM_ELEMENT = 0x1c; GameLib.Component.COMPONENT_IMAGE_FACTORY = 0x1d; +GameLib.Component.COMPONENT_STATS = 0x1e; +GameLib.Component.COMPONENT_GUI = 0x1f; /** * Components are linked at runtime - for storing, we just store the ID * @returns {*} */ GameLib.Component.prototype.toApiComponent = function() { - return this.id; + return this.id; }; GameLib.Component.prototype.buildIdToObject = function() { - if (!this.build) { - return; - } + if (!this.build) { + return; + } - this.build = false; + this.build = false; - this.idToObject = {}; + this.idToObject = {}; - for (var property in this.linkedObjects) { - if ( - this.linkedObjects.hasOwnProperty(property) && - this.hasOwnProperty(property) && - this[property] - ) { - if (this.linkedObjects[property] instanceof Array) { - this.idToObject = GameLib.Utils.LoadIdsFromArrayToIdObject(this[property], this.idToObject); - } else { - this.idToObject = GameLib.Utils.LoadIdsFromObjectToIdObject(this[property], this.idToObject); - } - } - } + for (var property in this.linkedObjects) { + if ( + this.linkedObjects.hasOwnProperty(property) && + this.hasOwnProperty(property) && + this[property] + ) { + if (this.linkedObjects[property] instanceof Array) { + this.idToObject = GameLib.Utils.LoadIdsFromArrayToIdObject(this[property], this.idToObject); + } else { + this.idToObject = GameLib.Utils.LoadIdsFromObjectToIdObject(this[property], this.idToObject); + } + } + } - this.idToObject[this.id] = this; + this.idToObject[this.id] = this; - this.build = true; + this.build = true; }; /** @@ -108,97 +113,97 @@ GameLib.Component.prototype.buildIdToObject = function() { */ GameLib.Component.prototype.linkObjects = function(idToObject) { - if (this.loaded) { - return; - } + if (this.loaded) { + return; + } - this.loaded = true; + this.loaded = true; - for (var property in this.linkedObjects) { - if ( - this.linkedObjects.hasOwnProperty(property) && - this.hasOwnProperty(property) && - this[property] - ) { + for (var property in this.linkedObjects) { + if ( + this.linkedObjects.hasOwnProperty(property) && + this.hasOwnProperty(property) && + this[property] + ) { - if (this.linkedObjects[property] instanceof Array) { - if (this[property] instanceof Array) { + if (this.linkedObjects[property] instanceof Array) { + if (this[property] instanceof Array) { - this[property] = this[property].map( - function(p) { - if (p instanceof Object) { + this[property] = this[property].map( + function(p) { + if (p instanceof Object) { - //p.parentObjects.push(this); + //p.parentObjects.push(this); - /** - * This object is already an object, does not need to be linked - */ - if (p.linkObjects) { - p.linkObjects(idToObject); - } + /** + * This object is already an object, does not need to be linked + */ + if (p.linkObjects) { + p.linkObjects(idToObject); + } - return p; - } else if (typeof p == 'string') { + return p; + } else if (typeof p === 'string') { - if (!idToObject[p]) { - console.warn('Could not locate the object to be linked in array - fix this'); - throw new Error('Could not locate the object to be linked in array - fix this'); - } + if (!idToObject[p]) { + console.warn('Could not locate the object to be linked in array - fix this'); + throw new Error('Could not locate the object to be linked in array - fix this'); + } - //idToObject[p].parentObjects.push(this); + //idToObject[p].parentObjects.push(this); - /** - * Perform deep-linking - */ - if (idToObject[p].linkObjects) { - idToObject[p].linkObjects(idToObject); - } + /** + * Perform deep-linking + */ + if (idToObject[p].linkObjects) { + idToObject[p].linkObjects(idToObject); + } - return idToObject[p]; - } else { - console.warn('Unhandled type : ', p); - throw new Error('Unhandled type : ', p); - } + return idToObject[p]; + } else { + console.warn('Unhandled type : ', p); + throw new Error('Unhandled type : ', p); + } - }.bind(this) - ) - } else { - console.warn('Incompatible Link Type - should be instance of array'); - throw new Error('Incompatible Link Type - should be instance of array'); - } - } else { + }.bind(this) + ) + } else { + console.warn('Incompatible Link Type - should be instance of array'); + throw new Error('Incompatible Link Type - should be instance of array'); + } + } else { - if (this[property] instanceof Object) { + if (this[property] instanceof Object) { - /** - * This object is already an object, perform deep linking - */ - if (this[property].linkObjects) { - this[property].linkObjects(idToObject); - } + /** + * This object is already an object, perform deep linking + */ + if (this[property].linkObjects) { + this[property].linkObjects(idToObject); + } - } else if (typeof this[property] == 'string') { + } else if (typeof this[property] === 'string') { - if (!idToObject[this[property]]) { - console.warn('Could not locate the object to be linked - fix this'); - throw new Error('Could not locate the object to be linked - fix this'); - } + if (!idToObject[this[property]]) { + console.warn('Could not locate the object to be linked - fix this'); + throw new Error('Could not locate the object to be linked - fix this'); + } - this[property] = idToObject[this[property]]; + this[property] = idToObject[this[property]]; - //this[property].parentObjects.push(this); + //this[property].parentObjects.push(this); - /** - * Perform deep-linking - */ - if (this[property].linkObjects) { - this[property].linkObjects(idToObject); - } - } else { - console.warn('Unhandled property type - fix this : ' + typeof this[property]); - throw new Error('Unhandled property type - fix this : ' + typeof this[property]); - } - } - } - } + /** + * Perform deep-linking + */ + if (this[property].linkObjects) { + this[property].linkObjects(idToObject); + } + } else { + console.warn('Unhandled property type - fix this : ' + typeof this[property]); + throw new Error('Unhandled property type - fix this : ' + typeof this[property]); + } + } + } + } }; \ No newline at end of file diff --git a/src/game-lib-d3-api-input-editor.js b/src/game-lib-d3-api-input-editor.js index 08ac365..36c4889 100644 --- a/src/game-lib-d3-api-input-editor.js +++ b/src/game-lib-d3-api-input-editor.js @@ -46,10 +46,6 @@ GameLib.D3.API.Input.Editor = function ( } this.camera = camera; - if (GameLib.Utils.UndefinedOrNull(selectDelayMs)) { - selectDelayMs = 300; - } - this.selectDelayMs = selectDelayMs; }; GameLib.D3.API.Input.Editor.prototype = Object.create(GameLib.Component.prototype); diff --git a/src/game-lib-d3-editor.js b/src/game-lib-d3-editor.js index 40cf5ef..2d41248 100644 --- a/src/game-lib-d3-editor.js +++ b/src/game-lib-d3-editor.js @@ -521,7 +521,7 @@ GameLib.D3.Editor.prototype.addScene = function(scene) { /** * Now we need to notify all systems of this new components */ - var systems = entity.getComponent(GameLib.System); + var systems = entity.getComponents(GameLib.System); systems.map( function(system){ diff --git a/src/game-lib-d3-helper.js b/src/game-lib-d3-helper.js index d8c5d18..bdda2c5 100644 --- a/src/game-lib-d3-helper.js +++ b/src/game-lib-d3-helper.js @@ -7,7 +7,7 @@ * @param helperType * @constructor */ -GameLib.D3.Helper = function Helper( +GameLib.D3.Helper = function( graphics, id, name, @@ -39,21 +39,21 @@ GameLib.D3.Helper = function Helper( if ( object instanceof GameLib.D3.Mesh && - object.meshType != GameLib.D3.Mesh.TYPE_CURVE + object.meshType !== GameLib.D3.Mesh.TYPE_CURVE ) { helperType = GameLib.D3.Helper.HELPER_TYPE_EDGES; } if (object instanceof GameLib.D3.Light) { - if (object.lightType == GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL) { + if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_DIRECTIONAL) { helperType = GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT; } - if (object.lightType == GameLib.D3.Light.LIGHT_TYPE_POINT) { + if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_POINT) { helperType = GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT; } - if (object.lightType == GameLib.D3.Light.LIGHT_TYPE_SPOT) { + if (object.lightType === GameLib.D3.Light.LIGHT_TYPE_SPOT) { helperType = GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT; } } @@ -91,27 +91,27 @@ GameLib.D3.Helper.prototype.createInstance = function(update) { instance = this.instance; } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_EDGES) { - instance = new THREE.EdgesHelper(this.object.instance, 0x007700); + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_EDGES) { + instance = new THREE.EdgesHelper(this.object.instance, 0x00FF00); } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT) { + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT) { instance = new THREE.DirectionalLightHelper(this.object.instance); } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT) { + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT) { instance = new THREE.PointLightHelper(this.object.instance, 1); } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT) { + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT) { instance = new THREE.SpotLightHelper(this.object.instance); } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_WIREFRAME) { - instance = new THREE.WireframeGeometry(this.object.instance, 0x007700); + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_WIREFRAME) { + instance = new THREE.WireframeGeometry(this.object.instance, 0x00FF00); } - if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_SKELETON) { + if (this.helperType === GameLib.D3.Helper.HELPER_TYPE_SKELETON) { instance = new THREE.SkeletonHelper(this.object.instance); } diff --git a/src/game-lib-d3-input-editor.js b/src/game-lib-d3-input-editor.js index a98a051..d16a4b7 100644 --- a/src/game-lib-d3-input-editor.js +++ b/src/game-lib-d3-input-editor.js @@ -56,7 +56,6 @@ GameLib.D3.Input.Editor = function ( this.mouseMove = null; this.mouseDown = null; this.keyDown = null; - this.contextMenu = null; this.raycaster = new GameLib.D3.Raycaster( this.graphics @@ -128,7 +127,7 @@ GameLib.D3.Input.Editor.prototype.onKeyDown = function(entity) { // BELOW is just a test to stop systems from keypress - it works nicely :) // but of course, when the system is stopped it can no longer be started by keypress - // var inputSystem = entity.getComponent(GameLib.System).reduce( + // var inputSystem = entity.getComponents(GameLib.System).reduce( // function(result, system){ // if (system.systemType === GameLib.System.SYSTEM_TYPE_INPUT) { // result = system; @@ -159,7 +158,7 @@ GameLib.D3.Input.Editor.prototype.onMouseMove = function(entity) { /** * MouseDown events - * @param entity + * @param entity GameLib.Entity * @returns {Function} */ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity) { @@ -178,7 +177,7 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity) { this.camera.instance ); - var meshes = entity.getComponent(GameLib.D3.Mesh); + var meshes = entity.getComponents(GameLib.D3.Mesh); var intersects = this.raycaster.getIntersectedObjects(meshes); @@ -194,33 +193,84 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity) { */ event.stopImmediatePropagation(); - intersects[0].instance.material.wireframe = !intersects[0].instance.material.wireframe; + /** + * Notify our component as being 'selected' + * @type {boolean} + */ + intersects[0].selected = !intersects[0].selected; - console.log('object(s) instersected'); + /** + * Add a helper to the scene + * @type GameLib.D3.Helper + */ + var helper = null; + + var scene = intersects[0].parentScene; + + if (!scene) { + console.warn('the scene object for this mesh could not be located : ' + intersects[0].name); + return; + } + + if (intersects[0].selected) { + + helper = new GameLib.D3.Helper( + this.graphics, + null, + intersects[0].name + ' Helper', + intersects[0], + GameLib.D3.Helper.HELPER_TYPE_EDGES + ); + + /** + * Backup the polygonOffset value, then set it to 'true' - helps for clear nice outlines + */ + intersects[0].polygonOffset = intersects[0].instance.material.polygonOffset; + + intersects[0].instance.material.polygonOffset = true; + + entity.addComponent(helper); + + scene.instance.add(helper.instance); + + var gui = entity.getFirstComponent(GameLib.GUI); + + gui.instance.add(intersects[0], 'name'); + + } else { + + var components = entity.getComponents(GameLib.D3.Helper); + + helper = components.reduce( + function(result, component) { + if (component.object === intersects[0]) { + result = component; + } + return result; + }, + null + ); + + if (helper) { + + scene.instance.remove(helper.instance); + + /** + * Restore the polygonOffset value + */ + intersects[0].instance.material.polygonOffset = intersects[0].polygonOffset; + + entity.removeComponent(helper); + + } else { + console.warn('failed to locate helper object which should exist for ' + intersects[0].name); + } + } } } } }; -/** - * Prevent Context Menu creation - * @param event - * @returns {boolean} - */ -GameLib.D3.Input.Editor.prototype.onContextMenu = function(event){ - - if (event.stopPropagation) { - event.stopPropagation(); - } - - if (event.preventDefault) { - event.preventDefault(); - } - - event.cancelBubble = true; - return false; -}; - // // console.log('keypressed ' + event.code); diff --git a/src/game-lib-d3-scene.js b/src/game-lib-d3-scene.js index 05bb935..fab28f2 100644 --- a/src/game-lib-d3-scene.js +++ b/src/game-lib-d3-scene.js @@ -274,88 +274,3 @@ GameLib.D3.Scene.FromObjectScene = function( computeNormals ); }; - -/** - * Transforms raw scene data into a GameLib.D3.Scene - * @param graphics - * @param objectScene Object (as it comes from the API) - * @param computeNormals - * @param onLoaded - * @param imageFactory GameLib.D3.ImageFactory - * @constructor - */ -GameLib.D3.Scene.LoadScene = function( - graphics, - objectScene, - computeNormals, - onLoaded, - imageFactory -) { - var scene = GameLib.D3.Scene.FromObjectScene( - graphics, - objectScene, - computeNormals, - imageFactory - ); - - onLoaded(scene); -}; - -/** - * Loads a scene directly from the API - * @param graphics GameLib.D3.Graphics - * @param partialSceneObject Object {path: '', name: ''} - * @param apiUrl - * @param onLoaded - */ -GameLib.D3.Scene.LoadSceneFromApi = function( - graphics, - partialSceneObject, - apiUrl, - 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', - apiUrl + '/scene/load' + partialSceneObject.path + '/' + partialSceneObject.name - ); - - xhr.onreadystatechange = function(xhr) { - - return function() { - - if (xhr.readyState == 4) { - - try { - var response = JSON.parse(xhr.responseText); - } catch (e) { - return onLoaded(null, new Error('Could not load scene : ' + e.message)); - } - - if (!response.scene || response.scene.length == 0) { - return onLoaded(null, new Error('Could not load scene')); - } - - var objectScene = response.scene[0]; - - GameLib.D3.Scene.LoadScene( - graphics, - objectScene, - true, - onLoaded - ); - } - } - }(xhr); - - xhr.send(); -}; \ No newline at end of file diff --git a/src/game-lib-d3-stats.js b/src/game-lib-d3-stats.js new file mode 100644 index 0000000..8b59b28 --- /dev/null +++ b/src/game-lib-d3-stats.js @@ -0,0 +1,77 @@ +/** + * Stats component for displaying some render statistics (framerate, memory consumption, etc) + * @param stats + * @param id + * @param name + * @param domElement + * @param parentEntity + * @constructor + */ +GameLib.D3.Stats = function( + stats, + id, + name, + domElement, + parentEntity +) { + if (GameLib.Utils.UndefinedOrNull(stats)) { + throw new Error('Need Stats object') + } + this.stats = stats; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_STATS, + { + 'domElement': GameLib.DomElement + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Stats (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(domElement)) { + console.warn('Need a DOM element for stats'); + throw new Error('Need a DOM element for stats'); + } + this.domElement = domElement; + + this.instance = this.createInstance(); +}; + +GameLib.D3.Stats.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.Stats.prototype.constructor = GameLib.D3.Stats; + +/** + * Creates a helper instance + * @param update + */ +GameLib.D3.Stats.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + this.instance = new this.stats(); + instance = this.instance; + } else { + instance = new this.stats(); + } + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Stats.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index a45f58a..c215130 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -193,7 +193,7 @@ GameLib.EntityManager.prototype.queryComponents = function(constructor) { var components = entities.reduce( function(result, entity){ - var ecs = entity.getComponent(constructor); + var ecs = entity.getComponents(constructor); ecs.map(function(ec){ result.push(ec); }); diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 66f6053..f02a915 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -105,13 +105,15 @@ GameLib.Entity.prototype.createInstance = function() { GameLib.Entity.prototype.addComponent = function(component) { this.components.push(component); component.parentEntity = this; + + }; /** * Returns all components of type 'constructor' * @param constructor */ -GameLib.Entity.prototype.getComponent = function(constructor) { +GameLib.Entity.prototype.getComponents = function(constructor) { var components = this.components.reduce( function(result, component) { @@ -132,7 +134,7 @@ GameLib.Entity.prototype.getComponent = function(constructor) { */ GameLib.Entity.prototype.getFirstComponent = function(constructor) { - var components = this.getComponent(constructor); + var components = this.getComponents(constructor); if (components.length > 0) { return components[0]; diff --git a/src/game-lib-gui.js b/src/game-lib-gui.js new file mode 100644 index 0000000..c35d104 --- /dev/null +++ b/src/game-lib-gui.js @@ -0,0 +1,77 @@ +/** + * Stats component for displaying some render statistics (framerate, memory consumption, etc) + * @param gui + * @param id + * @param name + * @param domElement + * @param parentEntity + * @constructor + */ +GameLib.GUI = function( + gui, + id, + name, + domElement, + parentEntity +) { + if (GameLib.Utils.UndefinedOrNull(gui)) { + throw new Error('Need Stats object') + } + this.gui = gui; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_GUI, + { + 'domElement': GameLib.DomElement + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'GUI (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(domElement)) { + console.warn('Need a DOM element for stats'); + throw new Error('Need a DOM element for stats'); + } + this.domElement = domElement; + + this.instance = this.createInstance(); +}; + +GameLib.GUI.prototype = Object.create(GameLib.Component.prototype); +GameLib.GUI.prototype.constructor = GameLib.GUI; + +/** + * Creates a helper instance + * @param update + */ +GameLib.GUI.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + this.instance = new this.gui( { autoPlace: false } ); + instance = this.instance; + } else { + instance = new this.gui( { autoPlace: false } ); + } + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.GUI.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; diff --git a/src/game-lib-system.js b/src/game-lib-system.js index 678e1ab..c83dad3 100644 --- a/src/game-lib-system.js +++ b/src/game-lib-system.js @@ -48,10 +48,12 @@ GameLib.System = function( GameLib.System.prototype = Object.create(GameLib.API.System.prototype); GameLib.System.prototype.constructor = GameLib.System; +GameLib.System.SYSTEM_TYPE_NONE = 0x0; GameLib.System.SYSTEM_TYPE_RENDER = 0x1; GameLib.System.SYSTEM_TYPE_ANIMATION = 0x2; GameLib.System.SYSTEM_TYPE_INPUT = 0x4; -GameLib.System.SYSTEM_TYPE_ALL = 0x7; +GameLib.System.SYSTEM_TYPE_STORAGE = 0x8; +GameLib.System.SYSTEM_TYPE_ALL = 0xFFFF; /** * @callback @@ -73,40 +75,21 @@ GameLib.System.prototype.start = function() { component.mouseDown = component.onMouseDown(entity).bind(component); component.mouseMove = component.onMouseMove(entity).bind(component); component.keyDown = component.onKeyDown(entity).bind(component); - // component.contextMenu = component.onContextMenu(entity).bind(component); - component.domElement.instance.addEventListener('mousedown', component.mouseDown, false); component.domElement.instance.addEventListener('mousemove', component.mouseMove, false); component.domElement.instance.addEventListener('keydown', component.keyDown, false); - component.controls = new THREE.EditorControls(component.camera.instance, component.domElement.instance); - // component.domElement.instance.addEventListener('contextmenu', component.contextMenu, false); + component.controls = new THREE.EditorControls( + component.camera.instance, + component.domElement.instance + ); }) } if (this.systemType === GameLib.System.SYSTEM_TYPE_RENDER) { - if (GameLib.Utils.UndefinedOrNull(this.domElement)) { - console.warn('Cannot start a rendering system without a valid DOM element'); - throw new Error('Cannot start a rendering system without a valid DOM element'); - } - - if (GameLib.Utils.UndefinedOrNull(this.domStats)) { - console.warn('No stats DOM - will run the render process without statistics information'); - } else { - //this.domElement.instance.appendChild(this.domStats.instance); - } - - // this.renderers = this.entityManager.queryComponents(GameLib.D3.Renderer); - - // this.renderers.forEach( - // function (renderer) { - // renderer.domElement.instance.appendChild(renderer.instance.domElement); - // }.bind(this) - // ); - this.renderEntities = this.entityManager.query( [ GameLib.D3.Viewport, @@ -116,6 +99,23 @@ GameLib.System.prototype.start = function() { ] ); + this.renderEntities.map( + function(entity) { + var stats = entity.getFirstComponent(GameLib.D3.Stats); + stats.instance.dom.style.position = 'absolute'; + // stats.instance.dom.style.float = 'left'; + stats.instance.dom.style.top = '34px'; + stats.instance.dom.style.left = 'unset'; + stats.domElement.instance.parentElement.appendChild(stats.instance.dom); + + var gui = entity.getFirstComponent(GameLib.GUI); + gui.instance.domElement.style.position = 'absolute'; + gui.instance.domElement.style.top = '34px'; + gui.instance.domElement.style.right = '0px'; + gui.domElement.instance.parentElement.appendChild(gui.instance.domElement); + } + ) + } if (this.systemType === GameLib.System.SYSTEM_TYPE_ANIMATION) { @@ -190,6 +190,9 @@ GameLib.System.prototype.update = function(deltaTime) { function(renderEntity) { + var stats = renderEntity.getFirstComponent(GameLib.D3.Stats); + stats.instance.begin(); + var renderer = renderEntity.getFirstComponent(GameLib.D3.Renderer); var camera = renderEntity.getFirstComponent(GameLib.D3.Camera); var viewport = renderEntity.getFirstComponent(GameLib.D3.Viewport); @@ -201,7 +204,7 @@ GameLib.System.prototype.update = function(deltaTime) { viewport.height ); - var scenes = renderEntity.getComponent(GameLib.D3.Scene); + var scenes = renderEntity.getComponents(GameLib.D3.Scene); if (scenes.length > 1) { renderer.instance.autoClear = false; @@ -216,6 +219,8 @@ GameLib.System.prototype.update = function(deltaTime) { ); //renderer.instance.clearDepth(); }); + + stats.instance.end(); } ); } @@ -292,7 +297,7 @@ GameLib.System.prototype.toApiSystem = function() { ); }; -GameLib.System.prototype.notify = function(property, constructor) { +GameLib.System.prototype.notify = function(property, constructor, action) { this[property] = this.entityManager.queryComponents(constructor); @@ -303,4 +308,102 @@ GameLib.System.prototype.notify = function(property, constructor) { } +}; + +GameLib.System.prototype.load = function() { + + if (this.systemType === GameLib.System.SYSTEM_TYPE_STORAGE) { + + } + + /** + * 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', + apiUrl + '/scene/load' + partialSceneObject.path + '/' + partialSceneObject.name + ); + + xhr.onreadystatechange = function(xhr) { + + return function() { + + if (xhr.readyState === 4) { + + try { + var response = JSON.parse(xhr.responseText); + } catch (e) { + return onLoaded(null, new Error('Could not load scene : ' + e.message)); + } + + if (!response.scene || response.scene.length === 0) { + return onLoaded(null, new Error('Could not load scene')); + } + + var objectScene = response.scene[0]; + + GameLib.D3.Scene.LoadScene( + graphics, + objectScene, + true, + onLoaded + ); + } + } + }(xhr); + + xhr.send(); + +}; + +/** + * Transforms raw scene data into a GameLib.D3.Scene + * @param graphics + * @param objectScene Object (as it comes from the API) + * @param computeNormals + * @param onLoaded + * @param imageFactory GameLib.D3.ImageFactory + * @constructor + */ +GameLib.D3.Scene.LoadScene = function( + graphics, + objectScene, + computeNormals, + onLoaded, + imageFactory +) { + var scene = GameLib.D3.Scene.FromObjectScene( + graphics, + objectScene, + computeNormals, + imageFactory + ); + + onLoaded(scene); +}; + +/** + * Loads a scene directly from the API + * @param graphics GameLib.D3.Graphics + * @param partialSceneObject Object {path: '', name: ''} + * @param apiUrl + * @param onLoaded + */ +GameLib.D3.Scene.LoadSceneFromApi = function( + graphics, + partialSceneObject, + apiUrl, + onLoaded +) { + + }; \ No newline at end of file