From 5a9e24a798fbb72ff3702c56d9ff0a0c33c5c739 Mon Sep 17 00:00:00 2001 From: "Theunis J. Botha" Date: Mon, 12 Dec 2016 17:24:05 +0100 Subject: [PATCH] stable load and save for components --- ...interface.js => game-lib-api-component.js} | 7 +- src/game-lib-api-entity.js | 56 +-- src/game-lib-api-vector4.js | 22 + src/game-lib-camera.js | 4 +- src/game-lib-color.js | 10 +- src/game-lib-component-a.js | 324 +++++++++++++ src/game-lib-component-camera.js | 72 ++- src/game-lib-component-colorflash.js | 2 +- src/game-lib-component-colorlerp.js | 2 +- src/game-lib-component-entity-parent.js | 2 +- src/game-lib-component-entity-permutation.js | 2 +- src/game-lib-component-fly-controls.js | 2 +- src/game-lib-component-follow.js | 47 +- src/game-lib-component-interface.js | 438 ------------------ src/game-lib-component-look-at.js | 45 +- src/game-lib-component-mesh-permutation.js | 2 +- src/game-lib-component-offsettor.js | 2 +- src/game-lib-component-path-ai.js | 2 +- src/game-lib-component-path-controls.js | 2 +- src/game-lib-component-path-following.js | 43 +- ...-lib-component-raycast-vehicle-controls.js | 2 +- src/game-lib-component-rotator.js | 2 +- src/game-lib-component-trigger-box-box.js | 2 +- src/game-lib-component-trigger-box-sphere.js | 2 +- ...ame-lib-component-trigger-sphere-sphere.js | 2 +- ...b-component-vehicle-ai-object-avoidance.js | 2 +- ...-lib-component-vehicle-ai-path-steering.js | 2 +- src/game-lib-entity.js | 230 ++++----- src/game-lib-image.js | 5 +- src/game-lib-matrix-4.js | 7 + src/game-lib-quaternion.js | 10 +- src/game-lib-raycast-vehicle.js | 2 +- src/game-lib-rigid-body.js | 2 +- src/game-lib-scene.js | 115 ++--- src/game-lib-utils.js | 24 +- src/game-lib-vector2.js | 10 +- src/game-lib-vector3.js | 1 - src/game-lib-vector4.js | 80 ++++ 38 files changed, 732 insertions(+), 854 deletions(-) rename src/{game-lib-api-component-interface.js => game-lib-api-component.js} (97%) create mode 100644 src/game-lib-api-vector4.js create mode 100644 src/game-lib-component-a.js delete mode 100644 src/game-lib-component-interface.js create mode 100644 src/game-lib-vector4.js diff --git a/src/game-lib-api-component-interface.js b/src/game-lib-api-component.js similarity index 97% rename from src/game-lib-api-component-interface.js rename to src/game-lib-api-component.js index 9d29925..003d97f 100644 --- a/src/game-lib-api-component-interface.js +++ b/src/game-lib-api-component.js @@ -30,15 +30,16 @@ * @param currentPosition * @constructor */ -GameLib.D3.API.ComponentInterface = function( +GameLib.D3.API.Component = function( // General id, name, componentType, + parentEntity, // Camera Component camera, - parentEntity, + // Follow Component targetEntity, @@ -83,7 +84,7 @@ GameLib.D3.API.ComponentInterface = function( this.name = name; if (GameLib.D3.Utils.UndefinedOrNull(componentType)) { - componentType = GameLib.D3.ComponentInterface.COMPONENT_INTERFACE; + componentType = GameLib.D3.Component.COMPONENT_INTERFACE; } this.componentType = componentType; diff --git a/src/game-lib-api-entity.js b/src/game-lib-api-entity.js index edf71db..3c37e85 100644 --- a/src/game-lib-api-entity.js +++ b/src/game-lib-api-entity.js @@ -1,8 +1,8 @@ /** - * Entity API + * Entity API Object (for storing / loading entities to and from API) * @param id * @param name - * @param ids + * @param components GameLib.D3.Component[] * @param position * @param quaternion * @param scale @@ -10,10 +10,10 @@ * @param mesh GameLib.D3.Mesh * @constructor */ -GameLib.D3.API.Entity = function Entity( +GameLib.D3.API.Entity = function( id, name, - ids, + components, position, quaternion, scale, @@ -30,10 +30,10 @@ GameLib.D3.API.Entity = function Entity( } this.name = name; - if (GameLib.D3.Utils.UndefinedOrNull(ids)) { - ids = []; + if (GameLib.D3.Utils.UndefinedOrNull(components)) { + components = []; } - this.ids = ids; + this.components = components; if(GameLib.D3.Utils.UndefinedOrNull(position)) { position = new GameLib.D3.API.Vector3(); @@ -50,7 +50,6 @@ GameLib.D3.API.Entity = function Entity( } this.scale = scale; - if (GameLib.D3.Utils.UndefinedOrNull(parentScene)) { parentScene = null; } @@ -61,44 +60,3 @@ GameLib.D3.API.Entity = function Entity( } this.mesh = mesh; }; - - -GameLib.D3.Entity = function Entity( - id, - name, - ids, - position, - quaternion, - scale -) { - this.id = id; - - if (GameLib.D3.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; - } - this.name = name; - - if (GameLib.D3.Utils.UndefinedOrNull(ids)) { - ids = []; - } - this.ids = ids; - - // constructed at runtime - this.parentScene = null; - this.mesh = null; - - if(GameLib.D3.Utils.UndefinedOrNull(position)) { - position = new GameLib.D3.API.Vector3(0, 0, 0); - } - this.position = position; - - if(GameLib.D3.Utils.UndefinedOrNull(quaternion)) { - quaternion = new GameLib.D3.API.Quaternion(0, 0, 0, 1); - } - this.quaternion = quaternion; - - if(GameLib.D3.Utils.UndefinedOrNull(scale)) { - scale = new GameLib.D3.API.Vector3(1, 1, 1); - } - this.scale = scale; -}; \ No newline at end of file diff --git a/src/game-lib-api-vector4.js b/src/game-lib-api-vector4.js new file mode 100644 index 0000000..433892a --- /dev/null +++ b/src/game-lib-api-vector4.js @@ -0,0 +1,22 @@ +GameLib.D3.API.Vector4 = function (x, y, z, w) { + + if (GameLib.D3.Utils.UndefinedOrNull(x)) { + x = 0; + } + this.x = x; + + if (GameLib.D3.Utils.UndefinedOrNull(y)) { + y = 0; + } + this.y = y; + + if (GameLib.D3.Utils.UndefinedOrNull(z)) { + z = 0; + } + this.z = z; + + if (GameLib.D3.Utils.UndefinedOrNull(w)) { + w = 1; + } + this.w = w; +}; \ No newline at end of file diff --git a/src/game-lib-camera.js b/src/game-lib-camera.js index 1c65014..101bff5 100644 --- a/src/game-lib-camera.js +++ b/src/game-lib-camera.js @@ -103,7 +103,9 @@ GameLib.D3.Camera.prototype.createInstance = function(update) { instance.quaternion.z = this.quaternion.z; instance.quaternion.w = this.quaternion.w; -// instance.lookAt(this.lookAt.instance); + if (!update) { + instance.lookAt(this.lookAt.instance); + } instance.updateProjectionMatrix(); diff --git a/src/game-lib-color.js b/src/game-lib-color.js index 84035db..0eff30b 100644 --- a/src/game-lib-color.js +++ b/src/game-lib-color.js @@ -2,15 +2,15 @@ * Runtime color for updating instance objects * @param graphics GameLib.D3.Graphics * @param parentObject GameLib.D3.* - * @param color GameLib.D3.API.Color + * @param apiColor GameLib.D3.API.Color * @param grain Number * @constructor */ -GameLib.D3.Color = function RuntimeColor(graphics, parentObject, color, grain) { +GameLib.D3.Color = function RuntimeColor(graphics, parentObject, apiColor, grain) { - for (var property in color) { - if (color.hasOwnProperty(property)) { - this[property] = color[property]; + for (var property in apiColor) { + if (apiColor.hasOwnProperty(property)) { + this[property] = apiColor[property]; } } diff --git a/src/game-lib-component-a.js b/src/game-lib-component-a.js new file mode 100644 index 0000000..0347167 --- /dev/null +++ b/src/game-lib-component-a.js @@ -0,0 +1,324 @@ +/** + * Common properties of all Components + * @param id + * @param name + * @param componentType GameLib.D3.Component.COMPONENT_* + * @param parentEntity GameLib.D3.Entity + * @param linkedProperties GameLib.D3.LinkedProperty[] + * @constructor + */ +GameLib.D3.Component = function Component( + id, + name, + componentType, + parentEntity, + linkedProperties +) { + this.id = id || GameLib.D3.Utils.RandomId(); + + if (GameLib.D3.Utils.UndefinedOrNull(name)) { + name = this.constructor.name; + } + this.name = name; + + if (GameLib.D3.Utils.UndefinedOrNull(componentType)) { + throw new Error('No Component Type - You should extend from this class not instantiate directly'); + } + this.componentType = componentType; + + if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; + + if (GameLib.D3.Utils.UndefinedOrNull(linkedProperties)) { + linkedProperties = []; + } + this.linkedProperties = linkedProperties; + + this.linkedProperties.push( + new GameLib.D3.Component.LinkedProperty( + 'parentEntity', + GameLib.D3.Entity + ) + ) +}; + +/** + * Each custom component has some properties which are converted to Strind IDs for storing to API, + * and then linked before Runtime (after loading from API) back to their actual objects (through the ID) + * @param propertyName String + * @param objectType GameLib.D3.Object + * @constructor + */ +GameLib.D3.Component.LinkedProperty = function( + propertyName, + objectType +) { + this.propertyName = propertyName; + this.objectType = objectType; +}; + +GameLib.D3.Component.COMPONENT_INTERFACE = 0x1; +GameLib.D3.Component.COMPONENT_CAMERA = 0x2; +GameLib.D3.Component.COMPONENT_COLOR_FLASH = 0x3; +GameLib.D3.Component.COMPONENT_COLOR_LERP = 0x4; +GameLib.D3.Component.COMPONENT_FLY_CONTROLS = 0x5; +GameLib.D3.Component.COMPONENT_FOLLOW = 0x6; +GameLib.D3.Component.COMPONENT_LOOK_AT = 0x7; +GameLib.D3.Component.COMPONENT_MESH_PERMUTATION = 0x8; +GameLib.D3.Component.COMPONENT_PATH_AI = 0x9; +GameLib.D3.Component.COMPONENT_PATH_CONTROLS = 0xA; +GameLib.D3.Component.COMPONENT_PATH_FOLLOWING = 0xB; +GameLib.D3.Component.COMPONENT_RAYCAST_VEHICLE_CONTROLS = 0xC; +GameLib.D3.Component.COMPONENT_TRIGGER_BOX_BOX = 0xD; +GameLib.D3.Component.COMPONENT_TRIGGER_BOX_SPHERE = 0xE; +GameLib.D3.Component.COMPONENT_TRIGGER_SPHERE_SPHERE = 0xF; +GameLib.D3.Component.COMPONENT_VEHICLE_AI_OBJECT_AVOIDENCE = 0x10; +GameLib.D3.Component.COMPONENT_VEHICLE_AI_PATH_STEERING = 0x11; + +GameLib.D3.Component.prototype.toApiComponent = function() { + + var apiComponent = new GameLib.D3.API.Component( + this.id, + this.name, + this.componentType, + GameLib.D3.Utils.IdOrNull(this.parentEntity) + ); + + var isObjectProperty; + + for (var property in apiComponent) { + if ( + apiComponent.hasOwnProperty(property) && + this.hasOwnProperty(property) + ) { + isObjectProperty = false; + + for (var l = 0; l < this.linkedProperties.length; l++) { + + var linkedProperty = this.linkedProperties[l]; + + if (linkedProperty.propertyName == property) { + isObjectProperty = true; + break; + } + } + + if (isObjectProperty) { + apiComponent[property] = GameLib.D3.Utils.IdOrNull(this[property]); + } else if ( + this[property] instanceof GameLib.D3.Vector2 || + this[property] instanceof GameLib.D3.Vector3 + ) { + apiComponent[property] = this[property].toApiVector(); + } else if (this[property] instanceof GameLib.D3.Quaternion) { + apiComponent[property] = this[property].toApiQuaternion(); + } else if ( + this[property] instanceof GameLib.D3.Matrix3 || + this[property] instanceof GameLib.D3.Matrix4 + ) { + apiComponent[property] = this[property].toApiMatrix(); + } else { + apiComponent[property] = this[property]; + } + } else if ( + apiComponent.hasOwnProperty(property) + ) { + delete apiComponent[property]; + } + + } + + return apiComponent; +}; + +/** + * Converts and Object component into a proper GameLib.D3.Component + * @param graphics + * @param objectComponent + * @constructor + */ +GameLib.D3.Component.FromObjectComponent = function(graphics, objectComponent) { + + var component = null; + + switch (objectComponent.componentType) { + + case GameLib.D3.Component.COMPONENT_CAMERA : + component = new GameLib.D3.ComponentCamera(); + break; + + case GameLib.D3.Component.COMPONENT_FOLLOW : + component = new GameLib.D3.ComponentFollow(null, null, graphics); + break; + + case GameLib.D3.Component.COMPONENT_LOOK_AT : + component = new GameLib.D3.ComponentLookAt(null, null, graphics); + break; + + case GameLib.D3.Component.COMPONENT_PATH_FOLLOWING : + component = new GameLib.D3.ComponentPathFollowing(null, null, graphics); + break; + default: + console.warn('This type of component is not yet read from the database:' + objectComponent.componentType); + + } + + for (var property in component) { + if ( + component.hasOwnProperty(property) && + objectComponent.hasOwnProperty(property) + ) { + if (component[property] instanceof GameLib.D3.Vector2) { + component[property] = new GameLib.D3.Vector2( + graphics, + component, + new GameLib.D3.API.Vector2( + objectComponent[property].x, + objectComponent[property].y + ) + ) + } else if (component[property] instanceof GameLib.D3.Vector3) { + component[property] = new GameLib.D3.Vector3( + graphics, + component, + new GameLib.D3.API.Vector3( + objectComponent[property].x, + objectComponent[property].y, + objectComponent[property].z + ) + ) + } else if (component[property] instanceof GameLib.D3.Quaternion) { + + component[property] = new GameLib.D3.Quaternion( + graphics, + component, + new GameLib.D3.API.Quaternion( + objectComponent[property].x, + objectComponent[property].y, + objectComponent[property].z, + objectComponent[property].w, + new GameLib.D3.API.Vector3( + objectComponent[property].axis.x, + objectComponent[property].axis.y, + objectComponent[property].axis.z + ), + objectComponent[property].angle + ) + ) + + } else if (component[property] instanceof GameLib.D3.Color) { + + component[property] = new GameLib.D3.Color( + graphics, + component, + new GameLib.D3.API.Color( + objectComponent[property].r, + objectComponent[property].g, + objectComponent[property].b, + objectComponent[property].a + ) + ) + + } else if (component[property] instanceof GameLib.D3.Matrix4) { + + component[property] = new GameLib.D3.Matrix4( + graphics, + component, + new GameLib.D3.API.Matrix4( + new GameLib.D3.API.Quaternion( + objectComponent[property].rows[0].x, + objectComponent[property].rows[0].y, + objectComponent[property].rows[0].z, + objectComponent[property].rows[0].w + ), + new GameLib.D3.API.Quaternion( + objectComponent[property].rows[1].x, + objectComponent[property].rows[1].y, + objectComponent[property].rows[1].z, + objectComponent[property].rows[1].w + ), + new GameLib.D3.API.Quaternion( + objectComponent[property].rows[2].x, + objectComponent[property].rows[2].y, + objectComponent[property].rows[2].z, + objectComponent[property].rows[2].w + ), + new GameLib.D3.API.Quaternion( + objectComponent[property].rows[3].x, + objectComponent[property].rows[3].y, + objectComponent[property].rows[3].z, + objectComponent[property].rows[3].w + ) + ) + ) + + } else { + component[property] = objectComponent[property]; + } + } + } + + return component; +}; + +/** + * Gets executed from every entity during each game state loop + * Set the callbacks to null initially to prevent unneccesary function calls + * @param deltaTime + * @override + * @callback + * @default null + */ +GameLib.D3.Component.prototype.onUpdate = null; + +/** + * Gets executed from every entity during each game loop - after onUpdate has been called + * Set the callbacks to null initially to prevent unneccesary function calls + * @param deltaTime + * @override + * @callback + */ +GameLib.D3.Component.prototype.onLateUpdate = null; + + +/** + * Gets executed when component is added to an Entity + * @param entity GameLib.D3.Entity + * @override + * @callback + */ +GameLib.D3.Component.prototype.onAdd = function(entity) {}; + +/** + * Gets executed when a component is removed from an Entity + * @param entity GameLib.D3.Entity + * @override + * @callback + */ +GameLib.D3.Component.prototype.onRemove = function(entity) {}; + +/** + * links object ids to actual objects + * @param idToObject Object linking object components to objects + */ +GameLib.D3.Component.prototype.linkObjects = function(idToObject) { + + this.linkedProperties.forEach( + function (linkedProperty) { + if (this[linkedProperty.propertyName]) { + this[linkedProperty.propertyName] = idToObject[this[linkedProperty.propertyName]]; + } + }.bind(this) + ); +}; + + +/** + * Clones this component + * @returns {*} + */ +GameLib.D3.Component.prototype.clone = function() { + return _.cloneDeep(this); +}; diff --git a/src/game-lib-component-camera.js b/src/game-lib-component-camera.js index 1dc2b61..2ddcfc9 100644 --- a/src/game-lib-component-camera.js +++ b/src/game-lib-component-camera.js @@ -3,63 +3,59 @@ * is. * @param id * @param name String - * @param camera GameLib.D3.Camera * @param parentEntity GameLib.D3.Entity + * @param camera GameLib.D3.Camera * @constructor */ GameLib.D3.ComponentCamera = function ComponentCamera( id, name, - camera, - parentEntity + parentEntity, + camera ) { - if (GameLib.D3.Utils.UndefinedOrNull(id)) { - id = GameLib.D3.Utils.RandomId(); - } - this.id = id; - - if (GameLib.D3.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; - } - this.name = name; - - if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; + GameLib.D3.Component.call( + this, + id, + name, + GameLib.D3.Component.COMPONENT_CAMERA, + parentEntity, + [ + new GameLib.D3.Component.LinkedProperty( + 'camera', + GameLib.D3.Camera + ) + ] + ); if (GameLib.D3.Utils.UndefinedOrNull(camera)) { camera = null; } this.camera = camera; - - GameLib.D3.Utils.Extend(GameLib.D3.ComponentCamera, GameLib.D3.ComponentInterface); }; -///////////////////////// Methods to override ////////////////////////// -GameLib.D3.ComponentCamera.prototype.onLateUpdate = function( - deltaTime, - parentEntity -) { +GameLib.D3.ComponentCamera.prototype = Object.create(GameLib.D3.Component.prototype); +GameLib.D3.ComponentCamera.prototype.constructor = GameLib.D3.ComponentCamera; + + +/** + * onLateUpdate override method + * @override + * @callback + */ +GameLib.D3.ComponentCamera.prototype.onLateUpdate = function() { if (this.camera) { - this.camera.quaternion.copy(this.parentEntity.quaternion); - this.camera.quaternion.normalize(); + this.camera.quaternion.x = this.parentEntity.quaternion.x; + this.camera.quaternion.y = this.parentEntity.quaternion.y; + this.camera.quaternion.z = this.parentEntity.quaternion.z; + this.camera.quaternion.w = this.parentEntity.quaternion.w; - this.camera.position.copy(this.parentEntity.position); + this.camera.position.x = this.parentEntity.position.x; + this.camera.position.y = this.parentEntity.position.y; + this.camera.position.z = this.parentEntity.position.z; - this.camera.quaternion.updateInstance(); - this.camera.position.updateInstance(); - - this.parentEntity.quaternion.x = this.camera.quaternion.x; - this.parentEntity.quaternion.y = this.camera.quaternion.y; - this.parentEntity.quaternion.z = this.camera.quaternion.z; - this.parentEntity.quaternion.w = this.camera.quaternion.w; - - this.parentEntity.quaternion.updateInstance(); - } else { - console.warn('no camera object'); + this.camera.updateInstance(); } }; \ No newline at end of file diff --git a/src/game-lib-component-colorflash.js b/src/game-lib-component-colorflash.js index 7179da8..af52648 100644 --- a/src/game-lib-component-colorflash.js +++ b/src/game-lib-component-colorflash.js @@ -18,7 +18,7 @@ GameLib.D3.ComponentColorFlash = function ComponentColorFlash( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentColorFlash, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentColorFlash, GameLib.D3.Component); }; ///////////////////////// Methods to override ////////////////////////// diff --git a/src/game-lib-component-colorlerp.js b/src/game-lib-component-colorlerp.js index 766525d..98b4256 100644 --- a/src/game-lib-component-colorlerp.js +++ b/src/game-lib-component-colorlerp.js @@ -14,7 +14,7 @@ GameLib.D3.ComponentColorLerp = function( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentColorLerp, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentColorLerp, GameLib.D3.Component); this.startColor = startColor || new GameLib.D3.API.Vector3(0, 0, 0); this.endColor = endColor || new GameLib.D3.API.Vector3(1, 1, 1); diff --git a/src/game-lib-component-entity-parent.js b/src/game-lib-component-entity-parent.js index c8ec093..c27ae75 100644 --- a/src/game-lib-component-entity-parent.js +++ b/src/game-lib-component-entity-parent.js @@ -24,7 +24,7 @@ GameLib.D3.ComponentEntityParent = function ComponentEntityParent( this.centerToOrigin = centerToOrigin; this.originPosition = new GameLib.D3.API.Vector3(0, 0, 0); - GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityParent, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityParent, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-entity-permutation.js b/src/game-lib-component-entity-permutation.js index ea01997..bcae2f0 100644 --- a/src/game-lib-component-entity-permutation.js +++ b/src/game-lib-component-entity-permutation.js @@ -37,7 +37,7 @@ GameLib.D3.ComponentEntityPermutation = function ComponentEntityPermutation( scaleOffset = new GameLib.D3.API.Vector3(1, 1, 1); } this.scaleOffset = scaleOffset; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityPermutation, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentEntityPermutation, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-fly-controls.js b/src/game-lib-component-fly-controls.js index caa4914..e05861b 100644 --- a/src/game-lib-component-fly-controls.js +++ b/src/game-lib-component-fly-controls.js @@ -18,7 +18,7 @@ GameLib.D3.ComponentFlyControls = function ComponentFlyControls( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentFlyControls, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentFlyControls, GameLib.D3.Component); // Component fields this.pitch = 0; diff --git a/src/game-lib-component-follow.js b/src/game-lib-component-follow.js index a837238..a8ef3a4 100644 --- a/src/game-lib-component-follow.js +++ b/src/game-lib-component-follow.js @@ -18,33 +18,32 @@ GameLib.D3.ComponentFollow = function ComponentFollow( id, name, graphics, + parentEntity, targetEntity, targetOffset, minDistance, moveSpeed, - parentEntity, target, targetToParent, rotatedTargetOffset, rotated ) { - if (GameLib.D3.Utils.UndefinedOrNull(id)) { - id = GameLib.D3.Utils.RandomId(); - } - this.id = id; - - if (GameLib.D3.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; - } - this.name = name; - this.graphics = graphics; this.graphics.isNotThreeThrow(); - if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; + GameLib.D3.Component.call( + this, + id, + name, + GameLib.D3.Component.COMPONENT_FOLLOW, + parentEntity, + [ + new GameLib.D3.Component.LinkedProperty( + 'targetEntity', + GameLib.D3.Entity + ) + ] + ); if (GameLib.D3.Utils.UndefinedOrNull(targetEntity)) { targetEntity = null; @@ -80,10 +79,8 @@ GameLib.D3.ComponentFollow = function ComponentFollow( this, target ); - this.target = target; - if(GameLib.D3.Utils.UndefinedOrNull(targetToParent)) { targetToParent = new GameLib.D3.API.Vector3(0, 0, 0); } @@ -103,7 +100,6 @@ GameLib.D3.ComponentFollow = function ComponentFollow( this, rotatedTargetOffset ); - this.rotatedTargetOffset = rotatedTargetOffset; if (GameLib.D3.Utils.UndefinedOrNull(rotated)) { @@ -114,19 +110,22 @@ GameLib.D3.ComponentFollow = function ComponentFollow( this, rotated ); - this.rotated = rotated; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentFollow, GameLib.D3.ComponentInterface); }; -///////////////////////// Methods to override ////////////////////////// +GameLib.D3.ComponentFollow.prototype = Object.create(GameLib.D3.Component.prototype); +GameLib.D3.ComponentFollow.prototype.constructor = GameLib.D3.ComponentFollow; + +/** + * onUpdate callback + * @param deltaTime + */ GameLib.D3.ComponentFollow.prototype.onUpdate = function( - deltaTime, - parentEntity + deltaTime ) { - if (this.targetEntity) { + if (this.parentEntity && this.targetEntity) { this.rotated.x = this.targetEntity.quaternion.x; this.rotated.y = this.targetEntity.quaternion.y; diff --git a/src/game-lib-component-interface.js b/src/game-lib-component-interface.js deleted file mode 100644 index 30c1701..0000000 --- a/src/game-lib-component-interface.js +++ /dev/null @@ -1,438 +0,0 @@ -/** - * - * @param id - * @param name - * @constructor - */ -GameLib.D3.ComponentInterface = function ComponentInterface( - id, - name -) { - this.id = id || GameLib.D3.Utils.RandomId(); - - if (typeof name == 'undefined') { - name = this.constructor.name; - } - this.name = name; - - // this will maybe not used - this.parentEntity = null; -}; - -GameLib.D3.ComponentInterface.COMPONENT_INTERFACE = 0x1; -GameLib.D3.ComponentInterface.COMPONENT_CAMERA = 0x2; -GameLib.D3.ComponentInterface.COMPONENT_COLOR_FLASH = 0x3; -GameLib.D3.ComponentInterface.COMPONENT_COLOR_LERP = 0x4; -GameLib.D3.ComponentInterface.COMPONENT_FLY_CONTROLS = 0x5; -GameLib.D3.ComponentInterface.COMPONENT_FOLLOW = 0x6; -GameLib.D3.ComponentInterface.COMPONENT_LOOK_AT = 0x7; -GameLib.D3.ComponentInterface.COMPONENT_MESH_PERMUTATION = 0x8; -GameLib.D3.ComponentInterface.COMPONENT_PATH_AI = 0x9; -GameLib.D3.ComponentInterface.COMPONENT_PATH_CONTROLS = 0xA; -GameLib.D3.ComponentInterface.COMPONENT_PATH_FOLLOWING = 0xB; -GameLib.D3.ComponentInterface.COMPONENT_RAYCAST_VEHICLE_CONTROLS = 0xC; -GameLib.D3.ComponentInterface.COMPONENT_TRIGGER_BOX_BOX = 0xD; -GameLib.D3.ComponentInterface.COMPONENT_TRIGGER_BOX_SPHERE = 0xE; -GameLib.D3.ComponentInterface.COMPONENT_TRIGGER_SPHERE_SPHERE = 0xF; -GameLib.D3.ComponentInterface.COMPONENT_VEHICLE_AI_OBJECT_AVOIDENCE = 0x10; -GameLib.D3.ComponentInterface.COMPONENT_VEHICLE_AI_PATH_STEERING = 0x11; - -GameLib.D3.ComponentInterface.prototype.toApiComponent = function() { - - var apiComponent = null; - - if (this instanceof GameLib.D3.ComponentCamera) { - - apiComponent = new GameLib.D3.API.ComponentInterface( - this.id, - this.name, - GameLib.D3.ComponentInterface.COMPONENT_CAMERA, - GameLib.D3.Utils.IdOrNull(this.camera), - GameLib.D3.Utils.IdOrNull(this.parentEntity) - ); - - } else if (this instanceof GameLib.D3.ComponentFollow) { - - apiComponent = new GameLib.D3.API.ComponentInterface( - this.id, - this.name, - GameLib.D3.ComponentInterface.COMPONENT_FOLLOW, - null, - GameLib.D3.Utils.IdOrNull(this.parentEntity), - GameLib.D3.Utils.IdOrNull(this.targetEntity), - this.targetOffset.toApiVector(), - this.minDistance, - this.moveSpeed, - this.target.toApiVector(), - this.targetToParent.toApiVector(), - this.rotatedTargetOffset.toApiVector(), - this.rotated.toApiQuaternion() - ); - - } else if (this instanceof GameLib.D3.ComponentLookAt) { - - apiComponent = new GameLib.D3.API.ComponentInterface( - this.id, - this.name, - GameLib.D3.ComponentInterface.COMPONENT_LOOK_AT, - null, - GameLib.D3.Utils.IdOrNull(this.parentEntity), - GameLib.D3.Utils.IdOrNull(this.targetEntity), - this.targetOffset.toApiVector(), - null, - null, - null, - null, - null, - null, - this.rotationSpeed, - this.lookAtMatrix.toApiMatrix(), - this.up.toApiVector() - ) - } else if (this instanceof GameLib.D3.ComponentPathFollowing) { - - apiComponent = new GameLib.D3.API.ComponentInterface( - this.id, - this.name, - GameLib.D3.ComponentInterface.COMPONENT_PATH_FOLLOWING, - null, - GameLib.D3.Utils.IdOrNull(this.parentEntity), - GameLib.D3.Utils.IdOrNull(this.targetEntity), - this.targetOffset.toApiVector(), - null, - null, - null, - null, - null, - null, - null, - null, - this.up.toApiVector(), - GameLib.D3.Utils.IdOrNull(this.spline), - GameLib.D3.Utils.IdOrNull(this.mesh), - this.accelleration, - this.maxSpeed, - this.baseOffset.toApiVector(), - this.maxOffset.toApiVector(), - this.steeringSpeed, - this.currentOffset.toApiVector(), - this.currentPathValue, - this.currentSpeed, - this.direction, - this.currentPosition.toApiVector() - ); - - } else { - console.warn('cannot save components of this type yet: ' + this.componentType); - } - - return apiComponent; -}; - -/** - * Converts and Object component into a proper GameLib.D3.Component - * @param graphics - * @param objectComponent - * @constructor - */ -GameLib.D3.ComponentInterface.FromObjectComponent = function(graphics, objectComponent) { - - var component = null; - - switch (objectComponent.componentType) { - - case GameLib.D3.ComponentInterface.COMPONENT_CAMERA : - component = new GameLib.D3.ComponentCamera( - objectComponent.id, - objectComponent.name, - objectComponent.camera, - objectComponent.parentEntity - ); - break; - - case GameLib.D3.ComponentInterface.COMPONENT_FOLLOW : - component = new GameLib.D3.ComponentFollow( - objectComponent.id, - objectComponent.name, - graphics, - objectComponent.targetEntity, - new GameLib.D3.API.Vector3 ( - objectComponent.targetOffset.x, - objectComponent.targetOffset.y, - objectComponent.targetOffset.z - ), - objectComponent.minDistance, - objectComponent.moveSpeed, - objectComponent.parentEntity, - new GameLib.D3.API.Vector3( - objectComponent.target.x, - objectComponent.target.y, - objectComponent.target.z - ), - new GameLib.D3.API.Vector3( - objectComponent.targetToParent.x, - objectComponent.targetToParent.y, - objectComponent.targetToParent.z - ), - new GameLib.D3.API.Vector3( - objectComponent.rotatedTargetOffset.x, - objectComponent.rotatedTargetOffset.y, - objectComponent.rotatedTargetOffset.z - ), - new GameLib.D3.API.Quaternion( - objectComponent.rotated.x, - objectComponent.rotated.x, - objectComponent.rotated.x, - objectComponent.rotated.x, - new GameLib.D3.API.Vector3( - objectComponent.rotated.axis.x, - objectComponent.rotated.axis.y, - objectComponent.rotated.axis.z - ), - objectComponent.rotated.angle - ) - ); - break; - - case GameLib.D3.ComponentInterface.COMPONENT_LOOK_AT : - component = new GameLib.D3.ComponentLookAt( - objectComponent.id, - objectComponent.name, - graphics, - objectComponent.parentEntity, - objectComponent.targetEntity, - new GameLib.D3.API.Vector3( - objectComponent.targetOffset.x, - objectComponent.targetOffset.y, - objectComponent.targetOffset.z - ), - objectComponent.rotationSpeed, - objectComponent.lookAtMatrix, - new GameLib.D3.API.Vector3( - objectComponent.up.x, - objectComponent.up.y, - objectComponent.up.z - ) - ); - break; - - case GameLib.D3.ComponentInterface.COMPONENT_PATH_FOLLOWING : - component = new GameLib.D3.ComponentPathFollowing( - objectComponent.id, - objectComponent.name, - graphics, - objectComponent.parentEntity, - objectComponent.spline, - objectComponent.mesh, - objectComponent.accelleration, - objectComponent.maxSpeed, - new GameLib.D3.API.Vector3( - objectComponent.baseOffset.x, - objectComponent.baseOffset.y, - objectComponent.baseOffset.z - ), - new GameLib.D3.API.Vector3( - objectComponent.maxOffset.x, - objectComponent.maxOffset.y, - objectComponent.maxOffset.z - ), - objectComponent.steeringSpeed, - new GameLib.D3.API.Vector3( - objectComponent.targetOffset.x, - objectComponent.targetOffset.y, - objectComponent.targetOffset.z - ), - new GameLib.D3.API.Vector3( - objectComponent.currentOffset.x, - objectComponent.currentOffset.y, - objectComponent.currentOffset.z - ), - objectComponent.currentPathValue, - objectComponent.currentSpeed, - objectComponent.direction, - null, - null, - null, - null, - null, - null, - new GameLib.D3.API.Vector3( - objectComponent.up.x, - objectComponent.up.y, - objectComponent.up.z - ) - ); - break; - default: - console.warn('This type of component is not yet read from the database:' + objectComponent.componentType); - - } - - return component; - // - // var apiComponent = new GameLib.D3.API.ComponentInterface( - // objectComponent.id, - // objectComponent.name, - // objectComponent.componentType, - // objectComponent.camera, - // new GameLib.D3.API.Color( - // objectComponent.startColor.r, - // objectComponent.startColor.g, - // objectComponent.startColor.b, - // objectComponent.startColor.a - // ), - // new GameLib.D3.API.Color( - // objectComponent.endColor.r, - // objectComponent.endColor.g, - // objectComponent.endColor.b, - // objectComponent.endColor.a - // ), - // objectComponent.lerpSpeed, - // objectComponent.targetEntity, - // new GameLib.D3.API.Vector3( - // objectComponent.targetOffset.x, - // objectComponent.targetOffset.y, - // objectComponent.targetOffset.z - // ), - // objectComponent.minDistance, - // objectComponent.moveSpeed, - // objectComponent.rotationSpeed, - // new GameLib.D3.API.Vector3( - // objectComponent.positionOffset.x, - // objectComponent.positionOffset.y, - // objectComponent.positionOffset.z - // ), - // new GameLib.D3.API.Vector3( - // objectComponent.quaternionOffset.x, - // objectComponent.quaternionOffset.y, - // objectComponent.quaternionOffset.z - // ), - // new GameLib.D3.API.Vector3( - // objectComponent.scaleOffset.x, - // objectComponent.scaleOffset.y, - // objectComponent.scaleOffset.z - // ), - // objectComponent.sensorLength, - // objectComponent.spline, - // objectComponent.accelleration, - // objectComponent.maxSpeed, - // new GameLib.D3.API.Vector3( - // objectComponent.baseOffset.x, - // objectComponent.baseOffset.y, - // objectComponent.baseOffset.z - // ), - // new GameLib.D3.API.Vector3( - // objectComponent.maxOffset.x, - // objectComponent.maxOffset.y, - // objectComponent.maxOffset.z - // ), - // objectComponent.steeringSpeed, - // objectComponent.frontLWheelIndex, - // objectComponent.frontRWheelIndex, - // objectComponent.backLWheelIndex, - // objectComponent.backRWheelIndex, - // objectComponent.maxForce, - // objectComponent.steering, - // objectComponent.entitiesToCheck.map(function(objectEntity){ - // return GameLib.D3.Entity.FromObjectEntity(graphics, objectEntity); - // }), - // objectComponent.onInside, - // objectComponent.onEnter, - // objectComponent.onLeave, - // objectComponent.onSetParent, - // objectComponent.sphereRadius, - // GameLib.D3.World.FromObjectWorld(objectComponent.world), - // objectComponent.maxSteerAngle - // ); - // - // var component = null; - // - // switch (apiComponent.componentType) { - // - // } - -}; - -// will be not used -GameLib.D3.ComponentInterface.prototype.setParentEntity = function( - parentScene, - parentEntity -) { - this.parentEntity = parentEntity; - this.onSetParentEntity(parentScene, parentEntity); -}; - - -GameLib.D3.ComponentInterface.prototype.update = function( - deltaTime, - parentEntity -) { - this.onUpdate(deltaTime, parentEntity); -}; - -GameLib.D3.ComponentInterface.prototype.lateUpdate = function( - deltaTime, - parentEntity -) { - this.onLateUpdate(deltaTime, parentEntity); -}; - -GameLib.D3.ComponentInterface.prototype.register = function( - parentScene -) { - this.onRegistered(parentScene); -}; - - -///////////////////////// Methods to override ////////////////////////// -GameLib.D3.ComponentInterface.prototype.onUpdate = function( - deltaTime, - parentEntity -) { - -}; - -GameLib.D3.ComponentInterface.prototype.onLateUpdate = function( - deltaTime, - parentEntity -) { - -}; - -GameLib.D3.ComponentInterface.prototype.onRegistered = function( - parentScene -) { - -}; - - -GameLib.D3.ComponentInterface.prototype.onSetParentEntity = function( - parentScene, - parentEntity -) { - -}; - -GameLib.D3.ComponentInterface.prototype.clone = function() { - return _.cloneDeep(this); -}; - -/** - * links component ids to actual objects - * @param idToObject Object linking object ids to objects - */ -GameLib.D3.ComponentInterface.prototype.linkObjects = function(idToObject) { - /** - * @param camera GameLib.D3.Camera - * @param parentEntity GameLib.D3.Entity - * @param targetEntity GameLib.D3.Entity - * @param spline GameLib.D3.Spline - * @param mesh GameLib.D3.Mesh - */ - - GameLib.D3.Utils.Link('camera', idToObject, this, this.camera); - GameLib.D3.Utils.Link('parentEntity', idToObject, this, this.parentEntity); - GameLib.D3.Utils.Link('targetEntity', idToObject, this, this.targetEntity); - GameLib.D3.Utils.Link('spline', idToObject, this, this.spline); - GameLib.D3.Utils.Link('mesh', idToObject, this, this.mesh); -}; \ No newline at end of file diff --git a/src/game-lib-component-look-at.js b/src/game-lib-component-look-at.js index 1bdc052..24c816a 100644 --- a/src/game-lib-component-look-at.js +++ b/src/game-lib-component-look-at.js @@ -24,22 +24,21 @@ GameLib.D3.ComponentLookAt = function ComponentLookAt( ) { this.graphics = graphics; this.graphics.isNotThreeThrow(); - - if (GameLib.D3.Utils.UndefinedOrNull(id)) { - id = GameLib.D3.Utils.RandomId(); - } - this.id = id; - if (GameLib.D3.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; - } - this.name = name; + GameLib.D3.Component.call( + this, + id, + name, + GameLib.D3.Component.COMPONENT_LOOK_AT, + parentEntity, + [ + new GameLib.D3.Component.LinkedProperty( + 'targetEntity', + GameLib.D3.Entity + ) + ] + ); - if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; - if (GameLib.D3.Utils.UndefinedOrNull(targetEntity)) { targetEntity = null; } @@ -91,16 +90,18 @@ GameLib.D3.ComponentLookAt = function ComponentLookAt( this, new GameLib.D3.API.Quaternion() ); - - GameLib.D3.Utils.Extend(GameLib.D3.ComponentLookAt, GameLib.D3.ComponentInterface); }; -///////////////////////// Methods to override ////////////////////////// -GameLib.D3.ComponentLookAt.prototype.onUpdate = function( - deltaTime, - parentEntity -) { - if (this.targetEntity) { +GameLib.D3.ComponentLookAt.prototype = Object.create(GameLib.D3.Component.prototype); +GameLib.D3.ComponentLookAt.prototype.constructor = GameLib.D3.ComponentLookAt; + +/** + * onUpdate + * @param deltaTime + */ +GameLib.D3.ComponentLookAt.prototype.onUpdate = function(deltaTime) { + + if (this.targetEntity && this.parentEntity) { this.targetPosition.x = this.targetEntity.position.x + this.targetOffset.x; this.targetPosition.y = this.targetEntity.position.y + this.targetOffset.y; diff --git a/src/game-lib-component-mesh-permutation.js b/src/game-lib-component-mesh-permutation.js index fe508b0..772c9f5 100644 --- a/src/game-lib-component-mesh-permutation.js +++ b/src/game-lib-component-mesh-permutation.js @@ -28,7 +28,7 @@ GameLib.D3.ComponentMeshPermutation = function ComponentMeshPermutation( this.scaleOffset = scaleOffset || new GameLib.D3.API.Vector3(1, 1, 1); // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentMeshPermutation, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentMeshPermutation, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-offsettor.js b/src/game-lib-component-offsettor.js index 5a63029..892bdf1 100644 --- a/src/game-lib-component-offsettor.js +++ b/src/game-lib-component-offsettor.js @@ -28,7 +28,7 @@ GameLib.D3.ComponentOffsettor = function ComponentOffsettor( this.getOffsetFunc = getOffsetFunc || function(entity, component, userData){ return component.offset; }; this.userData = userData; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentOffsettor, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentOffsettor, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-path-ai.js b/src/game-lib-component-path-ai.js index 8326f44..c42e5b1 100644 --- a/src/game-lib-component-path-ai.js +++ b/src/game-lib-component-path-ai.js @@ -20,7 +20,7 @@ GameLib.D3.ComponentPathAI = function ComponentPathAI( this.parentEntity = null; this.sensorLength = sensorLength || 5; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathAI, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathAI, GameLib.D3.Component); //#ifdef RUNTIME__ diff --git a/src/game-lib-component-path-controls.js b/src/game-lib-component-path-controls.js index 2563d70..c5682fa 100644 --- a/src/game-lib-component-path-controls.js +++ b/src/game-lib-component-path-controls.js @@ -25,7 +25,7 @@ GameLib.D3.ComponentPathControls = function ComponentPathControls( this.keyBackPressed = false; this.keyBreakPressed = false; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathControls, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathControls, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-path-following.js b/src/game-lib-component-path-following.js index fce37bb..f5bcfaf 100644 --- a/src/game-lib-component-path-following.js +++ b/src/game-lib-component-path-following.js @@ -54,23 +54,27 @@ GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( rotationMatrix, rotationVector ) { - if (GameLib.D3.Utils.UndefinedOrNull(id)) { - id = GameLib.D3.Utils.RandomId(); - } - this.id = id; - - if (GameLib.D3.Utils.UndefinedOrNull(name)) { - name = this.constructor.name; - } - this.name = name; this.graphics = graphics; this.graphics.isNotThreeThrow(); - if (GameLib.D3.Utils.UndefinedOrNull(parentEntity)) { - parentEntity = null; - } - this.parentEntity = parentEntity; + GameLib.D3.Component.call( + this, + id, + name, + GameLib.D3.Component.COMPONENT_PATH_FOLLOWING, + parentEntity, + [ + new GameLib.D3.Component.LinkedProperty( + 'spline', + GameLib.D3.Spline + ), + new GameLib.D3.Component.LinkedProperty( + 'mesh', + GameLib.D3.Mesh + ) + ] + ); if (GameLib.D3.Utils.UndefinedOrNull(spline)) { spline = null; @@ -231,13 +235,18 @@ GameLib.D3.ComponentPathFollowing = function ComponentPathFollowing( this, rotationVector ); - //rotationVector.normalize(); this.rotationVector = rotationVector; - - GameLib.D3.Utils.Extend(GameLib.D3.ComponentPathFollowing, GameLib.D3.ComponentInterface); }; -///////////////////////// Methods to override ////////////////////////// +GameLib.D3.ComponentPathFollowing.prototype = Object.create(GameLib.D3.Component.prototype); +GameLib.D3.ComponentPathFollowing.prototype.constructor = GameLib.D3.ComponentPathFollowing; + + +/** + * @param deltaTime + * @callback + * @override + */ GameLib.D3.ComponentPathFollowing.prototype.onUpdate = function( deltaTime ) { diff --git a/src/game-lib-component-raycast-vehicle-controls.js b/src/game-lib-component-raycast-vehicle-controls.js index 0686e06..54e53e4 100644 --- a/src/game-lib-component-raycast-vehicle-controls.js +++ b/src/game-lib-component-raycast-vehicle-controls.js @@ -38,7 +38,7 @@ GameLib.D3.ComponentRaycastVehicleControls = function ComponentRaycastVehicleCon this.keyBreakPressed = false; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentRaycastVehicleControls, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentRaycastVehicleControls, GameLib.D3.Component); }; ///////////////////////// Methods to override ////////////////////////// diff --git a/src/game-lib-component-rotator.js b/src/game-lib-component-rotator.js index 1ab4f0e..4d0db4e 100644 --- a/src/game-lib-component-rotator.js +++ b/src/game-lib-component-rotator.js @@ -28,7 +28,7 @@ GameLib.D3.ComponentRotator = function ComponentRotator( this.getRotationFunc = getRotationFunc || function(entity, component, userData){ return component.rotation; }; this.userData = userData; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentRotator, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentRotator, GameLib.D3.Component); }; //#ifdef RUNTIME__ diff --git a/src/game-lib-component-trigger-box-box.js b/src/game-lib-component-trigger-box-box.js index 8cb7cd1..60d181b 100644 --- a/src/game-lib-component-trigger-box-box.js +++ b/src/game-lib-component-trigger-box-box.js @@ -23,7 +23,7 @@ GameLib.D3.ComponentTriggerBoxBox = function ComponentTriggerBoxBox( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxBox, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxBox, GameLib.D3.Component); this.entitiesToCheck = entitiesToCheck || []; this.onInside = onInside || null; diff --git a/src/game-lib-component-trigger-box-sphere.js b/src/game-lib-component-trigger-box-sphere.js index d955f95..2a90d06 100644 --- a/src/game-lib-component-trigger-box-sphere.js +++ b/src/game-lib-component-trigger-box-sphere.js @@ -21,7 +21,7 @@ GameLib.D3.ComponentTriggerBoxSphere = function ComponentTriggerBoxSphere( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxSphere, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerBoxSphere, GameLib.D3.Component); this.entitiesToCheck = entitiesToCheck || []; this.onInside = onInside || null; diff --git a/src/game-lib-component-trigger-sphere-sphere.js b/src/game-lib-component-trigger-sphere-sphere.js index 3ee0b3e..3ea1112 100644 --- a/src/game-lib-component-trigger-sphere-sphere.js +++ b/src/game-lib-component-trigger-sphere-sphere.js @@ -32,7 +32,7 @@ GameLib.D3.ComponentTriggerSphereSphere = function ComponentTriggerSphereSphere( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerSphereSphere, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentTriggerSphereSphere, GameLib.D3.Component); this.entitiesToCheck = entitiesToCheck || []; this.sphereRadius = sphereRadius || 1.0; diff --git a/src/game-lib-component-vehicle-ai-object-avoidance.js b/src/game-lib-component-vehicle-ai-object-avoidance.js index 9c9ecc7..fdfc3a8 100644 --- a/src/game-lib-component-vehicle-ai-object-avoidance.js +++ b/src/game-lib-component-vehicle-ai-object-avoidance.js @@ -17,7 +17,7 @@ GameLib.D3.ComponentVehicleAIObjectAvoidance = function( this.name = name; this.parentEntity = null; - GameLib.D3.Utils.Extend(GameLib.D3.ComponentVehicleAIObjectAvoidance, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentVehicleAIObjectAvoidance, GameLib.D3.Component); this.raycastVehicleComponent = null; this.physicsWorld = world || null; diff --git a/src/game-lib-component-vehicle-ai-path-steering.js b/src/game-lib-component-vehicle-ai-path-steering.js index 5e5c14e..0d9447a 100644 --- a/src/game-lib-component-vehicle-ai-path-steering.js +++ b/src/game-lib-component-vehicle-ai-path-steering.js @@ -23,7 +23,7 @@ GameLib.D3.ComponentVehicleAIPathSteering = function( this.parentEntity = null; // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.ComponentVehicleAIPathSteering, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.ComponentVehicleAIPathSteering, GameLib.D3.Component); // this.targetEntity = targetEntity; diff --git a/src/game-lib-entity.js b/src/game-lib-entity.js index 84b574e..d223c3a 100644 --- a/src/game-lib-entity.js +++ b/src/game-lib-entity.js @@ -34,7 +34,50 @@ GameLib.D3.Entity = function Entity( this, this.scale ); +}; +/** + * Updates the Entity and it's components + * @param deltaTime Number + * @param late boolean to indicate whether or not this is a late update + */ +GameLib.D3.Entity.prototype.update = function( + deltaTime, + late +) { + + this.components.forEach( + function (component) { + if (!late && component.onUpdate) { + component.onUpdate(deltaTime, this); + } + + if (late && component.onLateUpdate) { + component.onLateUpdate(deltaTime, this); + } + } + ); + + if (this.mesh) { + + this.mesh.position.x = this.position.x; + this.mesh.position.y = this.position.y; + this.mesh.position.z = this.position.z; + + this.mesh.scale.x = this.scale.x; + this.mesh.scale.y = this.scale.y; + this.mesh.scale.z = this.scale.z; + + /** + * Caller is responsible for correct quaternion - i.e. normalize quaternion if needed + */ + this.mesh.quaternion.x = this.quaternion.x; + this.mesh.quaternion.y = this.quaternion.y; + this.mesh.quaternion.z = this.quaternion.z; + this.mesh.quaternion.w = this.quaternion.w; + + this.mesh.updateInstance(); + } }; /** @@ -43,16 +86,18 @@ GameLib.D3.Entity = function Entity( */ GameLib.D3.Entity.prototype.toApiEntity = function() { - return new GameLib.D3.API.Entity( + var apiEntity = new GameLib.D3.API.Entity( this.id, this.name, - this.ids, + GameLib.D3.Utils.IdArrayOrEmptyArray(this.components), this.position.toApiVector(), this.quaternion.toApiQuaternion(), this.scale.toApiVector(), GameLib.D3.Utils.IdOrNull(this.parentScene), GameLib.D3.Utils.IdOrNull(this.mesh) ); + + return apiEntity; }; /** @@ -66,7 +111,7 @@ GameLib.D3.Entity.FromObjectEntity = function(graphics, objectEntity) { var apiEntity = new GameLib.D3.API.Entity( objectEntity.id, objectEntity.name, - objectEntity.ids, + objectEntity.components, new GameLib.D3.API.Vector3( objectEntity.position.x, objectEntity.position.y, @@ -98,73 +143,6 @@ GameLib.D3.Entity.FromObjectEntity = function(graphics, objectEntity) { ); }; -/** - * Updates the Entity and it's components - * @param deltaTime Number - */ -GameLib.D3.Entity.prototype.update = function( - deltaTime -) { - for(var c in this.ids) { - var id = this.ids[c]; - var component = this.parentScene.idToObject[id]; - if(component && component.onUpdate) { - component.onUpdate(deltaTime, this); - } - } - - // todo: maybe we only need to call this AFTER late update - this.updateMesh(); - - this.onUpdate(deltaTime); -}; - -GameLib.D3.Entity.prototype.updateMesh = function() { - - if (this.mesh) { - - /** - * Normalize to prevent stretching - */ - this.quaternion.normalize(); - - this.mesh.position.x = this.position.x; - this.mesh.position.y = this.position.y; - this.mesh.position.z = this.position.z; - - this.mesh.scale.x = this.scale.x; - this.mesh.scale.y = this.scale.y; - this.mesh.scale.z = this.scale.z; - - this.mesh.quaternion.x = this.quaternion.x; - this.mesh.quaternion.y = this.quaternion.y; - this.mesh.quaternion.z = this.quaternion.z; - this.mesh.quaternion.w = this.quaternion.w; - - this.mesh.updateInstance(); - } -}; - -/** -* Late updates the Entity and it's components -* @param deltaTime Number -*/ -GameLib.D3.Entity.prototype.lateUpdate = function( - deltaTime -) { - for(var c in this.ids) { - var id = this.ids[c]; - var component = this.parentScene.idToObject[id]; - if(component && component.onLateUpdate) { - component.onLateUpdate(deltaTime, this); - } - } - - this.updateMesh(); - - this.onLateUpdate(deltaTime); -}; - /** * Gets called when the entity was registered with it's parent scene * @param parentScene GameLib.D3.Scene @@ -172,91 +150,67 @@ GameLib.D3.Entity.prototype.lateUpdate = function( GameLib.D3.Entity.prototype.register = function( parentScene ) { - // this.parentScene = parentScene; - // - // if (this.mesh && this.mesh.id != null && parentScene.meshIdToMesh[this.mesh.id]) { - // parentScene.instance.add(parentScene.meshIdToMesh[this.mesh.id]); - // this.mesh = parentScene.meshIdToMesh[this.id]; - // } - this.onRegistered(this.parentScene); -}; - -/** - * Add an already registered component to the entity - * @param id Number - */ -GameLib.D3.Entity.prototype.addComponentId = function( - id -) { - this.ids.push(id); }; /** * Adds a components to the entity and registers it with the entity's parent scene - * @param component GameLib.D3.ComponentInterface + * @param component GameLib.D3.Component */ GameLib.D3.Entity.prototype.addComponent = function( component ) { - this.parentScene.registerComponent(component); + this.components.push(component); - this.ids.push(component.id); - - if(component.setParentEntity && typeof component.setParentEntity == 'function') { - component.setParentEntity(this.parentScene, this); + if (_.isFunction(component.onAdd)) { + component.onAdd(this); } }; GameLib.D3.Entity.prototype.removeComponent = function(component) { - if(component && component.id && this.parentScene.idToObject[component.id]) { - this.ids = this.ids.splice(this.ids.indexOf(component), 1); - delete this.parentScene.idToObject[component.id]; + + var index = this.components.indexOf(component); + this.components.splice(index, 1); + + if (_.isFunction(component.onRemove)) { + component.onRemove(this); } }; -GameLib.D3.Entity.prototype.getComponent = function( - componentType -) { - for (var componentId in this.ids) { - if (this.ids.hasOwnProperty(componentId)) { - var id = this.ids[componentId]; - var component = this.parentScene.idToObject[id]; - if (component instanceof componentType) { - return component; - } - } - } - - return null; -}; - -///////////////////////// Methods to override ////////////////////////// - -GameLib.D3.Entity.prototype.onUpdate = function( - deltaTime -) { - -}; - -GameLib.D3.Entity.prototype.onLateUpdate = function( - deltaTime -) { - -}; - -GameLib.D3.Entity.prototype.onRegistered = function( - parentScene -) { - -}; - +/** + * Links object Ids to actual objects + * @param idToObject + */ GameLib.D3.Entity.prototype.linkObjects = function(idToObject) { - /** - * @param scene GameLib.D3.Scene - * @param mesh GameLib.D3.Mesh - */ - GameLib.D3.Utils.Link('parentScene', idToObject, this, this.parentScene); - GameLib.D3.Utils.Link('mesh', idToObject, this, this.mesh); + + this.components.forEach( + function(currentValue, index, array) { + + if (!idToObject[currentValue]) { + throw new Error('Unable to locate component with ID: ' + currentValue); + } + + array[index] = idToObject[currentValue]; + }.bind(this) + ); + + if (this.parentScene) { + + if (!idToObject[this.parentScene]) { + throw new Error('Unable to locate scene with ID: ' + this.parentScene); + } + + this.parentScene = idToObject[this.parentScene]; + + } + + if (this.mesh) { + + if (!idToObject[this.mesh]) { + throw new Error('Unable to locate mesh with ID: ' + this.mesh); + } + + this.mesh = idToObject[this.mesh]; + } }; \ No newline at end of file diff --git a/src/game-lib-image.js b/src/game-lib-image.js index 78135eb..7e4fce5 100644 --- a/src/game-lib-image.js +++ b/src/game-lib-image.js @@ -73,7 +73,8 @@ GameLib.D3.Image = function( id, filename, size, - contentType + contentType, + textureLink ) { if (GameLib.D3.Utils.UndefinedOrNull(id)) { id = GameLib.D3.Utils.RandomId(); @@ -104,4 +105,6 @@ GameLib.D3.Image = function( } } this.contentType = contentType; + + this.textureLink = textureLink; }; diff --git a/src/game-lib-matrix-4.js b/src/game-lib-matrix-4.js index 24c65fe..0611a40 100644 --- a/src/game-lib-matrix-4.js +++ b/src/game-lib-matrix-4.js @@ -105,7 +105,14 @@ GameLib.D3.Matrix4.prototype.createInstance = function(update) { * Updates this instance */ GameLib.D3.Matrix4.prototype.updateInstance = function() { + this.createInstance(true); + + if (this.parentObject) { + if (this.parentObject.updateInstance) { + this.parentObject.updateInstance(); + } + } }; GameLib.D3.Matrix4.prototype.lookAt = function (position, target, up) { diff --git a/src/game-lib-quaternion.js b/src/game-lib-quaternion.js index 1f3dfc0..37c1a30 100644 --- a/src/game-lib-quaternion.js +++ b/src/game-lib-quaternion.js @@ -2,20 +2,20 @@ * Runtime quaternion for updating instance objects * @param graphics GameLib.D3.Graphics * @param parentObject GameLib.D3.* - * @param quaternion GameLib.D3.API.Quaternion + * @param apiQuaternion GameLib.D3.API.Quaternion * @param grain Number * @constructor */ GameLib.D3.Quaternion = function RuntimeQuaternion( graphics, parentObject, - quaternion, + apiQuaternion, grain ) { - for (var property in quaternion) { - if (quaternion.hasOwnProperty(property)) { - this[property] = quaternion[property]; + for (var property in apiQuaternion) { + if (apiQuaternion.hasOwnProperty(property)) { + this[property] = apiQuaternion[property]; } } diff --git a/src/game-lib-raycast-vehicle.js b/src/game-lib-raycast-vehicle.js index 55befe0..36dc694 100644 --- a/src/game-lib-raycast-vehicle.js +++ b/src/game-lib-raycast-vehicle.js @@ -30,7 +30,7 @@ GameLib.D3.RaycastVehicle = function( this.instance = this.createInstance(); - GameLib.D3.Utils.Extend(GameLib.D3.RaycastVehicle, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.RaycastVehicle, GameLib.D3.Component); }; /** diff --git a/src/game-lib-rigid-body.js b/src/game-lib-rigid-body.js index 953f848..80b8a3d 100644 --- a/src/game-lib-rigid-body.js +++ b/src/game-lib-rigid-body.js @@ -62,7 +62,7 @@ GameLib.D3.RigidBody = function( this.instance = this.createInstance(); // Todo: this should be executed somewhere in game-lib-z, so that we don't execute it on every construction of an object. - GameLib.D3.Utils.Extend(GameLib.D3.RigidBody, GameLib.D3.ComponentInterface); + GameLib.D3.Utils.Extend(GameLib.D3.RigidBody, GameLib.D3.Component); }; /** diff --git a/src/game-lib-scene.js b/src/game-lib-scene.js index 097457c..48fef9d 100644 --- a/src/game-lib-scene.js +++ b/src/game-lib-scene.js @@ -258,7 +258,7 @@ GameLib.D3.Scene.FromObjectScene = function( ), objectScene.components.map( function (objectComponent) { - return GameLib.D3.ComponentInterface.FromObjectComponent( + return GameLib.D3.Component.FromObjectComponent( graphics, objectComponent ); @@ -386,20 +386,6 @@ GameLib.D3.Scene.LoadSceneFromApi = function( xhr.send(); }; - -GameLib.D3.Scene.prototype.intitializeComponents = function() { - for (var c = 0; c < this.components.length; c++) { - - var component = this.components[c]; - - this.registerComponent(component); - - if(component.setParentEntity && typeof component.setParentEntity == 'function') { - component.setParentEntity(this.parentScene, this); - } - } -}; - /** * Updates the scene * @param deltaTime @@ -407,25 +393,23 @@ GameLib.D3.Scene.prototype.intitializeComponents = function() { GameLib.D3.Scene.prototype.update = function( deltaTime ) { - for(var e in this.entities) { - if (this.entities.hasOwnProperty(e)) { - this.entities[e].update(deltaTime); - } - } -}; + this.entities.forEach( + function (entity) { + if (_.isFunction(entity.update)) { + /** + * Normal update + */ + entity.update(deltaTime, false); -/** - * Updates the scene - * @param deltaTime - */ -GameLib.D3.Scene.prototype.lateUpdate = function( - deltaTime -) { - for(var e in this.entities) { - if (this.entities.hasOwnProperty(e)) { - this.entities[e].lateUpdate(deltaTime); + //TODO: calculate new delta time? + + /** + * Late update + */ + entity.update(deltaTime, true); + } } - } + ); }; /** @@ -440,67 +424,22 @@ GameLib.D3.Scene.prototype.render = function( renderer.render(this.instance, this.cameras[this.activeCameraIndex].instance); }; -/** - * Registers an entity to the scene. - * This method also links the entity and it's components, - * if they are defined inside the ids array. - * The setParentEntity and onSetParentEntity methods are being called here. - * @param entity GameLib.D3.Entity - */ -GameLib.D3.Scene.prototype.registerEntity = function( - entity -) { - if (!this.idToObject.hasOwnProperty(entity.id)) { - this.idToObject[entity.id] = entity; - } - - if (this.entities.indexOf(entity) == -1) { - this.entities.push(entity); - } - - entity.register(this); - - for(var c = 0; c < entity.ids.length; c++) { - - var id = entity.ids[c]; - - var component = this.idToObject[id]; - - if (component) { - component.setParentEntity(this, entity); - } - } -}; - -/** - * Registers a component to the scene. - * This method also calls the onRegistered-method on the component - * @param component GameLib.D3.ComponentInterface - */ -GameLib.D3.Scene.prototype.registerComponent = function( - component -) { - this.components.push(component); - - this.idToObject[component.id] = component; - - if (component.onRegistered && typeof component.onRegistered == 'function') { - component.onRegistered(this); - } -}; - /** * After we created a scene and idToObject has been created, we should execute this function to map - * the components witht their ids to the proper objects + * the scene objects to the components and entities */ GameLib.D3.Scene.prototype.linkObjects = function() { - this.components.map(function(component) { - component.linkObjects(this.idToObject); - }.bind(this)); + this.components.map( + function(component) { + component.linkObjects(this.idToObject); + }.bind(this) + ); - this.entities.map(function(entity) { - entity.linkObjects(this.idToObject); - }.bind(this)); + this.entities.map( + function(entity) { + entity.linkObjects(this.idToObject); + }.bind(this) + ); }; \ No newline at end of file diff --git a/src/game-lib-utils.js b/src/game-lib-utils.js index fe703e7..be381c4 100644 --- a/src/game-lib-utils.js +++ b/src/game-lib-utils.js @@ -34,6 +34,28 @@ GameLib.D3.Utils.IdOrNull = function (object) { } }; +/** + * Returns an array of IDs representing the objects + * @param array + * @returns [] + * @constructor + */ +GameLib.D3.Utils.IdArrayOrEmptyArray = function (array) { + if (GameLib.D3.Utils.UndefinedOrNull(array)) { + return []; + } else { + + return array.map(function(item) { + + if (GameLib.D3.Utils.UndefinedOrNull(item.id)) { + throw new Error('No ID found while trying to store IDs to array'); + } + + return item.id + }); + } +}; + /** * Links an object to its parent through idToObject array * @param propertyString @@ -47,7 +69,7 @@ GameLib.D3.Utils.Link = function(propertyString, idToObject, parentObject, id) { if (!GameLib.D3.Utils.UndefinedOrNull(parentObject[propertyString])) { if (!idToObject.hasOwnProperty(id)) { - console.warn('camera linking failed for object:' + parentObject.name); + console.warn('Linking failed for object:' + parentObject.name); } parentObject[propertyString] = idToObject[id]; diff --git a/src/game-lib-vector2.js b/src/game-lib-vector2.js index 0cd6025..ca8b170 100644 --- a/src/game-lib-vector2.js +++ b/src/game-lib-vector2.js @@ -2,15 +2,15 @@ * Runtime vector2 for updating instance objects * @param graphics GameLib.D3.Graphics * @param parentObject GameLib.D3.* - * @param vector2 GameLib.D3.API.Vector2 + * @param apiVector2 GameLib.D3.API.Vector2 * @param grain Number * @constructor */ -GameLib.D3.Vector2 = function RuntimeVector2(graphics, parentObject, vector2, grain) { +GameLib.D3.Vector2 = function RuntimeVector2(graphics, parentObject, apiVector2, grain) { - for (var property in vector2) { - if (vector2.hasOwnProperty(property)) { - this[property] = vector2[property]; + for (var property in apiVector2) { + if (apiVector2.hasOwnProperty(property)) { + this[property] = apiVector2[property]; } } diff --git a/src/game-lib-vector3.js b/src/game-lib-vector3.js index 2f68d88..0720cc3 100644 --- a/src/game-lib-vector3.js +++ b/src/game-lib-vector3.js @@ -65,7 +65,6 @@ GameLib.D3.Vector3.prototype.updateInstance = function() { /** * Converts runtime vector to API Vector - * @returns {GameLib.D3.API.Vector3} */ GameLib.D3.Vector3.prototype.toApiVector = function() { return new GameLib.D3.API.Vector3( diff --git a/src/game-lib-vector4.js b/src/game-lib-vector4.js new file mode 100644 index 0000000..60b7a13 --- /dev/null +++ b/src/game-lib-vector4.js @@ -0,0 +1,80 @@ +/** + * Runtime apiVector4 for updating instance objects + * @param graphics GameLib.D3.Graphics + * @param parentObject GameLib.D3.* + * @param apiVector4 GameLib.D3.API.Vector4 + * @param grain Number + * @constructor + */ +GameLib.D3.Vector4 = function RuntimeVector4(graphics, parentObject, apiVector4, grain) { + + GameLib.D3.API.Vector4.call( + this, + apiVector4.x, + apiVector4.y, + apiVector4.z, + apiVector4.w + ); + + this.graphics = graphics; + + this.graphics.isNotThreeThrow(); + + this.parentObject = parentObject; + + if (GameLib.D3.Utils.UndefinedOrNull(grain)) { + grain = 0.001; + } + this.grain = grain; + + this.instance = this.createInstance(); +}; + +GameLib.D3.Vector4.prototype = Object.create(GameLib.D3.API.Vector4.prototype); +GameLib.D3.Vector4.prototype.constructor = GameLib.D3.Vector4; + +/** + * Creates an instance vector3 + * @param update + * @returns {*} + */ +GameLib.D3.Vector4.prototype.createInstance = function(update) { + + var instance = null; + + if (update) { + instance = this.instance; + instance.x = this.x; + instance.y = this.y; + instance.z = this.z; + instance.w = this.w; + } else { + instance = new THREE.Quaternion(this.x, this.y, this.z, this.w); + } + + return instance; +}; + +/** + * Updates the instance vector, calls updateInstance on the parent object + */ +GameLib.D3.Vector4.prototype.updateInstance = function() { + + this.createInstance(true); + + if (this.parentObject.updateInstance) { + this.parentObject.updateInstance(); + } +}; + +/** + * Converts runtime vector to API Vector + */ +GameLib.D3.Vector4.prototype.toApiVector = function() { + return new GameLib.D3.API.Vector4( + this.x, + this.y, + this.z, + this.w + ); +}; \ No newline at end of file