From c76c34dcd6951714ea0d489361a147394beb700b Mon Sep 17 00:00:00 2001 From: -=yb4f310 Date: Wed, 7 Feb 2018 16:51:38 +0100 Subject: [PATCH] reaching stability for effects and passes --- src/game-lib-a-1-event.js | 6 + src/game-lib-a-2-utils.js | 33 +++ src/game-lib-a-component-a.js | 32 ++- src/game-lib-api-controls-0.js | 63 +++--- src/game-lib-api-render-configuration.js | 2 +- src/game-lib-controls-d3-editor.js | 37 +++- src/game-lib-d3-api-composer.js | 7 + src/game-lib-d3-api-effect-a.js | 26 ++- src/game-lib-d3-api-light-a.js | 92 +++++--- src/game-lib-d3-api-material-a.js | 55 +++-- src/game-lib-d3-api-pass-0.js | 49 +++-- src/game-lib-d3-api-pass-bloom.js | 7 + src/game-lib-d3-api-pass-fxaa.js | 7 + src/game-lib-d3-composer.js | 18 +- src/game-lib-d3-light-a.js | 6 + src/game-lib-d3-material-a.js | 17 +- src/game-lib-d3-pass-0.js | 10 + src/game-lib-d3-pass-bloom.js | 16 +- src/game-lib-d3-pass-fxaa.js | 15 +- src/game-lib-d3-renderer.js | 7 + src/game-lib-d3-scene.js | 221 +++++++++---------- src/game-lib-entity-manager.js | 52 ++--- src/game-lib-entity.js | 261 ++++++++++++++--------- src/game-lib-render-configuration.js | 66 +++++- src/game-lib-system-gui.js | 23 +- src/game-lib-system-render.js | 259 +++++++++++++++------- 26 files changed, 921 insertions(+), 466 deletions(-) diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index 4382a5b..0a8b47f 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -129,6 +129,9 @@ GameLib.Event.MESH_FACE_DESELECTED = 0x6f; GameLib.Event.BEFORE_WINDOW_RESIZE = 0x70; GameLib.Event.GET_WINDOW_SIZE = 0x71; GameLib.Event.GET_RENDER_CONFIGURATION = 0x72; +GameLib.Event.SET_ACTIVE_RENDER_CONFIGURATION = 0x73; +GameLib.Event.REPLACE_COMPONENT = 0x74; +GameLib.Event.COMPONENT_REPLACED = 0x75; /** * Returns string name of event ID @@ -253,6 +256,9 @@ GameLib.Event.GetEventName = function(number) { case 0x70 : return 'before_window_resize'; case 0x71 : return 'get_window_size'; case 0x72 : return 'get_render_configuration'; + case 0x73 : return 'set_active_render_configuration'; + case 0x74 : return 'replace_component'; + case 0x75 : return 'component_replaced'; break; } diff --git a/src/game-lib-a-2-utils.js b/src/game-lib-a-2-utils.js index b64e0a7..3cac979 100644 --- a/src/game-lib-a-2-utils.js +++ b/src/game-lib-a-2-utils.js @@ -84,6 +84,39 @@ GameLib.Utils.ObjectPropertiesAsBoolean = function(object) { ); }; +/** + * Returns the window size or null + * @returns {*} + * @constructor + */ +GameLib.Utils.GetWindowSize = function() { + + var size = null; + + GameLib.Event.Emit( + GameLib.Event.GET_WINDOW_SIZE, + null, + function (data) { + size = data; + }.bind(this) + ); + + return size; + +}; + +/** + * Convenience function to update object width and height members with window size + * @param object + * @constructor + */ +GameLib.Utils.UpdateWindowSize = function(object) { + var size = GameLib.Utils.GetWindowSize(); + object.width = size.width; + object.height = size.height; +}; + + /** * Returns id of object with the name if it exists in the array, otherwise null * @param name diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 0f49a93..07c03b0 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -253,7 +253,7 @@ GameLib.Component.SHAPE_CONVEX_HULL = 0x2c; GameLib.Component.SHAPE_CONVEX_HULL_CYLINDER = 0x2d; GameLib.Component.SHAPE_HEIGHT_MAP = 0x2e; GameLib.Component.SHAPE_PLANE = 0x2f; -GameLib.Component.CONTROLS = 0x30; +//GameLib.Component.CONTROLS = 0x30; GameLib.Component.CONTROLS_EDITOR = 0x31; GameLib.Component.CONTROLS_TOUCH = 0x32; GameLib.Component.FRICTION_MATERIAL = 0x33; @@ -611,12 +611,12 @@ GameLib.Component.GetComponentInfo = function(number) { constructor : GameLib.D3.Shape.Plane, apiConstructor : GameLib.D3.API.Shape }; - case 0x30 : return { + case 0x30 : return null;/*return { name : 'GameLib.Controls', runtime : GameLib.Component.DEFAULT_RUNTIME, constructor : GameLib.Controls, apiConstructor : GameLib.API.Controls - }; + };*/ case 0x31 : return { name : 'GameLib.Controls.D3.Editor', runtime : GameLib.Component.GRAPHICS_RUNTIME, @@ -931,7 +931,7 @@ GameLib.Component.GetComponentInfo = function(number) { }; case 0x65 : return { name : 'GameLib.RenderConfiguration', - runtime : GameLib.Component.DEFAULT_RUNTIME, + runtime : GameLib.Component.GRAPHICS_RUNTIME, constructor : GameLib.RenderConfiguration, apiConstructor : GameLib.API.RenderConfiguration }; @@ -1204,6 +1204,30 @@ GameLib.Component.prototype.remove = function() { }; +GameLib.Component.prototype.replace = function(componentType) { + + var replacement = GameLib.Component.Construct(componentType); + + GameLib.Event.Emit( + GameLib.Event.REPLACE_COMPONENT, + { + current : this, + replacement : replacement + } + ); + + if (this.parentEntity && this.parentEntity.loaded) { + this.parentEntity.addComponent(replacement); + } + + this.remove(); + + GameLib.Event.Emit( + GameLib.Event.COMPONENT_REPLACED + ); +}; + + GameLib.Component.prototype.clone = function() { var apiObject = this.toApiObject(); diff --git a/src/game-lib-api-controls-0.js b/src/game-lib-api-controls-0.js index ae38499..f034e53 100644 --- a/src/game-lib-api-controls-0.js +++ b/src/game-lib-api-controls-0.js @@ -5,6 +5,7 @@ * @param name * @param canvas * @param parentEntity + * @property controlsType * @constructor */ GameLib.API.Controls = function( @@ -20,26 +21,7 @@ GameLib.API.Controls = function( this.id = id; if (GameLib.Utils.UndefinedOrNull(controlsType)) { - - if (this instanceof GameLib.Controls.D3.Editor) { - controlsType = GameLib.API.Controls.CONTROLS_TYPE_EDITOR; - } - - if (this instanceof GameLib.Controls.Touch) { - controlsType = GameLib.API.Controls.CONTROLS_TYPE_TOUCH; - } - - if (this instanceof GameLib.Controls.Keyboard) { - controlsType = GameLib.API.Controls.CONTROLS_TYPE_KEYBOARD; - } - - if (this instanceof GameLib.Controls.Mouse) { - controlsType = GameLib.API.Controls.CONTROLS_TYPE_MOUSE; - } - - if (GameLib.Utils.UndefinedOrNull(controlsType)) { - throw new Error('Could not determine controls type from this'); - } + controlsType = GameLib.API.Controls.CONTROLS_TYPE_NONE; } this.controlsType = controlsType; @@ -70,22 +52,24 @@ GameLib.API.Controls = function( } this.canvas = canvas; - var componentType = GameLib.Component.CONTROLS; + var componentType = null; - if (this.controlsType === GameLib.API.Controls.CONTROLS_TYPE_EDITOR) { - componentType = GameLib.Component.CONTROLS_EDITOR; - } - - if (this.controlsType === GameLib.API.Controls.CONTROLS_TYPE_TOUCH) { - componentType = GameLib.Component.CONTROLS_TOUCH - } - - if (this.controlsType === GameLib.API.Controls.CONTROLS_TYPE_KEYBOARD) { - componentType = GameLib.Component.CONTROLS_KEYBOARD - } - - if (this.controlsType === GameLib.API.Controls.CONTROLS_TYPE_MOUSE) { - componentType = GameLib.Component.CONTROLS_MOUSE + switch (this.controlsType) { + case GameLib.API.Controls.CONTROLS_TYPE_EDITOR : + componentType = GameLib.Component.CONTROLS_EDITOR; + break; + case GameLib.API.Controls.CONTROLS_TYPE_TOUCH : + componentType = GameLib.Component.CONTROLS_TOUCH; + break; + case GameLib.API.Controls.CONTROLS_TYPE_KEYBOARD : + componentType = GameLib.Component.CONTROLS_KEYBOARD; + break; + case GameLib.API.Controls.CONTROLS_TYPE_MOUSE : + componentType = GameLib.Component.CONTROLS_MOUSE; + break; + default : + throw new Error('unhandled controls type: ' + this.controlsType); + break; } GameLib.API.Component.call( @@ -104,7 +88,8 @@ GameLib.API.Controls.D3 = function() {}; * Controls Type * @type {number} */ -GameLib.API.Controls.CONTROLS_TYPE_EDITOR = 0x0; -GameLib.API.Controls.CONTROLS_TYPE_TOUCH = 0x1; -GameLib.API.Controls.CONTROLS_TYPE_KEYBOARD = 0x2; -GameLib.API.Controls.CONTROLS_TYPE_MOUSE = 0x3; +GameLib.API.Controls.CONTROLS_TYPE_NONE = 0xf; +GameLib.API.Controls.CONTROLS_TYPE_EDITOR = 0x0; +GameLib.API.Controls.CONTROLS_TYPE_TOUCH = 0x1; +GameLib.API.Controls.CONTROLS_TYPE_KEYBOARD = 0x2; +GameLib.API.Controls.CONTROLS_TYPE_MOUSE = 0x3; diff --git a/src/game-lib-api-render-configuration.js b/src/game-lib-api-render-configuration.js index 96cb6ca..e2738e6 100644 --- a/src/game-lib-api-render-configuration.js +++ b/src/game-lib-api-render-configuration.js @@ -66,7 +66,7 @@ GameLib.API.RenderConfiguration = function ( if (GameLib.Utils.UndefinedOrNull(activeScenes)) { activeScenes = []; } - this.activeScene = activeScenes; + this.activeScenes = activeScenes; if (GameLib.Utils.UndefinedOrNull(activeRenderer)) { activeRenderer = null; diff --git a/src/game-lib-controls-d3-editor.js b/src/game-lib-controls-d3-editor.js index 8ac8f95..b30053e 100644 --- a/src/game-lib-controls-d3-editor.js +++ b/src/game-lib-controls-d3-editor.js @@ -18,6 +18,10 @@ GameLib.Controls.D3.Editor = function ( }; } + if (GameLib.Utils.UndefinedOrNull()) { + apiEditorControls.controlsType = GameLib.API.Controls.CONTROLS_TYPE_EDITOR; + } + GameLib.API.Controls.D3.Editor.call( this, apiEditorControls, @@ -48,16 +52,23 @@ GameLib.Controls.D3.Editor.prototype.constructor = GameLib.Controls.D3.Editor; /** * Create Instance - * @returns {THREE.EditorControls} */ GameLib.Controls.D3.Editor.prototype.createInstance = function() { - if (!this.camera || !this.camera.instance) { - throw new Error('No camera at time of instance'); + if ( + GameLib.Utils.UndefinedOrNull(this.camera) || + GameLib.Utils.UndefinedOrNull(this.camera.instance) + ) { + console.warn('no camera at time of editor-controls create instance'); + return; } - if (!this.canvas || !this.canvas.instance) { - throw new Error('No canvas at time of instance'); + if ( + GameLib.Utils.UndefinedOrNull(this.canvas) || + GameLib.Utils.UndefinedOrNull(this.canvas.instance) + ) { + console.warn('no canvas at time of editor-controls create instance'); + return; } this.instance = new THREE.EditorControls( @@ -71,9 +82,21 @@ GameLib.Controls.D3.Editor.prototype.createInstance = function() { /** * Update Instance */ -GameLib.Controls.D3.Editor.prototype.updateInstance = function() { +GameLib.Controls.D3.Editor.prototype.updateInstance = function(property) { - console.warn('an update instance was called on editor controls - which, if not called from within a running system at the right time will affect the order of input event handling and cause system instability'); + if ( + property === 'canvas' || + property === 'camera' + ) { + if (GameLib.Utils.UndefinedOrNull(this.instance)) { + this.createInstance(); + } else { + this.instance.dispose(); + this.createInstance(); + } + } + + console.warn('an update instance was called on editor controls - which, if not called from within a running system at the right time will affect the order of input event handling and cause system instability'); GameLib.Controls.prototype.updateInstance.call(this); }; diff --git a/src/game-lib-d3-api-composer.js b/src/game-lib-d3-api-composer.js index b3fec32..fae34cd 100644 --- a/src/game-lib-d3-api-composer.js +++ b/src/game-lib-d3-api-composer.js @@ -3,6 +3,7 @@ * @param id * @param name * @param parentEntity + * @param autoUpdateSize * @param width * @param height * @param renderer @@ -14,6 +15,7 @@ GameLib.D3.API.Composer = function ( id, name, parentEntity, + autoUpdateSize, width, height, renderer, @@ -30,6 +32,11 @@ GameLib.D3.API.Composer = function ( } this.name = name; + if (GameLib.Utils.UndefinedOrNull(autoUpdateSize)) { + autoUpdateSize = true; + } + this.autoUpdateSize = autoUpdateSize; + if (GameLib.Utils.UndefinedOrNull(width)) { width = 512; } diff --git a/src/game-lib-d3-api-effect-a.js b/src/game-lib-d3-api-effect-a.js index 466465b..12a2ac8 100644 --- a/src/game-lib-d3-api-effect-a.js +++ b/src/game-lib-d3-api-effect-a.js @@ -27,16 +27,32 @@ GameLib.D3.API.Effect = function( } this.id = id; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Effect (' + this.id + ')'; - } - this.name = name; - if (GameLib.Utils.UndefinedOrNull(effectType)) { effectType = GameLib.D3.API.Effect.EFFECT_TYPE_NONE; } this.effectType = effectType; + if (GameLib.Utils.UndefinedOrNull(name)) { + + switch (this.effectType) { + case GameLib.D3.API.Effect.EFFECT_TYPE_ANAGLYPH : + name = 'Effect Anaglyph'; + break; + case GameLib.D3.API.Effect.EFFECT_TYPE_PARALLAX : + name = 'Effect Parallax'; + break; + case GameLib.D3.API.Effect.EFFECT_TYPE_STEREO : + name = 'Effect Stereo'; + break; + default : + console.warn('no nice name for effect'); + name = 'Effect'; + } + + name += ' (' + this.id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(renderer)) { renderer = null; } diff --git a/src/game-lib-d3-api-light-a.js b/src/game-lib-d3-api-light-a.js index d881040..f018d42 100644 --- a/src/game-lib-d3-api-light-a.js +++ b/src/game-lib-d3-api-light-a.js @@ -23,16 +23,41 @@ GameLib.D3.API.Light = function( } this.id = id; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Light (' + id + ')'; - } - this.name = name; - if (GameLib.Utils.UndefinedOrNull(lightType)) { lightType = GameLib.D3.API.Light.LIGHT_TYPE_AMBIENT; } this.lightType = lightType; - + + if (GameLib.Utils.UndefinedOrNull(name)) { + + switch (this.lightType) { + case GameLib.D3.API.Light.LIGHT_TYPE_SPOT : + name = 'Light Spot'; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_RECT_AREA : + name = 'Light RectArea'; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_POINT : + name = 'Light Point'; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_DIRECTIONAL : + name = 'Light Directional'; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_HEMISPHERE : + name = 'Light Hemisphere'; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_AMBIENT : + name = 'Light Ambient'; + break; + default : + console.warn('no nice name for light'); + name = 'Light'; + } + + name += ' (' + this.id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(color)) { color = new GameLib.API.Color(1,1,1); } @@ -48,30 +73,7 @@ GameLib.D3.API.Light = function( } this.parentScene = parentScene; - var componentType = null; - - switch (this.lightType) { - case GameLib.D3.API.Light.LIGHT_TYPE_AMBIENT : - componentType = GameLib.Component.LIGHT_AMBIENT; - break; - case GameLib.D3.API.Light.LIGHT_TYPE_DIRECTIONAL : - componentType = GameLib.Component.LIGHT_DIRECTIONAL; - break; - case GameLib.D3.API.Light.LIGHT_TYPE_POINT : - componentType = GameLib.Component.LIGHT_POINT; - break; - case GameLib.D3.API.Light.LIGHT_TYPE_SPOT : - componentType = GameLib.Component.LIGHT_SPOT; - break; - case GameLib.D3.API.Light.LIGHT_TYPE_HEMISPHERE : - componentType = GameLib.Component.LIGHT_HEMISPHERE; - break; - case GameLib.D3.API.Light.LIGHT_TYPE_RECT_AREA : - componentType = GameLib.Component.LIGHT_RECT_AREA; - break; - default : - console.error('could not determine light component type'); - } + var componentType = GameLib.D3.API.Light.GetComponentType(this.lightType); GameLib.API.Component.call( this, @@ -80,6 +82,36 @@ GameLib.D3.API.Light = function( ); }; +GameLib.D3.API.Light.GetComponentType = function(lightType) { + + var componentType = null; + + switch (lightType) { + case GameLib.D3.API.Light.LIGHT_TYPE_AMBIENT : + componentType = GameLib.Component.LIGHT_AMBIENT; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_DIRECTIONAL : + componentType = GameLib.Component.LIGHT_DIRECTIONAL; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_POINT : + componentType = GameLib.Component.LIGHT_POINT; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_SPOT : + componentType = GameLib.Component.LIGHT_SPOT; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_HEMISPHERE : + componentType = GameLib.Component.LIGHT_HEMISPHERE; + break; + case GameLib.D3.API.Light.LIGHT_TYPE_RECT_AREA : + componentType = GameLib.Component.LIGHT_RECT_AREA; + break; + default : + console.error('could not determine light component type'); + } + + return componentType; +}; + GameLib.D3.API.Light.prototype = Object.create(GameLib.API.Component.prototype); GameLib.D3.API.Light.prototype.constructor = GameLib.D3.API.Light; diff --git a/src/game-lib-d3-api-material-a.js b/src/game-lib-d3-api-material-a.js index b2ede6d..e0e7c0e 100644 --- a/src/game-lib-d3-api-material-a.js +++ b/src/game-lib-d3-api-material-a.js @@ -86,16 +86,29 @@ GameLib.D3.API.Material = function( } this.id = id; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Material (' + this.id + ')'; - } - this.name = name; - if (GameLib.Utils.UndefinedOrNull(materialType)) { materialType = GameLib.D3.API.Material.MATERIAL_TYPE_NONE; } this.materialType = materialType; + if (GameLib.Utils.UndefinedOrNull(name)) { + + switch (this.materialType) { + case GameLib.D3.API.Material.MATERIAL_TYPE_BASIC : + name = 'Material Basic'; + break; + case GameLib.D3.API.Material.MATERIAL_TYPE_STANDARD : + name = 'Material Standard'; + break; + default : + console.warn('no nice name for material'); + name = 'Material'; + } + + name += ' (' + this.id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(parentMeshes)) { parentMeshes = []; } @@ -271,18 +284,7 @@ GameLib.D3.API.Material = function( } this.visible = visible; - var componentType = null; - - switch (this.materialType) { - case GameLib.D3.API.Material.MATERIAL_TYPE_STANDARD : - componentType = GameLib.Component.MATERIAL_STANDARD; - break; - case GameLib.D3.API.Material.MATERIAL_TYPE_BASIC : - componentType = GameLib.Component.MATERIAL_BASIC; - break; - default : - throw new Error('unhandled material type: ' + this.materialType); - } + var componentType = GameLib.D3.API.Material.GetComponentType(this.materialType); this.needsUpdate = false; @@ -294,6 +296,25 @@ GameLib.D3.API.Material = function( }; +GameLib.D3.API.Material.GetComponentType = function(materialType) { + + var componentType = null; + + switch (materialType) { + case GameLib.D3.API.Material.MATERIAL_TYPE_STANDARD : + componentType = GameLib.Component.MATERIAL_STANDARD; + break; + case GameLib.D3.API.Material.MATERIAL_TYPE_BASIC : + componentType = GameLib.Component.MATERIAL_BASIC; + break; + default : + throw new Error('unhandled material type: ' + materialType); + } + + return componentType; + +}; + GameLib.D3.API.Material.prototype = Object.create(GameLib.API.Component.prototype); GameLib.D3.API.Material.prototype.constructor = GameLib.D3.API.Material; diff --git a/src/game-lib-d3-api-pass-0.js b/src/game-lib-d3-api-pass-0.js index e3d9b0c..0fecc84 100644 --- a/src/game-lib-d3-api-pass-0.js +++ b/src/game-lib-d3-api-pass-0.js @@ -19,24 +19,53 @@ GameLib.D3.API.Pass = function ( } this.id = id; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Pass (' + id + ')'; - } - this.name = name; - if (GameLib.Utils.UndefinedOrNull(passType)) { passType = GameLib.D3.API.Pass.PASS_TYPE_RENDER; } this.passType = passType; + if (GameLib.Utils.UndefinedOrNull(name)) { + switch (this.passType) { + case GameLib.D3.API.Pass.PASS_TYPE_RENDER: + name = 'Pass Render'; + break; + case GameLib.D3.API.Pass.PASS_TYPE_FXAA: + name = 'Pass FXAA'; + break; + case GameLib.D3.API.Pass.PASS_TYPE_BLOOM: + name = 'Pass Bloom'; + break; + case GameLib.D3.API.Pass.PASS_TYPE_SSAO: + name = 'Pass SSAO'; + break; + default: + console.warn('no custom pass name'); + name = 'Pass'; + } + + name += ' (' + id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(renderToScreen)) { renderToScreen = false; } this.renderToScreen = renderToScreen; + var componentType = GameLib.D3.API.Pass.GetComponentType(this.passType); + + GameLib.API.Component.call( + this, + componentType, + parentEntity + ); +}; + +GameLib.D3.API.Pass.GetComponentType = function(passType) { + var componentType = null; - switch (this.passType) { + switch (passType) { case GameLib.D3.API.Pass.PASS_TYPE_RENDER: componentType = GameLib.Component.PASS_RENDER; break; @@ -50,14 +79,10 @@ GameLib.D3.API.Pass = function ( componentType = GameLib.Component.PASS_FXAA; break; default : - throw new Error('unsupported pass type: ' + this.passType); + throw new Error('unsupported pass type: ' + passType); } - GameLib.API.Component.call( - this, - componentType, - parentEntity - ); + return componentType; }; GameLib.D3.API.Pass.prototype = Object.create(GameLib.API.Component.prototype); diff --git a/src/game-lib-d3-api-pass-bloom.js b/src/game-lib-d3-api-pass-bloom.js index c8ae57f..541aec4 100644 --- a/src/game-lib-d3-api-pass-bloom.js +++ b/src/game-lib-d3-api-pass-bloom.js @@ -1,6 +1,7 @@ /** * GameLib.D3.API.Pass.Bloom * @param apiPass + * @param autoUpdateSize * @param width * @param height * @param strength @@ -10,6 +11,7 @@ */ GameLib.D3.API.Pass.Bloom = function ( apiPass, + autoUpdateSize, width, height, strength, @@ -26,6 +28,11 @@ GameLib.D3.API.Pass.Bloom = function ( apiPass.passType = GameLib.D3.API.Pass.PASS_TYPE_BLOOM; } + if (GameLib.Utils.UndefinedOrNull(autoUpdateSize)) { + autoUpdateSize = true; + } + this.autoUpdateSize = autoUpdateSize; + if (GameLib.Utils.UndefinedOrNull(width)) { width = 512; } diff --git a/src/game-lib-d3-api-pass-fxaa.js b/src/game-lib-d3-api-pass-fxaa.js index bb027a4..32b26c1 100644 --- a/src/game-lib-d3-api-pass-fxaa.js +++ b/src/game-lib-d3-api-pass-fxaa.js @@ -1,12 +1,14 @@ /** * GameLib.D3.API.Pass.FXAA * @param apiPass + * @param autoUpdateSize * @param width * @param height * @constructor */ GameLib.D3.API.Pass.FXAA = function ( apiPass, + autoUpdateSize, width, height ) { @@ -20,6 +22,11 @@ GameLib.D3.API.Pass.FXAA = function ( apiPass.passType = GameLib.D3.API.Pass.PASS_TYPE_FXAA; } + if (GameLib.Utils.UndefinedOrNull(autoUpdateSize)) { + autoUpdateSize = true; + } + this.autoUpdateSize = autoUpdateSize; + if (GameLib.Utils.UndefinedOrNull(width)) { width = 512; } diff --git a/src/game-lib-d3-composer.js b/src/game-lib-d3-composer.js index 01e9535..c1c07b0 100644 --- a/src/game-lib-d3-composer.js +++ b/src/game-lib-d3-composer.js @@ -21,6 +21,7 @@ GameLib.D3.Composer = function ( apiComposer.id, apiComposer.name, apiComposer.parentEntity, + apiComposer.autoUpdateSize, apiComposer.width, apiComposer.height, apiComposer.renderer, @@ -82,6 +83,12 @@ GameLib.D3.Composer.prototype.createInstance = function() { }.bind(this) ); + if (this.autoUpdateSize) { + var size = GameLib.Utils.GetWindowSize(); + this.width = size.width; + this.height = size.height; + } + this.instance.setSize( this.width, this.height @@ -121,8 +128,16 @@ GameLib.D3.Composer.prototype.updateInstance = function(property) { if ( property === 'width' || - property === 'height' + property === 'height' || + property === 'autoUpdateSize' ) { + + if (this.autoUpdateSize) { + var size = GameLib.Utils.GetWindowSize(); + this.width = size.width; + this.height = size.height; + } + this.instance.setSize( this.width, this.height @@ -180,6 +195,7 @@ GameLib.D3.Composer.prototype.toApiObject = function() { this.id, this.name, GameLib.Utils.IdOrNull(this.parentEntity), + this.autoUpdateSize, this.width, this.height, GameLib.Utils.IdOrNull(this.renderer), diff --git a/src/game-lib-d3-light-a.js b/src/game-lib-d3-light-a.js index 6cb1004..fde8677 100644 --- a/src/game-lib-d3-light-a.js +++ b/src/game-lib-d3-light-a.js @@ -91,6 +91,12 @@ GameLib.D3.Light.prototype.updateInstance = function(property) { console.warn('no property for light: ' + this.name); } + if (property === 'lightType') { + var componentType = GameLib.D3.API.Light.GetComponentType(this.lightType); + this.replace(componentType); + return; + } + if (property === 'color') { this.instance.color.set(this.color.toHex()); } diff --git a/src/game-lib-d3-material-a.js b/src/game-lib-d3-material-a.js index f8e270c..6fbb39b 100644 --- a/src/game-lib-d3-material-a.js +++ b/src/game-lib-d3-material-a.js @@ -159,19 +159,12 @@ GameLib.D3.Material.prototype.updateInstance = function(property) { } if (property === 'materialType') { - console.warn('todo: material type update'); + + var componentType = GameLib.D3.API.Material.GetComponentType(this.materialType); + + this.replace(componentType); + return; - // - // this.createInstance(); - // - // this.publish( - // GameLib.Event.MATERIAL_TYPE_CHANGED, - // { - // material: this - // } - // ); - // - // return; } if (property === 'parentEntity') { diff --git a/src/game-lib-d3-pass-0.js b/src/game-lib-d3-pass-0.js index 5b8b579..809749a 100644 --- a/src/game-lib-d3-pass-0.js +++ b/src/game-lib-d3-pass-0.js @@ -72,6 +72,16 @@ GameLib.D3.Pass.prototype.createInstance = function() { */ GameLib.D3.Pass.prototype.updateInstance = function(property) { + + if (property === 'passType') { + + var componentType = GameLib.D3.API.Pass.GetComponentType(this.passType); + + this.replace(componentType); + + return; + } + if (property === 'renderToScreen') { this.instance.renderToScreen = this.renderToScreen; } diff --git a/src/game-lib-d3-pass-bloom.js b/src/game-lib-d3-pass-bloom.js index 4d09afe..94d8b9f 100644 --- a/src/game-lib-d3-pass-bloom.js +++ b/src/game-lib-d3-pass-bloom.js @@ -21,6 +21,7 @@ GameLib.D3.Pass.Bloom = function ( GameLib.D3.API.Pass.Bloom.call( this, apiPassBloom, + apiPassBloom.autoUpdateSize, apiPassBloom.width, apiPassBloom.height, apiPassBloom.strength, @@ -28,7 +29,7 @@ GameLib.D3.Pass.Bloom = function ( apiPassBloom.threshold ); - GameLib.D3.Pass.call( + GameLib.D3.Pass.call( this, this.graphics, this @@ -44,6 +45,10 @@ GameLib.D3.Pass.Bloom.prototype.constructor = GameLib.D3.Pass.Bloom; */ GameLib.D3.Pass.Bloom.prototype.createInstance = function() { + if (this.autoUpdateSize) { + GameLib.Utils.UpdateWindowSize(this); + } + this.instance = new THREE.UnrealBloomPass( new THREE.Vector2( this.width, @@ -66,12 +71,18 @@ GameLib.D3.Pass.Bloom.prototype.updateInstance = function(property) { if ( property === 'width' || - property === 'height' + property === 'height' || + property === 'autoUpdateSize' ) { + if (this.autoUpdateSize) { + GameLib.Utils.UpdateWindowSize(this); + } + this.instance.setSize( this.width, this.height ); + return; } @@ -115,6 +126,7 @@ GameLib.D3.Pass.Bloom.prototype.toApiObject = function() { var apiBloomPass = new GameLib.D3.API.Pass.Bloom( apiPass, + this.autoUpdateSize, this.width, this.height, this.strength, diff --git a/src/game-lib-d3-pass-fxaa.js b/src/game-lib-d3-pass-fxaa.js index 6e0f5b3..ca40363 100644 --- a/src/game-lib-d3-pass-fxaa.js +++ b/src/game-lib-d3-pass-fxaa.js @@ -21,6 +21,7 @@ GameLib.D3.Pass.FXAA = function ( GameLib.D3.API.Pass.FXAA.call( this, apiPassFXAA, + apiPassFXAA.autoUpdateSize, apiPassFXAA.width, apiPassFXAA.height ); @@ -43,12 +44,18 @@ GameLib.D3.Pass.FXAA.prototype.createInstance = function() { this.instance = new THREE.ShaderPass(THREE.FXAAShader); + if (this.autoUpdateSize) { + GameLib.Utils.UpdateWindowSize(this); + } + this.instance.uniforms['resolution'].value.set( 1 / this.width, 1 / this.height ); console.log('Constructed an FXAA pass instance'); + + GameLib.D3.Pass.prototype.createInstance.call(this); }; /** @@ -58,8 +65,13 @@ GameLib.D3.Pass.FXAA.prototype.updateInstance = function(property) { if ( property === 'width' || - property === 'height' + property === 'height' || + property === 'autoUpdateSize' ) { + if (this.autoUpdateSize) { + GameLib.Utils.UpdateWindowSize(this); + } + this.instance.uniforms['resolution'].value.set( 1 / this.width, 1 / this.height @@ -92,6 +104,7 @@ GameLib.D3.Pass.FXAA.prototype.toApiObject = function() { var apiFXAAPass = new GameLib.D3.API.Pass.FXAA( apiPass, + this.autoUpdateSize, this.width, this.height ); diff --git a/src/game-lib-d3-renderer.js b/src/game-lib-d3-renderer.js index 83c6be8..e120e40 100644 --- a/src/game-lib-d3-renderer.js +++ b/src/game-lib-d3-renderer.js @@ -443,6 +443,13 @@ GameLib.D3.Renderer.prototype.updateInstance = function(property) { } }; +/** + * Wrapper for clear() + */ +GameLib.D3.Renderer.prototype.clear = function() { + return this.instance.clear(); +}; + /** * Convenience function to set size * @param width diff --git a/src/game-lib-d3-scene.js b/src/game-lib-d3-scene.js index ebae6dc..a0456c0 100644 --- a/src/game-lib-d3-scene.js +++ b/src/game-lib-d3-scene.js @@ -193,66 +193,80 @@ GameLib.D3.Scene.prototype.updateInstance = function(property) { return; } - if (this.fog && this.fog.instance !== this.instance.fog) { - this.instance.fog = this.fog.instance; + if (property === 'fog') { + if (this.fog && this.fog.instance !== this.instance.fog) { + this.instance.fog = this.fog.instance; + } } - /** - * Add missing meshes - */ - this.meshes.map( - function(mesh) { - if (this.instance.children.indexOf(mesh.instance === -1)) { - this.instance.add(mesh.instance); - } - }.bind(this) - ); + if (property === 'meshes') { - /** - * Add missing lights - */ - this.lights.map( - function(light) { - if (this.instance.children.indexOf(light.instance) === -1) { - this.instance.add(light.instance); - } - }.bind(this) - ); - - /** - * Remove extra meshes and lights - */ - this.instance.children.map( - function(instanceObject) { - - var instanceMeshes = this.meshes.map( - function(mesh) { - return mesh.instance; + /** + * Add missing meshes + */ + this.meshes.map( + function (mesh) { + if (this.instance.children.indexOf(mesh.instance === -1)) { + this.instance.add(mesh.instance); } - ); + }.bind(this) + ); + } - var instanceLights = this.lights.map( - function(light) { - return light.instance; + if (property === 'lights') { + + /** + * Add missing lights + */ + this.lights.map( + function (light) { + if (this.instance.children.indexOf(light.instance) === -1) { + this.instance.add(light.instance); } - ); + }.bind(this) + ); + } - if ( - ( - instanceObject instanceof THREE.Mesh || - instanceObject instanceof THREE.Light - ) && - ( - instanceLights.indexOf(instanceObject) === -1 && - instanceMeshes.indexOf(instanceObject) === -1 - ) - ) { - this.instance.remove(instanceObject); - } + if ( + property === 'meshes' || + property === 'lights' + ) { + /** + * Remove extra meshes and lights + */ + this.instance.children.map( + function (instanceObject) { + + var instanceMeshes = this.meshes.map( + function (mesh) { + return mesh.instance; + } + ); + + var instanceLights = this.lights.map( + function (light) { + return light.instance; + } + ); + + if ( + ( + instanceObject instanceof THREE.Mesh || + instanceObject instanceof THREE.Light + ) && + ( + instanceLights.indexOf(instanceObject) === -1 && + instanceMeshes.indexOf(instanceObject) === -1 + ) + ) { + this.instance.remove(instanceObject); + } + + }.bind(this) + ); + return; + } - }.bind(this) - ); - if ( property === 'showGrid' || property === 'gridSize' || @@ -280,52 +294,25 @@ GameLib.D3.Scene.prototype.updateInstance = function(property) { */ GameLib.D3.Scene.prototype.toApiObject = function() { - var apiMeshes = this.meshes.reduce( - function(result, mesh) { + var apiMeshes = []; - /** - * Do not store any cloned meshes - */ - if ((this.clones.indexOf(mesh) === -1) || this.storeClones) { - result.push(GameLib.Utils.IdOrNull(mesh)); + if (this.storeClones) { + this.clones.map( + function (clone) { + GameLib.Utils.PushUnique( + apiMeshes, + GameLib.Utils.IdOrNull(clone) + ); } + ); + } - return result; - }.bind(this), - [] - ); - - var apiLights = this.lights.reduce( - function(result, light) { - - /** - * Do not store any cloned lights - */ - if (this.clones.indexOf(light) === -1 || this.storeClones) { - result.push(GameLib.Utils.IdOrNull(light)); - } - - return result; - - }.bind(this), - [] - ); - - var apiTextures = this.textures.map( - function(texture) { - return GameLib.Utils.IdOrNull(texture); - } - ); - - var apiMaterials = this.materials.map( - function(material) { - return GameLib.Utils.IdOrNull(material); - } - ); - - var apiImages = this.images.map( - function(image) { - return GameLib.Utils.IdOrNull(image); + this.meshes.map( + function(mesh) { + GameLib.Utils.PushUnique( + apiMeshes, + GameLib.Utils.IdOrNull(mesh) + ); } ); @@ -333,10 +320,26 @@ GameLib.D3.Scene.prototype.toApiObject = function() { this.id, this.name, apiMeshes, - apiLights, - apiTextures, - apiMaterials, - apiImages, + this.lights.map( + function(light) { + return GameLib.Utils.IdOrNull(light); + } + ), + this.textures.map( + function(texture) { + return GameLib.Utils.IdOrNull(texture); + } + ), + this.materials.map( + function(material) { + return GameLib.Utils.IdOrNull(material); + } + ), + this.images.map( + function(image) { + return GameLib.Utils.IdOrNull(image); + } + ), GameLib.Utils.IdOrNull(this.fog), this.showGrid, this.showAxis, @@ -354,27 +357,11 @@ GameLib.D3.Scene.prototype.toApiObject = function() { GameLib.D3.Scene.prototype.addObject = function(object) { if (object instanceof GameLib.D3.Mesh) { - if (this.meshes.indexOf(object) === -1) { - this.meshes.push(object); - } - } else if (object instanceof GameLib.D3.API.Mesh) { - object = new GameLib.D3.Mesh( - this.graphics, - object - ); - this.meshes.push(object); + GameLib.Utils.PushUnique(this.meshes, object); } if (object instanceof GameLib.D3.Light) { - if (this.lights.indexOf(object) === -1) { - this.lights.push(object); - } - } else if (object instanceof GameLib.D3.API.Light) { - object = new GameLib.D3.Light( - this.graphics, - object - ); - this.lights.push(object); + GameLib.Utils.PushUnique(this.lights, object); } object.parentScene = this; diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index fbd0883..1867f47 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -282,32 +282,32 @@ GameLib.EntityManager.prototype.removeEntity = function(entity) { * Returns all the entities with the following components * @param components GameLib.Component[] */ -GameLib.EntityManager.prototype.findEntities = function(components) { - - var entities = this.entities.reduce( - function(result, entity) { - - var hasAllComponents = components.reduce( - function(componentResult, component) { - if (!entity.hasComponent(component)) { - componentResult = false; - } - return componentResult; - }, - true - ); - - if (hasAllComponents) { - result.push(entity); - } - - return result; - }, - [] - ); - - return entities; -}; +// GameLib.EntityManager.prototype.findEntities = function(components) { +// +// var entities = this.entities.reduce( +// function(result, entity) { +// +// var hasAllComponents = components.reduce( +// function(componentResult, component) { +// if (!entity.hasComponent(component)) { +// componentResult = false; +// } +// return componentResult; +// }, +// true +// ); +// +// if (hasAllComponents) { +// result.push(entity); +// } +// +// return result; +// }, +// [] +// ); +// +// return entities; +// }; /** * Returns all actual components of all entities that contain this component diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 4b72b5d..1202b0a 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -18,6 +18,18 @@ GameLib.Entity = function ( apiEntity.parentEntity ); + this.instanceCreatedEventSubscription = this.subscribe( + GameLib.Event.INSTANCE_CREATED, + this.instanceCreatedEvent + ); + + this.removeComponentSubscription = this.subscribe( + GameLib.Event.REMOVE_COMPONENT, + this.removeComponentEvent + ); + + this.idRegister = {}; + GameLib.Component.call( this, { @@ -29,14 +41,61 @@ GameLib.Entity = function ( GameLib.Entity.prototype = Object.create(GameLib.Component.prototype); GameLib.Entity.prototype.constructor = GameLib.Entity; +/** + * Links a component to its parent entity + */ +GameLib.Entity.prototype.instanceCreatedEvent = function(data) { + + if (data.component === this) { + /** + * do nothing + */ + return; + } + + + if (data.component.parentEntity === this.id) { + this.addComponent(data.component); + } +}; + +GameLib.Entity.prototype.removeComponentEvent = function(data) { + + if (data.component === this) { + /** + * do nothing + */ + return; + } + + if (data.component.parentEntity === this) { + this.removeComponent(data.component); + } +}; + /** * Creates an entity instance */ GameLib.Entity.prototype.createInstance = function() { - /** - * FUCK ecsjs and tiny-ecs - no client-side support and shitty code (only takes constructors as args) - */ + + this.components.map( + function(component) { + component.parentEntity = this; + + Object.keys(component.idToObject).map( + function(componentId) { + GameLib.Utils.PushUnique(this.components, component.idToObject[componentId]); + component.idToObject[componentId].parentEntity = this; + }.bind(this) + ); + + }.bind(this) + ); + + this.buildIdRegister(); + this.instance = true; + GameLib.Component.prototype.createInstance.call(this); }; @@ -46,56 +105,66 @@ GameLib.Entity.prototype.createInstance = function() { */ GameLib.Entity.prototype.addComponent = function(component) { + component.parentEntity = this; + GameLib.Utils.PushUnique(this.components, component); - // if (component instanceof GameLib.D3.Mesh) { - // - // /** - // * For meshes, simply get the children components - // * @type {Array} - // */ - // component.getChildrenComponents().map(function(childComponent){ - // GameLib.Utils.PushUnique(this.components, childComponent); - // childComponent.parentEntity = this; - // }.bind(this)) - // - // } else { - - if (component instanceof GameLib.Component) { - - /** - * Here we will dig into this component - find all its 'parentEntity' members - and update them accordingly - */ - component.buildIdToObject(); - - /** - * Also add the child components of this component as components of this entity - */ - Object.keys(component.idToObject).map( - function(componentId) { - GameLib.Utils.PushUnique(this.components, component.idToObject[componentId]); - component.idToObject[componentId].parentEntity = this; - }.bind(this) - ); - - GameLib.Utils.PushUnique(this.components, component); + if (GameLib.Utils.UndefinedOrNull(this.idRegister[component.componentType])) { + this.idRegister[component.componentType] = []; } - // } + GameLib.Utils.PushUnique(this.idRegister[component.componentType], component); - /** - * Finally, we are the boss component - update my parent entity - * @type {GameLib.Entity} - */ - component.parentEntity = this; + Object.keys(component.idToObject).map( + function(componentId) { + if (component.id !== componentId) { + this.addComponent(component.idToObject[componentId]); + } + + }.bind(this) + ); +}; + +GameLib.Entity.prototype.removeComponent = function(component) { + + component.parentEntity = null; + + var index = this.components.indexOf(component); + + if (index === -1) { + console.warn('component not found in entity'); + } else { + this.components.splice(index, 1); + } + + if (GameLib.Utils.UndefinedOrNull(this.idRegister[component.componentType])) { + console.warn('component type not found in entity register'); + } else { + + index = this.idRegister[component.componentType].indexOf(component); + + if (index === -1) { + console.warn('component ' + component.name + ' not found in id register of entity ' + this.name); + } else { + this.idRegister[component.componentType].splice(index, 1); + } + + /** + * Remove the hash completely if it was the last one + */ + if (this.idRegister[component.componentType].length === 0) { + delete this.idRegister[component.componentType]; + } + + } }; /** - * Returns all components of type 'constructor' + * Returns all components of type 'constructor' - slower than queryComponents * @param constructor */ -GameLib.Entity.prototype.getComponents = function(constructor) { +GameLib.Entity.prototype.queryComponentsByConstructor = function(constructor) { var components = this.components.reduce( function(result, component) { @@ -111,69 +180,65 @@ GameLib.Entity.prototype.getComponents = function(constructor) { }; /** - * Returns the first component or null - * @param constructor + * Returns all child components of this entity by component type (via hash reference - very fast) + * @param componentType + * @returns {*} */ -GameLib.Entity.prototype.getFirstComponent = function(constructor) { - - var components = this.getComponents(constructor); - - if (components.length > 0) { - return components[0]; - } - - return null; +GameLib.Entity.prototype.queryComponents = function(componentType) { + return this.idRegister[componentType] || []; }; /** * Returns true when this entity has a certain component, false otherwise * @param constructor */ -GameLib.Entity.prototype.hasComponent = function(constructor) { +// GameLib.Entity.prototype.hasComponent = function(constructor) { +// +// var has = this.components.reduce( +// function(result, component) { +// if (component instanceof constructor) { +// result = true; +// } +// return result; +// }, +// false +// ); +// +// return has; +// }; - var has = this.components.reduce( - function(result, component) { - if (component instanceof constructor) { - result = true; +GameLib.Entity.prototype.buildIdRegister = function() { + console.log('updating id register for entity : ' + this.name); + + this.idRegister = {}; + + this.components.map( + function(component) { + + if (GameLib.Utils.UndefinedOrNull(this.idRegister[component.componentType])) { + this.idRegister[component.componentType] = []; } - return result; - }, - false + + this.idRegister[component.componentType].push(component); + + }.bind(this) ); - return has; -}; - -/** - * - * @param component - */ -GameLib.Entity.prototype.removeComponent = function(component) { - - if (GameLib.Utils.UndefinedOrNull(component)) { - component = this.activeComponent; - } - - var childIndex = this.components.indexOf(component); - if (childIndex !== -1) { - this.components.splice(childIndex, 1); - } else { - console.error('component not found'); - } - - /** - * Break the dependency to the parent - */ - component.parentEntity = null; - - return true; + console.log('done updating idRegister'); }; /** * Updates an entity instance */ -GameLib.Entity.prototype.updateInstance = function() { - console.log('entity update instance called'); +GameLib.Entity.prototype.updateInstance = function(property) { + + if (property === 'components') { + + this.buildIdRegister(); + + return; + } + }; /** @@ -198,18 +263,12 @@ GameLib.Entity.prototype.toApiObject = function() { }; /** - * Entity from Object - * @param objectEntity Object - * @returns {GameLib.Entity} - * @constructor + * Cleanup our subscriptions first */ -GameLib.Entity.FromObject = function(objectEntity) { +GameLib.Entity.prototype.remove = function() { - var entity = new GameLib.Entity( - objectEntity - ); + this.instanceCreatedEventSubscription.remove(); + this.removeComponentSubscription.remove(); - GameLib.EntityManager.Instance.addEntity(entity); - - return entity; -}; + GameLib.Component.prototype.remove.call(this); +}; \ No newline at end of file diff --git a/src/game-lib-render-configuration.js b/src/game-lib-render-configuration.js index e953be4..eceea1c 100644 --- a/src/game-lib-render-configuration.js +++ b/src/game-lib-render-configuration.js @@ -1,12 +1,17 @@ /** * GameLib.RenderConfiguration + * @param graphics * @param apiRenderConfiguration GameLib.API.RenderConfiguration * @constructor */ GameLib.RenderConfiguration = function ( + graphics, apiRenderConfiguration ) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiRenderConfiguration)) { apiRenderConfiguration = {}; } @@ -28,6 +33,12 @@ GameLib.RenderConfiguration = function ( apiRenderConfiguration.enableEffect ); + this.logicalSize = new GameLib.Vector2( + this.graphics, + this.logicalSize, + this + ); + GameLib.Component.call( this, { @@ -118,14 +129,45 @@ GameLib.RenderConfiguration.prototype.updateInstance = function(property) { if ( property === 'activeScenes' || - property === 'activeRenderer' || - property === 'activeComposer' || - property === 'activeEffect' + property === 'activeRenderer' ) { console.log('todo: active component update'); return; } + if ( + property === 'activeComposer' + ) { + + if (this.activeComposer === null) { + if (this.enableComposer) { + console.warn('no composer active - nothing will render'); + } + return; + } + + if ( + this.activeComposer.passes.length === 0 + ) { + console.warn('this composer has no passes - nothing will render when this composer is enabled'); + } + + return; + } + + if ( + property === 'activeEffect' + ) { + + if (this.activeEffect === null) { + if (this.enableEffect) { + console.warn('no effects active - nothing will render'); + } + } + + return; + } + if ( property === 'enableComposer' ) { @@ -136,6 +178,20 @@ GameLib.RenderConfiguration.prototype.updateInstance = function(property) { console.warn('Only one of effect or composer can be enabled, not both at the same time'); return; } + + if ( + this.activeComposer === null + ) { + console.warn('no composer active - nothing will render'); + return; + } + + if ( + this.activeComposer.passes.length === 0 + ) { + console.warn('this composer has no passes - nothing will render'); + } + } return; @@ -151,6 +207,10 @@ GameLib.RenderConfiguration.prototype.updateInstance = function(property) { console.warn('Only one of effect or composer can be enabled, not both at the same time'); return; } + + if (this.activeEffect === null) { + console.warn('no effect active - nothing will render'); + } } return; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index 908a97a..87c937b 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -1144,6 +1144,19 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, } ) ); + } else if (property === 'passType') { + controllers.push( + folder.add( + object, + property, + { + 'ssao': GameLib.D3.API.Pass.PASS_TYPE_SSAO, + 'bloom': GameLib.D3.API.Pass.PASS_TYPE_BLOOM, + 'fxaa': GameLib.D3.API.Pass.PASS_TYPE_FXAA, + 'render': GameLib.D3.API.Pass.PASS_TYPE_RENDER + } + ) + ); } else if (property === 'materialType') { controllers.push( folder.add( @@ -1151,11 +1164,11 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, property, { 'standard': GameLib.D3.API.Material.MATERIAL_TYPE_STANDARD, - 'basic': GameLib.D3.API.Material.MATERIAL_TYPE_BASIC, - 'phong': GameLib.D3.API.Material.MATERIAL_TYPE_PHONG, - 'points': GameLib.D3.API.Material.MATERIAL_TYPE_POINTS, - 'toon': GameLib.D3.API.Material.MATERIAL_TYPE_TOON, - 'line basic' : GameLib.D3.API.Material.MATERIAL_TYPE_LINE_BASIC + 'basic': GameLib.D3.API.Material.MATERIAL_TYPE_BASIC + // 'phong': GameLib.D3.API.Material.MATERIAL_TYPE_PHONG, + // 'points': GameLib.D3.API.Material.MATERIAL_TYPE_POINTS, + // 'toon': GameLib.D3.API.Material.MATERIAL_TYPE_TOON, + // 'line basic' : GameLib.D3.API.Material.MATERIAL_TYPE_LINE_BASIC } ) ); diff --git a/src/game-lib-system-render.js b/src/game-lib-system-render.js index d7f5e4a..446b653 100644 --- a/src/game-lib-system-render.js +++ b/src/game-lib-system-render.js @@ -16,12 +16,16 @@ GameLib.System.Render = function( this.renderSubscription = null; + this.replaceComponentSubscription = null; + this.clock = new GameLib.Clock(graphicsRuntime); this.delta = null; this.animationFrameHook = null; + this.activeRenderConfiguration = null; + this.renderConfigurations = []; this.renderers = []; @@ -63,7 +67,12 @@ GameLib.System.Render.prototype.start = function() { this.removeComponent.bind(this) ); - this.renderSubscription = this.subscribe( + this.replaceComponentSubscription = GameLib.Event.Subscribe( + GameLib.Event.REPLACE_COMPONENT, + this.replaceComponent.bind(this) + ); + + this.renderSubscription = this.subscribe( GameLib.Event.RENDER, this.render ); @@ -78,6 +87,11 @@ GameLib.System.Render.prototype.start = function() { this.getRenderConfiguration ); + this.setACtiveRenderConfigurationSubscription = this.subscribe( + GameLib.Event.SET_ACTIVE_RENDER_CONFIGURATION, + this.setActiveRenderConfiguration + ); + // this.delayedInstanceEncounteredSubscription = GameLib.Event.Subscribe( // GameLib.Event.DELAYED_INSTANCE_ENCOUNTERED, // this.delayedInstanceEncountered.bind(this) @@ -138,13 +152,18 @@ GameLib.System.Render.prototype.run = function() { // }; GameLib.System.Render.prototype.getRenderConfiguration = function (data, callback) { - if (this.renderConfigurations.length > 0) { - callback(this.renderConfigurations[0]); - } else { - callback(null); - } + callback(this.activeRenderConfiguration); }; +GameLib.System.Render.prototype.setActiveRenderConfiguration = function (data) { + + if (this.renderConfigurations.indexOf(data.renderConfiguration) !== -1) { + this.activeRenderConfiguration = data.renderConfiguration; + } else { + console.warn('active render configuration not found in render system'); + } + +}; GameLib.System.Render.prototype.getOffset = function (el) { var rect = el.getBoundingClientRect(), @@ -211,6 +230,10 @@ GameLib.System.Render.prototype.instanceCreated = function(data) { if (data.component instanceof GameLib.RenderConfiguration) { console.log('adding render configuration to render system'); this.renderConfigurations.push(data.component); + + if (this.renderConfigurations.length === 1) { + this.activeRenderConfiguration = this.renderConfigurations[0]; + } } if (data.component instanceof GameLib.D3.Renderer) { @@ -275,6 +298,64 @@ GameLib.System.Render.prototype.instanceCreated = function(data) { } }; +GameLib.System.Render.prototype.replaceComponent = function(data) { + + if (data.current instanceof GameLib.D3.Material) { + GameLib.EntityManager.Instance.queryComponentsByConstructor(GameLib.D3.Mesh).map( + function(mesh) { + + var index = mesh.materials.indexOf(data.current); + + if (index !== -1) { + mesh.materials[index] = data.replacement; + mesh.updateInstance('materials'); + } + + } + ); + } + + if (data.current instanceof GameLib.D3.Light) { + GameLib.EntityManager.Instance.queryComponents(GameLib.Component.SCENE).map( + function(scene) { + + var index = scene.lights.indexOf(data.current); + + if (index !== -1) { + scene.lights[index] = data.replacement; + scene.updateInstance('lights'); + } + + } + ); + } + + if (data.current instanceof GameLib.D3.Pass) { + GameLib.EntityManager.Instance.queryComponents(GameLib.Component.COMPOSER).map( + function(composer) { + + var index = composer.passes.indexOf(data.current); + + if (index !== -1) { + + if (data.current.renderToScreen === true) { + data.replacement.renderToScreen = true; + } + + if (data.replacement.loaded) { + composer.passes[index] = data.replacement; + } else { + composer.passes.splice(index, 1); + } + + composer.updateInstance('passes'); + } + + } + ); + } +}; + /** * Removes a particle engine from this system * @param data @@ -295,6 +376,14 @@ GameLib.System.Render.prototype.removeComponent = function(data) { } else { console.log('failed to find the render configuration in the system : ' + data.component.name); } + + if (this.renderConfigurations.length === 0) { + this.activeRenderConfiguration = null; + } + + if (this.renderConfigurations.length === 1) { + this.activeRenderConfiguration = this.renderConfigurations[0]; + } } if (data.component instanceof GameLib.D3.Renderer) { @@ -372,102 +461,102 @@ GameLib.System.Render.prototype.render = function(data) { data ); - this.renderConfigurations.map( - function(configuration) { + var configuration = this.activeRenderConfiguration; - var renderer = configuration.activeRenderer; + if (!configuration) { + return; + } - var scenes = configuration.activeScenes; + var renderer = configuration.activeRenderer; - var camera = configuration.activeCamera; + var scenes = configuration.activeScenes; - var effect = configuration.activeEffect; + var camera = configuration.activeCamera; - var composer = configuration.activeComposer; + var effect = configuration.activeEffect; - if ( - configuration.enableEffect && - (!effect || !effect.instance) - ) { - console.warn('no effect'); + var composer = configuration.activeComposer; + + if ( + configuration.enableEffect && + (!effect || !effect.instance) + ) { + renderer.clear(); + return; + } + + if ( + configuration.enableComposer && + (!composer || !composer.instance || composer.passes.length === 0) + ) { + renderer.clear(); + return; + } + + if ( + renderer.renderMode === GameLib.D3.API.Renderer.MODE_TARGET || + renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET + ) { + if (!renderer.renderTarget) { + console.warn('no render renderTarget'); + return; + } + } + + var size = renderer.getSize(); + + renderer.viewports.map( + + function(viewport) { + + renderer.setViewport( + viewport.x * size.width, + viewport.y * size.height, + viewport.width * size.width, + viewport.height * size.height + ); + + if (configuration.enableComposer) { + composer.render(); return; } - if ( - configuration.enableComposer && - (!composer || !composer.instance) - ) { - console.warn('no composer'); - return; - } + scenes.map( - if ( - renderer.renderMode === GameLib.D3.API.Renderer.MODE_TARGET || - renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET - ) { - if (!renderer.renderTarget) { - console.warn('no render renderTarget'); - return; - } - } + function (scene) { - var size = renderer.getSize(); - - renderer.viewports.map( - - function(viewport) { - - renderer.setViewport( - viewport.x * size.width, - viewport.y * size.height, - viewport.width * size.width, - viewport.height * size.height + /** + * Update any cube camera's based on the scene + */ + this.cubeCameras.map( + function(cubeCamera) { + cubeCamera.update(renderer, scene); + } ); - if (configuration.enableComposer) { - composer.render(); - return; + if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_TARGET || + renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET) { + + renderer.renderToTarget( + scene, + camera + ) + } - scenes.map( + if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS || + renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET) { - function (scene) { + if (configuration.enableEffect) { + effect.render(scene, camera); + return; + } - /** - * Update any cube camera's based on the scene - */ - this.cubeCameras.map( - function(cubeCamera) { - cubeCamera.update(renderer, scene); - } - ); + renderer.render(scene, camera); + } - if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_TARGET || - renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET) { - - renderer.renderToTarget( - scene, - camera - ) - - } - - if (renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS || - renderer.renderMode === GameLib.D3.API.Renderer.MODE_CANVAS_AND_TARGET) { - - if (configuration.enableEffect) { - effect.render(scene, camera); - return; - } - - renderer.render(scene, camera); - } - - }.bind(this) - ); }.bind(this) - ) - + ); }.bind(this) ); @@ -498,10 +587,14 @@ GameLib.System.Render.prototype.stop = function() { this.removeComponentSubscription.remove(); + this.replaceComponentSubscription.remove(); + this.renderSubscription.remove(); this.getRenderConfigurationSubscription.remove(); + this.setACtiveRenderConfigurationSubscription.remove(); + // this.delayedInstanceEncounteredSubscription.remove(); // window.removeEventListener(