diff --git a/bak/game-lib-d3-api-graphics.js b/bak/game-lib-d3-api-graphics.js new file mode 100644 index 0000000..e704a7d --- /dev/null +++ b/bak/game-lib-d3-api-graphics.js @@ -0,0 +1,39 @@ +/** + * Graphics API + * @param id String + * @param name + * @param graphicsType + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Graphics = function ( + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_GRAPHICS, + null, + null, + parentEntity + ); + + +}; + +GameLib.D3.API.Graphics.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Graphics.prototype.constructor = GameLib.D3.API.Graphics; + +/** + * Object to GameLib.D3.API.Graphics + * @param objectComponent + * @constructor + */ +GameLib.D3.API.Graphics.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.Graphics( + objectComponent.id, + objectComponent.name, + objectComponent.graphicsType, + objectComponent.parentEntity + ); +}; diff --git a/bak/game-lib-d3-api-helper.js b/bak/game-lib-d3-api-helper.js new file mode 100644 index 0000000..3bc0c9d --- /dev/null +++ b/bak/game-lib-d3-api-helper.js @@ -0,0 +1,87 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param helperType + * @param object + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Helper = function ( + id, + name, + helperType, + object, + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_HELPER, + null, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Helper (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(object)) { + console.warn('Cannot create a helper for an Object which does not exist'); + throw new Error('Cannot create a helper for an Object which does not exist'); + } + + if (GameLib.Utils.UndefinedOrNull(helperType)) { + if ( + object instanceof GameLib.D3.Mesh && + object.meshType != GameLib.D3.Mesh.TYPE_CURVE + ) { + helperType = GameLib.D3.Helper.HELPER_TYPE_WIREFRAME; + } + + if (object instanceof GameLib.D3.Light) { + 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) { + helperType = GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT; + } + + if (object.lightType == GameLib.D3.Light.LIGHT_TYPE_SPOT) { + helperType = GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT; + } + } + + if (object instanceof GameLib.D3.Skeleton) { + helperType = GameLib.D3.Helper.HELPER_TYPE_SKELETON; + } + } + this.helperType = helperType; + +}; + +GameLib.D3.API.Helper.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Helper.prototype.constructor = GameLib.D3.API.Helper; + +/** + * Object to GameLib.D3.API.Helper + * @param objectComponent + * @constructor + */ +GameLib.D3.API.Helper.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.Helper( + objectComponent.id, + objectComponent.name, + objectComponent.helperType, + objectComponent.object, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-input-editor.bak b/bak/game-lib-d3-api-input-editor.bak similarity index 100% rename from src/game-lib-d3-api-input-editor.bak rename to bak/game-lib-d3-api-input-editor.bak diff --git a/bak/game-lib-d3-api-selected-object.js b/bak/game-lib-d3-api-selected-object.js new file mode 100644 index 0000000..6eb9520 --- /dev/null +++ b/bak/game-lib-d3-api-selected-object.js @@ -0,0 +1,46 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param object + * @param helper + * @param lastUpdate + * @constructor + */ +GameLib.D3.API.SelectedObject = function ( + object, + helper, + lastUpdate +) { + if (GameLib.Utils.UndefinedOrNull(object)) { + console.warn('Cannot select no object'); + throw new Error('Cannot select no object'); + } + this.object = object; + + if (GameLib.Utils.UndefinedOrNull(helper)) { + helper = null; + } + this.helper = helper; + + if (GameLib.Utils.UndefinedOrNull(lastUpdate)) { + lastUpdate = Date.now(); + } + this.lastUpdate = lastUpdate; +}; + +/** + * Object to GameLib.D3.API.SelectedObject + * @param objectComponent + * @returns {GameLib.D3.API.SelectedObject} + * @constructor + */ +GameLib.D3.API.SelectedObject.FromObjectSelectedObject = function(objectComponent) { + return new GameLib.D3.API.SelectedObject( + objectComponent.id, + objectComponent.name, + objectComponent.object, + objectComponent.helper, + objectComponent.lastUpdate + ); +}; diff --git a/src/game-lib-d3-broadphase.js b/bak/game-lib-d3-broadphase.js similarity index 100% rename from src/game-lib-d3-broadphase.js rename to bak/game-lib-d3-broadphase.js diff --git a/src/game-lib-d3-engine.js b/bak/game-lib-d3-engine.js similarity index 100% rename from src/game-lib-d3-engine.js rename to bak/game-lib-d3-engine.js diff --git a/src/game-lib-d3-fly-controls.js b/bak/game-lib-d3-fly-controls.js similarity index 100% rename from src/game-lib-d3-fly-controls.js rename to bak/game-lib-d3-fly-controls.js diff --git a/src/game-lib-d3-heightmap.js b/bak/game-lib-d3-heightmap.js similarity index 100% rename from src/game-lib-d3-heightmap.js rename to bak/game-lib-d3-heightmap.js diff --git a/src/game-lib-d3-input-editor.bak b/bak/game-lib-d3-input-editor.bak similarity index 100% rename from src/game-lib-d3-input-editor.bak rename to bak/game-lib-d3-input-editor.bak diff --git a/src/game-lib-d3-input-fly.bak b/bak/game-lib-d3-input-fly.bak similarity index 100% rename from src/game-lib-d3-input-fly.bak rename to bak/game-lib-d3-input-fly.bak diff --git a/src/game-lib-d3-physics.js b/bak/game-lib-d3-physics.js similarity index 100% rename from src/game-lib-d3-physics.js rename to bak/game-lib-d3-physics.js diff --git a/src/game-lib-d3-raycast-vehicle.js b/bak/game-lib-d3-raycast-vehicle.js similarity index 100% rename from src/game-lib-d3-raycast-vehicle.js rename to bak/game-lib-d3-raycast-vehicle.js diff --git a/src/game-lib-d3-raycast-wheel.js b/bak/game-lib-d3-raycast-wheel.js similarity index 100% rename from src/game-lib-d3-raycast-wheel.js rename to bak/game-lib-d3-raycast-wheel.js diff --git a/src/game-lib-d3-rigid-body-vehicle.js b/bak/game-lib-d3-rigid-body-vehicle.js similarity index 100% rename from src/game-lib-d3-rigid-body-vehicle.js rename to bak/game-lib-d3-rigid-body-vehicle.js diff --git a/src/game-lib-d3-rigid-body.js b/bak/game-lib-d3-rigid-body.js similarity index 100% rename from src/game-lib-d3-rigid-body.js rename to bak/game-lib-d3-rigid-body.js diff --git a/src/game-lib-d3-rigid-wheel.js b/bak/game-lib-d3-rigid-wheel.js similarity index 100% rename from src/game-lib-d3-rigid-wheel.js rename to bak/game-lib-d3-rigid-wheel.js diff --git a/src/game-lib-d3-shape.js b/bak/game-lib-d3-shape.js similarity index 100% rename from src/game-lib-d3-shape.js rename to bak/game-lib-d3-shape.js diff --git a/src/game-lib-d3-sky-box.js b/bak/game-lib-d3-sky-box.js similarity index 100% rename from src/game-lib-d3-sky-box.js rename to bak/game-lib-d3-sky-box.js diff --git a/src/game-lib-d3-solver.js b/bak/game-lib-d3-solver.js similarity index 100% rename from src/game-lib-d3-solver.js rename to bak/game-lib-d3-solver.js diff --git a/src/game-lib-d3-world.js b/bak/game-lib-d3-world.js similarity index 100% rename from src/game-lib-d3-world.js rename to bak/game-lib-d3-world.js diff --git a/src/game-lib-matrix-3.js b/bak/game-lib-matrix-3.js similarity index 100% rename from src/game-lib-matrix-3.js rename to bak/game-lib-matrix-3.js diff --git a/src/api-lib.js/api-lib-scene.js b/src/api-lib.js/api-lib-scene.js deleted file mode 100644 index c626a41..0000000 --- a/src/api-lib.js/api-lib-scene.js +++ /dev/null @@ -1,9 +0,0 @@ -ApiLib = function() { - -}; - -ApiLib.Scene = function( - -) { - -}; \ No newline at end of file diff --git a/src/game-lib-a.js b/src/game-lib-a-0.js similarity index 100% rename from src/game-lib-a.js rename to src/game-lib-a-0.js diff --git a/src/game-lib-api-component.js b/src/game-lib-a-api-component.js similarity index 80% rename from src/game-lib-api-component.js rename to src/game-lib-a-api-component.js index e99aed4..91146ec 100644 --- a/src/game-lib-api-component.js +++ b/src/game-lib-a-api-component.js @@ -39,7 +39,7 @@ GameLib.API.Component = function( GameLib.API.Component.FromObjectComponent = function(objectComponent) { if (objectComponent instanceof Object) { - if (objectComponent.componentType == GameLib.Component.COMPONENT_TYPE_PATH_FOLLOWING) { + if (objectComponent.componentType == GameLib.Component.COMPONENT_PATH_FOLLOWING) { return GameLib.D3.API.PathFollowing.FromObjectComponent(objectComponent); } @@ -47,7 +47,15 @@ GameLib.API.Component.FromObjectComponent = function(objectComponent) { return GameLib.D3.API.Renderer.FromObjectComponent(objectComponent); } - if (objectComponent.componentType === GameLib.Component.COMPONENT_LOOK_AT) { + if (objectComponent.componentType === GameLib.Component.COMPONENT_COMPOSER) { + return GameLib.D3.API.Composer.FromObjectComponent(objectComponent); + } + + if (objectComponent.componentType === GameLib.Component.COMPONENT_PASS) { + return GameLib.D3.API.Pass.FromObjectComponent(objectComponent); + } + + if (objectComponent.componentType === GameLib.Component.COMPONENT_LOOK_AT) { return GameLib.D3.API.LookAt.FromObjectComponent(objectComponent); } @@ -55,8 +63,8 @@ GameLib.API.Component.FromObjectComponent = function(objectComponent) { return GameLib.D3.API.Follow.FromObjectComponent(objectComponent); } - if (objectComponent.componentType === GameLib.Component.COMPONENT_MESH) { - return GameLib.D3.API.Mesh.FromObjectComponent(objectComponent); + if (objectComponent.componentType === GameLib.Component.COMPONENT_RENDER_TARGET) { + return GameLib.D3.API.RenderTarget.FromObjectComponent(objectComponent); } if (objectComponent.componentType === GameLib.Component.COMPONENT_SPLINE) { diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js new file mode 100644 index 0000000..4901df0 --- /dev/null +++ b/src/game-lib-a-component-a.js @@ -0,0 +1,85 @@ +/** + * Component Interface + * @constructor + * @param componentType + * @param linkedObjects + * @param loaded + * @param parentEntity + */ +GameLib.Component = function( + componentType, + linkedObjects, + loaded, + parentEntity +) { + GameLib.API.Component.call( + this, + componentType, + linkedObjects, + loaded, + parentEntity + ); + + this.idToObject = {}; + + this.linkedObjects.parentEntity = GameLib.Entity; +}; + +GameLib.Component.prototype = Object.create(GameLib.API.Component.prototype); +GameLib.Component.prototype.constructor = GameLib.Component; + +GameLib.Component.COMPONENT_PATH_FOLLOWING = 0x1; +GameLib.Component.COMPONENT_MATERIAL = 0x2; +GameLib.Component.COMPONENT_RENDERER = 0x3; +GameLib.Component.COMPONENT_LOOK_AT = 0x5; +GameLib.Component.COMPONENT_CAMERA = 0x6; +GameLib.Component.COMPONENT_FOLLOW = 0x7; +GameLib.Component.COMPONENT_MESH = 0x8; +GameLib.Component.COMPONENT_SPLINE = 0x9; +GameLib.Component.COMPONENT_LIGHT = 0xa; +GameLib.Component.COMPONENT_INPUT_DRIVE = 0xb; +GameLib.Component.COMPONENT_COMPOSER = 0xc; +GameLib.Component.COMPONENT_RENDER_TARGET = 0xd; +GameLib.Component.COMPONENT_PASS = 0xe; +GameLib.Component.COMPONENT_SCENE = 0xf; +GameLib.Component.COMPONENT_GAME = 0x10; +GameLib.Component.COMPONENT_INPUT_EDITOR = 0x11; +GameLib.Component.COMPONENT_EDITOR = 0x12; +GameLib.Component.COMPONENT_VIEWPORT = 0x13; +GameLib.Component.COMPONENT_SYSTEM = 0x14; +GameLib.Component.COMPONENT_GRAPHICS = 0x15; +GameLib.Component.COMPONENT_HELPER = 0x16; +GameLib.Component.COMPONENT_CUSTOM_CODE = 0x17; +GameLib.Component.COMPONENT_MOUSE = 0x18; +GameLib.Component.COMPONENT_SKELETON = 0x19; +GameLib.Component.COMPONENT_TEXTURE = 0x1a; +GameLib.Component.COMPONENT_ENTITY_MANAGER = 0x1b; +GameLib.Component.COMPONENT_DOM_ELEMENT = 0x1c; + +/** + * Components are linked at runtime - for storing, we just store the ID + * @returns {*} + */ +GameLib.Component.prototype.toApiComponent = function() { + return this.id; +}; + +GameLib.Component.prototype.buildIdToObject = function() { + + this.idToObject = {}; + + for (var property in this.linkedObjects) { + if ( + this.linkedObjects.hasOwnProperty(property) && + this.hasOwnProperty(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; +}; diff --git a/src/game-lib-api-dom-element.js b/src/game-lib-api-dom-element.js new file mode 100644 index 0000000..bb10a29 --- /dev/null +++ b/src/game-lib-api-dom-element.js @@ -0,0 +1,60 @@ +/** + * API DomElement + * @param id + * @param name + * @param domElementId + * @param parentEntity + * @constructor + */ +GameLib.API.DomElement = function( + id, + name, + domElementId, + parentEntity +) { + + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_DOM_ELEMENT, + null, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'DOM Element (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(domElementId)) { + domElementId = ''; + } + this.domElementId = domElementId; +}; + +GameLib.API.DomElement.prototype = Object.create(GameLib.Component.prototype); +GameLib.API.DomElement.prototype.constructor = GameLib.API.DomElement; + +/** + * Returns an API domElement from an Object domElement + * @param objectDomElement + * @constructor + */ +GameLib.API.DomElement.FromObjectDomElement = function (objectDomElement) { + return new GameLib.API.DomElement( + objectDomElement.id, + objectDomElement.name, + objectDomElement.domElementId, + objectDomElement.parentEntity + ) +}; diff --git a/src/game-lib-api-entity-manager.js b/src/game-lib-api-entity-manager.js index f193b78..7634d74 100644 --- a/src/game-lib-api-entity-manager.js +++ b/src/game-lib-api-entity-manager.js @@ -1,17 +1,46 @@ /** * Entity API Object (for storing / loading entities to and from API) * @constructor + * @param id + * @param name * @param entities GameLib.API.Entity[] + * @param parentEntity */ GameLib.API.EntityManager = function( - entities + id, + name, + entities, + parentEntity ) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_ENTITY_MANAGER, + { + 'entities' : [GameLib.Entity] + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Entity Manager (' + this.id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(entities)) { entities = []; } this.entities = entities; }; +GameLib.API.EntityManager.prototype = Object.create(GameLib.Component.prototype); +GameLib.API.EntityManager.prototype.constructor = GameLib.API.EntityManager; + /** * Creates an API entity manager from an Object entity manager * @param objectEntityManager @@ -26,6 +55,9 @@ GameLib.API.EntityManager.FromObjectEntityManager = function(objectEntityManager ); return new GameLib.API.EntityManager( - apiEntities + objectEntityManager.id, + objectEntityManager.name, + apiEntities, + objectEntityManager.parentEntity ); }; diff --git a/src/game-lib-api-entity.js b/src/game-lib-api-entity.js index b0624cf..18bbf17 100644 --- a/src/game-lib-api-entity.js +++ b/src/game-lib-api-entity.js @@ -16,7 +16,7 @@ GameLib.API.Entity = function( this.id = id; if (GameLib.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; + name = 'Entity (' + this.id + ')'; } this.name = name; @@ -26,32 +26,6 @@ GameLib.API.Entity = function( this.components = components; }; - -/** - * Adds a components to the entity - * @param component GameLib.Component - */ -GameLib.API.Entity.prototype.addComponent = function(component) { - this.components.push(component); -}; - -/** - * Removes a component from this entity - * @param component GameLib.Component - */ -GameLib.API.Entity.prototype.removeComponent = function(component) { - - var index = this.components.indexOf(component); - - if (index == -1) { - console.log('failed to remove component'); - return false; - } - - this.components.splice(index, 1); - return true; -}; - /** * Returns an API entity from an Object entity * @param objectEntity diff --git a/src/game-lib-api-matrix4.js b/src/game-lib-api-matrix4.js index 45a8c0b..3a2d4dc 100644 --- a/src/game-lib-api-matrix4.js +++ b/src/game-lib-api-matrix4.js @@ -56,6 +56,33 @@ GameLib.API.Matrix4 = function ApiMatrix4( this.up = new GameLib.API.Vector4(); }; +/** + * Returns an API matrix from an Object matrix + * @param objectMatrix + * @constructor + */ +GameLib.API.Matrix4.FromObjectMatrix = function(objectMatrix) { + + if (objectMatrix.rows) { + return new GameLib.API.Matrix4( + GameLib.API.Vector4.FromObjectVector(objectMatrix.rows[0]), + GameLib.API.Vector4.FromObjectVector(objectMatrix.rows[1]), + GameLib.API.Vector4.FromObjectVector(objectMatrix.rows[2]), + GameLib.API.Vector4.FromObjectVector(objectMatrix.rows[3]) + ); + } else if (objectMatrix instanceof Array) { + return new GameLib.API.Matrix4( + GameLib.API.Vector4.FromObjectVector(objectMatrix[0]), + GameLib.API.Vector4.FromObjectVector(objectMatrix[1]), + GameLib.API.Vector4.FromObjectVector(objectMatrix[2]), + GameLib.API.Vector4.FromObjectVector(objectMatrix[3]) + ); + } else { + console.warn('Unsupported object matrix type - whats your DB version?'); + throw new Error('Unsupported object matrix type - whats your DB version?'); + } +}; + GameLib.API.Matrix4.prototype.rotationMatrixX = function (radians) { this.identity(); this.rows[1] = new GameLib.API.Vector4(0, Math.cos(radians), -1 * Math.sin(radians), 0); @@ -130,37 +157,3 @@ GameLib.API.Matrix4.prototype.identity = function () { new GameLib.API.Vector4(0, 0, 0, 1) ]; }; - -/** - * Returns an API matrix from an Object matrix - * @param objectMatrix - * @constructor - */ -GameLib.API.Matrix4.FromObjectMatrix = function(objectMatrix) { - return new GameLib.API.Matrix4( - new GameLib.API.Vector4( - objectMatrix.rows[0].x, - objectMatrix.rows[0].y, - objectMatrix.rows[0].z, - objectMatrix.rows[0].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[1].x, - objectMatrix.rows[1].y, - objectMatrix.rows[1].z, - objectMatrix.rows[1].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[2].x, - objectMatrix.rows[2].y, - objectMatrix.rows[2].z, - objectMatrix.rows[2].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[3].x, - objectMatrix.rows[3].y, - objectMatrix.rows[3].z, - objectMatrix.rows[3].w - ) - ) -}; diff --git a/src/game-lib-api-mouse.js b/src/game-lib-api-mouse.js new file mode 100644 index 0000000..c62c75d --- /dev/null +++ b/src/game-lib-api-mouse.js @@ -0,0 +1,69 @@ +/** + * API Mouse + * @param id + * @param name + * @param x + * @param y + * @param parentEntity + * @constructor + */ +GameLib.API.Mouse = function( + id, + name, + x, + y, + parentEntity +) { + + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_MOUSE, + null, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Mouse (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(x)) { + x = 0; + } + this.x = x; + + if (GameLib.Utils.UndefinedOrNull(y)) { + y = 0; + } + this.y = y; + +}; + +GameLib.API.Mouse.prototype = Object.create(GameLib.Component.prototype); +GameLib.API.Mouse.prototype.constructor = GameLib.API.Mouse; + +/** + * Returns an API mouse from an Object mouse + * @param objectMouse + * @constructor + */ +GameLib.API.Mouse.FromObjectMouse = function (objectMouse) { + return new GameLib.API.Mouse( + objectMouse.id, + objectMouse.name, + objectMouse.x, + objectMouse.y, + objectMouse.parentEntity + ) +}; diff --git a/src/game-lib-api-quaternion-a.js b/src/game-lib-api-quaternion-a.js index 8d4a853..4692128 100644 --- a/src/game-lib-api-quaternion-a.js +++ b/src/game-lib-api-quaternion-a.js @@ -1,4 +1,21 @@ -GameLib.API.Quaternion = function (x, y, z, w, axis, angle) { +/** + * Quaternion + * @param x + * @param y + * @param z + * @param w + * @param axis + * @param angle + * @constructor + */ +GameLib.API.Quaternion = function ( + x, + y, + z, + w, + axis, + angle +) { if (GameLib.Utils.UndefinedOrNull(x)) { x = 0; @@ -204,6 +221,7 @@ GameLib.API.Quaternion.prototype.slerp = function (quaternion, t) { GameLib.API.Quaternion.FromObjectQuaternion = function (objectQuaternion) { var apiAxis = null; + if (objectQuaternion.axis) { apiAxis = GameLib.API.Vector3.FromObjectVector(objectQuaternion.axis); } diff --git a/src/game-lib-api-system.js b/src/game-lib-api-system.js new file mode 100644 index 0000000..feed0c3 --- /dev/null +++ b/src/game-lib-api-system.js @@ -0,0 +1,83 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param systemType + * @param entityManager + * @param domElement + * @param domStats + * @param parentEntity + * @constructor + */ +GameLib.API.System = function ( + id, + name, + systemType, + entityManager, + domElement, + domStats, + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_SYSTEM, + { + 'entityManager' : GameLib.EntityManager, + 'domElement' : GameLib.DomElement, + 'domStats' : GameLib.DomElement + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = "System (" + this.id + ")"; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(systemType)) { + systemType = GameLib.System.SYSTEM_TYPE_RENDER; + } + this.systemType = systemType; + + if (GameLib.Utils.UndefinedOrNull(entityManager)) { + entityManager = null; + } + this.entityManager = entityManager; + + if (GameLib.Utils.UndefinedOrNull(domElement)){ + domElement = null; + } + this.domElement = domElement; + + if (GameLib.Utils.UndefinedOrNull(domStats)){ + domStats = null; + } + this.domStats = domStats; +}; + +GameLib.API.System.prototype = Object.create(GameLib.Component.prototype); +GameLib.API.System.prototype.constructor = GameLib.API.System; + +/** + * Object to GameLib.D3.API.System + * @param objectComponent + * @constructor + */ +GameLib.API.System.FromObjectComponent = function(objectComponent) { + return new GameLib.API.System( + objectComponent.id, + objectComponent.name, + objectComponent.systemType, + objectComponent.entityManager, + objectComponent.domElement, + objectComponent.domStats, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-api-vector2.js b/src/game-lib-api-vector2.js index a8054f1..fca51f1 100644 --- a/src/game-lib-api-vector2.js +++ b/src/game-lib-api-vector2.js @@ -1,4 +1,4 @@ -GameLib.API.Vector2 = function ApiVector2(x, y) { +GameLib.API.Vector2 = function (x, y) { if (GameLib.Utils.UndefinedOrNull(x)) { x = 0; diff --git a/src/game-lib-api-vector4.js b/src/game-lib-api-vector4.js index 2afe8d0..5aad9d5 100644 --- a/src/game-lib-api-vector4.js +++ b/src/game-lib-api-vector4.js @@ -27,7 +27,7 @@ GameLib.API.Vector4 = function (x, y, z, w) { * @constructor */ GameLib.API.Vector4.FromObjectVector = function (objectVector) { - return new GameLib.API.Vector2( + return new GameLib.API.Vector4( objectVector.x, objectVector.y, objectVector.z, diff --git a/src/game-lib-color.js b/src/game-lib-color.js index e03aa39..55989fe 100644 --- a/src/game-lib-color.js +++ b/src/game-lib-color.js @@ -6,11 +6,20 @@ * @param grain Number * @constructor */ -GameLib.Color = function (graphics, parentObject, apiColor, grain) { +GameLib.Color = function ( + graphics, + apiColor, + parentObject, + grain +) { this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiColor)) { + apiColor = {}; + } + GameLib.API.Color.call( this, apiColor.r, @@ -19,6 +28,9 @@ GameLib.Color = function (graphics, parentObject, apiColor, grain) { apiColor.a ); + if (GameLib.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { @@ -60,7 +72,8 @@ GameLib.Color.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject.updateInstance) { + if (this.parentObject && + this.parentObject.updateInstance) { this.parentObject.updateInstance(); } }; diff --git a/src/game-lib-component-a.js b/src/game-lib-component-a.js deleted file mode 100644 index 30ac9f3..0000000 --- a/src/game-lib-component-a.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Component Interface - * @constructor - * @param componentType - * @param linkedObjects - * @param loaded - * @param parentEntity - */ -GameLib.Component = function( - componentType, - linkedObjects, - loaded, - parentEntity -) { - GameLib.API.Component.call( - this, - componentType, - linkedObjects, - loaded, - parentEntity - ); - - this.linkedObjects.parentEntity = GameLib.Entity; -}; - -GameLib.Component.prototype = Object.create(GameLib.API.Component.prototype); -GameLib.Component.prototype.constructor = GameLib.Component; - -GameLib.Component.COMPONENT_TYPE_PATH_FOLLOWING = 0x1; -GameLib.Component.COMPONENT_MATERIAL = 0x2; -GameLib.Component.COMPONENT_RENDERER = 0x3; -GameLib.Component.COMPONENT_LOOK_AT = 0x5; -GameLib.Component.COMPONENT_CAMERA = 0x6; -GameLib.Component.COMPONENT_FOLLOW = 0x7; -GameLib.Component.COMPONENT_MESH = 0x8; -GameLib.Component.COMPONENT_SPLINE = 0x9; -GameLib.Component.COMPONENT_LIGHT = 0xa; -GameLib.Component.COMPONENT_INPUT_DRIVE = 0xb; - -/** - * Components are linked at runtime - for storing, we just store the ID - * @returns {*} - */ -GameLib.Component.prototype.toApiComponent = function() { - return this.id; -}; \ No newline at end of file diff --git a/src/game-lib-d3-api-camera.js b/src/game-lib-d3-api-camera.js index 9f86447..af84cbd 100644 --- a/src/game-lib-d3-api-camera.js +++ b/src/game-lib-d3-api-camera.js @@ -17,6 +17,8 @@ * @param maxZ * @param quaternion GameLib.Quaternion * @param parentEntity + * @param eyeSeparation + * @param focalLength * @constructor */ GameLib.D3.API.Camera = function( @@ -36,7 +38,9 @@ GameLib.D3.API.Camera = function( minZ, maxZ, quaternion, - parentEntity + parentEntity, + eyeSeparation, + focalLength ) { GameLib.Component.call( this, @@ -57,7 +61,7 @@ GameLib.D3.API.Camera = function( this.cameraType = cameraType; if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Camera (' + cameraType + ')'; + name = 'Camera (' + this.id + ')'; } this.name = name; @@ -133,6 +137,16 @@ GameLib.D3.API.Camera = function( maxZ = 100; } this.maxZ = maxZ; + + if (GameLib.Utils.UndefinedOrNull(eyeSeparation)) { + eyeSeparation = 30; + } + this.eyeSeparation = eyeSeparation; + + if (GameLib.Utils.UndefinedOrNull(focalLength)) { + focalLength = 150; + } + this.focalLength = focalLength; }; GameLib.D3.API.Camera.prototype = Object.create(GameLib.Component.prototype); @@ -162,7 +176,9 @@ GameLib.D3.API.Camera.FromObjectCamera = function(objectCamera) { objectCamera.minZ, objectCamera.maxZ, GameLib.API.Quaternion.FromObjectQuaternion(objectCamera.quaternion), - objectCamera.parentEntity + objectCamera.parentEntity, + objectCamera.eyeSeparation, + objectCamera.focalLength ); }; diff --git a/src/game-lib-d3-api-composer.js b/src/game-lib-d3-api-composer.js new file mode 100644 index 0000000..cfd0e80 --- /dev/null +++ b/src/game-lib-d3-api-composer.js @@ -0,0 +1,75 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param renderer GameLib.D3.Renderer + * @param renderTarget GameLib.D3.API.RenderTarget + * @param passes GameLib.D3.API.Pass[] + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Composer = function ( + id, + name, + renderer, + renderTarget, + passes, + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_COMPOSER, + { + 'renderer' : GameLib.D3.Renderer, + 'renderTarget' : GameLib.D3.RenderTarget, + 'passes' : [GameLib.D3.Pass] + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Composer (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(renderer)) { + renderer = null; + } + this.renderer = renderer; + + if (GameLib.Utils.UndefinedOrNull(renderTarget)) { + renderTarget = null; + } + this.renderTarget = renderTarget; + + if (GameLib.Utils.UndefinedOrNull(passes)) { + passes = []; + } + this.passes = passes; +}; + +GameLib.D3.API.Composer.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Composer.prototype.constructor = GameLib.D3.API.Composer; + +/** + * Object to GameLib.D3.API.Composer + * @param objectComponent + * @constructor + */ +GameLib.D3.API.Composer.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.Composer( + objectComponent.id, + objectComponent.name, + objectComponent.renderer, + objectComponent.renderTarget, + objectComponent.passes, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-custom-code.js b/src/game-lib-d3-api-custom-code.js new file mode 100644 index 0000000..832fc09 --- /dev/null +++ b/src/game-lib-d3-api-custom-code.js @@ -0,0 +1,74 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param code String + * @param domElementId + * @param parentEntity + * @param args + * @constructor + */ +GameLib.D3.API.CustomCode = function ( + id, + name, + code, + domElementId, + parentEntity, + args +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_CUSTOM_CODE, + { + 'args' : [GameLib.Component] + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'CustomCode (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(code)) { + code = ''; + } + this.code = code; + + if (GameLib.Utils.UndefinedOrNull(domElementId)) { + domElementId = "CustomCode_" + this.id; + } + this.domElementId = domElementId; + + if (GameLib.Utils.UndefinedOrNull(args)) { + args = []; + } + this.args = args; +}; + +GameLib.D3.API.CustomCode.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.CustomCode.prototype.constructor = GameLib.D3.API.CustomCode; + +/** + * Object to GameLib.D3.API.CustomCode + * @param objectComponent + * @returns {GameLib.D3.API.CustomCode} + * @constructor + */ +GameLib.D3.API.CustomCode.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.CustomCode( + objectComponent.id, + objectComponent.name, + objectComponent.code, + objectComponent.domElementId, + objectComponent.parentEntity, + objectComponent.args + ); +}; diff --git a/src/game-lib-d3-api-editor.js b/src/game-lib-d3-api-editor.js new file mode 100644 index 0000000..951551b --- /dev/null +++ b/src/game-lib-d3-api-editor.js @@ -0,0 +1,241 @@ +/** + * Raw Editor API object - should always correspond with the Editor Schema + * @param id + * @param name + * @param baseUrl + * @param path + * @param games [GameLib.API.D3.Game] + * @param scenes + * @param cameras + * @param composers + * @param viewports + * @param renderers + * @param renderTargets + * @param systems + * @param entityManager + * @param allSelected + * @param selectedObjects + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Editor = function( + id, + name, + baseUrl, + path, + games, + scenes, + cameras, + composers, + viewports, + renderers, + renderTargets, + systems, + entityManager, + allSelected, + selectedObjects, + parentEntity +) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_EDITOR, + { + 'games' : [GameLib.D3.Game], + 'scenes' : [GameLib.D3.Scene], + 'cameras' : [GameLib.D3.Camera], + 'composers' : [GameLib.D3.Composer], + 'viewports' : [GameLib.D3.Viewport], + 'renderers' : [GameLib.D3.Renderer], + 'renderTargets' : [GameLib.D3.RenderTarget], + 'systems' : [GameLib.System], + 'entityManager' : GameLib.EntityManager + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Editor (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(baseUrl)) { + baseUrl = ''; + } + this.baseUrl = baseUrl; + + if (GameLib.Utils.UndefinedOrNull(path)) { + path = ''; + } + this.path = path; + + if (GameLib.Utils.UndefinedOrNull(games)) { + games = []; + } + this.games = games; + + if (GameLib.Utils.UndefinedOrNull(scenes)) { + scenes = []; + } + this.scenes = scenes; + + if (GameLib.Utils.UndefinedOrNull(cameras)) { + cameras = []; + } + this.cameras = cameras; + + if (GameLib.Utils.UndefinedOrNull(composers)) { + composers = []; + } + this.composers = composers; + + if (GameLib.Utils.UndefinedOrNull(viewports)) { + viewports = []; + } + this.viewports = viewports; + + if (GameLib.Utils.UndefinedOrNull(renderers)) { + renderers = []; + } + this.renderers = renderers; + + if (GameLib.Utils.UndefinedOrNull(renderTargets)) { + renderTargets = []; + } + this.renderTargets = renderTargets; + + if (GameLib.Utils.UndefinedOrNull(systems)) { + systems = []; + } + this.systems = systems; + + if (GameLib.Utils.UndefinedOrNull(entityManager)) { + entityManager = new GameLib.API.EntityManager(); + } + this.entityManager = entityManager; + + if (GameLib.Utils.UndefinedOrNull(allSelected)) { + allSelected = false; + } + this.allSelected = allSelected; + + if (GameLib.Utils.UndefinedOrNull(selectedObjects)) { + selectedObjects = []; + } + this.selectedObjects = selectedObjects; + +}; + +GameLib.D3.API.Editor.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Editor.prototype.constructor = GameLib.D3.API.Editor; + +/** + * Creates an API Editor from an Object Editor + * @param objectEditor + * @constructor + */ +GameLib.D3.API.Editor.FromObjectEditor = function(objectEditor) { + + var apiGames = []; + var apiScenes = []; + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + var apiEntityManager = null; + + if (objectEditor.games) { + apiGames = objectEditor.games.map( + function(objectGame){ + return GameLib.D3.API.Game.FromObjectGame(objectGame); + } + ); + } + + if (objectEditor.scenes) { + apiScenes = objectEditor.scenes.map( + function(objectScene){ + return GameLib.D3.API.Scene.FromObjectScene(objectScene); + } + ); + } + + if (objectEditor.cameras) { + apiCameras = objectEditor.cameras.map( + function(objectCamera){ + return GameLib.D3.API.Camera.FromObjectCamera(objectCamera); + } + ); + } + + if (objectEditor.composers) { + apiComposers = objectEditor.composers.map( + function(objectComposer){ + return GameLib.D3.API.Composer.FromObjectComponent(objectComposer); + } + ); + } + + if (objectEditor.viewports) { + apiViewports = objectEditor.viewports.map( + function(objectViewport){ + return GameLib.D3.API.Viewport.FromObjectViewport(objectViewport); + } + ); + } + + if (objectEditor.renderers) { + apiRenderers = objectEditor.renderers.map( + function(objectRenderer){ + return GameLib.D3.API.Renderer.FromObjectComponent(objectRenderer); + } + ); + } + + if (objectEditor.renderTargets) { + apiRenderTargets = objectEditor.renderTargets.map( + function(objectRenderTarget){ + return GameLib.D3.API.RenderTarget.FromObjectComponent(objectRenderTarget); + } + ); + } + + if (objectEditor.systems) { + apiSystems = objectEditor.systems.map( + function(objectSystem){ + return GameLib.API.System.FromObjectComponent(objectSystem); + } + ); + } + + if (objectEditor.entityManager) { + apiEntityManager = GameLib.API.EntityManager.FromObjectEntityManager(objectEditor.entityManager); + } + + return new GameLib.D3.API.Editor( + objectEditor.id, + objectEditor.name, + objectEditor.baseUrl, + objectEditor.path, + apiGames, + apiScenes, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + objectEditor.allSelected, + objectEditor.selectedObjects, + objectEditor.parentEntity + ); +}; + diff --git a/src/game-lib-d3-api-game.js b/src/game-lib-d3-api-game.js new file mode 100644 index 0000000..92cb912 --- /dev/null +++ b/src/game-lib-d3-api-game.js @@ -0,0 +1,228 @@ +/** + * Raw Game API object - should always correspond with the Game Schema + * @param id + * @param name + * @param gameType + * @param width + * @param height + * @param baseUrl + * @param path + * @param cameras + * @param renderers + * @param composers + * @param renderTargets + * @param systems + * @param viewports + * @param entityManager + * @param mouse + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Game = function( + id, + name, + baseUrl, + path, + gameType, + width, + height, + cameras, + composers, + viewports, + renderers, + renderTargets, + systems, + entityManager, + mouse, + parentEntity +) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_GAME, + { + 'cameras' : [GameLib.D3.Camera], + 'composers' : [GameLib.D3.Composer], + 'viewports' : [GameLib.D3.Viewport], + 'renderers' : [GameLib.D3.Renderer], + 'renderTargets' : [GameLib.D3.RenderTarget], + 'systems' : [GameLib.System], + 'entityManager' : GameLib.EntityManager, + 'mouse' : GameLib.Mouse + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Game (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(baseUrl)) { + baseUrl = ''; + console.warn('The base URL required for downloading images is not set - textured meshes will not render properly'); + } + this.baseUrl = baseUrl; + + if (GameLib.Utils.UndefinedOrNull(path)) { + path = ''; + } + this.path = path; + + if (GameLib.Utils.UndefinedOrNull(gameType)) { + gameType = GameLib.D3.Game.GAME_TYPE_VR_PONG; + } + this.gameType = gameType; + + if (GameLib.Utils.UndefinedOrNull(width)) { + width = 800; + } + this.width = width; + + if (GameLib.Utils.UndefinedOrNull(height)) { + height = 600; + } + this.height = height; + + if (GameLib.Utils.UndefinedOrNull(cameras)) { + cameras = []; + } + this.cameras = cameras; + + if (GameLib.Utils.UndefinedOrNull(composers)) { + composers = []; + } + this.composers = composers; + + if (GameLib.Utils.UndefinedOrNull(viewports)) { + viewports = []; + } + this.viewports = viewports; + + if (GameLib.Utils.UndefinedOrNull(renderers)) { + renderers = []; + } + this.renderers = renderers; + + if (GameLib.Utils.UndefinedOrNull(renderTargets)) { + renderTargets = []; + } + this.renderTargets = renderTargets; + + if (GameLib.Utils.UndefinedOrNull(systems)) { + systems = []; + } + this.systems = systems; + + if (GameLib.Utils.UndefinedOrNull(entityManager)) { + entityManager = new GameLib.API.EntityManager(); + } + this.entityManager = entityManager; + + if (GameLib.Utils.UndefinedOrNull(mouse)) { + mouse = new GameLib.API.Mouse(); + } + this.mouse = mouse; +}; + +GameLib.D3.API.Game.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Game.prototype.constructor = GameLib.D3.API.Game; + +/** + * Creates an API camera from an Object camera + * @param objectGame + * @constructor + */ +GameLib.D3.API.Game.FromObjectGame = function(objectGame) { + + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + + var apiEntityManager = null; + var apiMouse = null; + + if (objectGame.cameras) { + apiCameras = objectGame.cameras.map( + function(objectCamera){ + return GameLib.D3.API.Camera.FromObjectCamera(objectCamera); + } + ); + } + + if (objectGame.composers) { + apiComposers = objectGame.composers.map( + function(objectComposer){ + return GameLib.D3.API.Composer.FromObjectComponent(objectComposer); + } + ); + } + + if (objectGame.viewports) { + apiViewports = objectGame.viewports.map( + function(objectViewport){ + return GameLib.D3.API.Viewport.FromObjectViewport(objectViewport); + } + ); + } + + if (objectGame.renderers) { + apiRenderers = objectGame.renderers.map( + function(objectRenderer){ + return GameLib.D3.API.Renderer.FromObjectComponent(objectRenderer); + } + ); + } + + if (objectGame.renderTargets) { + apiRenderTargets = objectGame.renderTargets.map( + function(objectRenderTarget){ + return GameLib.D3.API.RenderTarget.FromObjectComponent(objectRenderTarget); + } + ); + } + + if (objectGame.systems) { + apiSystems = objectGame.systems.map( + function(objectSystem){ + return GameLib.API.System.FromObjectComponent(objectSystem); + } + ); + } + + if (objectGame.entityManager) { + apiEntityManager = GameLib.API.EntityManager.FromObjectEntityManager(objectGame.entityManager); + } + + if (objectGame.mouse) { + apiMouse = GameLib.API.Mouse.FromObjectMouse(objectGame.mouse); + } + + return new GameLib.D3.API.Game( + objectGame.id, + objectGame.name, + objectGame.baseUrl, + objectGame.path, + objectGame.gameType, + objectGame.width, + objectGame.height, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + apiMouse, + objectGame.parentEntity + ); + +}; diff --git a/src/game-lib-d3-api-input-drive.js b/src/game-lib-d3-api-input-drive.js index fc93a3c..7eeae12 100644 --- a/src/game-lib-d3-api-input-drive.js +++ b/src/game-lib-d3-api-input-drive.js @@ -50,7 +50,7 @@ GameLib.D3.API.Input.Drive = function ( this.id = id; if (GameLib.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; + name = 'Input.Drive (' + this.id + ')'; } this.name = name; diff --git a/src/game-lib-d3-api-input-editor.js b/src/game-lib-d3-api-input-editor.js new file mode 100644 index 0000000..2c3ea95 --- /dev/null +++ b/src/game-lib-d3-api-input-editor.js @@ -0,0 +1,122 @@ +/** + * This component makes the parentEntity (ex. car) follow the path provided by the spline + * @param id String + * @param name String + * @param domElementId + * @param domContainerId + * @param editor GameLib.D3.API.Editor + * @param camera + * @param widthOffset + * @param heightOffset + * @param containerWidthOffset + * @param containerHeightOffset + * @param selectDelayMs + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Input.Editor = function ( + id, + name, + domElementId, + domContainerId, + editor, + camera, + widthOffset, + heightOffset, + containerWidthOffset, + containerHeightOffset, + selectDelayMs, + parentEntity +) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_INPUT_EDITOR, + { + 'editor' : GameLib.D3.Editor, + 'camera' : GameLib.D3.Camera + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Input Editor (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(domElementId)) { + domElementId = 'divCanvas'; + } + this.domElementId = domElementId; + + if (GameLib.Utils.UndefinedOrNull(domContainerId)) { + domContainerId = 'divContainer'; + } + this.domContainerId = domContainerId; + + if (GameLib.Utils.UndefinedOrNull(editor)) { + editor = null; + } + this.editor = editor; + + if (GameLib.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + + if (GameLib.Utils.UndefinedOrNull(widthOffset)) { + widthOffset = 400; + } + this.widthOffset = widthOffset; + + if (GameLib.Utils.UndefinedOrNull(heightOffset)) { + heightOffset = 0; + } + this.heightOffset = heightOffset; + + if (GameLib.Utils.UndefinedOrNull(containerWidthOffset)) { + containerWidthOffset = 0; + } + this.containerWidthOffset = containerWidthOffset; + + if (GameLib.Utils.UndefinedOrNull(containerHeightOffset)) { + containerHeightOffset = 80; + } + this.containerHeightOffset = containerHeightOffset; + + if (GameLib.Utils.UndefinedOrNull(selectDelayMs)) { + selectDelayMs = 300; + } + this.selectDelayMs = selectDelayMs; +}; + +GameLib.D3.API.Input.Editor.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Input.Editor.prototype.constructor = GameLib.D3.API.Input.Editor; + +/** + * Object to GameLib.D3.API.Input.Editor + * @param objectComponent + * @returns {GameLib.D3.API.Input.Editor} + * @constructor + */ +GameLib.D3.API.Input.Editor.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.Input.Editor( + objectComponent.id, + objectComponent.name, + objectComponent.domElementId, + objectComponent.domContainerId, + objectComponent.editor, + objectComponent.camera, + objectComponent.widthOffset, + objectComponent.heightOffset, + objectComponent.containerWidthOffset, + objectComponent.containerHeightOffset, + objectComponent.selectDelayMs, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-material.js b/src/game-lib-d3-api-material.js index 5008e25..d09296e 100644 --- a/src/game-lib-d3-api-material.js +++ b/src/game-lib-d3-api-material.js @@ -142,6 +142,7 @@ GameLib.D3.API.Material = function( specularMap, parentEntity ) { + GameLib.Component.call( this, GameLib.Component.COMPONENT_MATERIAL, diff --git a/src/game-lib-d3-api-mesh.js b/src/game-lib-d3-api-mesh.js index 2fdd1bf..64092ad 100644 --- a/src/game-lib-d3-api-mesh.js +++ b/src/game-lib-d3-api-mesh.js @@ -52,9 +52,10 @@ GameLib.D3.API.Mesh = function( this, GameLib.Component.COMPONENT_MESH, { - 'parentMesh' : GameLib.D3.Mesh, - 'parentScene' : GameLib.D3.Scene, - 'materials' : [GameLib.D3.Material] + 'parentMesh' : GameLib.D3.Mesh, + 'parentScene' : GameLib.D3.Scene, + 'materials' : [GameLib.D3.Material], + 'skeleton' : GameLib.D3.Skeleton }, null, parentEntity @@ -177,63 +178,77 @@ GameLib.D3.API.Mesh.prototype.constructor = GameLib.D3.API.Mesh; GameLib.D3.API.Mesh.FromObjectMesh = function (objectMesh){ var apiSkeleton = null; - var apiPosition = null; - var apiQuaternion = null; - var apiScale = null; - var apiLocalPosition = null; - var apiLocalRotation = null; - var apiLocalScale = null; - var apiUp = null; - var apiModelMatrix = null; if (objectMesh.skeleton) { apiSkeleton = GameLib.D3.API.Skeleton.FromObjectSkeleton(objectMesh.skeleton); } + var apiMaterials = []; + if (objectMesh.materials) { + apiMaterials = objectMesh.materials.map( + function (objectMaterial) { + return GameLib.D3.API.Material.FromObjectMaterial(objectMaterial); + } + ) + } + + var apiVertices = []; + if (objectMesh.vertices) { + apiVertices = objectMesh.vertices.map( + function (objectVertex) { + return GameLib.D3.API.Vertex.FromObjectVertex(objectVertex); + } + ) + } + + var apiPosition = new GameLib.API.Vector3(); if (objectMesh.position) { apiPosition = GameLib.API.Vector3.FromObjectVector(objectMesh.position); } + var apiQuaternion = new GameLib.API.Quaternion(); if (objectMesh.quaternion) { apiQuaternion = GameLib.API.Quaternion.FromObjectQuaternion(objectMesh.quaternion); } - if (objectMesh.scale) { - apiScale = GameLib.API.Vector3.FromObjectVector(objectMesh.scale); - } + var apiScale = new GameLib.API.Vector3(1,1,1); + if (objectMesh.scale) { + apiScale = GameLib.API.Vector3.FromObjectVector(objectMesh.scale); + } - if (objectMesh.localPosition) { - apiLocalPosition = GameLib.API.Vector3.FromObjectVector(objectMesh.localPosition); - } + var apiLocalPosition = new GameLib.API.Vector3(); + if (objectMesh.localPosition) { + apiLocalPosition = GameLib.API.Vector3.FromObjectVector(objectMesh.localPosition); + } - if (objectMesh.localRotation) { - apiLocalRotation = GameLib.API.Vector3.FromObjectVector(objectMesh.localRotation); - } + var apiLocalRotation = new GameLib.API.Vector3(); + if (objectMesh.localRotation) { + apiLocalRotation = GameLib.API.Vector3.FromObjectVector(objectMesh.localRotation); + } - if (objectMesh.localScale) { - apiLocalScale = GameLib.API.Vector3.FromObjectVector(objectMesh.localScale); - } + var apiLocalScale = new GameLib.API.Vector3(1,1,1); + if (objectMesh.localScale) { + apiLocalScale = GameLib.API.Vector3.FromObjectVector(objectMesh.localScale); + } - if (objectMesh.up) { - apiUp = GameLib.API.Vector3.FromObjectVector(objectMesh.up); - } + var apiUp = new GameLib.API.Vector3(0,1,0); + if (objectMesh.up) { + apiUp = GameLib.API.Vector3.FromObjectVector(objectMesh.up); + } - if (objectMesh.modelMatrix) { - apiModelMatrix = GameLib.API.Matrix4.FromObjectMatrix(objectMesh.modelMatrix); - } + var apiModelMatrix = new GameLib.API.Matrix4(); + if (objectMesh.modelMatrix) { + apiModelMatrix = GameLib.API.Matrix4.FromObjectMatrix(objectMesh.modelMatrix); + } return new GameLib.D3.API.Mesh( objectMesh.id, objectMesh.meshType, objectMesh.name, - objectMesh.vertices.map( - function (objectVertex) { - return GameLib.D3.API.Vertex.FromObjectVertex(objectVertex); - } - ), + apiVertices, objectMesh.faces, objectMesh.faceVertexUvs, - objectMesh.materials, + apiMaterials, objectMesh.parentMesh, objectMesh.parentScene, apiSkeleton, diff --git a/src/game-lib-d3-api-pass.js b/src/game-lib-d3-api-pass.js new file mode 100644 index 0000000..b50c50c --- /dev/null +++ b/src/game-lib-d3-api-pass.js @@ -0,0 +1,92 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param passType + * @param camera + * @param scene + * @param renderToScreen + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Pass = function ( + id, + name, + passType, + camera, + scene, + renderToScreen, + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_PASS, + { + 'camera' : GameLib.D3.Camera, + 'scene' : GameLib.D3.Scene + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Pass (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(passType)) { + passType = GameLib.D3.Pass.PASS_TYPE_RENDER; + } + this.passType = passType; + + if (GameLib.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + + if (GameLib.Utils.UndefinedOrNull(scene)) { + scene = null; + } + this.scene = scene; + + if (GameLib.Utils.UndefinedOrNull(renderToScreen)) { + + if (this.passType == GameLib.D3.Pass.PASS_TYPE_RENDER) { + renderToScreen = false; + } else if (GameLib.D3.Pass.PASS_TYPE_COPY_SHADER) { + renderToScreen = true; + } else { + console.warn('Unsupported Render Pass Type : ' + this.passType); + throw new Error('Unsupported Render Pass Type : ' + this.passType); + } + + } + this.renderToScreen = renderToScreen; + +}; + +GameLib.D3.API.Pass.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Pass.prototype.constructor = GameLib.D3.API.Pass; + +/** + * Object to GameLib.D3.API.Pass + * @param objectComponent + * @constructor + */ +GameLib.D3.API.Pass.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.Pass( + objectComponent.id, + objectComponent.name, + objectComponent.passType, + objectComponent.camera, + objectComponent.scene, + objectComponent.renderToScreen, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-path-following.js b/src/game-lib-d3-api-path-following.js index 8586a08..b733f20 100644 --- a/src/game-lib-d3-api-path-following.js +++ b/src/game-lib-d3-api-path-following.js @@ -51,7 +51,7 @@ GameLib.D3.API.PathFollowing = function ( GameLib.Component.call( this, - GameLib.Component.COMPONENT_TYPE_PATH_FOLLOWING, + GameLib.Component.COMPONENT_PATH_FOLLOWING, { 'spline': GameLib.D3.Spline, 'mesh' : GameLib.D3.Mesh, diff --git a/src/game-lib-d3-api-raycaster.js b/src/game-lib-d3-api-raycaster.js index 36d83c0..c4c429e 100644 --- a/src/game-lib-d3-api-raycaster.js +++ b/src/game-lib-d3-api-raycaster.js @@ -1,14 +1,28 @@ /** * Raycaster for GameLib.D3 + * @param id + * @param name * @param position GameLib.API.Vector3 * @param direction GameLib.API.Vector3 * @constructor */ GameLib.D3.API.Raycaster = function( + id, + name, position, direction ) { + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Raycaster (' + this.id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(position)) { position = new GameLib.API.Vector3(); } @@ -27,6 +41,8 @@ GameLib.D3.API.Raycaster = function( */ GameLib.D3.API.Raycaster.FromObjectRaycaster = function(objectRaycaster) { return new GameLib.D3.API.Raycaster( + objectRaycaster.id, + objectRaycaster.name, GameLib.API.Vector3.FromObjectVector(objectRaycaster.position), GameLib.API.Vector3.FromObjectVector(objectRaycaster.direction) ); diff --git a/src/game-lib-d3-api-render-target.js b/src/game-lib-d3-api-render-target.js new file mode 100644 index 0000000..3f201b7 --- /dev/null +++ b/src/game-lib-d3-api-render-target.js @@ -0,0 +1,106 @@ +/** + * This component renders a scene + * @param id String + * @param name String + * @param width + * @param height + * @param minFilter + * @param magFilter + * @param format + * @param stencilBuffer + * @param texture + * @param parentEntity + * @constructor + */ +GameLib.D3.API.RenderTarget = function ( + id, + name, + width, + height, + minFilter, + magFilter, + format, + stencilBuffer, + texture, + parentEntity +) { + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_RENDER_TARGET, + { + 'texture' : GameLib.D3.Texture + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Render Target (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(width)) { + width = 800; + } + this.width = width; + + if (GameLib.Utils.UndefinedOrNull(height)) { + height = 600; + } + this.height = height; + + if (GameLib.Utils.UndefinedOrNull(minFilter)) { + minFilter = GameLib.D3.RenderTarget.LINEAR_FILTER; + } + this.minFilter = minFilter; + + if (GameLib.Utils.UndefinedOrNull(magFilter)) { + magFilter = GameLib.D3.RenderTarget.LINEAR_FILTER; + } + this.magFilter = magFilter; + + if (GameLib.Utils.UndefinedOrNull(format)) { + format = GameLib.D3.RenderTarget.RGB_FORMAT; + } + this.format = format; + + if (GameLib.Utils.UndefinedOrNull(stencilBuffer)) { + stencilBuffer = false; + } + this.stencilBuffer = stencilBuffer; + + if (GameLib.Utils.UndefinedOrNull(texture)) { + texture = null; + } + this.texture = texture; + +}; + +GameLib.D3.API.RenderTarget.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.RenderTarget.prototype.constructor = GameLib.D3.API.RenderTarget; + +/** + * Object to GameLib.D3.API.RenderTarget + * @param objectComponent + * @constructor + */ +GameLib.D3.API.RenderTarget.FromObjectComponent = function(objectComponent) { + return new GameLib.D3.API.RenderTarget( + objectComponent.id, + objectComponent.name, + objectComponent.width, + objectComponent.height, + objectComponent.minFilter, + objectComponent.magFilter, + objectComponent.format, + objectComponent.stencilBuffer, + objectComponent.texture, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-renderer.js b/src/game-lib-d3-api-renderer.js index 2db8b41..a361f5f 100644 --- a/src/game-lib-d3-api-renderer.js +++ b/src/game-lib-d3-api-renderer.js @@ -2,34 +2,31 @@ * This component renders a scene * @param id String * @param name String - * @param scene GameLib.D3.Scene - * @param camera GameLib.D3.Camera + * @param rendererType * @param autoClear bool * @param localClipping * @param width * @param height * @param parentEntity + * @param preserveDrawingBuffer * @constructor */ GameLib.D3.API.Renderer = function ( id, name, - scene, - camera, + rendererType, autoClear, localClipping, width, height, - parentEntity + parentEntity, + preserveDrawingBuffer ) { GameLib.Component.call( this, GameLib.Component.COMPONENT_RENDERER, - { - 'scene' : GameLib.D3.Scene, - 'camera' : GameLib.D3.Camera - }, + null, null, parentEntity ); @@ -40,22 +37,25 @@ GameLib.D3.API.Renderer = function ( this.id = id; if (GameLib.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; + name = "Renderer (" + this.id + ")"; } this.name = name; - if (GameLib.Utils.UndefinedOrNull(scene)) { - scene = null; + if (GameLib.Utils.UndefinedOrNull(rendererType)) { + rendererType = GameLib.D3.Renderer.RENDER_TYPE_NORMAL; } - this.scene = scene; - - if (GameLib.Utils.UndefinedOrNull(camera)) { - camera = null; - } - this.camera = camera; + this.rendererType = rendererType; if (GameLib.Utils.UndefinedOrNull(autoClear)) { - autoClear = true; + + if (this.rendererType == GameLib.D3.Renderer.RENDER_TYPE_NORMAL) { + autoClear = true; + } else if (this.rendererType == GameLib.D3.Renderer.RENDER_TYPE_STEREO) { + autoClear = false; + } else { + console.warn('Unhandled render type : ' + this.rendererType); + throw new Error('Unhandled render type : ' + this.rendererType); + } } this.autoClear = autoClear; @@ -74,6 +74,18 @@ GameLib.D3.API.Renderer = function ( } this.height = height; + if (GameLib.Utils.UndefinedOrNull(preserveDrawingBuffer)) { + + if (this.rendererType == GameLib.D3.Renderer.RENDER_TYPE_NORMAL) { + preserveDrawingBuffer = false; + } else if (this.rendererType == GameLib.D3.Renderer.RENDER_TYPE_STEREO) { + preserveDrawingBuffer = true; + } else { + console.warn('Unhandled render type : ' + this.rendererType); + throw new Error('Unhandled render type : ' + this.rendererType); + } + } + this.preserveDrawingBuffer = preserveDrawingBuffer; }; GameLib.D3.API.Renderer.prototype = Object.create(GameLib.Component.prototype); @@ -88,12 +100,12 @@ GameLib.D3.API.Renderer.FromObjectComponent = function(objectComponent) { return new GameLib.D3.API.Renderer( objectComponent.id, objectComponent.name, - objectComponent.scene, - objectComponent.camera, + objectComponent.rendererType, objectComponent.autoClear, objectComponent.localClipping, objectComponent.width, objectComponent.height, - objectComponent.parentEntity + objectComponent.parentEntity, + objectComponent.preserveDrawingBuffer ); }; diff --git a/src/game-lib-d3-api-scene.js b/src/game-lib-d3-api-scene.js index 423cd8a..0963e22 100644 --- a/src/game-lib-d3-api-scene.js +++ b/src/game-lib-d3-api-scene.js @@ -1,52 +1,50 @@ /** * Raw Scene API object - should always correspond with the Scene Schema * @param id String - * @param path String * @param name String - * @param meshes GameLib.D3.API.Mesh [] + * @param meshes [GameLib.D3.API.Mesh] * @param position GameLib.API.Vector3 * @param quaternion GameLib.API.Quaternion * @param scale GameLib.API.Vector3 - * @param parentSceneId - * @param lights GameLib.D3.API.Light[] - * @param worlds GameLib.D3.API.World[] - * @param entityManager GameLib.EntityManager - * @param shapes GameLib.D3.API.Shape[] - * @param cameras - * @param activeCameraIndex - * @param textures GameLib.D3.Texture[] - additional textures + * @param parentGameId + * @param lights [GameLib.D3.API.Light] + * @param parentEntity * @constructor */ GameLib.D3.API.Scene = function( id, - path, name, meshes, position, quaternion, scale, - parentSceneId, + parentGameId, lights, - worlds, - entityManager, - shapes, - cameras, - activeCameraIndex, textures, - materials + materials, + parentEntity ) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_SCENE, + { + 'meshes' : [GameLib.D3.Mesh], + 'lights' : [GameLib.D3.Light], + 'textures' : [GameLib.D3.Texture], + 'materials' : [GameLib.D3.Material], + 'imageFactory' : GameLib.D3.ImageFactory + }, + false, + parentEntity + ); + if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } this.id = id; - if (GameLib.Utils.UndefinedOrNull(path)) { - path = null; - } - this.path = path; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'unnamed'; + name = 'Scene (' + this.id + ')'; } this.name = name; @@ -70,41 +68,16 @@ GameLib.D3.API.Scene = function( } this.scale = scale; - if (GameLib.Utils.UndefinedOrNull(parentSceneId)) { - parentSceneId = null; + if (GameLib.Utils.UndefinedOrNull(parentGameId)) { + parentGameId = null; } - this.parentSceneId = parentSceneId; + this.parentGameId = parentGameId; if (GameLib.Utils.UndefinedOrNull(lights)) { lights = []; } this.lights = lights; - if (GameLib.Utils.UndefinedOrNull(worlds)) { - worlds = []; - } - this.worlds = worlds; - - if (GameLib.Utils.UndefinedOrNull(entityManager)) { - entityManager = new GameLib.API.EntityManager(); - } - this.entityManager = entityManager; - - if (GameLib.Utils.UndefinedOrNull(shapes)) { - shapes = []; - } - this.shapes = shapes; - - if (GameLib.Utils.UndefinedOrNull(cameras)) { - cameras = []; - } - this.cameras = cameras; - - if (GameLib.Utils.UndefinedOrNull(activeCameraIndex)) { - activeCameraIndex = 0; - } - this.activeCameraIndex = activeCameraIndex; - if (GameLib.Utils.UndefinedOrNull(textures)) { textures = []; } @@ -114,8 +87,12 @@ GameLib.D3.API.Scene = function( materials = []; } this.materials = materials; + }; +GameLib.D3.API.Scene.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Scene.prototype.constructor = GameLib.D3.API.Scene; + /** * Returns an API scene from an Object scene * @param objectScene @@ -123,19 +100,29 @@ GameLib.D3.API.Scene = function( */ GameLib.D3.API.Scene.FromObjectScene = function(objectScene) { - var apiEntityManager = null; - var apiPosition = null; - var apiQuaternion = null; - var apiScale = null; - - var apiTextures = []; - var apiMaterials = []; var apiMeshes = []; var apiLights = []; - var apiCameras = []; + var apiTextures = []; + var apiMaterials = []; - if (objectScene.entityManager) { - apiEntityManager = GameLib.API.EntityManager.FromObjectEntityManager(objectScene.entityManager); + var apiPosition = new GameLib.API.Vector3(); + var apiQuaternion = new GameLib.API.Quaternion(); + var apiScale = new GameLib.API.Vector3(1,1,1); + + if (objectScene.meshes) { + apiMeshes = objectScene.meshes.map( + function(objectMesh) { + return GameLib.D3.API.Mesh.FromObjectMesh(objectMesh); + } + ) + } + + if (objectScene.lights) { + apiLights = objectScene.lights.map( + function(objectLight) { + return GameLib.D3.API.Light.FromObjectLight(objectLight); + } + ) } if (objectScene.textures) { @@ -154,30 +141,6 @@ GameLib.D3.API.Scene.FromObjectScene = function(objectScene) { ) } - if (objectScene.meshes) { - apiMeshes = objectScene.meshes.map( - function(objectMesh) { - return GameLib.D3.API.Mesh.FromObjectMesh(objectMesh); - } - ) - } - - if (objectScene.lights) { - apiLights = objectScene.lights.map( - function(objectLight) { - return GameLib.D3.API.Light.FromObjectLight(objectLight); - } - ) - } - - if (objectScene.cameras) { - apiCameras = objectScene.cameras.map( - function(objectCamera) { - return GameLib.D3.API.Camera.FromObjectCamera(objectCamera); - } - ) - } - if (objectScene.position) { apiPosition = GameLib.API.Vector3.FromObjectVector(objectScene.position); } @@ -192,21 +155,16 @@ GameLib.D3.API.Scene.FromObjectScene = function(objectScene) { return new GameLib.D3.API.Scene( objectScene.id, - objectScene.path, objectScene.name, apiMeshes, apiPosition, apiQuaternion, apiScale, - objectScene.parentSceneId, + objectScene.parentGameId, apiLights, - [], //TODO : implement worlds here - apiEntityManager, - [], //TODO : implement shapes here - apiCameras, - objectScene.activeCameraIndex, apiTextures, - apiMaterials + apiMaterials, + objectScene.parentEntity ); }; diff --git a/src/game-lib-d3-api-skeleton.js b/src/game-lib-d3-api-skeleton.js index 7ddcb12..00dde18 100644 --- a/src/game-lib-d3-api-skeleton.js +++ b/src/game-lib-d3-api-skeleton.js @@ -9,6 +9,7 @@ * @param boneTextureHeight Number * @param boneMatrices GameLib.API.Matrix4[] * @param boneTexture null (not implemented) + * @param parentEntity * @constructor */ GameLib.D3.API.Skeleton = function ( @@ -20,8 +21,24 @@ GameLib.D3.API.Skeleton = function ( boneTextureWidth, boneTextureHeight, boneMatrices, - boneTexture + boneTexture, + parentEntity ) { + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_SKELETON, + { + 'bones' : [GameLib.D3.Bone] + }, + false, + parentEntity + ); + if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } @@ -77,6 +94,9 @@ GameLib.D3.API.Skeleton = function ( this.boneTexture = boneTexture; }; +GameLib.D3.API.Skeleton.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Skeleton.prototype.constructor = GameLib.D3.API.Skeleton; + /** * Creates an API skeleton from an Object skeleton * @param objectSkeleton @@ -104,6 +124,7 @@ GameLib.D3.API.Skeleton.FromObjectSkeleton = function(objectSkeleton) { return GameLib.D3.API.Matrix4.FromObjectMatrix(boneMatrix); } ), - objectSkeleton.boneTexture + objectSkeleton.boneTexture, + objectSkeleton.parentEntity ); }; \ No newline at end of file diff --git a/src/game-lib-d3-api-texture.js b/src/game-lib-d3-api-texture.js index 2c1548c..a515942 100644 --- a/src/game-lib-d3-api-texture.js +++ b/src/game-lib-d3-api-texture.js @@ -21,6 +21,7 @@ * @param unpackAlignment * @param premultiplyAlpha * @param encoding + * @param parentEntity * @constructor */ GameLib.D3.API.Texture = function( @@ -44,8 +45,22 @@ GameLib.D3.API.Texture = function( mipmaps, unpackAlignment, premultiplyAlpha, - encoding + encoding, + parentEntity ) { + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_TEXTURE, + null, + null, + parentEntity + ); + if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } @@ -179,6 +194,7 @@ GameLib.D3.API.Texture.FromObjectTexture = function(objectTexture) { objectTexture.mipmaps, objectTexture.unpackAlignment, objectTexture.premultiplyAlpha, - objectTexture.encoding + objectTexture.encoding, + objectTexture.parentEntity ) }; diff --git a/src/game-lib-d3-api-viewport.js b/src/game-lib-d3-api-viewport.js new file mode 100644 index 0000000..b06b2c2 --- /dev/null +++ b/src/game-lib-d3-api-viewport.js @@ -0,0 +1,117 @@ +/** + * Raw Viewport API object - should always correspond with the Viewport Schema + * @param id + * @param name + * @param width + * @param height + * @param x + * @param y + * @param composer GameLib.D3.API.Composer + * @param renderer GameLib.D3.API.Renderer + * @param scene GameLib.D3.API.Scene + * @param camera GameLib.D3.API.Camera + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Viewport = function( + id, + name, + width, + height, + x, + y, + composer, + renderer, + scene, + camera, + parentEntity +) { + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_VIEWPORT, + { + 'composer' : GameLib.D3.Composer, + 'renderer' : GameLib.D3.Renderer, + 'scene' : GameLib.D3.Scene, + 'camera' : GameLib.D3.Camera + }, + null, + parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Viewport (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(width)) { + width = 800; + } + this.width = width; + + if (GameLib.Utils.UndefinedOrNull(height)) { + height = 600; + } + this.height = height; + + if (GameLib.Utils.UndefinedOrNull(x)) { + x = 0; + } + this.x = x; + + if (GameLib.Utils.UndefinedOrNull(y)) { + y = 0; + } + this.y = y; + + if (GameLib.Utils.UndefinedOrNull(composer)) { + composer = null; + } + this.composer = composer; + + if (GameLib.Utils.UndefinedOrNull(renderer)) { + renderer = null; + } + this.renderer = renderer; + + if (GameLib.Utils.UndefinedOrNull(scene)) { + scene = null; + } + this.scene = scene; + + if (GameLib.Utils.UndefinedOrNull(camera)) { + camera = null; + } + this.camera = camera; + +}; + +GameLib.D3.API.Viewport.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Viewport.prototype.constructor = GameLib.D3.API.Viewport; + +/** + * Creates an API Viewport from an Object Viewport + * @param objectViewport + * @constructor + */ +GameLib.D3.API.Viewport.FromObjectViewport = function(objectViewport) { + return new GameLib.D3.API.Viewport( + objectViewport.id, + objectViewport.name, + objectViewport.width, + objectViewport.height, + objectViewport.x, + objectViewport.y, + objectViewport.composer, + objectViewport.renderer, + objectViewport.scene, + objectViewport.camera, + objectViewport.parentEntity + ); +}; + diff --git a/src/game-lib-d3-bone-weight.js b/src/game-lib-d3-bone-weight.js index 0ed77bb..3378288 100644 --- a/src/game-lib-d3-bone-weight.js +++ b/src/game-lib-d3-bone-weight.js @@ -10,7 +10,11 @@ GameLib.D3.BoneWeight = function ( ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); - + + if (GameLib.Utils.UndefinedOrNull(apiBoneWeight)) { + apiBoneWeight = {}; + } + GameLib.D3.API.BoneWeight.call( this, apiBoneWeight.boneIndex, diff --git a/src/game-lib-d3-bone.js b/src/game-lib-d3-bone.js index a5c5076..7052063 100644 --- a/src/game-lib-d3-bone.js +++ b/src/game-lib-d3-bone.js @@ -10,7 +10,11 @@ GameLib.D3.Bone = function ( ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); - + + if (GameLib.Utils.UndefinedOrNull(apiBone)) { + apiBone = {}; + } + GameLib.D3.API.Bone.call( this, apiBone.id, @@ -25,26 +29,26 @@ GameLib.D3.Bone = function ( this.position = new GameLib.Vector3( graphics, - this, - this.position + this.position, + this ); this.quaternion = new GameLib.Quaternion( graphics, - this, - this.quaternion + this.quaternion, + this ); this.scale = new GameLib.Vector3( graphics, - this, - this.scale + this.scale, + this ); this.up = new GameLib.Vector3( graphics, - this, - this.up + this.up, + this ); this.instance = this.createInstance(); diff --git a/src/game-lib-d3-camera.js b/src/game-lib-d3-camera.js index 2c22c3a..87d759b 100644 --- a/src/game-lib-d3-camera.js +++ b/src/game-lib-d3-camera.js @@ -4,7 +4,7 @@ * @param apiCamera GameLib.D3.API.Camera * @constructor */ -GameLib.D3.Camera = function Camera( +GameLib.D3.Camera = function( graphics, apiCamera ) { @@ -12,6 +12,10 @@ GameLib.D3.Camera = function Camera( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiCamera)) { + apiCamera = {}; + } + GameLib.D3.API.Camera.call( this, apiCamera.id, @@ -30,26 +34,43 @@ GameLib.D3.Camera = function Camera( apiCamera.minZ, apiCamera.maxZ, apiCamera.quaternion, - apiCamera.parentEntity + apiCamera.parentEntity, + apiCamera.eyeSeparation, + apiCamera.focalLength ); - this.position = new GameLib.Vector3( - graphics, - this, - this.position - ); + if (this.position instanceof GameLib.API.Vector3) { + this.position = new GameLib.Vector3( + graphics, + this.position, + this + ); + } else { + console.warn('position not instance of API.Vector3'); + throw new Error('position not instance of API.Vector3'); + } - this.quaternion = new GameLib.Quaternion( - graphics, - this, - this.quaternion - ); + if (this.quaternion instanceof GameLib.API.Quaternion) { + this.quaternion = new GameLib.Quaternion( + graphics, + this.quaternion, + this + ); + } else { + console.warn('quaternion not instance of API.Quaternion'); + throw new Error('quaternion not instance of API.Quaternion'); + } - this.lookAt = new GameLib.Vector3( - graphics, - this, - this.lookAt - ); + if (this.lookAt instanceof GameLib.API.Vector3) { + this.lookAt = new GameLib.Vector3( + graphics, + this.lookAt, + this + ); + } else { + console.warn('lookAt not instance of API.Vector3'); + throw new Error('lookAt not instance of API.Vector3'); + } this.instance = this.createInstance(); @@ -59,13 +80,9 @@ GameLib.D3.Camera = function Camera( GameLib.D3.Camera.prototype = Object.create(GameLib.D3.API.Camera.prototype); GameLib.D3.Camera.prototype.constructor = GameLib.D3.Camera; -/** - * Camera types - * @type {number} - */ -GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE = 0x1; -GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL = 0x2; -GameLib.D3.Camera.CAMERA_TYPE_STEREO = 0x3; +GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE = 0x1; +GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL = 0x2; +GameLib.D3.Camera.CAMERA_TYPE_STEREO = 0x3; /** * Creates a camera instance of 'graphics' type (only THREE for now) @@ -80,15 +97,15 @@ GameLib.D3.Camera.prototype.createInstance = function(update) { } if (!instance) { - if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE) { - instance = new this.graphics.instance.PerspectiveCamera( + if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE ) { + instance = new THREE.PerspectiveCamera( this.fov, this.aspect, this.near, this.far ); } else if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) { - instance = new this.graphics.instance.OrthographicCamera( + instance = new THREE.OrthographicCamera( this.minX, this.maxX, this.minY, @@ -96,20 +113,42 @@ GameLib.D3.Camera.prototype.createInstance = function(update) { this.minZ, this.maxZ ); + } else if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_STEREO) { + instance = new THREE.StereoCamera(); } } if (update) { - instance.minX = this.minX; - instance.maxX = this.maxX; - instance.minY = this.minY; - instance.maxY = this.maxY; - instance.minZ = this.minZ; - instance.maxZ = this.maxZ; - instance.fov = this.fov; - instance.aspect = this.aspect; - instance.near = this.near; - instance.far = this.far; + + if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_ORTHOGONAL) { + instance.minX = this.minX; + instance.maxX = this.maxX; + instance.minY = this.minY; + instance.maxY = this.maxY; + instance.minZ = this.minZ; + instance.maxZ = this.maxZ; + } + + if ( + this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_PERSPECTIVE || + this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_STEREO + ) { + instance.fov = this.fov; + instance.aspect = this.aspect; + instance.near = this.near; + instance.far = this.far; + } + + if (this.cameraType == GameLib.D3.Camera.CAMERA_TYPE_STEREO) { + instance.eyeSeparation = this.eyeSeparation; + instance.focalLength = this.focalLength; + instance.update(instance); + } + } + + if (!instance) { + console.log('Unsupported camera type : ' + this.cameraType); + throw new Error('Unsupported camera type : ' + this.cameraType); } instance.position.x = this.position.x; @@ -121,9 +160,7 @@ GameLib.D3.Camera.prototype.createInstance = function(update) { instance.quaternion.z = this.quaternion.z; instance.quaternion.w = this.quaternion.w; - if (!update) { - instance.lookAt(this.lookAt.instance); - } + instance.lookAt(this.lookAt.instance); instance.updateProjectionMatrix(); @@ -160,7 +197,9 @@ GameLib.D3.Camera.prototype.toApiCamera = function() { this.minZ, this.maxZ, this.quaternion.toApiQuaternion(), - GameLib.Utils.IdOrNull(this.parentEntity) + GameLib.Utils.IdOrNull(this.parentEntity), + this.eyeSeparation, + this.focalLength ); }; diff --git a/src/game-lib-d3-coder.js b/src/game-lib-d3-coder.js new file mode 100644 index 0000000..e908934 --- /dev/null +++ b/src/game-lib-d3-coder.js @@ -0,0 +1,76 @@ +/** + * Coder + * @param id + * @param name + * @param coderType + * @constructor + */ +GameLib.D3.Coder = function Coder( + id, + name, + coderType +) { + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Coder (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(coderType)) { + coderType = GameLib.D3.Coder.CODER_TYPE_CODE_MIRROR; + } + this.coderType = coderType; + + this.instance = this.createInstance(); +}; + +/** + * GameLib.D3.Coder Types + * @type {number} + */ +GameLib.D3.Coder.CODER_TYPE_CODE_MIRROR = 0x1; + +/** + * @returns {THREE.Coder} + */ +GameLib.D3.Coder.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } else { + instance = CodeMirror; + } + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Coder.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * True if THREE physics + * @returns {boolean} + */ +GameLib.D3.Coder.prototype.isCodeMirror = function() { + return (this.coderType == GameLib.D3.Coder.CODER_TYPE_CODE_MIRROR) +}; + +/** + * Logs a warning and throws an error if not cannon + */ +GameLib.D3.Coder.prototype.isNotCodeMirrorThrow = function() { + if (this.coderType != GameLib.D3.Coder.CODER_TYPE_CODE_MIRROR) { + console.warn('Only CodeMirror supported for this function'); + throw new Error('Only CodeMirror supported for this function'); + } +}; diff --git a/src/game-lib-d3-composer.js b/src/game-lib-d3-composer.js new file mode 100644 index 0000000..9c54254 --- /dev/null +++ b/src/game-lib-d3-composer.js @@ -0,0 +1,117 @@ +/** + * Renders a scene with a camera + * @param graphics GameLib.D3.Graphics + * @param apiComposer GameLib.D3.API.Composer + * @constructor + */ +GameLib.D3.Composer = function ( + graphics, + apiComposer +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiComposer)) { + apiComposer = {}; + } + + GameLib.D3.API.Composer.call( + this, + apiComposer.id, + apiComposer.name, + apiComposer.renderer, + apiComposer.renderTarget, + apiComposer.passes, + apiComposer.parentEntity + ); + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.Composer.prototype = Object.create(GameLib.D3.API.Composer.prototype); +GameLib.D3.Composer.prototype.constructor = GameLib.D3.Composer; + +/** + * Creates a Composer instance + * @param update + * @returns {*} + */ +GameLib.D3.Composer.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + if (this.renderer && + this.renderTarget) { + + if (!THREE.EffectComposer) { + console.warn('No THREE.EffectComposer'); + throw new Error('No THREE.EffectComposer'); + } + + instance = new THREE.EffectComposer( + this.renderer.instance, + this.renderTarget.instance + ); + + this.passes.map( + function(pass) { + this.instance.addPass(pass.instance); + }.bind(this) + ); + } + + return instance; +}; + +/** + * Updates Composer instance + */ +GameLib.D3.Composer.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * GameLib.D3.Composer to GameLib.D3.API.Composer + * @returns {GameLib.D3.API.Composer} + */ +GameLib.D3.Composer.prototype.toApiComponent = function() { + + var apiComposer = new GameLib.D3.API.Composer( + this.id, + this.name, + GameLib.Utils.IdOrNull(this.renderer), + GameLib.Utils.IdOrNull(this.renderTarget), + this.passes.map( + function(pass) { + return GameLib.Utils.IdOrNull(pass); + } + ), + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiComposer; +}; + +/** + * + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.Composer} + * @constructor + */ +GameLib.D3.Composer.FromObjectComponent = function(graphics, objectComponent) { + + var apiComposer = GameLib.D3.API.Composer.FromObjectComponent(objectComponent); + + return new GameLib.D3.Composer( + graphics, + apiComposer + ); +}; diff --git a/src/game-lib-d3-custom-code.js b/src/game-lib-d3-custom-code.js new file mode 100644 index 0000000..c4bf130 --- /dev/null +++ b/src/game-lib-d3-custom-code.js @@ -0,0 +1,100 @@ +/** + * Creates a CustomCode object + * @param apiCustomCode GameLib.D3.API.CustomCode + * @constructor + */ +GameLib.D3.CustomCode = function( + apiCustomCode +) { + + if (GameLib.Utils.UndefinedOrNull(apiCustomCode)) { + apiCustomCode = {}; + } + + GameLib.D3.API.CustomCode.call( + this, + apiCustomCode.id, + apiCustomCode.name, + apiCustomCode.code, + apiCustomCode.domElementId, + apiCustomCode.parentEntity, + apiCustomCode.args + ); + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.CustomCode.prototype = Object.create(GameLib.D3.API.CustomCode.prototype); +GameLib.D3.CustomCode.prototype.constructor = GameLib.D3.CustomCode; + +/** + * Creates a camera instance of 'graphics' type (only THREE for now) + * @returns {THREE.CustomCode} + */ +GameLib.D3.CustomCode.prototype.createInstance = function(update) { + + var instance = function(deltaTime) { + this.args['deltaTime'] = deltaTime; + var f = new Function(this.code).apply(this.parentEntity, this.args); + f(); + }; + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.CustomCode.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * Converts a GameLib.D3.CustomCode to a new GameLib.D3.API.CustomCode + * @returns {GameLib.D3.API.CustomCode} + */ +GameLib.D3.CustomCode.prototype.toApiCustomCode = function() { + + var apiArgs = []; + + if (this.args) { + apiArgs = this.args.map( + function(arg) { + return GameLib.Utils.IdOrNull(arg); + } + ) + } + + return new GameLib.D3.API.CustomCode( + this.id, + this.name, + this.code, + this.domElementId, + GameLib.Utils.IdOrNull(this.parentEntity), + apiArgs + ); + +}; + +/** + * Converts from an Object CustomCode to a GameLib.D3.CustomCode + * @param objectCustomCode Object + * @returns {GameLib.D3.CustomCode} + * @constructor + */ +GameLib.D3.CustomCode.FromObjectCustomCode = function(objectCustomCode) { + + var apiCustomCode = GameLib.D3.API.CustomCode.FromObjectCustomCode(objectCustomCode); + + return new GameLib.D3.CustomCode( + apiCustomCode + ); + +}; + + +GameLib.D3.CustomCode.prototype.update = function(deltaTime) { + this.instance(deltaTime); +}; \ No newline at end of file diff --git a/src/game-lib-d3-editor.js b/src/game-lib-d3-editor.js new file mode 100644 index 0000000..7609f2f --- /dev/null +++ b/src/game-lib-d3-editor.js @@ -0,0 +1,440 @@ +/** + * Creates a Editor object + * @param graphics GameLib.D3.Graphics + * @param apiEditor GameLib.D3.API.Editor + * @param onSelectionChanged + * @param onSelectObject + * @param onDeSelectObject + * @constructor + */ +GameLib.D3.Editor = function( + graphics, + apiEditor, + onSelectionChanged, + onSelectObject, + onDeSelectObject +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiEditor)) { + apiEditor = {}; + } + + GameLib.D3.API.Editor.call( + this, + apiEditor.id, + apiEditor.name, + apiEditor.baseUrl, + apiEditor.path, + apiEditor.games, + apiEditor.scenes, + apiEditor.cameras, + apiEditor.composers, + apiEditor.viewports, + apiEditor.renderers, + apiEditor.renderTargets, + apiEditor.systems, + apiEditor.entityManager, + apiEditor.allSelected, + apiEditor.selectedObjects, + apiEditor.parentEntity + ); + + this.imageFactory = new GameLib.D3.ImageFactory( + this.graphics, + this.baseUrl + this.path + ); + + if (this.games) { + this.games = this.games.map( + function (apiGame) { + if (apiGame instanceof GameLib.D3.API.Game) { + return new GameLib.D3.Game( + this.graphics, + apiGame + ) + } + else { + console.warn('game not of type API.Game'); + throw new Error('game not of type API.Game'); + } + }.bind(this) + ) + } + + this.scenes = this.scenes.map( + function (apiScene) { + if (apiScene instanceof GameLib.D3.API.Scene) { + return new GameLib.D3.Scene( + this.graphics, + apiScene, + this.imageFactory, + true + ) + } else { + console.warn('apiScene not of type API.Scene'); + throw new Error('apiScene not of type API.Scene'); + } + }.bind(this) + ); + + this.cameras = this.cameras.map( + function (apiCamera) { + if (apiCamera instanceof GameLib.D3.API.Camera) { + return new GameLib.D3.Camera( + this.graphics, + apiCamera + ) + } else { + console.warn('apiCamera not of type API.Camera'); + throw new Error('apiCamera not of type API.Camera'); + } + }.bind(this) + ); + + this.composers = this.composers.map( + function (apiComposer) { + if (apiComposer instanceof GameLib.D3.API.Composer) { + return new GameLib.D3.Composer( + this.graphics, + apiComposer + ) + } else { + console.warn('apiComposer not of type API.Composer'); + throw new Error('apiComposer not of type API.Composer'); + } + }.bind(this) + ); + + this.viewports = this.viewports.map( + function (apiViewport) { + if (apiViewport instanceof GameLib.D3.API.Viewport) { + return GameLib.D3.Viewport( + this.graphics, + apiViewport + ) + } else { + console.warn('apiViewport not of type API.Viewport'); + throw new Error('apiViewport not of type API.Viewport'); + } + }.bind(this) + ); + + this.renderers = this.renderers.map( + function (apiRenderer) { + if (apiRenderer instanceof GameLib.D3.API.Renderer) { + return GameLib.D3.Renderer( + this.graphics, + apiRenderer + ) + } else { + console.warn('apiRenderer not of type API.Renderer'); + throw new Error('apiRenderer not of type API.Renderer'); + } + }.bind(this) + ); + + this.renderTargets = this.renderTargets.map( + function (apiRenderTarget) { + if (apiRenderTarget instanceof GameLib.D3.API.RenderTarget) { + return GameLib.D3.RenderTarget( + this.graphics, + apiRenderTarget + ) + } else { + console.warn('apiRenderTarget not of type API.RenderTarget'); + throw new Error('apiRenderTarget not of type API.RenderTarget'); + } + }.bind(this) + ); + + this.systems = this.systems.map( + function (apiSystem) { + if (apiSystem instanceof GameLib.D3.API.System) { + return GameLib.D3.System( + this.graphics, + apiSystem + ) + } else { + console.warn('apiSystem not of type API.System'); + throw new Error('apiSystem not of type API.System'); + } + }.bind(this) + ); + + if (this.entityManager) { + if (this.entityManager instanceof GameLib.API.EntityManager) { + this.entityManager = new GameLib.EntityManager( + this.graphics, + this.entityManager + ); + } else { + console.warn('entityManager not of type API.EntityManager'); + throw new Error('entityManager not of type API.EntityManager'); + } + } + + if (GameLib.Utils.UndefinedOrNull(onSelectionChanged)) { + onSelectionChanged = null; + } + this.onSelectionChanged = onSelectionChanged; + + if (GameLib.Utils.UndefinedOrNull(onSelectObject)) { + onSelectObject = null; + } + this.onSelectObject = onSelectObject; + + if (GameLib.Utils.UndefinedOrNull(onDeSelectObject)) { + onDeSelectObject = null; + } + this.onDeSelectObject = onDeSelectObject; + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.Editor.prototype = Object.create(GameLib.D3.API.Editor.prototype); +GameLib.D3.Editor.prototype.constructor = GameLib.D3.Editor; + +/** + * Creates a camera instance of 'graphics' type (only THREE for now) + * @returns {THREE.Editor} + */ +GameLib.D3.Editor.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Editor.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * Converts a GameLib.D3.Editor to a new GameLib.D3.API.Editor + * @returns {GameLib.D3.API.Editor} + */ +GameLib.D3.Editor.prototype.toApiEditor = function() { + + var apiGames = []; + var apiScenes = []; + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + var apiEntityManager = null; + + if (this.games) { + apiGames = this.games.map( + function(game) { + if (game instanceof GameLib.D3.Game) { + return game.toApiGame(); + } else { + console.warn('game not an instance of Game'); + throw new Error('game not an instance of Game'); + } + } + ); + } + + if (this.scenes) { + apiScenes = this.scenes.map( + function(scene) { + if (scene instanceof GameLib.D3.Scene) { + return scene.toApiScene(); + } else { + console.warn('scene not an instance of Scene'); + throw new Error('scene not an instance of Scene'); + } + } + ); + } + + if (this.cameras) { + apiCameras = this.cameras.map( + function(camera) { + if (camera instanceof GameLib.D3.Camera) { + return camera.toApiCamera(); + } else { + console.warn('camera not an instance of Camera'); + throw new Error('camera not an instance of Camera'); + } + } + ); + } + + if (this.composers) { + apiComposers = this.composers.map( + function(composer) { + if (composer instanceof GameLib.D3.Composer) { + return composer.toApiComponent(); + } else { + console.warn('composer not an instance of Composer'); + throw new Error('composer not an instance of Composer'); + } + } + ); + } + + if (this.viewports) { + apiViewports = this.viewports.map( + function(viewport) { + if (viewport instanceof GameLib.D3.Viewport) { + return viewport.toApiComponent(); + } else { + console.warn('viewport not an instance of Viewport'); + throw new Error('viewport not an instance of Viewport'); + } + } + ); + } + + if (this.renderers) { + apiRenderers = this.renderers.map( + function(renderer) { + if (renderer instanceof GameLib.D3.Renderer) { + return renderer.toApiComponent(); + } else { + console.warn('renderer not an instance of Renderer'); + throw new Error('renderer not an instance of Renderer'); + } + } + ); + } + + if (this.renderTargets) { + apiRenderTargets = this.renderTargets.map( + function(renderTarget) { + if (renderTarget instanceof GameLib.D3.RenderTarget) { + return renderTarget.toApiComponent(); + } else { + console.warn('renderTarget not an instance of RenderTarget'); + throw new Error('renderTarget not an instance of RenderTarget'); + } + } + ); + } + + if (this.systems) { + apiSystems = this.systems.map( + function(system) { + if (system instanceof GameLib.System) { + return system.toApiComponent(); + } else { + console.warn('system not an instance of System'); + throw new Error('system not an instance of System'); + } + } + ); + } + + if (this.entityManager) { + if (this.entityManager instanceof GameLib.EntityManager) { + apiEntityManager = this.entityManager.toApiEntityManager(); + } else { + console.warn('entityManager not an instance of EntityManager'); + throw new Error('entityManager not an instance of EntityManager'); + } + } + + return new GameLib.D3.API.Editor( + this.id, + this.name, + this.baseUrl, + this.path, + apiGames, + apiScenes, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + this.allSelected, + this.selectedObjects, + GameLib.Utils.IdOrNull(this.parentEntity) + ); + +}; + +/** + * Converts from an Object Editor to a GameLib.D3.Editor + * @param graphics GameLib.D3.Graphics + * @param objectEditor Object + * @returns {GameLib.D3.Editor} + * @constructor + */ +GameLib.D3.Editor.FromObjectEditor = function(graphics, objectEditor) { + + var apiEditor = GameLib.D3.API.Editor.FromObjectEditor(objectEditor); + + return new GameLib.D3.Editor( + graphics, + apiEditor + ); + +}; + +/** + * Selects a GameLib Object + * @param object GameLib.* + */ +GameLib.D3.Editor.prototype.selectObject = function(object) { + + this.selectedObjects.push( + new GameLib.D3.SelectedObject( + this.graphics, + object + ) + ); + + if (this.onSelectObject) { + this.onSelectObject(); + } + +}; + +/** + * Selects a GameLib Object + * @param object GameLib.* + */ +GameLib.D3.Editor.prototype.deSelectObject = function(object) { + + var results = this.selectedObjects.reduce( + function(results, selectedObject) { + + if (selectedObject.object.id == object.id) { + results.removed = selectedObject; + } else { + results.rest.push(selectedObject); + } + + return results; + }, + { + removed : null, + rest : [] + } + ); + + this.selectedObjects = results.rest; + + if (this.onDeSelectObject) { + this.onDeSelectObject(results); + } + +}; diff --git a/src/game-lib-d3-follow.js b/src/game-lib-d3-follow.js index 2af3080..f2d9b00 100644 --- a/src/game-lib-d3-follow.js +++ b/src/game-lib-d3-follow.js @@ -11,6 +11,10 @@ GameLib.D3.Follow = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiFollow)) { + apiFollow = {}; + } + GameLib.D3.API.Follow.call( this, apiFollow.id, @@ -25,33 +29,36 @@ GameLib.D3.Follow = function ( this.targetPositionOffset = new GameLib.Vector3( this.graphics, - this, - this.targetPositionOffset + this.targetPositionOffset, + this ); this.target = new GameLib.Vector3( this.graphics, - this, - this.target + this.target, + this ); this.targetToParent = new GameLib.Vector3( this.graphics, - this, - this.targetToParent + this.targetToParent, + this ); this.rotatedTargetOffset = new GameLib.Vector3( this.graphics, - this, - this.rotatedTargetOffset + this.rotatedTargetOffset, + this ); this.rotated = new GameLib.Quaternion( this.graphics, - this, - this.rotated + this.rotated, + this ); + + this.buildIdToObject(); + }; GameLib.D3.Follow.prototype = Object.create(GameLib.D3.API.Follow.prototype); diff --git a/src/game-lib-d3-game.js b/src/game-lib-d3-game.js new file mode 100644 index 0000000..0232c17 --- /dev/null +++ b/src/game-lib-d3-game.js @@ -0,0 +1,441 @@ +/** + * Game Runtime + * @param graphics GameLib.D3.Graphics + * @param apiGame GameLib.D3.API.Game + * @param imageFactory GameLib.D3.ImageFactory + * @constructor + */ +GameLib.D3.Game = function ( + graphics, + apiGame, + imageFactory +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiGame)) { + apiGame = {}; + } + + GameLib.D3.API.Game.call( + this, + apiGame.id, + apiGame.name, + apiGame.baseUrl, + apiGame.path, + apiGame.gameType, + apiGame.width, + apiGame.height, + apiGame.cameras, + apiGame.composers, + apiGame.viewports, + apiGame.renderers, + apiGame.renderTargets, + apiGame.systems, + apiGame.entityManager, + apiGame.mouse, + apiGame.parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(imageFactory)) { + imageFactory = GameLib.D3.ImageFactory( + this.graphics, + this.baseUrl + this.path + ); + } + this.imageFactory = imageFactory; + + this.cameras = this.cameras.map( + function (apiCamera) { + if (apiCamera instanceof GameLib.D3.API.Camera) { + return new GameLib.D3.Camera( + this.graphics, + apiCamera + ) + } else { + console.warn('apiCamera not of type API.Camera'); + throw new Error('apiCamera not of type API.Camera'); + } + }.bind(this) + ); + + this.composers = this.composers.map( + function (apiComposer) { + if (apiComposer instanceof GameLib.D3.API.Composer) { + return new GameLib.D3.Composer( + this.graphics, + apiComposer + ) + } else { + console.warn('apiComposer not of type API.Composer'); + throw new Error('apiComposer not of type API.Composer'); + } + }.bind(this) + ); + + this.viewports = this.viewports.map( + function (apiViewport) { + if (apiViewport instanceof GameLib.D3.API.Viewport) { + return GameLib.D3.Viewport( + this.graphics, + apiViewport + ) + } else { + console.warn('apiViewport not of type API.Viewport'); + throw new Error('apiViewport not of type API.Viewport'); + } + }.bind(this) + ); + + this.renderers = this.renderers.map( + function (apiRenderer) { + if (apiRenderer instanceof GameLib.D3.API.Renderer) { + return GameLib.D3.Renderer( + this.graphics, + apiRenderer + ) + } else { + console.warn('apiRenderer not of type API.Renderer'); + throw new Error('apiRenderer not of type API.Renderer'); + } + }.bind(this) + ); + + this.renderTargets = this.renderTargets.map( + function (apiRenderTarget) { + if (apiRenderTarget instanceof GameLib.D3.API.RenderTarget) { + return GameLib.D3.RenderTarget( + this.graphics, + apiRenderTarget + ) + } else { + console.warn('apiRenderTarget not of type API.RenderTarget'); + throw new Error('apiRenderTarget not of type API.RenderTarget'); + } + }.bind(this) + ); + + this.systems = this.systems.map( + function (apiSystem) { + if (apiSystem instanceof GameLib.D3.API.System) { + return GameLib.D3.System( + this.graphics, + apiSystem + ) + } else { + console.warn('apiSystem not of type API.System'); + throw new Error('apiSystem not of type API.System'); + } + }.bind(this) + ); + + if (this.entityManager) { + if (this.entityManager instanceof GameLib.API.EntityManager) { + this.entityManager = new GameLib.EntityManager( + this.graphics, + this.entityManager + ); + } else { + console.warn('entityManager not of type API.EntityManager'); + throw new Error('entityManager not of type API.EntityManager'); + } + } + + if (this.mouse instanceof GameLib.API.Mouse) { + this.mouse = new GameLib.Mouse( + this.graphics, + this.mouse + ); + } else { + console.warn('mouse not of type API.Mouse'); + throw new Error('mouse not of type API.Mouse'); + } + + this.buildIdToObject(); + + this.entityManager.linkObjects(this.idToObject); +}; + +GameLib.D3.Game.prototype = Object.create(GameLib.D3.API.Game.prototype); +GameLib.D3.Game.prototype.constructor = GameLib.D3.Game; + +GameLib.D3.Game.GAME_TYPE_VR_PONG = 0x1; +GameLib.D3.Game.GAME_TYPE_VR_RACER = 0x2; + +/** + * Creates a camera instance of 'graphics' type (only THREE for now) + * @returns {THREE.Game} + */ +GameLib.D3.Game.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + return instance; +}; + +// GameLib.D3.Game.prototype.setSize = function(width, height) { +// +// // var w = 0; +// // var h = 0; +// +// this.viewports.map( +// function(viewport) { +// // w = viewport.width; +// // h = viewport.height; +// // +// // //TODO : calculate width and height decrease or increase ratio and adjust viewport x and y offset according +// // var wx = width / w; +// // var hx = height / h; +// +// viewport.width = width; +// viewport.height = height; +// +// viewport.updateInstance(); +// } +// ) +// +// }; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Game.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * Converts a GameLib.D3.Game to a new GameLib.D3.API.Game + * @returns {GameLib.D3.API.Game} + */ +GameLib.D3.Game.prototype.toApiGame = function() { + + var apiCameras = []; + var apiComposers = []; + var apiViewports = []; + var apiRenderers = []; + var apiRenderTargets = []; + var apiSystems = []; + var apiEntityManager = null; + var apiMouse = null; + + if (this.cameras) { + apiCameras = this.cameras.map( + function(camera) { + if (camera instanceof GameLib.D3.Camera) { + return camera.toApiCamera(); + } else { + console.warn('camera not an instance of Camera'); + throw new Error('camera not an instance of Camera'); + } + } + ); + } + + if (this.composers) { + apiComposers = this.composers.map( + function(composer) { + if (composer instanceof GameLib.D3.Composer) { + return composer.toApiComponent(); + } else { + console.warn('composer not an instance of Composer'); + throw new Error('composer not an instance of Composer'); + } + } + ); + } + + if (this.viewports) { + apiViewports = this.viewports.map( + function(viewport) { + if (viewport instanceof GameLib.D3.Viewport) { + return viewport.toApiComponent(); + } else { + console.warn('viewport not an instance of Viewport'); + throw new Error('viewport not an instance of Viewport'); + } + } + ); + } + + if (this.renderers) { + apiRenderers = this.renderers.map( + function(renderer) { + if (renderer instanceof GameLib.D3.Renderer) { + return renderer.toApiComponent(); + } else { + console.warn('renderer not an instance of Renderer'); + throw new Error('renderer not an instance of Renderer'); + } + } + ); + } + + if (this.renderTargets) { + apiRenderTargets = this.renderTargets.map( + function(renderTarget) { + if (renderTarget instanceof GameLib.D3.RenderTarget) { + return renderTarget.toApiComponent(); + } else { + console.warn('renderTarget not an instance of RenderTarget'); + throw new Error('renderTarget not an instance of RenderTarget'); + } + } + ); + } + + if (this.systems) { + apiSystems = this.systems.map( + function(system) { + if (system instanceof GameLib.System) { + return system.toApiComponent(); + } else { + console.warn('system not an instance of System'); + throw new Error('system not an instance of System'); + } + } + ); + } + + if (this.entityManager) { + if (this.entityManager instanceof GameLib.EntityManager) { + apiEntityManager = this.entityManager.toApiEntityManager(); + } else { + console.warn('entityManager not an instance of EntityManager'); + throw new Error('entityManager not an instance of EntityManager'); + } + } + + if (this.mouse) { + if (this.mouse instanceof GameLib.Mouse) { + apiMouse = this.mouse.toApiMouse(); + } else { + console.warn('Mouse not an instance of Mouse'); + throw new Error('Mouse not an instance of Mouse'); + } + } + + return new GameLib.D3.API.Game( + this.id, + this.name, + this.baseUrl, + this.path, + this.gameType, + this.width, + this.height, + apiCameras, + apiComposers, + apiViewports, + apiRenderers, + apiRenderTargets, + apiSystems, + apiEntityManager, + apiMouse, + GameLib.Utils.IdOrNull(this.parentEntity) + ); +}; + +/** + * Converts from an Object Game to a GameLib.D3.Game + * @param graphics GameLib.D3.Graphics + * @param objectGame Object + * @returns {GameLib.D3.Game} + * @constructor + */ +GameLib.D3.Game.FromObjectGame = function(graphics, objectGame) { + + var apiGame = GameLib.D3.API.Game.FromObjectGame(objectGame); + + return new GameLib.D3.Game( + graphics, + apiGame + ); + +}; + +/** + * Loads a Game + * @param graphics + * @param objectGame + * @param onLoaded + * @constructor + */ +GameLib.D3.Game.LoadGame = function( + graphics, + objectGame, + onLoaded +) { + var game = GameLib.D3.Game.FromObjectGame( + graphics, + objectGame + ); + + onLoaded(game); +}; + +/** + * Loads a Game from the API + * @param graphics GameLib.D3.Graphics + * @param partialGameObject Object + * @param onLoaded callback + * @param apiUrl + * @returns {*} + * @constructor + */ +GameLib.D3.Game.LoadGameFromApi = function( + graphics, + partialGameObject, + onLoaded, + apiUrl +) { + + /** + * 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 + '/game/load' + partialGameObject.path + '/' + partialGameObject.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 game : ' + e.message)); + } + + if (!response.game || response.game.length == 0) { + return onLoaded(null, new Error('Could not load game')); + } + + var objectGame = response.game[0]; + + GameLib.D3.Game.LoadGame( + graphics, + objectGame, + onLoaded + ); + } + } + }(xhr); + + xhr.send(); +}; diff --git a/src/game-lib-d3-graphics.js b/src/game-lib-d3-graphics.js index 578a410..f884712 100644 --- a/src/game-lib-d3-graphics.js +++ b/src/game-lib-d3-graphics.js @@ -1,15 +1,60 @@ /** - * Graphics Superset + * Graphics + * @param id + * @param name * @param graphicsType - * @param instance {THREE} * @constructor */ GameLib.D3.Graphics = function Graphics( - graphicsType, - instance + id, + name, + graphicsType ) { + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Graphics (' + id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(graphicsType)) { + graphicsType = GameLib.D3.Graphics.GRAPHICS_TYPE_THREE; + } this.graphicsType = graphicsType; - this.instance = instance; + + this.instance = this.createInstance(); +}; + +/** + * GameLib.D3.Graphics Types + * @type {number} + */ +GameLib.D3.Graphics.GRAPHICS_TYPE_THREE = 0x1; + +/** + * @returns {THREE.Graphics} + */ +GameLib.D3.Graphics.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } else { + instance = THREE; + } + + return instance; +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Graphics.prototype.updateInstance = function() { + this.instance = this.createInstance(true); }; /** @@ -29,9 +74,3 @@ GameLib.D3.Graphics.prototype.isNotThreeThrow = function() { throw new Error('Only THREE supported for this function'); } }; - -/** - * Physics GameLib.D3.Graphics Types - * @type {number} - */ -GameLib.D3.Graphics.GRAPHICS_TYPE_THREE = 0x1; \ No newline at end of file diff --git a/src/game-lib-d3-helper.js b/src/game-lib-d3-helper.js index 578386a..3357d8f 100644 --- a/src/game-lib-d3-helper.js +++ b/src/game-lib-d3-helper.js @@ -1,42 +1,69 @@ /** * Helpers for displaying outlines or making 'invisible' scene objects visible + * @param graphics GameLib.D3.Graphics * @param id - * @param object GameLib.D3.Object * @param name - * @param graphics + * @param object * @param helperType * @constructor */ GameLib.D3.Helper = function Helper( + graphics, id, - object, - helperType, name, - graphics + object, + helperType ) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(id)) { id = GameLib.Utils.RandomId(); } this.id = id; + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Helper (' + id + ')'; + } + this.name = name; + if (GameLib.Utils.UndefinedOrNull(object)) { - throw new Error('Cannot create helpers for unknown objects'); + console.warn('Cannot create a helper for an Object which does not exist'); + throw new Error('Cannot create a helper for an Object which does not exist'); } this.object = object; if (GameLib.Utils.UndefinedOrNull(helperType)) { - helperType = GameLib.D3.Helper.HELPER_TYPE_EDGES; + + helperType = GameLib.D3.Helper.HELPER_TYPE_NONE; + + if ( + object instanceof GameLib.D3.Mesh && + object.meshType != GameLib.D3.Mesh.TYPE_CURVE + ) { + helperType = GameLib.D3.Helper.HELPER_TYPE_WIREFRAME; + } + + if (object instanceof GameLib.D3.Light) { + 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) { + helperType = GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT; + } + + if (object.lightType == GameLib.D3.Light.LIGHT_TYPE_SPOT) { + helperType = GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT; + } + } + + if (object instanceof GameLib.D3.Skeleton) { + helperType = GameLib.D3.Helper.HELPER_TYPE_SKELETON; + } } this.helperType = helperType; - if (GameLib.Utils.UndefinedOrNull(name)) { - name = 'Helper (' + this.helperType + ')'; - } - this.name = name; - - this.graphics = graphics; - this.graphics.isNotThreeThrow(); - this.instance = this.createInstance(); }; @@ -44,13 +71,13 @@ GameLib.D3.Helper = function Helper( * Helper types * @type {string} */ -GameLib.D3.Helper.HELPER_TYPE_EDGES = 'edges'; -GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT = 'directional-light'; -GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT = 'spot-light'; -GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT = 'point-light'; -GameLib.D3.Helper.HELPER_TYPE_WIREFRAME = 'wireframe'; -GameLib.D3.Helper.HELPER_TYPE_SKELETON = 'skeleton'; - +GameLib.D3.Helper.HELPER_TYPE_NONE = 0x0; +GameLib.D3.Helper.HELPER_TYPE_EDGES = 0x1; +GameLib.D3.Helper.HELPER_TYPE_DIRECTIONAL_LIGHT = 0x2; +GameLib.D3.Helper.HELPER_TYPE_SPOT_LIGHT = 0x3; +GameLib.D3.Helper.HELPER_TYPE_POINT_LIGHT = 0x4; +GameLib.D3.Helper.HELPER_TYPE_WIREFRAME = 0x5; +GameLib.D3.Helper.HELPER_TYPE_SKELETON = 0x6; /** * Creates a helper instance @@ -60,6 +87,10 @@ GameLib.D3.Helper.prototype.createInstance = function(update) { var instance = null; + if (update) { + instance = this.instance; + } + if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_EDGES) { instance = new THREE.WireframeHelper(this.object.instance, 0x007700); } @@ -77,20 +108,19 @@ GameLib.D3.Helper.prototype.createInstance = function(update) { } if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_WIREFRAME) { - instance = new THREE.WireframeHelper(this.object.instance, 0x007700); + instance = new THREE.WireframeGeometry(this.object.instance, 0x007700); } if (this.helperType == GameLib.D3.Helper.HELPER_TYPE_SKELETON) { - instance = new THREE.SkeletonHelper(this.object.skeleton.instance); - } - - if (!instance) { - throw new Error('Unsupported helper type: ' + this.helperType); - } - - if (update) { - this.instance = instance; + instance = new THREE.SkeletonHelper(this.object.instance); } return instance; }; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Helper.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; diff --git a/src/game-lib-d3-input-drive.js b/src/game-lib-d3-input-drive.js index b9492ef..87bfb96 100644 --- a/src/game-lib-d3-input-drive.js +++ b/src/game-lib-d3-input-drive.js @@ -1,18 +1,23 @@ /** * Input parent class * @param graphics GameLib.D3.Graphics - * @param parentObject * @param apiInputDrive GameLib.D3.API.Input.Drive + * @param dom GameLib.Dom * @constructor */ GameLib.D3.Input.Drive = function ( graphics, - apiInputDrive + apiInputDrive, + dom ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiInputDrive)) { + apiInputDrive = {}; + } + GameLib.D3.API.Input.Drive.call( this, apiInputDrive.id, @@ -30,10 +35,18 @@ GameLib.D3.Input.Drive = function ( apiInputDrive.rotationFactor ); + if (GameLib.Utils.UndefinedOrNull(dom)) { + console.warn('Cannot create Input without an handle to the DOM'); + throw new Error('Cannot create Input without an handle to the DOM'); + } + this.dom = dom; + this.keyLeft = false; this.keyRight = false; + this.buildIdToObject(); + this.instance = this.createInstance(); }; @@ -46,7 +59,7 @@ GameLib.D3.Input.Drive.prototype.createInstance = function(update) { return this.instance; } - var instance = document.getElementById(this.domElementId); + var instance = this.dom.document.getElementById(this.domElementId); instance.addEventListener( 'keydown', diff --git a/src/game-lib-d3-input-editor.js b/src/game-lib-d3-input-editor.js new file mode 100644 index 0000000..5e3a7e9 --- /dev/null +++ b/src/game-lib-d3-input-editor.js @@ -0,0 +1,474 @@ +/** + * Input parent class + * @param graphics GameLib.D3.Graphics + * @param apiInputEditor GameLib.D3.API.Input.Editor + * @param dom GameLib.DOM + * @constructor + */ +GameLib.D3.Input.Editor = function ( + graphics, + apiInputEditor, + dom +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiInputEditor)) { + apiInputEditor = {}; + } + + GameLib.D3.API.Input.Editor.call( + this, + apiInputEditor.id, + apiInputEditor.name, + apiInputEditor.domElementId, + apiInputEditor.domContainerId, + apiInputEditor.editor, + apiInputEditor.camera, + apiInputEditor.widthOffset, + apiInputEditor.heightOffset, + apiInputEditor.containerWidthOffset, + apiInputEditor.containerHeightOffset, + apiInputEditor.selectDelayMs, + apiInputEditor.parentEntity + ); + + if (GameLib.Utils.UndefinedOrNull(dom)) { + console.warn('Cannot create Input without an handle to the DOM'); + throw new Error('Cannot create Input without an handle to the DOM'); + } + this.dom = dom; + + this.element = null; + this.container = null; + + this.meshMoveMode = false; + this.meshMoveXMode = false; + this.meshMoveYMode = false; + this.meshMoveZMode = false; + + /** + * We need new function pointers with scope bound to this so we can remove the + * window event handlers when we need to + * @type {function()} + */ + this.resize = this.onWindowResize.bind(this); + this.mouseMove = this.onMouseMove.bind(this); + this.mouseDown = this.onMouseDown.bind(this); + this.keyPress = this.onKeyPress.bind(this); + this.contextMenu = this.onContextMenu.bind(this); + + this.raycaster = new GameLib.D3.Raycaster( + this.graphics + ); + + this.mouse = new GameLib.Mouse( + this.graphics + ); + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.Input.Editor.prototype = Object.create(GameLib.D3.API.Input.Editor.prototype); +GameLib.D3.Input.Editor.prototype.constructor = GameLib.D3.Input.Editor; + +GameLib.D3.Input.Editor.prototype.createInstance = function(update) { + + this.element = this.dom.document.getElementById(this.domElementId); + if (!this.element) { + console.warn('Could not locate DOM element with ID: ' + this.domElementId); + throw new Error('Could not locate DOM element with ID: ' + this.domElementId); + } + + this.container = this.dom.document.getElementById(this.domContainerId); + if (!this.container) { + console.warn('Could not locate DOM container with ID: ' + this.domContainerId); + throw new Error('Could not locate DOM container with ID: ' + this.domContainerId); + } + + var instance = null; + + if (update) { + instance = this.instance; + instance.camera = this.camera.instance; + return instance; + } else { + instance = new THREE.EditorControls( + this.camera.instance, + this.element + ) + } + + this.element.addEventListener( + 'mousemove', + this.mouseMove, + false + ); + + this.element.addEventListener( + 'contextmenu', + this.contextMenu, + false + ); + + this.element.addEventListener( + 'mousedown', + this.mouseDown, + false + ); + + this.element.addEventListener( + 'keydown', + this.keyPress, + false + ); + + this.dom.window.addEventListener( + 'resize', + this.resize, + false + ); + + return instance; +}; + +GameLib.D3.Input.Editor.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * GameLib.D3.Input.Editor to GameLib.D3.API.Input.Editor + * @returns {GameLib.D3.API.Input.Editor} + */ +GameLib.D3.Input.Editor.prototype.toApiComponent = function() { + + var apiInputEditor = new GameLib.D3.API.Input.Editor( + this.id, + this.name, + this.domElementId, + this.domContainerId, + GameLib.Utils.IdOrNull(this.editor), + GameLib.Utils.IdOrNull(this.camera), + this.widthOffset, + this.heightOffset, + this.containerWidthOffset, + this.containerHeightOffset, + this.selectDelayMs, + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiInputEditor; +}; + +GameLib.D3.Input.Editor.FromObjectComponent = function(graphics, objectComponent) { + + var apiInputEditor = GameLib.D3.API.Input.Editor.FromObjectComponent(objectComponent); + + return new GameLib.D3.Input.Editor( + graphics, + apiInputEditor + ); +}; + +GameLib.D3.Input.Editor.prototype.onWindowResize = function() { + + this.container.style.height = (this.window.innerHeight - this.containerHeightOffset) + 'px'; + this.container.style.width = (this.window.innerWidth - this.containerWidthOffset) + 'px'; + + var width = this.window.innerWidth - this.widthOffset; + + var height = this.window.innerHeight - this.heightOffset; + + //TODO: map the relative viewport sizes and offsets with the size differences + + this.editor.viewports.map( + function(viewport) { + viewport.width = width; + viewport.height = height; + viewport.updateInstance(); + } + ); + + this.editor.game.viewports.map( + function(viewport) { + viewport.width = width; + viewport.height = height; + viewport.updateInstance(); + } + ); + // + // this.scene.cameras[this.scene.activeCameraIndex].aspect = () / window.innerHeight; + // this.scene.cameras[this.scene.activeCameraIndex].updateInstance(); + // + // this.scene.renderers[this.scene.activeRendererIndex].width = window.innerWidth - 400; + // this.scene.renderers[this.scene.activeRendererIndex].height = window.innerHeight; + // this.scene.renderers[this.scene.activeRendererIndex].updateInstance(); +}; + +/** + * Keypress events + * @param event + */ +GameLib.D3.Input.Editor.prototype.onKeyPress = function(event) { + + if (event.code == "KeyQ") { + + this.editor.allSelected = !this.editor.allSelected; + + this.editor.selectedObjects = []; + + if (this.editor.allSelected) { + for (var property in this.editor.idToObject) { + if (this.editor.idToObject.hasOwnProperty(property)) { + this.editor.selectedObjects.push( + new GameLib.D3.SelectedObject( + this.graphics, + this.editor.idToObject(property) + ) + ) + } + } + } + + if (this.editor.onSelectionChanged) { + this.editor.onSelectionChanged(this.editor); + } + } + + if (event.code == 'KeyG') { + if (!this.meshMoveMode) { + console.log('move mode'); + this.meshMoveMode = true; + } + } + + if (event.code == 'KeyX') { + if (this.meshMoveMode) { + console.log('move along x'); + this.meshMoveXMode = true; + this.meshMoveYMode = false; + this.meshMoveZMode = false; + } + } + + if (event.code == 'KeyY') { + if (this.meshMoveMode) { + console.log('move along y'); + this.meshMoveXMode = false; + this.meshMoveYMode = true; + this.meshMoveZMode = false; + } + } + + if (event.code == 'KeyZ') { + if (this.meshMoveMode) { + console.log('move along z'); + this.meshMoveXMode = false; + this.meshMoveYMode = false; + this.meshMoveZMode = true; + } + } + + if (event.code == 'Escape') { + if (this.meshMoveMode) { + this.meshMoveMode = false; + console.log('TODO: implement restore positions'); + } + } + + if (event.code == 'Enter') { + if (this.meshMoveMode) { + this.meshMoveMode = false; + console.log('TODO: implement apply positions'); + } + } +}; + +/** + * Mouse click events + * @param event + * @returns {boolean} + */ +GameLib.D3.Input.Editor.prototype.onMouseDown = function(event) { + + if (event.button == 2) { + + event.cancelBubble = true; + + event.preventDefault(); + + if (event.stopPropagation) { + event.stopPropagation(); + } + + var meshes = []; + + for (var property in this.editor.idToObject) { + if (this.editor.idToObject.hasOwnProperty(property)) { + if (this.editor.idToObject[property] instanceof GameLib.D3.Mesh) { + meshes.push(this.editor.idToObject[property]); + } + } + } + + var intersects = this.raycaster.getIntersectedObjects(meshes); + + if (intersects.length > 0) { + + var index = -1; + + for (var s = 0; s < this.editor.selectedObjects.length; s++) { + if (this.editor.selectedObjects[s].object == intersects[0]) { + index = s; + break; + } + } + + if (index == -1) { + /** + * The object is not selected, select it + */ + this.selectObject(intersects[0]); + + } else { + /** + * De-select the objec + */ + var delta = Date.now() - this.editor.selectedObjects[index].lastUpdate; + if (delta > this.selectDelayMs) { + this.unselectObject(intersects[0]); + } + } + + if (this.editor.onSelectionChanged) { + this.editor.onSelectionChanged(this.editor); + } + } + + return false; + } + + if (event.button == 0) { + if (this.meshMoveMode) { + this.meshMoveMode = false; + this.meshMoveXMode = false; + this.meshMoveYMode = false; + this.meshMoveZMode = false; + } + } +}; + +/** + * Mouse move events + * @param event + */ +GameLib.D3.Input.Editor.prototype.onMouseMove = function(event) { + + var clientX = event.clientX - this.widthOffset; + + this.mouse.x = ((clientX / (window.innerWidth - this.widthOffset))) * 2 - 1; + this.mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; + + this.raycaster.instance.setFromCamera( + this.mouse, + this.cameras[this.scene.activeCameraIndex].instance + ); + + if (this.meshMoveMode) { + + var units = event.movementY; + + if (this.meshMoveXMode) { + this.moveSelectedObjects('x', units); + } + + if (this.meshMoveYMode) { + this.moveSelectedObjects('y', units); + } + + if (this.meshMoveZMode) { + this.moveSelectedObjects('z', units); + } + } +}; + +/** + * Moves selected objects along an axis + * @param alongAxis + * @param units + */ +GameLib.D3.Input.Editor.prototype.moveSelectedObjects = function(alongAxis, units) { + + for (var s = 0; s < this.editor.selectedObjects.length; s++) { + + var object = this.editor.selectedObjects[s].object; + + if (object.position) { + if (alongAxis == 'x') { + object.position.x += units; + } + if (alongAxis == 'y') { + object.position.y += units; + } + if (alongAxis == 'z') { + object.position.z += units; + } + + if (object.updateInstance) { + object.updateInstance(); + } + } + } +}; + +/** + * 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; +}; + +GameLib.D3.Input.Editor.prototype.update = function(deltaTime) { + if (this.pathFollowingComponent) { + + this.pathFollowingComponent.mesh.localPosition.x = (this.heightOffset * this.pathFollowingComponent.rotationMatrix.up.x); + this.pathFollowingComponent.mesh.localPosition.y = (this.heightOffset * this.pathFollowingComponent.rotationMatrix.up.y); + this.pathFollowingComponent.mesh.localPosition.z = (this.heightOffset * this.pathFollowingComponent.rotationMatrix.up.z); + + if (this.keyLeft) { + this.distance -= this.distanceGrain; + } + + if (this.keyRight) { + this.distance += this.distanceGrain; + } + + this.pathFollowingComponent.mesh.localPosition.x += (this.distance * this.pathFollowingComponent.rotationMatrix.left.x); + this.pathFollowingComponent.mesh.localPosition.y += (this.distance * this.pathFollowingComponent.rotationMatrix.left.y); + this.pathFollowingComponent.mesh.localPosition.z += (this.distance * this.pathFollowingComponent.rotationMatrix.left.z); + + this.wheelFL.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + this.wheelFR.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + + this.wheelFL.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + this.wheelFR.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + + this.wheelRL.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + this.wheelRR.localRotation.x += this.rotationFactor * this.pathFollowingComponent.currentSpeed; + } +}; \ No newline at end of file diff --git a/src/game-lib-d3-light.js b/src/game-lib-d3-light.js index 8ffb536..a1f97ee 100644 --- a/src/game-lib-d3-light.js +++ b/src/game-lib-d3-light.js @@ -11,6 +11,10 @@ GameLib.D3.Light = function Light( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiLight)) { + apiLight = {}; + } + GameLib.D3.API.Light.call( this, apiLight.id, @@ -33,33 +37,32 @@ GameLib.D3.Light = function Light( this.color = new GameLib.Color( graphics, - this, this.color, - 0.01 + this ); this.position = new GameLib.Vector3( graphics, - this, - this.position + this.position, + this ); this.targetPosition = new GameLib.Vector3( graphics, - this, - this.targetPosition + this.targetPosition, + this ); this.scale = new GameLib.Vector3( graphics, - this, - this.scale + this.scale, + this ); this.quaternion = new GameLib.Quaternion( graphics, - this, - this.quaternion + this.quaternion, + this ); this.instance = this.createInstance(); diff --git a/src/game-lib-d3-look-at.js b/src/game-lib-d3-look-at.js index e2048ce..0acb04d 100644 --- a/src/game-lib-d3-look-at.js +++ b/src/game-lib-d3-look-at.js @@ -11,6 +11,10 @@ GameLib.D3.LookAt = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiLookAt)) { + apiLookAt = {}; + } + GameLib.D3.API.LookAt.call( this, apiLookAt.id, @@ -24,33 +28,35 @@ GameLib.D3.LookAt = function ( this.targetPositionOffset = new GameLib.Vector3( this.graphics, - this, - this.targetPositionOffset + this.targetPositionOffset, + this ); this.lookAtMatrix = new GameLib.Matrix4( this.graphics, - this, - this.lookAtMatrix + this.lookAtMatrix, + this ); this.up = new GameLib.Vector3( this.graphics, - this, - this.up + this.up, + this ); this.currentRotation = new GameLib.Quaternion( this.graphics, - this, - this.currentRotation + this.currentRotation, + this ); this.targetPosition = new GameLib.Vector3( this.graphics, - this, - this.targetPosition + this.targetPosition, + this ); + + this.buildIdToObject(); }; GameLib.D3.LookAt.prototype = Object.create(GameLib.D3.API.LookAt.prototype); @@ -95,29 +101,33 @@ GameLib.D3.LookAt.prototype.update = function(deltaTime) { this.targetPosition.updateInstance(); - this.lookAtMatrix.lookAt( - this.currentComponent.position, - this.targetPosition, - this.up - ); - - this.currentRotation = new GameLib.Quaternion(this.graphics, this, new GameLib.API.Quaternion()); - - this.currentRotation.setFromRotationMatrix(this.lookAtMatrix); + // this.lookAtMatrix.lookAt( + // this.currentComponent.position, + // this.targetPosition, + // this.up + // ); + // + // this.currentRotation = new GameLib.Quaternion(this.graphics, this, new GameLib.API.Quaternion()); + // + // this.currentRotation.setFromRotationMatrix(this.lookAtMatrix); // var t = deltaTime * this.rotationSpeed; // t = t * t * t * (t * (6.0 * t - 15.0) + 10.0); // this.currentRotation.slerp(this.currentRotation, t); - this.currentRotation.normalize(); + // this.currentRotation.normalize(); + // + // this.currentComponent.quaternion.x = this.currentRotation.x; + // this.currentComponent.quaternion.y = this.currentRotation.y; + // this.currentComponent.quaternion.z = this.currentRotation.z; + // this.currentComponent.quaternion.w = this.currentRotation.w; + // + this.currentComponent.lookAt.x = this.targetPosition.x; + this.currentComponent.lookAt.y = this.targetPosition.y; + this.currentComponent.lookAt.z = this.targetPosition.z; - this.currentComponent.quaternion.x = this.currentRotation.x; - this.currentComponent.quaternion.y = this.currentRotation.y; - this.currentComponent.quaternion.z = this.currentRotation.z; - this.currentComponent.quaternion.w = this.currentRotation.w; - - this.currentComponent.quaternion.updateInstance(); + this.currentComponent.lookAt.updateInstance(); } }; \ No newline at end of file diff --git a/src/game-lib-d3-material.js b/src/game-lib-d3-material.js index 8962cb3..26991d5 100644 --- a/src/game-lib-d3-material.js +++ b/src/game-lib-d3-material.js @@ -15,7 +15,17 @@ GameLib.D3.Material = function Material( this.graphics = graphics; this.graphics.isNotThreeThrow(); - + + if (GameLib.Utils.UndefinedOrNull(apiMaterial)) { + apiMaterial = {}; + } + + if (GameLib.Utils.UndefinedOrNull(imageFactory)) { + console.warn('Cannot create a Material fully without specifying an ImageFactory'); + imageFactory = null; + } + this.imageFactory = imageFactory; + GameLib.D3.API.Material.call( this, apiMaterial.id, @@ -263,6 +273,8 @@ GameLib.D3.Material = function Material( } } + this.buildIdToObject(); + this.instance = this.createInstance(); }; @@ -539,61 +551,85 @@ GameLib.D3.Material.prototype.createInstance = function(update) { if (property == 'alphaMap') { if (this.alphaMap) { instance.alphaMap = this.alphaMap.instance; + } else { + instance.alphaMap = null; } } else if (property == 'aoMap') { if (this.aoMap) { instance.aoMap = this.aoMap.instance; + } else { + instance.aoMap = null; } } else if (property == 'bumpMap') { if (this.bumpMap) { instance.bumpMap = this.bumpMap.instance; + } else { + instance.bumpMap = null; } } else if (property == 'map') { if (this.diffuseMap) { instance.map = this.diffuseMap.instance; + } else { + instance.map = null; } } else if (property == 'displacementMap') { if (this.displacementMap) { instance.displacementMap = this.displacementMap.instance; + } else { + instance.displacementMap = null; } } else if (property == 'emissiveMap') { if (this.emissiveMap) { instance.emissiveMap = this.emissiveMap.instance; + } else { + instance.emissiveMap = null; } } else if (property == 'envMap') { if (this.environmentMap) { instance.envMap = this.environmentMap.instance; + } else { + instance.envMap = null; } } else if (property == 'lightMap') { if (this.lightMap) { instance.lightMap = this.lightMap.instance; + } else { + instance.lightMap = null; } } else if (property == 'metalnessMap') { if (this.metalnessMap) { instance.metalnessMap = this.metalnessMap.instance; + } else { + instance.metalnessMap = null; } } else if (property == 'normalMap') { if (this.normalMap) { instance.normalMap = this.normalMap.instance; + } else { + instance.normalMap = null; } } else if (property == 'roughnessMap') { if (this.roughnessMap) { instance.roughnessMap = this.roughnessMap.instance; + } else { + instance.roughnessMap = null; } } else if (property == 'specularMap') { if (this.specularMap) { instance.specularMap = this.specularMap.instance; + } else { + instance.specularMap = null; } } else if (property == 'size') { diff --git a/src/game-lib-d3-mesh.js b/src/game-lib-d3-mesh.js index c4fe4c7..ac00e9e 100644 --- a/src/game-lib-d3-mesh.js +++ b/src/game-lib-d3-mesh.js @@ -1,20 +1,35 @@ /** * Mesh Superset - The apiMesh properties get moved into the Mesh object itself, and then the instance is created * @param graphics GameLib.D3.Graphics - * @param computeNormals Boolean * @param apiMesh GameLib.D3.API.Mesh * @param imageFactory GameLib.D3.ImageFactory + * @param computeNormals Boolean * @constructor */ GameLib.D3.Mesh = function ( graphics, apiMesh, - computeNormals, - imageFactory + imageFactory, + computeNormals ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiMesh)) { + apiMesh = {}; + } + + if (GameLib.Utils.UndefinedOrNull(computeNormals)) { + computeNormals = true; + } + this.computeNormals = computeNormals; + + if (GameLib.Utils.UndefinedOrNull(imageFactory)) { + console.warn('Cannot create Meshes fully without specifying an ImageFactory for downloading Textures'); + imageFactory = null; + } + this.imageFactory = imageFactory; + GameLib.D3.API.Mesh.call( this, apiMesh.id, @@ -41,22 +56,28 @@ GameLib.D3.Mesh = function ( apiMesh.renderOrder ); - // this.materials = this.materials.map( - // function (apiMaterial) { - // return new GameLib.D3.Material( - // this.graphics, - // apiMaterial, - // imageFactory - // ) - // }.bind(this) - // ); + this.materials = this.materials.map( + function (apiMaterial) { + + if (apiMaterial instanceof GameLib.D3.API.Material) { + return new GameLib.D3.Material( + this.graphics, + apiMaterial, + this.imageFactory + ) + } else { + console.warn('API material not of instance API.Material'); + throw new Error('API material not of instance API.Material'); + } + + }.bind(this) + ); if (this.skeleton) { this.skeleton = new GameLib.D3.Skeleton( this.graphics, this.skeleton ); - } this.vertices = this.vertices.map( @@ -70,56 +91,53 @@ GameLib.D3.Mesh = function ( this.position = new GameLib.Vector3( this.graphics, - this, this.position, - 0.001 + this ); this.scale = new GameLib.Vector3( this.graphics, - this, this.scale, - 0.001 + this ); this.up = new GameLib.Vector3( this.graphics, - this, this.up, - 0.001 + this ); this.quaternion = new GameLib.Quaternion( this.graphics, - this, - this.quaternion + this.quaternion, + this ); this.localPosition = new GameLib.Vector3( this.graphics, - this, - this.localPosition + this.localPosition, + this ); this.localRotation = new GameLib.Vector3( this.graphics, - this, - this.localRotation + this.localRotation, + this ); this.localScale = new GameLib.Vector3( this.graphics, - this, - this.localScale + this.localScale, + this ); this.modelMatrix = new GameLib.Matrix4( this.graphics, - this, - this.modelMatrix + this.modelMatrix, + this ); - this.computeNormals = computeNormals; + this.buildIdToObject(); this.instance = this.createInstance(false); diff --git a/src/game-lib-d3-pass.js b/src/game-lib-d3-pass.js new file mode 100644 index 0000000..9e084b6 --- /dev/null +++ b/src/game-lib-d3-pass.js @@ -0,0 +1,130 @@ +/** + * Renders a scene with a camera + * @param graphics GameLib.D3.Graphics + * @param apiPass GameLib.D3.API.Pass + * @constructor + */ +GameLib.D3.Pass = function ( + graphics, + apiPass +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiPass)) { + apiPass = {}; + } + + GameLib.D3.API.Pass.call( + this, + apiPass.id, + apiPass.name, + apiPass.passType, + apiPass.camera, + apiPass.scene, + apiPass.renderToScreen, + apiPass.parentEntity + ); + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.Pass.prototype = Object.create(GameLib.D3.API.Pass.prototype); +GameLib.D3.Pass.prototype.constructor = GameLib.D3.Pass; + +GameLib.D3.Pass.PASS_TYPE_RENDER = 0x1; +GameLib.D3.Pass.PASS_TYPE_COPY_SHADER = 0x2; + +/** + * Create Pass instance + * @param update + * @returns {*} + */ +GameLib.D3.Pass.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + if (this.passType == GameLib.D3.Pass.PASS_TYPE_RENDER) { + + if (this.scene && this.camera) { + if (!THREE.RenderPass) { + console.warn('No THREE.RenderPass'); + throw new Error('No THREE.RenderPass'); + } + + instance = new THREE.RenderPass( + this.scene.instance, + this.camera.instance + ); + } + + } else if (this.passType == GameLib.D3.Pass.PASS_TYPE_COPY_SHADER) { + + if (!THREE.CopyShader) { + console.warn('No THREE.CopyShader'); + throw new Error('No THREE.CopyShader'); + } + + instance = THREE.CopyShader; + + } else { + console.warn('Render pass not supported yet: ' + this.passType); + throw new Error('Render pass not supported yet: ' + this.passType); + } + + if (instance) { + instance.renderToScreen = this.renderToScreen; + } + + return instance; +}; + +/** + * Update Pass instance + */ +GameLib.D3.Pass.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * GameLib.D3.Pass to GameLib.D3.API.Pass + * @returns {GameLib.D3.API.Pass} + */ +GameLib.D3.Pass.prototype.toApiComponent = function() { + + var apiPass = new GameLib.D3.API.Pass( + this.id, + this.name, + this.passType, + GameLib.Utils.IdOrNull(this.camera), + GameLib.Utils.IdOrNull(this.scene), + this.renderToScreen, + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiPass; +}; + +/** + * GameLib.D3.Pass from Object + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.Pass} + * @constructor + */ +GameLib.D3.Pass.FromObjectComponent = function(graphics, objectComponent) { + + var apiPass = GameLib.D3.API.Pass.FromObjectComponent(objectComponent); + + return new GameLib.D3.Pass( + graphics, + apiPass + ); +}; diff --git a/src/game-lib-d3-path-following.js b/src/game-lib-d3-path-following.js index be72939..224b1c7 100644 --- a/src/game-lib-d3-path-following.js +++ b/src/game-lib-d3-path-following.js @@ -12,6 +12,10 @@ GameLib.D3.PathFollowing = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiPathFollowing)) { + apiPathFollowing = {}; + } + GameLib.D3.API.PathFollowing.call( this, apiPathFollowing.id, @@ -40,26 +44,26 @@ GameLib.D3.PathFollowing = function ( this.baseOffset = new GameLib.Vector3( this.graphics, - this, - this.baseOffset + this.baseOffset, + this ); this.maxOffset = new GameLib.Vector3( this.graphics, - this, - this.maxOffset + this.maxOffset, + this ); this.targetOffset = new GameLib.Vector3( this.graphics, - this, - this.targetOffset + this.targetOffset, + this ); this.currentOffset = new GameLib.Vector3( this.graphics, - this, - this.currentOffset + this.currentOffset, + this ); this.raycaster = new GameLib.D3.Raycaster( @@ -69,42 +73,39 @@ GameLib.D3.PathFollowing = function ( this.currentPosition = new GameLib.Vector3( this.graphics, - this, - this.currentPosition + this.currentPosition, + this ); this.futurePosition = new GameLib.Vector3( this.graphics, - this, - this.futurePosition + this.futurePosition, + this ); this.up = new GameLib.Vector3( this.graphics, - this, - this.up + this.up, + this ); this.rotationMatrix = new GameLib.Matrix4( this.graphics, - this, - this.rotationMatrix + this.rotationMatrix, + this ); this.rotationVector = new GameLib.Quaternion( this.graphics, - this, - this.rotationVector + this.rotationVector, + this ); this.mx = new GameLib.Utils.MovingAverage(10); this.my = new GameLib.Utils.MovingAverage(10); this.mz = new GameLib.Utils.MovingAverage(10); - this.posx = new GameLib.Utils.MovingAverage(10); - this.posy = new GameLib.Utils.MovingAverage(10); - this.posz = new GameLib.Utils.MovingAverage(10); - + this.buildIdToObject(); }; GameLib.D3.PathFollowing.prototype = Object.create(GameLib.D3.API.PathFollowing.prototype); @@ -221,9 +222,9 @@ GameLib.D3.PathFollowing.prototype.update = function(deltaTime) { this.rotationVector.setFromRotationMatrix(this.rotationMatrix); - this.mesh.position.x = this.posx(this.futurePosition.x); - this.mesh.position.y = this.posy(this.futurePosition.y); - this.mesh.position.z = this.posz(this.futurePosition.z); + this.mesh.position.x = this.futurePosition.x; + this.mesh.position.y = this.futurePosition.y; + this.mesh.position.z = this.futurePosition.z; /** * Update Rotation diff --git a/src/game-lib-d3-raycaster.js b/src/game-lib-d3-raycaster.js index 9470062..4fe3ebb 100644 --- a/src/game-lib-d3-raycaster.js +++ b/src/game-lib-d3-raycaster.js @@ -1,7 +1,6 @@ /** * Raycaster for GameLib.D3 * @param graphics GameLib.D3.Graphics - * @param parentObject * @param apiRaycaster * @constructor */ @@ -13,22 +12,28 @@ GameLib.D3.Raycaster = function( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiRaycaster)) { + apiRaycaster = {}; + } + GameLib.D3.API.Raycaster.call( this, + apiRaycaster.id, + apiRaycaster.name, apiRaycaster.position, apiRaycaster.direction ); this.position = new GameLib.Vector3( this.graphics, - this, - this.position + this.position, + this ); this.direction = new GameLib.Vector3( this.graphics, - this, - this.direction + this.direction, + this ); this.instance = this.createInstance(); @@ -59,8 +64,14 @@ GameLib.D3.Raycaster.prototype.createInstance = function(update) { return instance; }; +GameLib.D3.Raycaster.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + GameLib.D3.Raycaster.prototype.toApiRaycaster = function() { return new GameLib.D3.API.Raycaster( + this.id, + this.name, this.position.toApiVector(), this.direction.toApiVector() ) @@ -72,7 +83,6 @@ GameLib.D3.Raycaster.FromObjectRaycaster = function(graphics, parentObject, obje var raycaster = new GameLib.D3.Raycaster( graphics, - parentObject, apiRaycaster ); @@ -98,8 +108,6 @@ GameLib.D3.Raycaster.prototype.set = function( this.position.updateInstance(); this.direction.updateInstance(); - - this.createInstance(true); }; /** @@ -114,8 +122,6 @@ GameLib.D3.Raycaster.prototype.setDirection = function( this.direction.z = direction.z; this.direction.updateInstance(); - - this.createInstance(true); }; /** @@ -130,10 +136,36 @@ GameLib.D3.Raycaster.prototype.setPosition = function( this.position.z = position.z; this.position.updateInstance(); - - this.createInstance(true); }; +/** + * Gets all interesected GameLib.D3.Mesh objects + * @param meshes [GameLib.D3.Mesh] + */ +GameLib.D3.Raycaster.prototype.getIntersectedObjects = function(meshes) { + + var meshInstances = meshes.map( + function (mesh) { + return mesh.instance; + } + ); + + var instanceIdToMesh = meshes.reduce( + function (result, mesh) { + result[mesh.instance.id] = mesh; + }, + {} + ); + + var intersects = this.instance.intersectObjects(meshInstances); + + return intersects.map(function (intersect) { + return instanceIdToMesh[intersect.object.id]; + }); + +}; + + /** * Returns the face normal (if any) of an intersection between current ray position, direction and a provided mesh * @param mesh GameLib.D3.Mesh @@ -148,14 +180,15 @@ GameLib.D3.Raycaster.prototype.getFaceNormal = function(mesh) { ); if (intersect && intersect.length > 0) { + normal = new GameLib.Vector3( this.graphics, - this, new GameLib.API.Vector3( intersect[0].face.normal.x, intersect[0].face.normal.y, intersect[0].face.normal.z - ) + ), + this ); } @@ -178,12 +211,12 @@ GameLib.D3.Raycaster.prototype.getIntersectPoint = function(mesh) { if (intersect && intersect.length > 0) { point = new GameLib.Vector3( this.graphics, - this, new GameLib.API.Vector3( intersect[0].point.x, intersect[0].point.y, intersect[0].point.z - ) + ), + this ); } diff --git a/src/game-lib-d3-render-target.js b/src/game-lib-d3-render-target.js new file mode 100644 index 0000000..8d95d75 --- /dev/null +++ b/src/game-lib-d3-render-target.js @@ -0,0 +1,131 @@ +/** + * Renders a scene with a camera + * @param graphics GameLib.D3.Graphics + * @param apiRenderTarget GameLib.D3.API.RenderTarget + * @constructor + */ +GameLib.D3.RenderTarget = function ( + graphics, + apiRenderTarget +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiRenderTarget)) { + apiRenderTarget = {}; + } + + GameLib.D3.API.RenderTarget.call( + this, + apiRenderTarget.id, + apiRenderTarget.name, + apiRenderTarget.width, + apiRenderTarget.height, + apiRenderTarget.minFilter, + apiRenderTarget.magFilter, + apiRenderTarget.format, + apiRenderTarget.stencilBuffer, + apiRenderTarget.texture + ); + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.RenderTarget.prototype = Object.create(GameLib.D3.API.RenderTarget.prototype); +GameLib.D3.RenderTarget.prototype.constructor = GameLib.D3.RenderTarget; + +/** + * Some constants (based on THREE.js constants - update if needed) + * @type {number} + */ +GameLib.D3.RenderTarget.LINEAR_FILTER = 1006; +GameLib.D3.RenderTarget.RGB_FORMAT = 1022; +GameLib.D3.RenderTarget.RGBA_FORMAT = 1023; + +/** + * Creates a Render Target instance + * @param update + * @returns {*} + */ +GameLib.D3.RenderTarget.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + instance.width = this.width; + instance.height = this.height; + instance.minFilter = this.minFilter; + instance.magFilter = this.magFilter; + instance.format = this.format; + instance.stencilBuffer = this.stencilBuffer; + instance.texture = this.texture.instance; + instance.texture.needsUpdate = true; + } else { + instance = new THREE.WebGLRenderTarget( + this.width, + this.height, + { + minFilter : this.minFilter, + magFilter : this.magFilter, + format : this.format, + stencilBuffer : this.stencilBuffer + } + ); + + if (this.texture instanceof GameLib.D3.Texture && this.texture.instance) { + instance.texture = this.texture.instance; + } + } + + return instance; +}; + +/** + * updates instance + */ +GameLib.D3.RenderTarget.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * Render Target to API Render Target + * @returns {GameLib.D3.API.RenderTarget} + */ +GameLib.D3.RenderTarget.prototype.toApiComponent = function() { + + var apiRenderTarget = new GameLib.D3.API.RenderTarget( + this.id, + this.name, + this.width, + this.height, + this.minFilter, + this.magFilter, + this.format, + this.stencilBuffer, + GameLib.Utils.IdOrNull(this.texture), + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiRenderTarget; +}; + +/** + * + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.RenderTarget} + * @constructor + */ +GameLib.D3.RenderTarget.FromObjectComponent = function(graphics, objectComponent) { + + var apiRenderTarget = GameLib.D3.API.RenderTarget.FromObjectComponent(objectComponent); + + return new GameLib.D3.RenderTarget( + graphics, + apiRenderTarget + ); +}; diff --git a/src/game-lib-d3-renderer.js b/src/game-lib-d3-renderer.js index 1140a8d..1d32d69 100644 --- a/src/game-lib-d3-renderer.js +++ b/src/game-lib-d3-renderer.js @@ -12,17 +12,21 @@ GameLib.D3.Renderer = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiRenderer)) { + apiRenderer = {}; + } + GameLib.D3.API.Renderer.call( this, apiRenderer.id, apiRenderer.name, - apiRenderer.scene, - apiRenderer.camera, + apiRenderer.rendererType, apiRenderer.autoClear, apiRenderer.localClipping, apiRenderer.width, apiRenderer.height, - apiRenderer.parentEntity + apiRenderer.parentEntity, + apiRenderer.preserveDrawingBuffer ); this.instance = this.createInstance(); @@ -31,6 +35,14 @@ GameLib.D3.Renderer = function ( GameLib.D3.Renderer.prototype = Object.create(GameLib.D3.API.Renderer.prototype); GameLib.D3.Renderer.prototype.constructor = GameLib.D3.Renderer; +GameLib.D3.Renderer.RENDER_TYPE_NORMAL = 0x1; +GameLib.D3.Renderer.RENDER_TYPE_STEREO = 0x2; + +/** + * Create Renderer Instance + * @param update + * @returns {*} + */ GameLib.D3.Renderer.prototype.createInstance = function(update) { var instance = null; @@ -42,15 +54,14 @@ GameLib.D3.Renderer.prototype.createInstance = function(update) { } instance.localClippingEnabled = this.localClipping; - instance.setSize(this.width, this.height); + + instance.setSize( + this.width, + this.height + ); + instance.autoClear = this.autoClear; - - if (this.camera && this.camera.instance) { - this.camera.instance.aspect = this.width / this.height; - this.camera.instance.updateProjectionMatrix(); - } - - this.instance = instance; + instance.preserveDrawingBuffer = this.preserveDrawingBuffer; return instance; }; @@ -64,29 +75,31 @@ GameLib.D3.Renderer.prototype.toApiComponent = function() { var apiRenderer = new GameLib.D3.API.Renderer( this.id, this.name, - GameLib.Utils.IdOrNull(this.scene), - GameLib.Utils.IdOrNull(this.camera), + this.rendererType, this.autoClear, this.localClipping, this.width, this.height, - GameLib.Utils.IdOrNull(this.parentEntity) + GameLib.Utils.IdOrNull(this.parentEntity), + preserveDrawingBuffer ); return apiRenderer; }; +/** + * + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.Renderer} + * @constructor + */ GameLib.D3.Renderer.FromObjectComponent = function(graphics, objectComponent) { var apiRenderer = GameLib.D3.API.Renderer.FromObjectComponent(objectComponent); return new GameLib.D3.Renderer( graphics, - this, apiRenderer ); }; - -GameLib.D3.Renderer.prototype.render = function() { - this.instance.render(this.scene.instance, this.camera.instance); -}; \ No newline at end of file diff --git a/src/game-lib-d3-scene.js b/src/game-lib-d3-scene.js index 13f39a4..87a89a7 100644 --- a/src/game-lib-d3-scene.js +++ b/src/game-lib-d3-scene.js @@ -2,15 +2,13 @@ * Scene Superset - The apiScene properties get moved into the Scene object itself, and then the instance is * created * @param graphics - * @param progressCallback * @param apiScene GameLib.D3.API.Scene * @param imageFactory * @param computeNormals * @constructor */ -GameLib.D3.Scene = function Scene( +GameLib.D3.Scene = function ( graphics, - progressCallback, apiScene, imageFactory, computeNormals @@ -18,163 +16,131 @@ GameLib.D3.Scene = function Scene( this.graphics = graphics; this.graphics.isNotThreeThrow(); - this.imageFactory = imageFactory; + if (GameLib.Utils.UndefinedOrNull(apiScene)) { + apiScene = {}; + } + + if (GameLib.Utils.UndefinedOrNull(computeNormals)) { + computeNormals = true; + } + this.computeNormals = computeNormals; GameLib.D3.API.Scene.call( this, apiScene.id, - apiScene.path, apiScene.name, - apiScene.meshes, - apiScene.position, - apiScene.quaternion, - apiScene.scale, - apiScene.parentSceneId, - apiScene.lights, - apiScene.worlds, - apiScene.entityManager, - apiScene.shapes, - apiScene.cameras, - apiScene.activeCameraIndex, + apiScene.meshes, + apiScene.position, + apiScene.quaternion, + apiScene.scale, + apiScene.parentGameId, + apiScene.lights, apiScene.textures, - apiScene.materials + apiScene.materials, + apiScene.parentEntity ); + if (GameLib.Utils.UndefinedOrNull(imageFactory)) { + console.warn('Creating a scene without an ImageFactory'); + imageFactory = null; + } + this.imageFactory = imageFactory; + this.meshes = this.meshes.map( function(apiMesh) { - return new GameLib.D3.Mesh( - this.graphics, - apiMesh, - computeNormals, - imageFactory - ) + + if (apiMesh instanceof GameLib.D3.API.Mesh) { + + return new GameLib.D3.Mesh( + this.graphics, + apiMesh, + this.computeNormals, + this.imageFactory + ); + + } else { + console.warn('apiMesh not an instance of API.Mesh'); + throw new Error('apiMesh not an instance of API.Mesh'); + } + }.bind(this) ); + this.position = new GameLib.Vector3( + this.graphics, + this.position, + this + ); + + this.quaternion = new GameLib.Quaternion( + this.graphics, + this.quaternion, + this + ); + + this.scale = new GameLib.Vector3( + this.graphics, + this.scale, + this + ); + this.lights = this.lights.map( function(apiLight) { - return new GameLib.D3.Light( - this.graphics, - apiLight - ) - }.bind(this) - ); - if (this.entityManager) { - this.entityManager = new GameLib.EntityManager( - this.graphics, - this.entityManager - ); - } + if (apiLight instanceof GameLib.D3.API.Light) { + + return new GameLib.D3.Light( + this.graphics, + apiLight + ); + + } else { + console.warn('apiLight not an instance of API.Light'); + throw new Error('apiLight not an instance of API.Light'); + } - this.cameras = this.cameras.map( - function(apiCamera) { - return new GameLib.D3.Camera( - this.graphics, - apiCamera - ) }.bind(this) ); this.textures = this.textures.map( function(apiTexture) { - return new GameLib.D3.Texture( - this.graphics, - apiTexture, - null, - null, - this.imageFactory - ) + + if (apiTexture instanceof GameLib.D3.API.Texture) { + return new GameLib.D3.Texture( + this.graphics, + apiTexture, + null, + null, + this.imageFactory + ); + } else { + console.warn('apiTexture not an instance of API.Texture'); + throw new Error('apiTexture not an instance of API.Texture'); + } + }.bind(this) ); this.materials = this.materials.map( function(apiMaterial) { - return new GameLib.D3.Material( - this.graphics, - apiMaterial, - this.imageFactory - ) - }.bind(this) - ); - this.position = new GameLib.Vector3( - graphics, - this, - this.position - ); - - this.quaternion = new GameLib.Quaternion( - graphics, - this, - this.quaternion - ); - - this.scale = new GameLib.Vector3( - graphics, - this, - this.scale - ); - - this.progressCallback = progressCallback; - - this.instance = this.createInstance(); - - this.interestingProperties = [ - "cameras", - "meshes", - "lights", - "textures", - "materials" - ]; - - this.idToObject = {}; - - this.idToObject[this.id] = this; - - // var material = null; - - for (var p = 0; p < this.interestingProperties.length; p++) { - property = this.interestingProperties[p]; - if (this.hasOwnProperty(property)) { - for (var i = 0; i < this[property].length; i++) { - var object = this[property][i]; - this.idToObject[object.id] = object; + if (apiMaterial instanceof GameLib.D3.API.Material) { + return new GameLib.D3.Material( + this.graphics, + apiMaterial, + this.imageFactory + ); + } else { + console.warn('apiMaterial not an instance of API.Material'); + throw new Error('apiMaterial not an instance of API.Material'); } - } - } - - for (var m = 0; m < this.meshes.length; m++) { - if (this.meshes[m].skeleton) { - this.meshes[m].skeleton.bones.map( - function (bone) { - this.idToObject[bone.id] = bone; - }.bind(this) - ); - - this.idToObject[this.meshes[m].skeleton.id] = this.meshes[m].skeleton; - } - - if (this.meshes[m].materials[0]) { - this.meshes[m].materials[0] = this.idToObject[this.meshes[m].materials[0]]; - this.meshes[m].materials[0].diffuseMap = this.idToObject[this.meshes[m].materials[0].diffuseMap]; - } - } - - this.entityManager.entities.map( - function (entity) { - this.idToObject[entity.id] = entity; - entity.components.map( - function(component) { - if (component instanceof GameLib.Component) { - this.idToObject[component.id] = component; - } - }.bind(this) - ) + }.bind(this) ); - this.entityManager.linkObjects(this.idToObject); + this.buildIdToObject(); + + this.instance = this.createInstance(); }; GameLib.D3.Scene.prototype = Object.create(GameLib.D3.API.Scene.prototype); @@ -182,7 +148,7 @@ GameLib.D3.Scene.prototype.constructor = GameLib.D3.Scene; /** * Creates an instance scene - * @returns {GameLib.D3.Scene|THREE.Scene|ApiLib.Scene|*|Scene} + * @returns {THREE.Scene} */ GameLib.D3.Scene.prototype.createInstance = function() { @@ -204,8 +170,6 @@ GameLib.D3.Scene.prototype.createInstance = function() { instance.add(this.lights[l].instance); } - instance.render = true; - return instance; }; @@ -227,51 +191,30 @@ GameLib.D3.Scene.prototype.toApiScene = function() { } ); - var apiEntityManager = null; - if (this.entityManager) { - apiEntityManager = this.entityManager.toApiEntityManager(); - } - - var apiCameras = this.cameras.map( - function(camera) { - return camera.toApiCamera(); - } - ); - - var apiWorlds = this.worlds.map( - function(world) { - return world.toApiWorld(); - } - ); - - var apiShapes = this.shapes.map( - function(shape) { - return shape.toApiShape(); - } - ); - var apiTextures = this.textures.map( function(texture) { return texture.toApiTexture(); } ); + var apiMaterials = this.materials.map( + function(material) { + return material.toApiMaterial(); + } + ); + return new GameLib.D3.API.Scene( this.id, - this.path, this.name, apiMeshes, this.position.toApiVector(), this.quaternion.toApiQuaternion(), this.scale.toApiVector(), - this.parentSceneId, + this.parentGameId, apiLights, - apiWorlds, - apiEntityManager, - apiShapes, - apiCameras, - this.activeCameraIndex, - apiTextures + apiTextures, + apiMaterials, + GameLib.Utils.IdOrNull(this.parentEntity) ); }; @@ -279,79 +222,67 @@ GameLib.D3.Scene.prototype.toApiScene = function() { * Converts a scene Object to a GameLib.D3.Scene object * @param graphics GameLib.D3.Graphics * @param objectScene Object - * @param computeNormals boolean to indicate whether or not to recalculate normals * @param imageFactory GameLib.D3.ImageFactory - * @param progressCallback callback + * @param computeNormals boolean to indicate whether or not to recalculate normals * @returns {GameLib.D3.Scene} * @constructor */ GameLib.D3.Scene.FromObjectScene = function( graphics, objectScene, - computeNormals, imageFactory, - progressCallback + computeNormals ) { var apiScene = GameLib.D3.API.Scene.FromObjectScene(objectScene); return new GameLib.D3.Scene( graphics, - progressCallback, apiScene, imageFactory, computeNormals ); - }; /** * Transforms raw scene data into a GameLib.D3.Scene - * @param objectScene Object (as it comes from the API) - * @param onLoaded * @param graphics - * @param uploadUrl - * @param progressCallback + * @param objectScene Object (as it comes from the API) * @param computeNormals + * @param onLoaded + * @param imageFactory GameLib.D3.ImageFactory * @constructor */ GameLib.D3.Scene.LoadScene = function( - objectScene, - onLoaded, graphics, - uploadUrl, - progressCallback, - computeNormals + objectScene, + computeNormals, + onLoaded, + imageFactory ) { - onLoaded( - GameLib.D3.Scene.FromObjectScene( - graphics, - objectScene, - computeNormals, - GameLib.D3.ImageFactory( - graphics, - uploadUrl - ), - progressCallback - ) + var scene = GameLib.D3.Scene.FromObjectScene( + graphics, + objectScene, + imageFactory, + computeNormals ); + + onLoaded(scene); }; /** * Loads a scene directly from the API - * @param partialSceneObject Object {path: '', name: ''} - * @param onLoaded callback * @param graphics GameLib.D3.Graphics - * @param uploadUrl String - * @param progressCallback callback + * @param partialSceneObject Object {path: '', name: ''} * @param apiUrl + * @param onLoaded + * @param imageFactory GameLib.D3.ImageFactory */ GameLib.D3.Scene.LoadSceneFromApi = function( - partialSceneObject, - onLoaded, graphics, - uploadUrl, - progressCallback, - apiUrl + partialSceneObject, + apiUrl, + onLoaded, + imageFactory ) { /** @@ -374,18 +305,28 @@ GameLib.D3.Scene.LoadSceneFromApi = function( if (xhr.readyState == 4) { - var response = JSON.parse(xhr.responseText); + 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 scene = response.scene[0]; + var objectScene = response.scene[0]; - GameLib.D3.Scene.LoadScene(scene, onLoaded, graphics, uploadUrl, progressCallback, true); + GameLib.D3.Scene.LoadScene( + graphics, + objectScene, + true, + onLoaded, + imageFactory + ); } } }(xhr); xhr.send(); -}; +}; \ No newline at end of file diff --git a/src/game-lib-d3-selected-object.js b/src/game-lib-d3-selected-object.js new file mode 100644 index 0000000..20f3405 --- /dev/null +++ b/src/game-lib-d3-selected-object.js @@ -0,0 +1,38 @@ +/** + * Selected Objects + * @param graphics GameLib.D3.Graphics + * @param object + * @param helper + * @param lastUpdate + * @constructor + */ +GameLib.D3.SelectedObject = function SelectedObject( + graphics, + object, + helper, + lastUpdate +) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(object)) { + console.warn('Cannot select no object'); + throw new Error('Cannot select no object'); + } + this.object = object; + + if (GameLib.Utils.UndefinedOrNull(helper)) { + helper = new GameLib.D3.Helper( + this.graphics, + null, + null, + object + ) + } + this.helper = helper; + + if (GameLib.Utils.UndefinedOrNull(lastUpdate)) { + lastUpdate = Date.now(); + } + this.lastUpdate = lastUpdate; +}; diff --git a/src/game-lib-d3-skeleton.js b/src/game-lib-d3-skeleton.js index 86edc73..43c7203 100644 --- a/src/game-lib-d3-skeleton.js +++ b/src/game-lib-d3-skeleton.js @@ -10,7 +10,11 @@ GameLib.D3.Skeleton = function Skeleton( ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); - + + if (GameLib.Utils.UndefinedOrNull(apiSkeleton)) { + apiSkeleton = {}; + } + GameLib.D3.API.Skeleton.call( this, apiSkeleton.id, @@ -21,39 +25,62 @@ GameLib.D3.Skeleton = function Skeleton( apiSkeleton.boneTextureWidth, apiSkeleton.boneTextureHeight, apiSkeleton.boneMatrices, - apiSkeleton.boneTexture + apiSkeleton.boneTexture, + apiSkeleton.parentEntity ); this.bones = this.bones.map( function(apiBone) { - return new GameLib.D3.Bone( - this.graphics, - apiBone - ) + + if (apiBone instanceof GameLib.D3.API.Bone) { + return new GameLib.D3.Bone( + this.graphics, + apiBone + ) + } else { + console.warn('apiBone not an instance of API.Bone'); + throw new Error('apiBone not an instance of API.Bone'); + } + }.bind(this) ); this.boneInverses = this.boneInverses.map( function(boneInverse) { - return new GameLib.Matrix4( - this.graphics, - this, - boneInverse - ); + + if (boneInverse instanceof GameLib.API.Matrix4) { + return new GameLib.Matrix4( + this.graphics, + boneInverse, + this + ); + } else { + console.warn('boneInverse not an instance of API.Matrix4'); + throw new Error('boneInverse not an instance of API.Matrix4'); + } + }.bind(this) ); this.boneMatrices = this.boneMatrices.map( function(boneMatrices) { - return new GameLib.Matrix4( - this.graphics, - this, - boneMatrices - ); + if (boneMatrices instanceof GameLib.API.Matrix4) { + return new GameLib.Matrix4( + this.graphics, + boneMatrices, + this + ); + } else { + console.warn('boneMatrices not an instance of API.Matrix4'); + throw new Error('boneMatrices not an instance of API.Matrix4'); + } + }.bind(this) ); + this.buildIdToObject(); + this.instance = this.createInstance(); }; @@ -168,7 +195,8 @@ GameLib.D3.Skeleton.prototype.toApiSkeleton = function() { return boneMatrix.toApiMatrix(); } ), - this.boneTexture + this.boneTexture, + this.parentEntity ); return apiSkeleton; diff --git a/src/game-lib-d3-spline.js b/src/game-lib-d3-spline.js index c7a420c..ea6c272 100644 --- a/src/game-lib-d3-spline.js +++ b/src/game-lib-d3-spline.js @@ -11,6 +11,10 @@ GameLib.D3.Spline = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiSpline)) { + apiSpline = {}; + } + GameLib.D3.API.Spline.call( this, apiSpline.id, @@ -23,8 +27,8 @@ GameLib.D3.Spline = function ( function (vertex) { return new GameLib.Vector3( graphics, - this, - vertex + vertex, + this ) } ); @@ -108,8 +112,8 @@ GameLib.D3.Spline.prototype.getPointAt = function(proper) { var point = this.instance.getPointAt(proper); return new GameLib.Vector3( this.graphics, - this, new GameLib.API.Vector3(point.x, point.y, point.z), + this, 0.1 ); }; diff --git a/src/game-lib-d3-texture.js b/src/game-lib-d3-texture.js index 6b5ed20..120ac3b 100644 --- a/src/game-lib-d3-texture.js +++ b/src/game-lib-d3-texture.js @@ -3,21 +3,27 @@ * created * @param apiTexture * @param graphics GameLib.D3.Graphics - * @param parentMaterial GameLib.D3.Material - * @param parentMaterialInstanceMapId String - * @param imageFactory GameLib.D3.ImageFactory result + * @param imageFactory GameLib.D3.ImageFactory * @constructor */ GameLib.D3.Texture = function Texture( graphics, apiTexture, - parentMaterial, - parentMaterialInstanceMapId, imageFactory ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); - + + if (GameLib.Utils.UndefinedOrNull(apiTexture)) { + apiTexture = {}; + } + + if (GameLib.Utils.UndefinedOrNull(imageFactory)) { + console.warn('Cannot create a Texture without specifying an ImageFactory'); + imageFactory = null; + } + this.imageFactory = imageFactory; + GameLib.D3.API.Texture.call( this, apiTexture.id, @@ -40,30 +46,27 @@ GameLib.D3.Texture = function Texture( apiTexture.mipmaps, apiTexture.unpackAlignment, apiTexture.premultiplyAlpha, - apiTexture.encoding + apiTexture.encoding, + apiTexture.parentEntity ); this.offset = new GameLib.Vector2( graphics, - this, - this.offset + this.offset, + this ); this.repeat = new GameLib.Vector2( graphics, - this, - this.repeat + this.repeat, + this ); - this.parentMaterial = parentMaterial; - - this.parentMaterialInstanceMapId = parentMaterialInstanceMapId; - this.imageInstance = null; this.instance = null; - this.loadTexture(imageFactory); + this.loadTexture(); }; GameLib.D3.Texture.prototype = Object.create(GameLib.D3.API.Texture.prototype); @@ -71,18 +74,15 @@ GameLib.D3.Texture.prototype.constructor = GameLib.D3.Texture; /** * Loads a texture from the image factory, it could already have downloaded, and then it updates the instance - * @param imageFactory */ -GameLib.D3.Texture.prototype.loadTexture = function(imageFactory) { +GameLib.D3.Texture.prototype.loadTexture = function() { - this.imageData = imageFactory(this.imagePath); + this.imageData = this.imageFactory(this.imagePath); this.imageData.then( function (imageInstance){ this.imageInstance = imageInstance; this.instance = this.createInstance(); - this.parentMaterial.instance[this.parentMaterialInstanceMapId] = this.instance; - this.parentMaterial.instance.needsUpdate = true; }.bind(this), function onRejected() { } @@ -177,31 +177,29 @@ GameLib.D3.Texture.TEXTURE_TYPE_SPECULAR = 'specular'; */ GameLib.D3.Texture.prototype.createInstance = function(update) { - // var instance = null; - // - // if (update) { - // instance = this.instance; - // instance.mapping = this.mapping; - // instance.wrapS = this.wrapS; - // instance.wrapT = this.wrapT; - // instance.magFilter = this.magFilter; - // instance.minFilter = this.minFilter; - // instance.anisotropy = this.anisotropy; - // } else { - // - // } + var instance = null; - var instance = new THREE.Texture( - this.imageInstance, - this.mapping, - this.wrapS, - this.wrapT, - this.magFilter, - this.minFilter, - undefined, //format and textureType is different on different archs - undefined, - this.anisotropy - ); + if (update) { + instance = this.instance; + instance.mapping = this.mapping; + instance.wrapS = this.wrapS; + instance.wrapT = this.wrapT; + instance.magFilter = this.magFilter; + instance.minFilter = this.minFilter; + instance.anisotropy = this.anisotropy; + } else { + instance = new THREE.Texture( + this.imageInstance, + this.mapping, + this.wrapS, + this.wrapT, + this.magFilter, + this.minFilter, + undefined, //format and textureType is different on different archs + undefined, + this.anisotropy + ); + } instance.name = this.name; instance.flipY = this.flipY; @@ -215,12 +213,6 @@ GameLib.D3.Texture.prototype.createInstance = function(update) { instance.premultiplyAlpha = this.premultiplyAlpha; instance.textureType = this.textureType; - if (this.parentMaterial && - this.parentMaterial.instance && - this.parentMaterialInstanceMapId) { - this.parentMaterial.instance[this.parentMaterialInstanceMapId] = instance; - } - instance.needsUpdate = true; return instance; @@ -268,7 +260,8 @@ GameLib.D3.Texture.prototype.toApiTexture = function() { this.mipmaps, this.unpackAlignment, this.premultiplyAlpha, - this.encoding + this.encoding, + this.parentEntity ) }; @@ -277,23 +270,19 @@ GameLib.D3.Texture.prototype.toApiTexture = function() { * Converts from an Object texture to a GameLib.D3.Texture * @param graphics GameLib.D3.Graphics * @param objectTexture Object - * @param gameLibMaterial GameLib.D3.Material - * @param instanceMapId String * @param imageFactory GameLib.D3.ImageFactory * @constructor */ GameLib.D3.Texture.FromObjectTexture = function( graphics, objectTexture, - gameLibMaterial, - instanceMapId, imageFactory ) { + var apiTexture = GameLib.D3.API.Texture.FromObjectTexture(objectTexture); + return new GameLib.D3.Texture( graphics, - GameLib.D3.API.Texture.FromObjectTexture(objectTexture), - gameLibMaterial, - instanceMapId, + apiTexture, imageFactory ); }; diff --git a/src/game-lib-d3-vertex.js b/src/game-lib-d3-vertex.js index 821a2a8..27a62f8 100644 --- a/src/game-lib-d3-vertex.js +++ b/src/game-lib-d3-vertex.js @@ -11,6 +11,10 @@ GameLib.D3.Vertex = function Vertex( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiVertex)) { + apiVertex = {}; + } + GameLib.D3.API.Vertex.call( this, apiVertex.position, @@ -19,8 +23,8 @@ GameLib.D3.Vertex = function Vertex( this.position = new GameLib.Vector3( this.graphics, - null, - this.position + this.position, + null ); this.boneWeights = this.boneWeights.map( diff --git a/src/game-lib-d3-viewport.js b/src/game-lib-d3-viewport.js new file mode 100644 index 0000000..c28c16d --- /dev/null +++ b/src/game-lib-d3-viewport.js @@ -0,0 +1,185 @@ +/** + * Viewport Runtime + * @param graphics GameLib.D3.Graphics + * @param apiViewport GameLib.D3.API.Viewport + * @constructor + */ +GameLib.D3.Viewport = function ( + graphics, + apiViewport +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiViewport)) { + apiViewport = {}; + } + + GameLib.D3.API.Viewport.call( + this, + apiViewport.id, + apiViewport.name, + apiViewport.width, + apiViewport.height, + apiViewport.x, + apiViewport.y, + apiViewport.composer, + apiViewport.scene, + apiViewport.camera, + apiViewport.parentEntity + ); + + if (this.composer instanceof GameLib.D3.API.Composer) { + this.composer = new GameLib.D3.Composer( + this.graphics, + this.composer + ) + } + + if (this.renderer instanceof GameLib.D3.API.Renderer) { + this.renderer = new GameLib.D3.Renderer( + this.graphics, + this.renderer + ) + } + + if (this.scene instanceof GameLib.D3.API.Scene) { + this.scene = new GameLib.D3.Scene( + this.graphics, + this.scene + ) + } + + if (this.camera instanceof GameLib.D3.API.Camera) { + this.camera = new GameLib.D3.Camera( + this.graphics, + this.camera + ) + } + + this.buildIdToObject(); + + this.instance = this.createInstance(); +}; + +GameLib.D3.Viewport.prototype = Object.create(GameLib.D3.API.Viewport.prototype); +GameLib.D3.Viewport.prototype.constructor = GameLib.D3.Viewport; + +//GameLib.D3.Viewport.VIEWPORT_TYPE_GAME = 0x1; + +/** + * + * @param update + * @returns {*} + */ +GameLib.D3.Viewport.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + if (this.renderer) { + this.renderer.width = this.width - this.x; + this.renderer.height = this.height - this.y; + this.renderer.updateInstance(); + + this.renderer.instance.setViewport( + this.x, + this.y, + this.width, + this.height + ); + } else if (this.composer) { + this.composer.renderer.width = this.width - this.x; + this.composer.renderer.height = this.height - this.y; + this.composer.renderer.updateInstance(); + + this.composer.renderer.instance.setViewport( + this.x, + this.y, + this.width, + this.height + ); + + this.composer.passes.map( + function(pass) { + if (pass.camera instanceof GameLib.D3.Camera) { + pass.camera.aspect = (this.width - this.x) / (this.height / this.y); + pass.camera.updateInstance(); + } + }.bind(this) + ) + } + + if (this.camera) { + this.camera.aspect = (this.width - this.x) / (this.height / this.y); + this.camera.updateInstance(); + } + + return instance; +}; + +/** + * + */ +GameLib.D3.Viewport.prototype.updateInstance = function() { + this.instance = this.createInstance(true); +}; + +/** + * GameLib.D3.Viewport to GameLib.D3.API.Viewport + * @returns {GameLib.D3.API.Viewport} + */ +GameLib.D3.Viewport.prototype.toApiComponent = function() { + + var apiViewport = new GameLib.D3.API.Viewport( + this.id, + this.name, + this.width, + this.height, + this.x, + this.y, + GameLib.Utils.IdOrNull(this.composer), + GameLib.Utils.IdOrNull(this.scene), + GameLib.Utils.IdOrNull(this.camera), + GameLib.Utils.IdOrNull(this.parentEntity) + ); + + return apiViewport; +}; + +/** + * GameLib.D3.Viewport from Object Viewport + * @param graphics + * @param objectComponent + * @returns {GameLib.D3.Viewport} + * @constructor + */ +GameLib.D3.Viewport.FromObjectComponent = function(graphics, objectComponent) { + + var apiViewport = GameLib.D3.API.Viewport.FromObjectComponent(objectComponent); + + return new GameLib.D3.Viewport( + graphics, + apiViewport + ); +}; + +/** + * Component update override + */ +GameLib.D3.Viewport.prototype.update = function() { + + if (this.renderer && this.scene && this.camera) { + this.renderer.instance.render( + this.scene.instance, + this.camera.instance + ) + } else if (this.composer) { + this.composer.instance.render(); + } + +}; \ No newline at end of file diff --git a/src/game-lib-dom-element.js b/src/game-lib-dom-element.js new file mode 100644 index 0000000..a4c8d86 --- /dev/null +++ b/src/game-lib-dom-element.js @@ -0,0 +1,71 @@ +/** + * Runtime domElement for updating instance objects + * @param graphics GameLib.D3.Graphics + * @param apiDomElement GameLib.API.DomElement + * @constructor + */ +GameLib.DomElement = function (graphics, apiDomElement) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + GameLib.API.DomElement.call( + this, + apiDomElement.id, + apiDomElement.name, + apiDomElement.domElementId, + apiDomElement.parentEntity + ); + + this.instance = this.createInstance(); +}; + +GameLib.DomElement.prototype = Object.create(GameLib.API.DomElement.prototype); +GameLib.DomElement.prototype.constructor = GameLib.DomElement; + +/** + * Creates an instance domElement + * @param update + * @returns {*} + */ +GameLib.DomElement.prototype.createInstance = function(update) { + + var instance = document.getElementById(this.domElementId); + + return instance; +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +GameLib.DomElement.prototype.updateInstance = function() { + this.createInstance(true); +}; + +/** + * Converts runtime vector to API Vector + * @returns {GameLib.API.DomElement} + */ +GameLib.DomElement.prototype.toApiDomElement = function() { + return new GameLib.API.DomElement( + this.id, + this.name, + this.domElementId, + this.parentEntity + ); +}; + +/** + * Appends domInstance to DOM instance + * @param domInstance + */ +GameLib.DomElement.prototype.append = function(domInstance) { + this.instance.appendChild(domInstance); +}; + +/** + * Clears DOM instance + */ +GameLib.DomElement.prototype.clear = function() { + this.instance.innerHTML = ''; +}; diff --git a/src/game-lib-dom.js b/src/game-lib-dom.js new file mode 100644 index 0000000..913360c --- /dev/null +++ b/src/game-lib-dom.js @@ -0,0 +1,13 @@ +/** + * Runtime Dom + * @constructor + * @param document DOM Document + * @param window DOM Window + */ +GameLib.Dom = function( + document, + window +) { + this.document = document; + this.window = window; +}; diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index 576f733..8304b41 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -12,20 +12,36 @@ GameLib.EntityManager = function( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiEntityManager)) { + apiEntityManager = {}; + } + GameLib.API.EntityManager.call( this, - apiEntityManager.entities + apiEntityManager.id, + apiEntityManager.name, + apiEntityManager.entities, + apiEntityManager.parentEntity ); this.entities = this.entities.map( function(apiEntity) { - return new GameLib.Entity( - this.graphics, - apiEntity - ) + + if (apiEntity instanceof GameLib.API.Entity) { + return new GameLib.Entity( + this.graphics, + apiEntity + ) + } else { + console.warn('Entity not of type API.Entity'); + throw new Error('Entity not of type API.Entity'); + } + }.bind(this) ); + this.buildIdToObject(); + this.instance = this.createInstance(); }; @@ -49,9 +65,15 @@ GameLib.EntityManager.prototype.createInstance = function() { */ GameLib.EntityManager.prototype.createEntity = function(name) { - var apiEntity = new GameLib.API.Entity(null, name); + var apiEntity = new GameLib.API.Entity( + null, + name + ); - var entity = new GameLib.Entity(this.graphics, apiEntity); + var entity = new GameLib.Entity( + this.graphics, + apiEntity + ); this.entities.push(entity); @@ -157,7 +179,10 @@ GameLib.EntityManager.prototype.toApiEntityManager = function() { ); var apiEntityManager = new GameLib.API.EntityManager( - apiEntities + this.id, + this.name, + apiEntities, + this.parentEntity ); return apiEntityManager; diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 74fd19b..6297704 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -12,6 +12,10 @@ GameLib.Entity = function ( this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiEntity)) { + apiEntity = {}; + } + GameLib.API.Entity.call( this, apiEntity.id, @@ -19,6 +23,8 @@ GameLib.Entity = function ( apiEntity.components ); + this.componentToCreate = 0; + this.components = this.components.map( function (apiComponent) { @@ -31,6 +37,22 @@ GameLib.Entity = function ( return new GameLib.D3.Renderer(this.graphics, apiComponent); } + if (apiComponent instanceof GameLib.D3.API.RenderTarget) { + return new GameLib.D3.RenderTarget(this.graphics, apiComponent); + } + + if (apiComponent instanceof GameLib.D3.API.Pass) { + return new GameLib.D3.Pass(this.graphics, apiComponent); + } + + if (apiComponent instanceof GameLib.D3.API.Composer) { + return new GameLib.D3.Composer(this.graphics, apiComponent); + } + + if (apiComponent instanceof GameLib.D3.API.Camera) { + return new GameLib.D3.Camera(this.graphics, apiComponent); + } + if (apiComponent instanceof GameLib.D3.API.LookAt) { return new GameLib.D3.LookAt(this.graphics, apiComponent); } @@ -72,7 +94,12 @@ GameLib.Entity.prototype.createInstance = function() { * Adds a component to this entity through the instance (should notify the entity manager instance) * @param component */ -GameLib.Entity.prototype.addComponent = function(component) { +GameLib.Entity.prototype.addComponent = function() { + + if (this.componentToCreate == GameLib.Component.COMPONENT_CUSTOM_CODE) { + var component = new GameLib.D3.CustomCode(); + } + this.components.push(component); component.parentEntity = this; }; diff --git a/src/game-lib-game.js b/src/game-lib-game.js deleted file mode 100644 index 004fb3d..0000000 --- a/src/game-lib-game.js +++ /dev/null @@ -1,53 +0,0 @@ -GameLib.D3.Game = function ( - -) { - this.scenes = {}; -}; - -GameLib.D3.Game.prototype.addScene = function( - scene, - identifer -) { - this.scenes[identifer] = scene; -}; - -GameLib.D3.Game.prototype.processPhysics = function ( - dt -) { - for(var s in this.scenes) { - var scene = this.scenes[s]; - - for(var w in scene.worlds) { - var world = scene.worlds[w]; - world.step(dt); - } - } -}; - -GameLib.D3.Game.prototype.render = function( - dt, - renderer -) { - for(var s in this.scenes) { - var scene = this.scenes[s]; - scene.render(dt, renderer); - } -}; - -GameLib.D3.Game.prototype.update = function( - dt, - fixedDt -) { - for(var s in this.scenes) { - var scene = this.scenes[s]; - - for(var w in scene.worlds) { - var world = scene.worlds[w]; - // NOTE: We are calling the step function with a variable timestep! - world.step(fixedDt, dt); - } - - scene.update(dt); - scene.lateUpdate(dt); - } -}; \ No newline at end of file diff --git a/src/game-lib-matrix-4.js b/src/game-lib-matrix-4.js index a4924ab..46fb2be 100644 --- a/src/game-lib-matrix-4.js +++ b/src/game-lib-matrix-4.js @@ -8,11 +8,18 @@ */ GameLib.Matrix4 = function( graphics, - parentObject, apiMatrix4, + parentObject, grain ) { + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiMatrix4)) { + apiMatrix4 = {}; + } + GameLib.API.Matrix4.call( this, apiMatrix4.rows[0], @@ -21,10 +28,9 @@ GameLib.Matrix4 = function( apiMatrix4.rows[3] ); - this.graphics = graphics; - - this.graphics.isNotThreeThrow(); - + if (GameLib.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { @@ -32,53 +38,41 @@ GameLib.Matrix4 = function( } this.grain = grain; - this.rows[0] = new GameLib.Vector4( - this.graphics, - this, - this.rows[0], - grain - ); - - this.rows[1] = new GameLib.Vector4( - this.graphics, - this, - this.rows[1], - grain - ); - - this.rows[2] = new GameLib.Vector4( - this.graphics, - this, - this.rows[2], - grain - ); - - this.rows[3] = new GameLib.Vector4( - this.graphics, - this, - this.rows[3], - grain + this.rows = this.rows.map( + function(row) { + if (row instanceof GameLib.API.Vector4) { + return new GameLib.Vector4( + this.graphics, + row, + this, + this.grain + ); + } else { + console.warn('Attempted conversion of wrong instance'); + throw new Error('Attempted conversion of wrong instance'); + } + }.bind(this) ); this.forward = new GameLib.Vector4( this.graphics, - this, this.forward, - grain + this, + this.grain ); this.left = new GameLib.Vector4( this.graphics, - this, this.left, - grain + this, + this.grain ); this.up = new GameLib.Vector4( this.graphics, - this, this.up, - grain + this, + this.grain ); this.instance = this.createInstance(); @@ -136,10 +130,9 @@ GameLib.Matrix4.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject) { - if (this.parentObject.updateInstance) { - this.parentObject.updateInstance(); - } + if (this.parentObject && + this.parentObject.updateInstance) { + this.parentObject.updateInstance(); } }; @@ -148,12 +141,18 @@ GameLib.Matrix4.prototype.updateInstance = function() { * @returns {*} */ GameLib.Matrix4.prototype.toApiMatrix = function () { - return new GameLib.API.Matrix4( - this.rows[0].toApiVector(), - this.rows[1].toApiVector(), - this.rows[2].toApiVector(), - this.rows[3].toApiVector() - ) + + return this.rows.map( + function(row) { + if (row instanceof GameLib.Vector4) { + return row.toApiVector(); + } else { + console.warn('Incompatible conversion to API matrix for vector: ', row); + throw new Error('Incompatible conversion to API matrix for a vector'); + } + } + ); + }; /** @@ -166,40 +165,7 @@ GameLib.Matrix4.prototype.toApiMatrix = function () { */ GameLib.Matrix4.FromObjectMatrix = function(graphics, objectMatrix, parentObject) { - if (GameLib.Utils.UndefinedOrNull(objectMatrix)) { - return new GameLib.Matrix4( - graphics, - parentObject, - new GameLib.API.Matrix4() - ) - } - - var apiMatrix = new GameLib.API.Matrix4( - new GameLib.API.Vector4( - objectMatrix.rows[0].x, - objectMatrix.rows[0].y, - objectMatrix.rows[0].z, - objectMatrix.rows[0].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[1].x, - objectMatrix.rows[1].y, - objectMatrix.rows[1].z, - objectMatrix.rows[1].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[2].x, - objectMatrix.rows[2].y, - objectMatrix.rows[2].z, - objectMatrix.rows[2].w - ), - new GameLib.API.Vector4( - objectMatrix.rows[3].x, - objectMatrix.rows[3].y, - objectMatrix.rows[3].z, - objectMatrix.rows[3].w - ) - ); + var apiMatrix = new GameLib.API.Matrix4.FromObjectMatrix(objectMatrix); return new GameLib.Matrix4( graphics, @@ -208,6 +174,13 @@ GameLib.Matrix4.FromObjectMatrix = function(graphics, objectMatrix, parentObject ) }; +/** + * Lookat + * @param position + * @param target + * @param up + * @returns {GameLib.Matrix4} + */ GameLib.Matrix4.prototype.lookAt = function (position, target, up) { var pv = new GameLib.API.Vector3(position.x, position.y, position.z); @@ -256,35 +229,42 @@ GameLib.Matrix4.prototype.lookAt = function (position, target, up) { return this; }; +/** + * Identity + */ GameLib.Matrix4.prototype.identity = function () { this.rows = [ new GameLib.Vector4( this.graphics, - this, new GameLib.API.Vector4(1,0,0,0), + this, this.grain ), new GameLib.Vector4( this.graphics, - this, new GameLib.API.Vector4(0,1,0,0), + this, this.grain ), new GameLib.Vector4( this.graphics, - this, new GameLib.API.Vector4(0,0,1,0), + this, this.grain ), new GameLib.Vector4( this.graphics, - this, new GameLib.API.Vector4(0,0,0,1), + this, this.grain ) ]; }; +/** + * Transpose + * @returns {GameLib.Matrix4} + */ GameLib.Matrix4.prototype.transpose = function () { this.temp[0].x = this.rows[0].x; diff --git a/src/game-lib-mouse.js b/src/game-lib-mouse.js new file mode 100644 index 0000000..f0a6d7d --- /dev/null +++ b/src/game-lib-mouse.js @@ -0,0 +1,62 @@ +/** + * Runtime mouse for updating instance objects + * @param graphics GameLib.D3.Graphics + * @param apiMouse GameLib.API.Mouse + * @constructor + */ +GameLib.Mouse = function (graphics, apiMouse) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + GameLib.API.Mouse.call( + this, + apiMouse.id, + apiMouse.name, + apiMouse.x, + apiMouse.y, + apiMouse.parentEntity + ); + + this.instance = this.createInstance(); +}; + +GameLib.Mouse.prototype = Object.create(GameLib.API.Mouse.prototype); +GameLib.Mouse.prototype.constructor = GameLib.Mouse; + +/** + * Creates an instance mouse + * @param update + * @returns {*} + */ +GameLib.Mouse.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + } + + return instance; +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +GameLib.Mouse.prototype.updateInstance = function() { + this.createInstance(true); +}; + +/** + * Converts runtime vector to API Vector + * @returns {GameLib.API.Mouse} + */ +GameLib.Mouse.prototype.toApiMouse = function() { + return new GameLib.API.Mouse( + this.id, + this.name, + this.x, + this.y, + this.parentEntity + ); +}; diff --git a/src/game-lib-quaternion.js b/src/game-lib-quaternion.js index 4708b03..823307d 100644 --- a/src/game-lib-quaternion.js +++ b/src/game-lib-quaternion.js @@ -8,39 +8,39 @@ */ GameLib.Quaternion = function ( graphics, - parentObject, apiQuaternion, + parentObject, grain ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiQuaternion)) { + apiQuaternion = {}; + } + GameLib.API.Quaternion.call( this, apiQuaternion.x, apiQuaternion.y, apiQuaternion.z, apiQuaternion.w, - new GameLib.API.Vector3( - apiQuaternion.axis.x, - apiQuaternion.axis.y, - apiQuaternion.axis.z - ), + apiQuaternion.axis, apiQuaternion.angle ); - this.axis = new GameLib.Vector3( - this.graphics, - this, - this.axis, - 0.001 - ); - if (GameLib.Utils.UndefinedOrNull(parentObject)) { parentObject = null; } this.parentObject = parentObject; + this.axis = new GameLib.Vector3( + this.graphics, + this.axis, + this, + this.grain + ); + if (GameLib.Utils.UndefinedOrNull(grain)) { grain = 0.001; } @@ -68,7 +68,12 @@ GameLib.Quaternion.prototype.createInstance = function(update) { instance.z = this.z; instance.w = this.w; } else { - instance = new THREE.Quaternion(this.x, this.y, this.z, this.w); + instance = new THREE.Quaternion( + this.x, + this.y, + this.z, + this.w + ); } return instance; @@ -81,7 +86,8 @@ GameLib.Quaternion.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject.updateInstance) { + if (this.parentObject && + this.parentObject.updateInstance) { this.parentObject.updateInstance(); } }; diff --git a/src/game-lib-system-a.js b/src/game-lib-system-a.js deleted file mode 100644 index e2c6c86..0000000 --- a/src/game-lib-system-a.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * System takes care of updating all the entities (based on their component data) - * @param entityManager GameLib.EntityManager - * @constructor - */ -GameLib.System = function( - entityManager -) { - if (GameLib.Utils.UndefinedOrNull(entityManager)) { - entityManager = null; - } - this.entityManager = entityManager; - -}; - -GameLib.System.SYSTEM_TYPE_RENDER = 0x1; -GameLib.System.SYSTEM_TYPE_ANIMATION = 0x2; -GameLib.System.SYSTEM_TYPE_INPUT = 0x3; -GameLib.System.SYSTEM_TYPE_ALL = 0x4; - -/** - * @callback - * @override - */ -GameLib.System.prototype.start = function() {}; - -/** - * @callback - * @override - */ -GameLib.System.prototype.update = function() {}; - -/** - * @callback - * @override - */ -GameLib.System.prototype.stop = function() {}; \ No newline at end of file diff --git a/src/game-lib-system-animation.js b/src/game-lib-system-animation.js deleted file mode 100644 index 9bd4c29..0000000 --- a/src/game-lib-system-animation.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * System takes care of updating all the entities (based on their component data) - * @constructor - */ -GameLib.System.Animation = function( - entityManager -) { - GameLib.System.call( - this, - entityManager - ); - - - this.pathFollowingObjects = []; - this.followObjects = []; - this.meshObjects = []; - this.lookAtObjects = []; - this.cameraObjects = []; - this.lightObjects = []; -}; - -GameLib.System.Animation.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Animation.prototype.constructor = GameLib.System.Animation; - -GameLib.System.Animation.prototype.start = function() { - this.pathFollowingObjects = this.entityManager.query([GameLib.D3.PathFollowing]); - this.followObjects = this.entityManager.query([GameLib.D3.Follow]); - this.meshObjects = this.entityManager.query([GameLib.D3.Mesh]); - this.lookAtObjects = this.entityManager.query([GameLib.D3.LookAt]); - this.cameraObjects = this.entityManager.query([GameLib.D3.Camera]); - this.lightObjects = this.entityManager.query([GameLib.D3.Light]); -}; - -/** - * @override - */ -GameLib.System.Animation.prototype.update = function(deltaTime) { - - this.pathFollowingObjects.forEach(function(object) { - object.update(deltaTime); - }); - - this.followObjects.forEach(function(object) { - object.update(deltaTime); - }); - - this.lookAtObjects.forEach(function(object) { - object.update(deltaTime); - }); - - this.meshObjects.forEach(function(object) { - object.updateInstance(); - }); - - this.cameraObjects.forEach(function(object) { - object.updateInstance(); - }); - - this.lightObjects.forEach(function(object) { - object.updateInstance(); - }); -}; - -GameLib.System.Animation.prototype.stop = function() { - this.pathFollowingObjects = []; - this.followObjects = []; - this.meshObjects = []; - this.lookAtObjects = []; - this.cameraObjects = []; - this.lightObjects = []; -}; \ No newline at end of file diff --git a/src/game-lib-system-input.js b/src/game-lib-system-input.js deleted file mode 100644 index 74119fa..0000000 --- a/src/game-lib-system-input.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * System takes care of updating all the entities (based on their component data) - * @constructor - */ -GameLib.System.Input = function( - entityManager -) { - GameLib.System.call( - this, - entityManager - ); - - this.driveInputObjects = []; - -}; - -GameLib.System.Input.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Input.prototype.constructor = GameLib.System.Input; - -GameLib.System.Input.prototype.start = function() { - this.driveInputObjects = this.entityManager.query([GameLib.D3.Input.Drive]); -}; - -/** - * - * @param deltaTime - */ -GameLib.System.Input.prototype.update = function(deltaTime) { - this.driveInputObjects.forEach( - function(object) { - object.update(deltaTime); - } - ); -}; - -GameLib.System.Input.prototype.stop = function() { - this.driveInputObjects = []; -}; \ No newline at end of file diff --git a/src/game-lib-system-render.js b/src/game-lib-system-render.js deleted file mode 100644 index 496eac6..0000000 --- a/src/game-lib-system-render.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * System takes care of updating all the entities (based on their component data) - * @constructor - */ -GameLib.System.Render = function( - entityManager, - domElement, - stats -) { - GameLib.System.call( - this, - entityManager - ); - - if (GameLib.Utils.UndefinedOrNull(domElement)) { - domElement = null; - } - this.domElement = domElement; - - if (GameLib.Utils.UndefinedOrNull(stats)) { - stats = null; - } - this.stats = stats; - - this.renderers = []; - -}; - -GameLib.System.Render.prototype = Object.create(GameLib.System.prototype); -GameLib.System.Render.prototype.constructor = GameLib.System.Render; - -/** - * - */ -GameLib.System.Render.prototype.start = function() { - - this.domElement.innerHTML = ''; - this.domElement.appendChild(this.stats.dom); - - this.renderers = this.entityManager.query([GameLib.D3.Renderer]); - this.renderers.forEach( - function (renderer) { - - if (!renderer.instance) { - renderer.createInstance(); - } else { - renderer.updateInstance(); - } - - this.domElement.appendChild(renderer.instance.domElement); - - }.bind(this) - ); -}; - -/** - * @override - */ -GameLib.System.Render.prototype.update = function(deltaTime) { - -// var renderers = this.entityManager.query([GameLib.D3.Renderer]); - - this.renderers.forEach( - function (renderer) { - renderer.render(deltaTime); - } - ); - - // renderObjects.forEach(function(object) { - // - // //TODO camera component stuff - // object.quaternion.x = this.parentEntity.quaternion.x; - // object.quaternion.y = this.parentEntity.quaternion.y; - // object.quaternion.z = this.parentEntity.quaternion.z; - // object.quaternion.w = this.parentEntity.quaternion.w; - // - // object.position.x = this.parentEntity.position.x; - // object.position.y = this.parentEntity.position.y; - // object.position.z = this.parentEntity.position.z; - // - // object.updateInstance(); - // - // //TODO scene component stuff - // renderer.render(this.instance, this.cameras[this.activeCameraIndex].instance); - // }); - -}; - -GameLib.System.Render.prototype.stop = function() { - - this.domElement.innerHTML = ''; - - this.renderers = []; -}; \ No newline at end of file diff --git a/src/game-lib-system.js b/src/game-lib-system.js new file mode 100644 index 0000000..b786131 --- /dev/null +++ b/src/game-lib-system.js @@ -0,0 +1,191 @@ +/** + * System takes care of updating all the entities (based on their component data) + * @param graphics + * @param apiSystem GameLib.API.System + * @constructor + */ +GameLib.System = function( + graphics, + apiSystem +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiSystem)) { + apiSystem = {}; + } + + GameLib.API.System.call( + this, + apiSystem.id, + apiSystem.name, + apiSystem.systemType, + apiSystem.entityManager, + apiSystem.domElement, + apiSystem.domStats, + apiSystem.parentEntity + ); + + +}; + +GameLib.System.prototype = Object.create(GameLib.API.System.prototype); +GameLib.System.prototype.constructor = GameLib.System; + +GameLib.System.SYSTEM_TYPE_RENDER = 0x1; +GameLib.System.SYSTEM_TYPE_ANIMATION = 0x2; +GameLib.System.SYSTEM_TYPE_INPUT = 0x4; +GameLib.System.SYSTEM_TYPE_ALL = 0x7; + +/** + * @callback + * @override + */ +GameLib.System.prototype.start = function() { + + if (this.systemType == GameLib.System.SYSTEM_TYPE_INPUT) { + this.driveInputObjects = this.entityManager.query([GameLib.D3.Input.Drive]); + } + + 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'); + } + + this.domElement.innerHTML = ''; + + if (GameLib.Utils.UndefinedOrNull(this.domStats)) { + console.warn('No stats DOM - will run the render process without statistics information'); + } else { + this.domElement.appendChild(this.domStats); + } + + this.renderers = this.entityManager.query([GameLib.D3.Renderer]); + this.renderers.forEach( + function (renderer) { + this.domElement.appendChild(renderer.instance.domElement); + }.bind(this) + ); + + this.viewports = this.entityManager.query([GameLib.D3.Viewport]); + } + + if (this.systemType == GameLib.System.SYSTEM_TYPE_ANIMATION) { + this.pathFollowingObjects = this.entityManager.query([GameLib.D3.PathFollowing]); + this.followObjects = this.entityManager.query([GameLib.D3.Follow]); + this.meshObjects = this.entityManager.query([GameLib.D3.Mesh]); + this.lookAtObjects = this.entityManager.query([GameLib.D3.LookAt]); + this.cameraObjects = this.entityManager.query([GameLib.D3.Camera]); + this.lightObjects = this.entityManager.query([GameLib.D3.Light]); + } + +}; + +/** + * @callback + * @override + */ +GameLib.System.prototype.update = function(deltaTime) { + + if (this.systemType == GameLib.System.SYSTEM_TYPE_INPUT) { + this.driveInputObjects.forEach( + function(object) { + object.update(deltaTime); + } + ); + } + + if (this.systemType == GameLib.System.SYSTEM_TYPE_ANIMATION) { + this.pathFollowingObjects.forEach( + function(object) { + object.update(deltaTime); + } + ); + + this.followObjects.forEach( + function(object) { + object.update(deltaTime); + } + ); + + this.lookAtObjects.forEach( + function(object) { + object.update(deltaTime); + } + ); + + this.meshObjects.forEach( + function(object) { + object.updateInstance(); + } + ); + + this.cameraObjects.forEach( + function(object) { + object.updateInstance(); + } + ); + + this.lightObjects.forEach( + function(object) { + object.updateInstance(); + } + ); + } + + if (this.systemType == GameLib.System.SYSTEM_TYPE_RENDER) { + this.viewports.forEach( + function (viewport) { + viewport.update(deltaTime); + } + ); + } + +}; + +/** + * @callback + * @override + */ +GameLib.System.prototype.stop = function() { + + if (this.systemType == GameLib.System.SYSTEM_TYPE_INPUT) { + this.driveInputObjects = []; + } + + if (this.systemType == GameLib.System.SYSTEM_TYPE_RENDER) { + this.domElement.innerHTML = 'Rendering System Stopped'; + this.renderers = []; + this.viewports = []; + } + + if (this.systemType == GameLib.System.SYSTEM_TYPE_ANIMATION) { + this.pathFollowingObjects = []; + this.followObjects = []; + this.meshObjects = []; + this.lookAtObjects = []; + this.cameraObjects = []; + this.lightObjects = []; + } + +}; + +/** + * Converts runtime vector to API Vector + * @returns {GameLib.API.Mouse} + */ +GameLib.System.prototype.toApiSystem = function() { + + //TODO + return new GameLib.API.System( + this.id, + this.name, + this.systemType, + this.domElement.toApiDo, + this.domStats, + GameLib.Utils.IdOrNull(this.parentEntity) + ); +}; diff --git a/src/game-lib-utils.js b/src/game-lib-utils.js index 6caf11e..a032f36 100644 --- a/src/game-lib-utils.js +++ b/src/game-lib-utils.js @@ -61,6 +61,50 @@ GameLib.Utils.ObjectIdWithNameInArray = function(name, array) { // } // }; +GameLib.Utils.LoadIdsFromArrayToIdObject = function(array, idToObject) { + array.map( + function(object) { + + if (object.buildIdToObject) { + object.buildIdToObject(); + var _idToObject = object.idToObject; + + for (var property in _idToObject) { + if (_idToObject.hasOwnProperty(property)) { + idToObject[property] = _idToObject[property]; + } + } + } + + idToObject[object.id] = object; + } + ); + + return idToObject; +}; + +GameLib.Utils.LoadIdsFromObjectToIdObject = function(object, idToObject) { + + if (!object) { + return idToObject; + } + + if (object.buildIdToObject) { + object.buildIdToObject(); + var _idToObject = object.idToObject; + + for (var property in _idToObject) { + if (_idToObject.hasOwnProperty(property)) { + idToObject[property] = _idToObject[property]; + } + } + } + + idToObject[object.id] = object; + + return idToObject; +}; + GameLib.Utils.UndefinedOrNull = function ( variable ) { diff --git a/src/game-lib-vector2.js b/src/game-lib-vector2.js index 87ed63b..da8e7f7 100644 --- a/src/game-lib-vector2.js +++ b/src/game-lib-vector2.js @@ -6,20 +6,28 @@ * @param grain Number * @constructor */ -GameLib.Vector2 = function (graphics, parentObject, apiVector2, grain) { - - for (var property in apiVector2) { - if (apiVector2.hasOwnProperty(property)) { - this[property] = apiVector2[property]; - } - } - - GameLib.Utils.Extend(GameLib.Vector2, GameLib.API.Vector2); - +GameLib.Vector2 = function ( + graphics, + apiVector2, + parentObject, + grain +) { this.graphics = graphics; - this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiVector2)) { + apiVector2 = {}; + } + + GameLib.API.Vector2.call( + this, + apiVector2.x, + apiVector2.y + ); + + if (GameLib.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { @@ -30,6 +38,10 @@ GameLib.Vector2 = function (graphics, parentObject, apiVector2, grain) { this.instance = this.createInstance(); }; +GameLib.Vector2.prototype = Object.create(GameLib.API.Vector2.prototype); +GameLib.Vector2.prototype.constructor = GameLib.Vector2; + + /** * Creates an instance vector2 * @param update @@ -44,7 +56,7 @@ GameLib.Vector2.prototype.createInstance = function(update) { instance.x = this.x; instance.y = this.y; } else { - instance = new this.graphics.instance.Vector2(this.x, this.y); + instance = new THREE.Vector2(this.x, this.y); } return instance; @@ -57,7 +69,8 @@ GameLib.Vector2.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject.updateInstance) { + if (this.parentObject && + this.parentObject.updateInstance) { this.parentObject.updateInstance(); } }; @@ -73,99 +86,209 @@ GameLib.Vector2.prototype.toApiVector = function() { ); }; +/** + * Copy + * TODO: Test + * @param v optional + * @returns {GameLib.Vector2} + */ GameLib.Vector2.prototype.copy = function (v) { - if (!GameLib.Utils.UndefinedOrNull(v)) { + + if (GameLib.Utils.UndefinedOrNull(v)) { + + return new GameLib.Vector2( + this.graphics, + new GameLib.API.Vector2( + this.x, + this.y + ), + this.parentObject, + this.grain + ); + + } else { + this.x = v.x; this.y = v.y; + return this; - } else { - return new GameLib.Vector2( - this.x, - this.y - ); } }; +/** + * Equals + * TODO: Test + * @param v + * @returns {boolean} + */ GameLib.Vector2.prototype.equals = function(v) { - return (((this.x == v.x) && - (this.y == v.y)) || - ((this.y == v.x) && - (this.x == v.y))); + + if ((this.x == v.x) && + (this.y == v.y)) { + return true; + } else { + return false; + } + }; +/** + * Add + * TODO: Test + * @param v + */ GameLib.Vector2.prototype.add = function(v) { - return new GameLib.Vector2( - this.x + v.x, - this.y + v.y - ); + + if ( + v instanceof GameLib.API.Vector2 || + v instanceof GameLib.API.Vector3 || + v instanceof GameLib.API.Vector4 || + v instanceof GameLib.API.Quaternion + ) { + this.x += v.x; + this.y += v.y; + } else { + console.warn('Could not add Vector2'); + throw new Error('Could not add Vector2'); + } + }; +/** + * Subtract + * TODO: Test + * @param v + */ GameLib.Vector2.prototype.subtract = function(v) { - return new GameLib.Vector2( - this.x - v.x, - this.y - v.y - ); + + if ( + v instanceof GameLib.API.Vector2 || + v instanceof GameLib.API.Vector3 || + v instanceof GameLib.API.Vector4 || + v instanceof GameLib.API.Quaternion + ) { + this.x -= v.x; + this.y -= v.y; + } else { + console.warn('Could not subtract Vector2'); + throw new Error('Could not subtract Vector2'); + } + }; +/** + * Multiply + * TODO: Test + * @param v + */ GameLib.Vector2.prototype.multiply = function(v) { - if (v instanceof GameLib.Vector2) { - return new GameLib.Vector2( - this.x * v.x, - this.y * v.y - ); - } else if (isNumber(v)) { - return new GameLib.Vector2( - this.x * v, - this.y * v - ); + + if ( + v instanceof GameLib.API.Vector2 || + v instanceof GameLib.API.Vector3 || + v instanceof GameLib.API.Vector4 || + v instanceof GameLib.API.Quaternion + ) { + this.x *= v.x; + this.y *= v.y; + } else if (typeof v == 'number') { + this.x *= v; + this.y *= v; + } else { + console.warn('Could not multiply Vector2'); + throw new Error('Could not multiply Vector2'); } + }; +/** + * Divide + * TODO: Test + * @param v + */ GameLib.Vector2.prototype.divide = function(v) { - if (v instanceof GameLib.Vector2) { - return new GameLib.Vector2( - this.x * (1.0 / v.x), - this.y * (1.0 / v.y) - ); - } else if (isNumber(v)) { - var invS = 1.0 / v; - return new GameLib.Vector2( - this.x * invS, - this.y * invS - ); + + if ( + v instanceof GameLib.API.Vector2 || + v instanceof GameLib.API.Vector3 || + v instanceof GameLib.API.Vector4 || + v instanceof GameLib.API.Quaternion + ) { + this.x *= (1.0 / v.x); + this.y *= (1.0 / v.y); + } else if (typeof v == 'number') { + this.x *= 1.0 / v; + this.y *= 1.0 / v; + } else { + console.warn('Could not divide Vector2'); + throw new Error('Could not divide Vector2'); } + }; -GameLib.Vector2.prototype.set = function(x, y) { - this.x = x; - this.y = y; -}; - +/** + * Clamp + * TODO: Test + * @param min GameLib.API.Vector2 + * @param max GameLib.API.Vector2 + * @returns {GameLib.Vector2} + */ GameLib.Vector2.prototype.clamp = function(min, max) { - return new GameLib.Vector2( - Math.max(min.x, Math.min(max.x, this.x)), - Math.max(min.y, Math.min(max.y, this.y)) + + this.x = Math.max(min.x, Math.min(max.x, this.x)); + this.y = Math.max(min.y, Math.min(max.y, this.y)); + + return this; + +}; + +/** + * Length + * TODO: Test + * @returns {number} + */ +GameLib.Vector2.prototype.length = function() { + return Math.sqrt( + this.x * this.x + this.y * this.y ); }; -GameLib.Vector2.prototype.length = function() { - return Math.sqrt(this.x * this.x + this.y * this.y); -}; - +/** + * Dot product + * TODO: Test + * @param v + * @returns {number} + */ GameLib.Vector2.prototype.dot = function(v) { return this.x * v.x + this.y * v.y; }; +/** + * Normalize + * TODO: Test + */ GameLib.Vector2.prototype.normalize = function() { return this.multiply(1.0 / this.length()); }; +/** + * TODO: Test + * Angle between this vector and origin + * @returns {number} + */ GameLib.Vector2.prototype.angle = function() { var angle = Math.atan2(this.y, this.x); if ( angle < 0 ) angle += 2 * Math.PI; return angle; }; +/** + * Interpolate to v from here + * TODO: Test + * @param v + * @param alpha + * @returns {GameLib.Vector2} + */ GameLib.Vector2.prototype.lerp = function ( v, alpha ) { return new GameLib.Vector2( this.x + ( v.x - this.x ) * alpha, diff --git a/src/game-lib-vector3.js b/src/game-lib-vector3.js index 5f688e4..9e48636 100644 --- a/src/game-lib-vector3.js +++ b/src/game-lib-vector3.js @@ -1,25 +1,34 @@ /** * Runtime apiVector3 for updating instance objects * @param graphics GameLib.D3.Graphics - * @param parentObject GameLib.D3.* * @param apiVector3 GameLib.API.Vector3 + * @param parentObject GameLib.* * @param grain Number * @constructor */ -GameLib.Vector3 = function (graphics, parentObject, apiVector3, grain) { - - for (var property in apiVector3) { - if (apiVector3.hasOwnProperty(property)) { - this[property] = apiVector3[property]; - } - } - - GameLib.Utils.Extend(GameLib.Vector3, GameLib.API.Vector3); - +GameLib.Vector3 = function ( + graphics, + apiVector3, + parentObject, + grain +) { this.graphics = graphics; - this.graphics.isNotThreeThrow(); + if (GameLib.Utils.UndefinedOrNull(apiVector3)) { + apiVector3 = {}; + } + + GameLib.API.Vector3.call( + this, + apiVector3.x, + apiVector3.y, + apiVector3.z + ); + + if (GameLib.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { @@ -30,6 +39,9 @@ GameLib.Vector3 = function (graphics, parentObject, apiVector3, grain) { this.instance = this.createInstance(); }; +GameLib.Vector3.prototype = Object.create(GameLib.API.Vector3.prototype); +GameLib.Vector3.prototype.constructor = GameLib.Vector3; + /** * Creates an instance vector3 * @param update @@ -45,7 +57,11 @@ GameLib.Vector3.prototype.createInstance = function(update) { instance.y = this.y; instance.z = this.z; } else { - instance = new THREE.Vector3(this.x, this.y, this.z); + instance = new THREE.Vector3( + this.x, + this.y, + this.z + ); } return instance; @@ -58,7 +74,8 @@ GameLib.Vector3.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject.updateInstance) { + if (this.parentObject && + this.parentObject.updateInstance) { this.parentObject.updateInstance(); } }; @@ -75,17 +92,17 @@ GameLib.Vector3.prototype.toApiVector = function() { }; /** - * Converts runtime vector to API Vector + * Creates a new copy of this Vector3 */ GameLib.Vector3.prototype.copy = function() { return new GameLib.Vector3( this.graphics, - this.parentObject, new GameLib.API.Vector3( this.x, this.y, this.z ), + this.parentObject, this.grain ) }; diff --git a/src/game-lib-vector4.js b/src/game-lib-vector4.js index 4a3f4d1..654b921 100644 --- a/src/game-lib-vector4.js +++ b/src/game-lib-vector4.js @@ -1,12 +1,24 @@ /** * Runtime apiVector4 for updating instance objects * @param graphics GameLib.D3.Graphics - * @param parentObject GameLib.D3.* * @param apiVector4 GameLib.API.Vector4 + * @param parentObject GameLib.* * @param grain Number * @constructor */ -GameLib.Vector4 = function (graphics, parentObject, apiVector4, grain) { +GameLib.Vector4 = function ( + graphics, + apiVector4, + parentObject, + grain +) { + + this.graphics = graphics; + this.graphics.isNotThreeThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiVector4)) { + apiVector4 = {}; + } GameLib.API.Vector4.call( this, @@ -16,10 +28,9 @@ GameLib.Vector4 = function (graphics, parentObject, apiVector4, grain) { apiVector4.w ); - this.graphics = graphics; - - this.graphics.isNotThreeThrow(); - + if (GameLib.Utils.UndefinedOrNull(parentObject)) { + parentObject = null; + } this.parentObject = parentObject; if (GameLib.Utils.UndefinedOrNull(grain)) { @@ -62,7 +73,8 @@ GameLib.Vector4.prototype.updateInstance = function() { this.createInstance(true); - if (this.parentObject.updateInstance) { + if (this.parentObject && + this.parentObject.updateInstance) { this.parentObject.updateInstance(); } }; diff --git a/src/game-lib-z.js b/src/game-lib-z.js index 771958c..f586a6c 100644 --- a/src/game-lib-z.js +++ b/src/game-lib-z.js @@ -1,3 +1,9 @@ + + + + + + if (typeof module !== 'undefined') { module.exports = GameLib; } \ No newline at end of file