diff --git a/src/game-lib-a-1-event.js b/src/game-lib-a-1-event.js index 46657a1..f2e75f1 100644 --- a/src/game-lib-a-1-event.js +++ b/src/game-lib-a-1-event.js @@ -82,6 +82,8 @@ GameLib.Event.GET_API_URL = 0x40; GameLib.Event.GET_PHYSICS_ENGINE = 0x41; GameLib.Event.PARENT_WORLD_CHANGE = 0x42; GameLib.Event.ANIMATE = 0x43; +GameLib.Event.ANIMATION_COMPILE_SUCCESS = 0x44; +GameLib.Event.ANIMATION_COMPILE_FAILED = 0x45; /** * Returns string name of event ID @@ -159,6 +161,8 @@ GameLib.Event.GetEventName = function(number) { case 0x41 : return 'get_physics_engine'; case 0x42 : return 'parent_world_change'; case 0x43 : return 'animate'; + case 0x44 : return 'animation_compile_success'; + case 0x45 : return 'animation_compile_failed'; break; } diff --git a/src/game-lib-a-component-a.js b/src/game-lib-a-component-a.js index 9f32b97..64687ab 100644 --- a/src/game-lib-a-component-a.js +++ b/src/game-lib-a-component-a.js @@ -151,6 +151,7 @@ GameLib.Component.COMPONENT_FRICTION_CONTACT_MATERIAL = 0x34; GameLib.Component.COMPONENT_RAYCAST_VEHICLE = 0x35; GameLib.Component.COMPONENT_RAYCAST_WHEEL = 0x36; GameLib.Component.COMPONENT_CLOCK = 0x37; +GameLib.Component.COMPONENT_ANIMATION = 0x38; /** * Returns string name for component number @@ -215,6 +216,7 @@ GameLib.Component.GetComponentName = function(number) { case 0x35 : return 'GameLib.D3.RaycastVehicle'; case 0x36 : return 'GameLib.D3.RaycastWheel'; case 0x37 : return 'GameLib.Clock'; + case 0x38 : return 'GameLib.D3.Animation'; break; } diff --git a/src/game-lib-d3-api-animation.js b/src/game-lib-d3-api-animation.js new file mode 100644 index 0000000..da80a6b --- /dev/null +++ b/src/game-lib-d3-api-animation.js @@ -0,0 +1,108 @@ +/** + * Animation Component + * @param id + * @param name + * @param rotationSpeed + * @param translationSpeed + * @param scaleSpeed + * @param rotationFn + * @param translationFn + * @param scaleFn + * @param blocking + * @param parentMesh + * @param parentEntity + * @constructor + */ +GameLib.D3.API.Animation = function ( + id, + name, + rotationSpeed, + translationSpeed, + scaleSpeed, + rotationFn, + translationFn, + scaleFn, + blocking, + parentMesh, + parentEntity +) { + if (GameLib.Utils.UndefinedOrNull(id)) { + id = GameLib.Utils.RandomId(); + } + this.id = id; + + if (GameLib.Utils.UndefinedOrNull(name)) { + name = 'Animation (' + this.id + ')'; + } + this.name = name; + + if (GameLib.Utils.UndefinedOrNull(rotationSpeed)) { + rotationSpeed = 0; + } + this.rotationSpeed = rotationSpeed; + + if (GameLib.Utils.UndefinedOrNull(translationSpeed)) { + translationSpeed = 0; + } + this.translationSpeed = translationSpeed; + + if (GameLib.Utils.UndefinedOrNull(scaleSpeed)) { + scaleSpeed = 0; + } + this.scaleSpeed = scaleSpeed; + + if (GameLib.Utils.UndefinedOrNull(rotationFn)) { + rotationFn = null; + } + this.rotationFn = rotationFn; + + if (GameLib.Utils.UndefinedOrNull(translationFn)) { + translationFn = null; + } + this.translationFn = translationFn; + + if (GameLib.Utils.UndefinedOrNull(scaleFn)) { + scaleFn = null; + } + this.scaleFn = scaleFn; + + if (GameLib.Utils.UndefinedOrNull(blocking)) { + blocking = true; + } + this.blocking = blocking; + + if (GameLib.Utils.UndefinedOrNull(parentMesh)) { + parentMesh = null; + } + this.parentMesh = parentMesh; + + if (GameLib.Utils.UndefinedOrNull(parentEntity)) { + parentEntity = null; + } + this.parentEntity = parentEntity; +}; + +GameLib.D3.API.Animation.prototype = Object.create(GameLib.Component.prototype); +GameLib.D3.API.Animation.prototype.constructor = GameLib.D3.API.Animation; + +/** + * Object to GameLib.D3.API.Animation + * @param objectComponent + * @returns {GameLib.D3.API.Animation} + * @constructor + */ +GameLib.D3.API.Animation.FromObject = function(objectComponent) { + return new GameLib.D3.API.Animation( + objectComponent.id, + objectComponent.name, + objectComponent.rotationSpeed, + objectComponent.translationSpeed, + objectComponent.scaleSpeed, + objectComponent.rotationFn, + objectComponent.translationFn, + objectComponent.scaleFn, + objectComponent.blocking, + objectComponent.parentMesh, + objectComponent.parentEntity + ); +}; diff --git a/src/game-lib-d3-api-mesh.js b/src/game-lib-d3-api-mesh.js index a7e9119..a115499 100644 --- a/src/game-lib-d3-api-mesh.js +++ b/src/game-lib-d3-api-mesh.js @@ -14,9 +14,6 @@ * @param position GameLib.API.Vector3 * @param quaternion GameLib.API.Quaternion * @param scale GameLib.API.Vector3 - * @param localPosition GameLib.API.Vector3 - * @param localRotation GameLib.API.Vector3 - * @param localScale GameLib.API.Vector3 * @param up * @param modelMatrix GameLib.API.Matrix4 * @param parentEntity @@ -39,9 +36,6 @@ GameLib.D3.API.Mesh = function( position, quaternion, scale, - localPosition, - localRotation, - localScale, up, modelMatrix, parentEntity, @@ -118,21 +112,6 @@ GameLib.D3.API.Mesh = function( } this.scale = scale; - if (GameLib.Utils.UndefinedOrNull(localPosition)) { - localPosition = new GameLib.API.Vector3(0,0,0); - } - this.localPosition = localPosition; - - if (GameLib.Utils.UndefinedOrNull(localRotation)) { - localRotation = new GameLib.API.Vector3(0,0,0); - } - this.localRotation = localRotation; - - if (GameLib.Utils.UndefinedOrNull(localScale)) { - localScale = new GameLib.API.Vector3(1,1,1); - } - this.localScale = localScale; - if (GameLib.Utils.UndefinedOrNull(up)) { up = new GameLib.API.Vector3(0,1,0); } @@ -223,21 +202,6 @@ GameLib.D3.API.Mesh.FromObject = function (objectMesh){ apiScale = GameLib.API.Vector3.FromObject(objectMesh.scale); } - var apiLocalPosition = new GameLib.API.Vector3(); - if (objectMesh.localPosition) { - apiLocalPosition = GameLib.API.Vector3.FromObject(objectMesh.localPosition); - } - - var apiLocalRotation = new GameLib.API.Vector3(); - if (objectMesh.localRotation) { - apiLocalRotation = GameLib.API.Vector3.FromObject(objectMesh.localRotation); - } - - var apiLocalScale = new GameLib.API.Vector3(1,1,1); - if (objectMesh.localScale) { - apiLocalScale = GameLib.API.Vector3.FromObject(objectMesh.localScale); - } - var apiUp = new GameLib.API.Vector3(0,1,0); if (objectMesh.up) { apiUp = GameLib.API.Vector3.FromObject(objectMesh.up); @@ -263,9 +227,6 @@ GameLib.D3.API.Mesh.FromObject = function (objectMesh){ apiPosition, apiQuaternion, apiScale, - apiLocalPosition, - apiLocalRotation, - apiLocalScale, apiUp, apiModelMatrix, objectMesh.parentEntity, diff --git a/src/game-lib-d3-api-z-animation.js b/src/game-lib-d3-api-z-animation.js new file mode 100644 index 0000000..1d6b36b --- /dev/null +++ b/src/game-lib-d3-api-z-animation.js @@ -0,0 +1,228 @@ +/** + * Creates a Animation object + * @param coder + * @param apiAnimation GameLib.D3.API.Animation + * @constructor + */ +GameLib.D3.Animation = function( + coder, + apiAnimation +) { + + this.coder = coder; + this.coder.isNotCodeMirrorThrow(); + + if (GameLib.Utils.UndefinedOrNull(apiAnimation)) { + apiAnimation = {}; + } + + if (apiAnimation instanceof GameLib.D3.Animation) { + return apiAnimation; + } + + GameLib.D3.API.Animation.call( + this, + apiAnimation.id, + apiAnimation.name, + apiAnimation.rotationSpeed, + apiAnimation.translationSpeed, + apiAnimation.scaleSpeed, + apiAnimation.rotationFn, + apiAnimation.translationFn, + apiAnimation.scaleFn, + apiAnimation.blocking, + apiAnimation.parentMesh, + apiAnimation.parentEntity + ); + + this.functionType = GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION; + + this.editor = null; + + GameLib.Component.call( + this, + GameLib.Component.COMPONENT_ANIMATION + ); +}; + +GameLib.D3.Animation.prototype = Object.create(GameLib.D3.API.Animation.prototype); +GameLib.D3.Animation.prototype.constructor = GameLib.D3.Animation; + +GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION = 1; +GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION = 2; +GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE = 3; + +GameLib.D3.Animation.prototype.createInstance = function() { + + try { + + var instance = { + rotation : null, + translation : null, + scale : null + }; + + if (this.rotationFn) { + instance.rotation = new Function( + 'data', + this.rotationFn + ).bind(this); + } + + if (this.translationFn) { + instance.translation = new Function( + 'data', + this.translationFn + ).bind(this); + } + + if (this.scaleFn) { + instance.scale = new Function( + 'data', + this.scaleFn + ).bind(this); + } + + return instance; + + } catch (error) { + /** + * Return true here to indicate that even though the compilation failed, the instance will be fine and + * this component loaded fine. + */ + return true; + } +}; + +/** + * Updates the instance with the current state + */ +GameLib.D3.Animation.prototype.updateInstance = function() { + try { + + if (this.rotationFn) { + this.instance.rotation = new Function('data', this.rotationFn).bind(this); + this.publish( + GameLib.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION + } + ) + } + + if (this.translationFn) { + this.instance.translation = new Function('data', this.translationFn).bind(this); + this.publish( + GameLib.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION + } + ) + } + + if (this.scaleFn) { + this.instance.scale = new Function('data', this.scaleFn).bind(this); + this.publish( + GameLib.Event.ANIMATION_COMPILE_SUCCESS, + { + component : this, + type : GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE + } + ) + } + + } catch (error) { + this.publish( + GameLib.Event.ANIMATION_COMPILE_FAILED, + { + component : this + } + ) + } +}; + +/** + * Converts a GameLib.D3.Animation to a new GameLib.D3.API.Animation + * @returns {GameLib.D3.API.Animation} + */ +GameLib.D3.Animation.prototype.toApiObject = function() { + + return new GameLib.D3.API.Animation( + this.id, + this.name, + this.rotationSpeed, + this.translationSpeed, + this.scaleSpeed, + this.rotationFn, + this.translationFn, + this.scaleFn, + this.blocking, + GameLib.Utils.IdOrNull(this.parentMesh), + GameLib.Utils.IdOrNull(this.parentEntity) + ); + +}; + +/** + * Converts from an Object Animation to a GameLib.D3.Animation + * @param coder GameLib.D3.Coder + * @param objectAnimation Object + * @returns {GameLib.D3.Animation} + * @constructor + */ +GameLib.D3.Animation.FromObject = function(coder, objectAnimation) { + var apiAnimation = GameLib.D3.API.Animation.FromObject(objectAnimation); + return new GameLib.D3.Animation( + coder, + apiAnimation + ); +}; + +GameLib.D3.Animation.prototype.launchEditor = function(){ + + var property = null; + + if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION) { + this.rotationFn = '//when the animation is complete, return true\nreturn true;'; + property = 'rotationFn'; + } + + if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION) { + this.translationFn = '//when the animation is complete, return true\nreturn true;'; + property = 'translationFn'; + } + + if (this.functionType === GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE) { + this.scaleFn = '//when the animation is complete, return true\nreturn true;'; + property = 'scaleFn'; + } + + if (property) { + this.editor = this.coder.instance( + document.body, + { + value : this[property], + mode : 'javascript', + lineNumbers : true, + scrollbarStyle : 'overlay' + } + ); + + this.editor.on('change', function(){ + + this[property] = this.editor.getValue(); + + this.updateInstance(); + + }.bind(this)) + } else { + console.warn('invalid function type selected'); + } +}; + +GameLib.D3.Animation.prototype.closeEditor = function(){ + var dom = this.editor.getWrapperElement(); + dom.parentElement.removeChild(dom); +}; \ No newline at end of file diff --git a/src/game-lib-d3-mesh-0.js b/src/game-lib-d3-mesh-0.js index 373a49a..d781bfa 100644 --- a/src/game-lib-d3-mesh-0.js +++ b/src/game-lib-d3-mesh-0.js @@ -35,9 +35,6 @@ GameLib.D3.Mesh = function ( apiMesh.position, apiMesh.quaternion, apiMesh.scale, - apiMesh.localPosition, - apiMesh.localRotation, - apiMesh.localScale, apiMesh.up, apiMesh.modelMatrix, apiMesh.parentEntity, @@ -113,42 +110,6 @@ GameLib.D3.Mesh = function ( this ); - this.localPosition = new GameLib.Vector3( - this.graphics, - this.localPosition, - this - ); - - this.localRotation = new GameLib.Vector3( - this.graphics, - this.localRotation, - this - ); - - Object.defineProperty( - this.localRotation, - 'x', - GameLib.Utils.LimitToPI('x', this.localRotation.x) - ); - - Object.defineProperty( - this.localRotation, - 'y', - GameLib.Utils.LimitToPI('y', this.localRotation.y) - ); - - Object.defineProperty( - this.localRotation, - 'z', - GameLib.Utils.LimitToPI('z', this.localRotation.z) - ); - - this.localScale = new GameLib.Vector3( - this.graphics, - this.localScale, - this - ); - this.modelMatrix = new GameLib.Matrix4( this.graphics, this.modelMatrix, @@ -463,19 +424,10 @@ GameLib.D3.Mesh.prototype.createInstanceGeometry = function(instanceGeometry) { */ GameLib.D3.Mesh.prototype.createInstance = function() { - // console.log('mesh create instance'); - var geometry = this.createInstanceGeometry(); var instance = null; - - var instanceMaterials = function(result, material){ - material.instance.needsUpdate = true; - result.push(material.instance); - return result; - }; - if (this.skeleton) { if (this.materials.length === 1) { @@ -524,8 +476,6 @@ GameLib.D3.Mesh.prototype.createInstance = function() { */ GameLib.D3.Mesh.prototype.updateInstance = function() { - // console.log('mesh update instance'); - if (( this.isBufferMesh && !(this.instance.geometry instanceof THREE.BufferGeometry)) || ( !this.isBufferMesh && (this.instance.geometry instanceof THREE.BufferGeometry))) { @@ -553,30 +503,18 @@ GameLib.D3.Mesh.prototype.updateInstance = function() { } if (this.parentMesh && this.parentMesh.loaded) { - if (this.instance.parent !== this.parentMesh.instance) { this.instance.parent = this.parentMesh.instance; } + } - this.instance.position.x = this.localPosition.x; - this.instance.position.y = this.localPosition.y; - this.instance.position.z = this.localPosition.z; + this.instance.scale.x = this.scale.x; + this.instance.scale.y = this.scale.y; + this.instance.scale.z = this.scale.z; - this.instance.scale.x = this.localScale.x; - this.instance.scale.y = this.localScale.y; - this.instance.scale.z = this.localScale.z; - - } else { - - this.instance.position.x = this.position.x + this.localPosition.x; - this.instance.position.y = this.position.y + this.localPosition.y; - this.instance.position.z = this.position.z + this.localPosition.z; - - this.instance.scale.x = this.scale.x * this.localScale.x; - this.instance.scale.y = this.scale.y * this.localScale.y; - this.instance.scale.z = this.scale.z * this.localScale.z; - - } + this.instance.position.x = this.position.x; + this.instance.position.y = this.position.y; + this.instance.position.z = this.position.z; this.instance.up.x = this.up.x; this.instance.up.y = this.up.y; @@ -593,11 +531,7 @@ GameLib.D3.Mesh.prototype.updateInstance = function() { if (this.helper) { this.removeHelper(); this.createHelper(); - // this.helper.updateInstance(); } - - // this.computeBoundingBox(this.instance.geometry); - }; /** @@ -605,10 +539,10 @@ GameLib.D3.Mesh.prototype.updateInstance = function() { * @param geometryInstance */ GameLib.D3.Mesh.prototype.updateVerticesFromGeometryInstance = function(geometryInstance) { + /** * Setup vertices */ - this.vertices = []; this.faces = []; @@ -866,48 +800,29 @@ GameLib.D3.Mesh.prototype.createInstanceDefaults = function(instance) { instance.name = this.name; if (this.parentMesh && this.parentMesh.loaded) { - if (this.parentMesh.loaded) { instance.parent = this.parentMesh.instance; - - instance.position.x = this.localPosition.x; - instance.position.y = this.localPosition.y; - instance.position.z = this.localPosition.z; - - instance.quaternion.x = this.quaternion.x; - instance.quaternion.y = this.quaternion.y; - instance.quaternion.z = this.quaternion.z; - instance.quaternion.w = this.quaternion.w; - instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); - - instance.scale.x = this.localScale.x; - instance.scale.y = this.localScale.y; - instance.scale.z = this.localScale.z; - } else { - console.warn('parent mesh not loaded at time of creating instance - provide callback here') } - - } else { - - instance.quaternion.x = this.quaternion.x; - instance.quaternion.y = this.quaternion.y; - instance.quaternion.z = this.quaternion.z; - instance.quaternion.w = this.quaternion.w; - instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); - - instance.position.x = this.position.x + this.localPosition.x; - instance.position.y = this.position.y + this.localPosition.y; - instance.position.z = this.position.z + this.localPosition.z; - - instance.scale.x = this.scale.x * this.localScale.x; - instance.scale.y = this.scale.y * this.localScale.y; - instance.scale.z = this.scale.z * this.localScale.z; - - instance.up.x = this.up.x; - instance.up.y = this.up.y; - instance.up.z = this.up.z; } + instance.position.x = this.position.x; + instance.position.y = this.position.y; + instance.position.z = this.position.z; + + instance.quaternion.x = this.quaternion.x; + instance.quaternion.y = this.quaternion.y; + instance.quaternion.z = this.quaternion.z; + instance.quaternion.w = this.quaternion.w; + instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); + + instance.scale.x = this.scale.x; + instance.scale.y = this.scale.y; + instance.scale.z = this.scale.z; + + instance.up.x = this.up.x; + instance.up.y = this.up.y; + instance.up.z = this.up.z; + instance.renderOrder = this.renderOrder; }; @@ -972,9 +887,6 @@ GameLib.D3.Mesh.prototype.toApiObject = function() { this.position.toApiObject(), this.quaternion.toApiObject(), this.scale.toApiObject(), - this.localPosition.toApiObject(), - this.localRotation.toApiObject(), - this.localScale.toApiObject(), this.up.toApiObject(), this.modelMatrix.toApiObject(), GameLib.Utils.IdOrNull(this.parentEntity), @@ -1006,25 +918,21 @@ GameLib.D3.Mesh.FromObject = function(graphics, objectMesh) { */ GameLib.D3.Mesh.prototype.centerAroundOrigin = function() { - var localPosition = this.instance.geometry.center(); + var position = this.instance.geometry.center(); this.instance.position.set(0,0,0); this.instance.updateMatrix(); - this.position.x = this.instance.position.x; - this.position.y = this.instance.position.y; - this.position.z = this.instance.position.z; - for (var v = 0; v < this.instance.geometry.vertices.length; v++) { this.vertices[v].position.x = this.instance.geometry.vertices[v].x; this.vertices[v].position.y = this.instance.geometry.vertices[v].y; this.vertices[v].position.z = this.instance.geometry.vertices[v].z; } - this.localPosition.x = -localPosition.x; - this.localPosition.y = -localPosition.y; - this.localPosition.z = -localPosition.z; + this.position.x = -position.x; + this.position.y = -position.y; + this.position.z = -position.z; this.updateInstance(); }; @@ -1032,88 +940,36 @@ GameLib.D3.Mesh.prototype.centerAroundOrigin = function() { /** * Applies position, rotation and scale to the object vertice data, resets scale, rotation and sets position to origin. */ -GameLib.D3.Mesh.prototype.applyLocalPositionRotationScale = function() { +GameLib.D3.Mesh.prototype.applyPositionRotationScale = function() { this.instance.updateMatrix(); this.instance.geometry.applyMatrix(this.instance.matrix); - this.position.x = 0; + this.position.x = 0; this.position.y = 0; this.position.z = 0; + this.instance.position.set(0,0,0); - this.scale.x = 1; + this.scale.x = 1; this.scale.y = 1; this.scale.z = 1; + this.instance.scale.set(1,1,1); - this.localPosition.x = 0; - this.localPosition.y = 0; - this.localPosition.z = 0; - - this.quaternion.axis.x = 0; - this.quaternion.axis.y = 0; - this.quaternion.axis.z = 0; - this.quaternion.axis.w = 1; - this.quaternion.angle = 0; - - this.instance.position.set(0,0,0); + this.quaternion.axis.x = 0; + this.quaternion.axis.y = 0; + this.quaternion.axis.z = 0; + this.quaternion.axis.w = 1; + this.quaternion.angle = 0; this.instance.quaternion.setFromAxisAngle(this.quaternion.axis.instance, this.quaternion.angle); - this.instance.scale.set(1,1,1); + this.quaternion.x = this.instance.quaternion.x; + this.quaternion.y = this.instance.quaternion.y; + this.quaternion.z = this.instance.quaternion.z; + this.quaternion.w = this.instance.quaternion.w; this.instance.updateMatrix(); this.updateVerticesFromGeometryInstance(this.instance.geometry); - - // var geometry = this.createInstanceGeometry(); - // - // /** - // * The face normals got re-calculated - so update again the faces - // */ - // this.updateVerticesFromGeometryInstance(this.instance.geometry); - // - // this.instance.geometry = geometry; - - // this.position.x = 0; - // this.position.y = 0; - // this.position.z = 0; - // - // this.localPosition.x = 0; - // this.localPosition.y = 0; - // this.localPosition.z = 0; - // - // this.localRotation.x = 0; - // this.localRotation.y = 0; - // this.localRotation.z = 0; - // - // this.localScale.x = 1; - // this.localScale.y = 1; - // this.localScale.z = 1; - // - // this.updateInstance(); - // - // this.localPosition.x = this.instance.position.x; - // this.localPosition.y = this.instance.position.y; - // this.localPosition.z = this.instance.position.z; - // - // this.localScale.x = this.instance.scale.x; - // this.localScale.y = this.instance.scale.y; - // this.localScale.z = this.instance.scale.z; - // - // this.rotation.x = this.instance.rotation.x; - // this.rotation.y = this.instance.rotation.y; - // this.rotation.z = this.instance.rotation.z; - // - // console.log('TODO: update vertices from vertex array - we store them indexed but they live non-indexed'); - // // ; - // // - // // for (var v = 0; v < vertices.length; v+=3) { - // // - // // this.vertices[v/3].position.x = vertices[v+0]; - // // this.vertices[v/3].position.y = vertices[v+1]; - // // this.vertices[v/3].position.z = vertices[v+2]; - // // } - // - // this.updateInstance(); }; diff --git a/src/game-lib-d3-raycast-wheel.js b/src/game-lib-d3-raycast-wheel.js index 7334415..71e7c28 100644 --- a/src/game-lib-d3-raycast-wheel.js +++ b/src/game-lib-d3-raycast-wheel.js @@ -168,8 +168,8 @@ GameLib.D3.RaycastWheel.prototype.setChassisLocalConnectionPoint = function() { console.log('you need to set the parent mesh first'); } - this.chassisConnectionPointLocal.x = this.parentMesh.localPosition.x; - this.chassisConnectionPointLocal.y = this.parentMesh.localPosition.y; - this.chassisConnectionPointLocal.z = this.parentMesh.localPosition.z; + this.chassisConnectionPointLocal.x = this.parentMesh.position.x; + this.chassisConnectionPointLocal.y = this.parentMesh.position.y; + this.chassisConnectionPointLocal.z = this.parentMesh.position.z; }; \ No newline at end of file diff --git a/src/game-lib-entity-manager.js b/src/game-lib-entity-manager.js index 3998743..21e0b0c 100644 --- a/src/game-lib-entity-manager.js +++ b/src/game-lib-entity-manager.js @@ -251,7 +251,7 @@ GameLib.EntityManager.prototype.removeEntity = function(entity) { * Returns all the entities with the following components * @param components GameLib.Component[] */ -GameLib.EntityManager.prototype.query = function(components) { +GameLib.EntityManager.prototype.findEntities = function(components) { var entities = this.entities.reduce( function(result, entity) { diff --git a/src/game-lib-system-0.js b/src/game-lib-system-0.js index 14cf1a0..b479ebc 100644 --- a/src/game-lib-system-0.js +++ b/src/game-lib-system-0.js @@ -157,6 +157,7 @@ GameLib.System.prototype.toApiObject = function() { }; GameLib.System.prototype.restart = function() { + console.log('restarting system : ' + this.name); this.stop(); this.start(); }; \ No newline at end of file diff --git a/src/game-lib-system-animation.js b/src/game-lib-system-animation.js index 9f856fc..f8244c3 100644 --- a/src/game-lib-system-animation.js +++ b/src/game-lib-system-animation.js @@ -19,54 +19,259 @@ GameLib.System.Animation.prototype.start = function() { GameLib.System.prototype.start.call(this); - this.renderSubscriptions = []; + this.animationEntities = GameLib.EntityManager.Instance.findEntities([GameLib.D3.Animation]); - this.animateSubscription = GameLib.Event.Subscribe( - GameLib.Event.ANIMATE, - this.animate.bind(this) - ); + this.animationEntities.map( + function(animationEntity) { + /** + * Get all meshes and all animation components + */ + var meshComponents = animationEntity.getComponents(GameLib.D3.Mesh); + var animationComponents = animationEntity.getComponents(GameLib.D3.Animation); -}; + animationComponents.map(function(animation){ -GameLib.System.Animation.prototype.animate = function(animationData, clientCallback) { + meshComponents.map(function(mesh){ - this.renderSubscriptions.push( + if (animation.rotationSpeed) { - new GameLib.Event.Subscribe( + /** + * Back up the current property descriptor + */ + mesh.animationObject = { + backupAngleDescriptor : Object.getOwnPropertyDescriptor(mesh.quaternion, 'angle'), + targetAngle : mesh.quaternion.angle, + angleIncrement : true, + intermediateAngle : mesh.quaternion.angle, + subscription : null + }; - GameLib.Event.BEFORE_RENDER, + var getIntermediateAngle = function() { + return mesh.animationObject.intermediateAngle; + }; - function(subscriptionIndex) { - return function(renderData) { + var animateRotation = function(value) { - if ( - clientCallback( - { - renderData : renderData, - animationData : animationData + mesh.animationObject.intermediateAngle = value; + + var done = false; + + if (mesh.animationObject.angleIncrement) { + /** + * We are rotating upwards + */ + if (value >= mesh.animationObject.targetAngle) { + /** + * We need to stop + */ + done = true; + } + } else { + /** + * We are rotating downwards + */ + if (value <= mesh.animationObject.targetAngle) { + /** + * We need to stop + */ + done = true; + } } - ) - ) { - this.renderSubscriptions[subscriptionIndex].remove(); + if (done) { - animationData.done(); + /** + * Stop subscribing to before render events + */ + mesh.animationObject.subscription.remove(); + + /** + * + * @type {null} + */ + mesh.animationObject.subscription = null; + + /** + * Start checking again for animation requests + */ + Object.defineProperty( + mesh.quaternion, + 'angle', + { + 'get' : getIntermediateAngle, + 'set' : animationCheck, + 'configurable' : true + } + ); + + /** + * Set our target angle value + */ + mesh.animationObject.intermediateAngle = mesh.animationObject.targetAngle; + + /** + * Update our actual angle + */ + mesh.quaternion.angle = mesh.animationObject.targetAngle; + + /** + * Update our instance + */ + mesh.updateInstance(); + + /** + * Now we say that our intermediate angle is zero, because we will apply our rotation + * and this will prevent us from re-registering a new 'animationRender' event + */ + mesh.animationObject.intermediateAngle = 0; + + /** + * Apply our position, rotation and scale to the mesh + */ + mesh.applyPositionRotationScale(); + } + }; + + var animationCheck = function(value) { + + /** + * Check if we have work to do + */ + if (mesh.animationObject.intermediateAngle === value) { + /** + * Nothing to do + */ + return; + } else if (mesh.animationObject.intermediateAngle > value) { + /** + * We will rotate towards by decrementing + */ + mesh.animationObject.angleIncrement = false; + } else { + /** + * We will rotate towards by incrementing + */ + mesh.animationObject.angleIncrement = true; + } + + /** + * We say what our target angle is - when we reach our target angle, we want + * to stop our animation + */ + mesh.animationObject.targetAngle = value; + + /** + * Now override the setter again + */ + Object.defineProperty( + mesh.quaternion, + 'angle', + { + 'get' : getIntermediateAngle, + 'set' : animateRotation, + 'configurable' : true + } + ); + + /** + * Now we subscribe to 'before render' events, and slowly increment the value + * @type {{fn, remove}} + */ + mesh.animationObject.subscription = GameLib.Event.Subscribe( + GameLib.Event.BEFORE_RENDER, + function(data) { + + var increment = Math.abs(animation.rotationSpeed); + + if (mesh.angleIncrement) { + increment *= -1; + } + + mesh.quaternion.angle = (data.delta * increment) + mesh.animationObject.intermediateAngle; + + var backup = mesh.updateRotationFromAxisAngle; + + mesh.updateRotationFromAxisAngle = true; + mesh.updateInstance(); + mesh.updateRotationFromAxisAngle = backup; + } + ); + }; + + + /** + * Override the property descriptor - to slowly increment the angle, but report back its + * target angle as its actual angle. + */ + Object.defineProperty( + mesh.quaternion, + 'angle', + { + 'get' : getIntermediateAngle, + 'set' : animationCheck, + 'configurable' : true + } + ); } - - }.bind(this); - - }.bind(this)(this.renderSubscriptions.length) - ) + }); + }); + } ); - - }; +/** + * Stop Animation System + */ GameLib.System.Animation.prototype.stop = function() { GameLib.System.prototype.stop.call(this); - this.animateSubscription.remove(); + this.animationEntities = GameLib.EntityManager.Instance.findEntities([GameLib.D3.Animation]); + + this.animationEntities.map( + function(animationEntity) { + + /** + * Get all meshes and all animation components + */ + var meshComponents = animationEntity.getComponents(GameLib.D3.Mesh); + var animationComponents = animationEntity.getComponents(GameLib.D3.Animation); + + animationComponents.map( + function (animation) { + + meshComponents.map( + function (mesh) { + + if (animation.rotationSpeed) { + + if (mesh.animationObject) { + + if (mesh.animationObject.backupAngleDescriptor) { + Object.defineProperty( + mesh.quaternion, + 'angle', + mesh.animationObject.backupAngleDescriptor + ) + } + + if (mesh.animationObject.targetAngle) { + mesh.quaternion.angle = mesh.animationObject.targetAngle; + } + + if (mesh.animationObject.subscription) { + mesh.animationObject.subscription.remove(); + } + + delete mesh.animationObject; + } + } + } + ) + } + ) + } + ); }; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index 40c7bce..2693b40 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -215,20 +215,6 @@ GameLib.System.GUI.prototype.controller = function(folder, object, property, sub max = 100; } - - if ( - property === 'localRotation' - ) { - min = -Math.PI; - max = Math.PI; - } - - if (property === 'localScale') { - min = -2; //some weird shit happens when localscale is negative... - max = 10; - step = -0.01; - } - if ( // property === 'chassisConnectionPointLocal' || property === 'axleLocal' || @@ -349,13 +335,6 @@ GameLib.System.GUI.prototype.buildVectorControl = function(folder, componentTemp var controllers = []; - if ( - property === 'localRotation' || - property === 'localPosition' - ) { - step = 0.001; - } - if (GameLib.Utils.isVector4(object[property])) { controllers.push(this.controller(folder, object, property, 'w', step, listen, affected)); @@ -1054,7 +1033,19 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, options ) ); - } else { + } else if (property === 'functionType') { + controllers.push( + folder.add( + object, + property, + { + 'rotation': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_ROTATION, + 'translation': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_TRANSLATION, + 'scale': GameLib.D3.Animation.ANIMATION_FUNCTION_TYPE_SCALE + } + ) + ); + } else { /** * Try to guess a scale for this property diff --git a/src/game-lib-system-storage.js b/src/game-lib-system-storage.js index 4e27552..2a5525a 100644 --- a/src/game-lib-system-storage.js +++ b/src/game-lib-system-storage.js @@ -394,20 +394,18 @@ GameLib.System.Storage.prototype.loadComponent = function(apiUrl, toProcess, inc parentEntity = runtimeComponent; } else { - if (component.componentType === GameLib.Component.COMPONENT_CUSTOM_CODE) { + try { runtimeComponent = fn(__system.coder, component); - } else { - try { + } catch (error) { + try { runtimeComponent = fn(__system.graphics, component); } catch (error) { - runtimeComponent = null; - } - - if (!runtimeComponent) { - try { + try { runtimeComponent = fn(__system.physics, component); } catch (error) { - runtimeComponent = null; + /** + * ok - we don't cannot create this component + */ } } }