From d7a6185e46256f95d238c135abc98e906b0f67f5 Mon Sep 17 00:00:00 2001 From: -=yb4f310 Date: Sun, 4 Jun 2017 14:36:13 +0200 Subject: [PATCH] parent scenes change - helpers are now components - intersects are now per scene / camera and sorted to distance --- src/game-lib-a-1-event.js | 1 + src/game-lib-d3-helper.js | 8 ++ src/game-lib-d3-input-editor.js | 74 ++++++++++++------ src/game-lib-d3-raycaster.js | 7 +- src/game-lib-entity-manager.js | 130 ++++++++++++++++++++++++++++++++ src/game-lib-gui.js | 38 +++++++--- src/game-lib-utils.js | 9 ++- 7 files changed, 232 insertions(+), 35 deletions(-) diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index 6cc2a7f..304a0f5 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -16,6 +16,7 @@ GameLib.Event.Subscriptions = {}; */ GameLib.Event.WINDOW_RESIZE = 0x1; GameLib.Event.PARENT_SCENE_CHANGE = 0x2; +GameLib.Event.PARENT_ENTITY_CHANGE = 0x3; /** * Subscribe to some events diff --git a/src/game-lib-d3-helper.js b/src/game-lib-d3-helper.js index bdda2c5..6352c0a 100644 --- a/src/game-lib-d3-helper.js +++ b/src/game-lib-d3-helper.js @@ -17,6 +17,11 @@ GameLib.D3.Helper = function( this.graphics = graphics; this.graphics.isNotThreeThrow(); + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_HELPER + ); + if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } @@ -67,6 +72,9 @@ GameLib.D3.Helper = function( this.instance = this.createInstance(); }; +GameLib.D3.Helper.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.Helper.prototype.constructor = GameLib.D3.Helper; + /** * Helper types * @type {string} diff --git a/src/game-lib-d3-input-editor.js b/src/game-lib-d3-input-editor.js index 96f572d..3b86074 100644 --- a/src/game-lib-d3-input-editor.js +++ b/src/game-lib-d3-input-editor.js @@ -191,12 +191,30 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) var cameras = entity.getComponents(GameLib.D3.Camera); + var scenes = entity.getComponents(GameLib.D3.Scene); + var meshes = entity.getComponents(GameLib.D3.Mesh); var intersects = cameras.reduce( function(result, camera){ + var scene = scenes.reduce( + function(result, scene) { + + if (scene.activeCamera === camera) { + result = scene; + } + + return result; + }, + null + ); + + if (scene) { + meshes = scene.meshes; + } + this.raycaster.instance.setFromCamera( this.mouse, camera.instance @@ -206,14 +224,34 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) intersects.map(function(intersect){ result.push(intersect); - }) + }); return result; }.bind(this), [] ); - if (intersects.length > 0) { + intersects.sort( + function(a, b) { + if (a.distance < b.distance) { + return -1; + } + + if (a.distance > b.distance) { + return 1; + } + + return 0; + } + ); + + meshes = intersects.map(function(intersect){ + return intersect.mesh; + }); + + var mesh = meshes[0]; + + if (mesh) { /** * Prevent default action (like context menu or whatever) @@ -229,7 +267,7 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) * Notify our component as being 'selected' * @type {boolean} */ - intersects[0].selected = !intersects[0].selected; + mesh.selected = !mesh.selected; /** * Add a helper to the scene @@ -237,53 +275,47 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) */ var helper = null; - var scene = intersects[0].parentScene; + var scene = mesh.parentScene; if (!scene) { - console.warn('the scene object for this mesh could not be located : ' + intersects[0].name); + console.warn('the scene object for this mesh could not be located : ' + mesh.name); return; } var gui = entity.getFirstComponent(GameLib.GUI); - if (intersects[0].selected) { + if (mesh.selected) { helper = new GameLib.D3.Helper( this.graphics, null, - intersects[0].name + ' Helper', - intersects[0], + mesh.name + ' Helper', + mesh, 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; + mesh.polygonOffset = mesh.instance.material.polygonOffset; - intersects[0].instance.material.polygonOffset = true; + mesh.instance.material.polygonOffset = true; entity.addComponent(helper); scene.instance.add(helper.instance); - scene.subscribe(GameLib.Event.PARENT_SCENE_CHANGE, function(data) { - if (data.old === scene) { - scene.instance.remove(helper.instance); - } - }); - - gui.addObject(intersects[0]); + gui.addObject(mesh); } else { - gui.removeObject(intersects[0]); + gui.removeObject(mesh); var components = entity.getComponents(GameLib.D3.Helper); helper = components.reduce( function(result, component) { - if (component.object === intersects[0]) { + if (component.object === mesh) { result = component; } return result; @@ -298,12 +330,12 @@ GameLib.D3.Input.Editor.prototype.onMouseDown = function(entity, entityManager) /** * Restore the polygonOffset value */ - intersects[0].instance.material.polygonOffset = intersects[0].polygonOffset; + mesh.instance.material.polygonOffset = mesh.polygonOffset; entity.removeComponent(helper); } else { - console.warn('failed to locate helper object which should exist for ' + intersects[0].name); + console.warn('failed to locate helper object which should exist for ' + mesh.name); } } diff --git a/src/game-lib-d3-raycaster.js b/src/game-lib-d3-raycaster.js index 8082804..c7429d1 100644 --- a/src/game-lib-d3-raycaster.js +++ b/src/game-lib-d3-raycaster.js @@ -163,7 +163,12 @@ GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) { meshes.map( function(mesh){ if (mesh.instance === intersect.object){ - result.push(mesh); + result.push( + { + mesh : mesh, + distance : intersect.distance + } + ); } } ); diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index 4294f2b..398cb50 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -64,6 +64,8 @@ GameLib.EntityManager = function( this.buildIdToObject(); this.instance = this.createInstance(); + + this.registerCallbacks(); }; GameLib.EntityManager.prototype = Object.create(GameLib.API.EntityManager.prototype); @@ -104,6 +106,54 @@ GameLib.EntityManager.prototype.createEntity = function(name) { return entity; }; +/** + * Returns an entity by ID or null + * @param id + * @returns {*} + */ +GameLib.EntityManager.prototype.findEntityById = function(id) { + + return this.entities.reduce( + function(result, entity){ + + if (entity.id === id) { + result = entity; + } + + return result; + }, + null + ); +}; + +GameLib.EntityManager.prototype.findHelperByObject = function(object) { + + return this.entities.reduce( + function(result, entity) { + var helpers = entity.getComponents(GameLib.D3.Helper); + var helper = helpers.reduce( + function(helperResult, tmpHelper) { + + if (tmpHelper.object === object) { + helperResult = tmpHelper; + } + + return helperResult; + }, + null + ); + + if (helper) { + result = helper; + } + + return result; + }, + null + ); + +}; + /** * Adds an entity to this manager * @param entity GameLib.Entity @@ -258,6 +308,86 @@ GameLib.EntityManager.FromObjectEntityManager = function(graphics, objectEntityM return entityManager; }; +GameLib.EntityManager.prototype.onParentSceneChange = function(data) { + + if (data.object instanceof GameLib.D3.Mesh) { + + /** + * We remove the helper (if any) from the old scene and add it to the new scene + */ + var helper = this.findHelperByObject(data.object); + if (helper) { + data.originalScene.instance.remove(helper.instance); + data.newScene.instance.add(helper.instance); + } + + /** + * We remove the mesh from the old scene and add it to the new scene + */ + data.originalScene.removeMesh(data.object); + data.newScene.addMesh(data.object); + + /** + * We inherit the parent entity of this new scene + */ + var originalEntity = null; + var newEntity = null; + + if (data.object.hasOwnProperty('parentEntity')) { + originalEntity = data.object.parentEntity + } + + if (data.newScene.hasOwnProperty('parentEntity')) { + newEntity = data.newScene.parentEntity; + } + + if (originalEntity && newEntity) { + + /** + * We also transfer the helper (as a component) to the new entity + */ + if (helper) { + originalEntity.removeComponent(helper); + newEntity.addComponent(helper); + } + + originalEntity.removeComponent(data.object); + newEntity.addComponent(data.object); + + /** + * Now also remove the object from the GUI + */ + var gui = originalEntity.getFirstComponent(GameLib.GUI); + if (gui) { + gui.removeObject(data.object); + gui.build(this); + + gui = newEntity.getFirstComponent(GameLib.GUI); + if (gui) { + gui.addObject(data.object); + gui.build(this); + } + } + } + } + + if (data.object instanceof GameLib.D3.Light) { + console.log('implement remove light here'); + } +}; + +/** + * + */ +GameLib.EntityManager.prototype.registerCallbacks = function() { + + this.subscribe( + GameLib.Event.PARENT_SCENE_CHANGE, + this.onParentSceneChange + ) + +}; + /** * Links object Ids to actual objects * @param idToObject diff --git a/src/game-lib-gui.js b/src/game-lib-gui.js index aaab240..a69e566 100644 --- a/src/game-lib-gui.js +++ b/src/game-lib-gui.js @@ -764,10 +764,10 @@ GameLib.GUI.prototype.buildSelectControl = function(folder, object, property, en GameLib.Event.Emit( GameLib.Event.PARENT_SCENE_CHANGE, { - old: this.initialValue, - current: object[property], + originalScene: this.initialValue, + newScene: object[property], object: object, - property: property + entityManager: entityManager } ); } else { @@ -841,12 +841,20 @@ GameLib.GUI.prototype.buildEntitySelectionControlFromArray = function( ); folder.add(object, property, options).name(property).listen().onChange( - function(value) { - GameLib.Event.Emit( - GameLib.Event.PARENT_ENTITY_CHANGE, - {} - ); - } + function(entityManager) { + return function(value) { + + GameLib.Event.Emit( + GameLib.Event.PARENT_ENTITY_CHANGE, + { + originalEntity : this.initialValue, + newEntity : entityManager.findEntityById(value), + object : object + } + ); + + }; + }(entityManager) ); }; @@ -884,12 +892,20 @@ GameLib.GUI.prototype.build = function(entityManager) { var apiObject = object.toApiObject(); + var folder = null; + try { - var folder = this.instance.addFolder(apiObject.name); + folder = this.instance.addFolder(apiObject.name); } catch (e) { - //todo increase name count + console.log(e.message); + apiObject.name += GameLib.Utils.RandomId(3); + folder = this.instance.addFolder(apiObject.name); } + if (!folder) { + throw new Error('Could not create folder'); + } + var property; for (property in apiObject) { diff --git a/src/game-lib-utils.js b/src/game-lib-utils.js index db5e4ad..4ed7e18 100644 --- a/src/game-lib-utils.js +++ b/src/game-lib-utils.js @@ -204,8 +204,13 @@ GameLib.Utils.Raycast = function ( * @returns {string} * @constructor */ -GameLib.Utils.RandomId = function() { - return Math.random().toString(36).substr(2, 10); +GameLib.Utils.RandomId = function(length) { + + if (GameLib.Utils.UndefinedOrNull(length)) { + length = 10; + } + + return Math.random().toString(36).substr(2, length); }; GameLib.Utils.InvertWindingOrder = function(triangles) {