diff --git a/src/game-lib-d3-api-particle-engine.js b/src/game-lib-d3-api-particle-engine.js index 2014431..497a4a3 100644 --- a/src/game-lib-d3-api-particle-engine.js +++ b/src/game-lib-d3-api-particle-engine.js @@ -2,10 +2,15 @@ * Raw ParticleEngine API object - should always correspond with the ParticleEngine Schema * @param id * @param name + * @param meshes * @param materials * @param position + * @param rotation * @param direction + * @param lookAt * @param particlesPerSecond + * @param frequency + * @param elapsed * @param distanceType * @param minDistance * @param maxDistance @@ -24,6 +29,8 @@ GameLib.D3.API.ParticleEngine = function( meshes, materials, position, + rotation, + scale, direction, lookAt, particlesPerSecond, @@ -66,6 +73,16 @@ GameLib.D3.API.ParticleEngine = function( } this.position = position; + if (GameLib.Utils.UndefinedOrNull(rotation)) { + rotation = new GameLib.API.Vector3(0, 0, 0); + } + this.rotation = rotation; + + if (GameLib.Utils.UndefinedOrNull(scale)) { + scale = new GameLib.API.Vector3(1, 1, 1); + } + this.scale = scale; + if (GameLib.Utils.UndefinedOrNull(direction)) { direction = new GameLib.API.Vector3(0, 0, 1); } @@ -185,6 +202,8 @@ GameLib.D3.API.ParticleEngine.FromObject = function(objectParticleEngine) { apiMeshes, apiMaterials, GameLib.API.Vector3.FromObject(objectParticleEngine.position), + GameLib.API.Vector3.FromObject(objectParticleEngine.rotation), + GameLib.API.Vector3.FromObject(objectParticleEngine.scale), GameLib.API.Vector3.FromObject(objectParticleEngine.direction), GameLib.API.Vector3.FromObject(objectParticleEngine.lookAt), objectParticleEngine.particlesPerSecond, diff --git a/src/game-lib-d3-mesh-0.js b/src/game-lib-d3-mesh-0.js index 477ae2d..86abfbf 100644 --- a/src/game-lib-d3-mesh-0.js +++ b/src/game-lib-d3-mesh-0.js @@ -1175,27 +1175,24 @@ GameLib.D3.Mesh.prototype.applyPositionRotationScale = function() { this.scale.z = 1; this.instance.scale.set(1,1,1); + /** + * Reset rotation + * @type {number} + */ + this.quaternion.x = 0; + this.quaternion.y = 0; + this.quaternion.z = 0; + this.quaternion.w = 1; + this.quaternion.axis.x = 0; + this.quaternion.axis.y = 0; + this.quaternion.axis.z = 0; + this.quaternion.angle = 0; - if (this.useQuaternion) { - /** - * Reset rotation - * @type {number} - */ - this.quaternion.x = 0; - this.quaternion.y = 0; - this.quaternion.z = 0; - this.quaternion.w = 1; - this.quaternion.axis.x = 0; - this.quaternion.axis.y = 0; - this.quaternion.axis.z = 0; - this.quaternion.angle = 0; - this.updateInstanceRotationFromAxisAngle(); - } else { - this.rotation.x = 0; - this.rotation.y = 0; - this.rotation.z = 0; - this.instance.rotation.set(0,0,0); - } + this.rotation.x = 0; + this.rotation.y = 0; + this.rotation.z = 0; + + this.updateInstanceRotation(); /** * Update our instance matrix @@ -1231,13 +1228,24 @@ GameLib.D3.Mesh.prototype.updateInstanceRotationFromAxisAngle = function(axis, a GameLib.D3.Mesh.prototype.updateInstanceRotation = function() { - this.rotation.instance.set( - this.rotation.x, - this.rotation.y, - this.rotation.z - ); + if (this.useQuaternion) { - this.instance.rotation.copy(this.rotation.instance); + this.updateInstanceRotationFromAxisAngle(); + + } else { + + this.rotation.instance.set( + this.rotation.x, + this.rotation.y, + this.rotation.z + ); + + this.instance.rotation.set( + this.rotation.x, + this.rotation.y, + this.rotation.z + ); + } if (this.helper) { this.helper.updateInstance(); diff --git a/src/game-lib-d3-particle-engine.js b/src/game-lib-d3-particle-engine.js index 9d0a7ed..41fc52f 100644 --- a/src/game-lib-d3-particle-engine.js +++ b/src/game-lib-d3-particle-engine.js @@ -27,6 +27,8 @@ GameLib.D3.ParticleEngine = function( apiParticleEngine.meshes, apiParticleEngine.materials, apiParticleEngine.position, + apiParticleEngine.rotation, + apiParticleEngine.scale, apiParticleEngine.direction, apiParticleEngine.lookAt, apiParticleEngine.particlesPerSecond, @@ -77,6 +79,30 @@ GameLib.D3.ParticleEngine = function( throw new Error('position not instance of API.Vector3'); } + if (this.rotation instanceof GameLib.API.Vector3) { + this.rotation = new GameLib.Vector3( + graphics, + this.rotation, + this + ); + } else { + console.warn('rotation not instance of API.Vector3'); + throw new Error('rotation not instance of API.Vector3'); + } + + + if (this.scale instanceof GameLib.API.Vector3) { + this.scale = new GameLib.Vector3( + graphics, + this.scale, + this + ); + } else { + console.warn('scale not instance of API.Vector3'); + throw new Error('scale not instance of API.Vector3'); + } + + if (this.direction instanceof GameLib.API.Vector3) { this.direction = new GameLib.Vector3( graphics, @@ -99,10 +125,17 @@ GameLib.D3.ParticleEngine = function( throw new Error('lookAt not instance of API.Vector3'); } + /** + * This is just a reference to the first mesh in the array + * @type {null} + */ + this.parentMesh = null; + GameLib.Component.call( this, GameLib.Component.COMPONENT_PARTICLE_ENGINE, { + parentMesh : GameLib.D3.Mesh, meshes : [GameLib.D3.Mesh], materials : [GameLib.D3.Material] } @@ -125,37 +158,56 @@ GameLib.D3.ParticleEngine.prototype.createInstance = function() { this.frequency = Number(1 / this.particlesPerSecond); - for (var i = 0; i < this.frequency; i++) { + this.parentMesh = null; - var parentMesh = null; + for (var i = 0; i < this.particlesPerSecond; i++) { - if (i !== 0) { - parentMesh = this.meshes[0]; + if (i === 0) { + + var apiMesh = new GameLib.D3.API.Mesh( + null, + GameLib.D3.Mesh.MESH_TYPE_PLANE, + 'Particle Mesh', + null, + null, + this.materials, + null + ); + + this.parentMesh = new GameLib.D3.Mesh.Plane( + this.graphics, + apiMesh, + 1, + 1, + 1, + 1 + ); + + this.parentMesh.useQuaternion = false; + + this.parentMesh.position.setFrom(this.position); + this.parentMesh.rotation.setFrom(this.rotation); + this.parentMesh.scale.setFrom(this.scale); + + this.meshes.push(this.parentMesh); + + } else { + + var mesh = this.parentMesh.clone(); + + mesh.parentMesh = this.parentMesh; + + mesh.updateInstance(); + + this.meshes.push(mesh); } - var apiMesh = new GameLib.D3.API.Mesh( - null, - GameLib.D3.Mesh.MESH_TYPE_PLANE, - 'Particle Mesh', - null, - null, - this.materials, - parentMesh - ); - - var mesh = new GameLib.D3.Mesh.Plane( - this.graphics, - apiMesh, - 1, - 1, - 1, - 1 - ); - - this.meshes.push(mesh); } - this.instance = { + this.updateDistances(); + + this.instance = true;/* { + parentMesh : this.parentMesh.instance, position : this.position.instance, direction : this.direction.instance, lookAt : this.lookAt.instance, @@ -169,16 +221,94 @@ GameLib.D3.ParticleEngine.prototype.createInstance = function() { return material.instance } ) - }; + };*/ GameLib.Component.prototype.createInstance.call(this); }; +GameLib.D3.ParticleEngine.prototype.updateDistances = function() { + + var distanceGrain = 1; + + if (this.particlesPerSecond > 1) { + distanceGrain = Number(1 / (this.particlesPerSecond - 1)); + } + + var minDistance = this.direction.clone().multiply(this.minDistance, true); + minDistance.parentObject = null; + minDistance.updateInstance(); + + var maxDistance = this.direction.clone().multiply(this.maxDistance, true); + maxDistance.parentObject = null; + maxDistance.updateInstance(); + + this.meshes.map( + function(mesh, index) { + + if (index === 0) { + return; + } + + var distance = minDistance.instance.lerp(maxDistance.instance, (index * distanceGrain)); + + mesh.position.x = this.direction.x * (distance.x); + mesh.position.y = this.direction.y * (distance.y); + mesh.position.z = this.direction.z * (distance.z); + + mesh.updateInstancePosition(); + + }.bind(this) + ); + +}; + /** * Updates the instance with the current state */ -GameLib.D3.ParticleEngine.prototype.updateInstance = function() { - GameLib.Event.Emit(GameLib.Event.PARTICLE_INSTANCE_UPDATED, {component:this}); +GameLib.D3.ParticleEngine.prototype.updateInstance = function(property) { + + console.log('property : ' + property); + + if (property === 'position') { + this.parentMesh.position.setFrom(this.position); + this.parentMesh.updateInstancePosition(); + } + + if (property === 'rotation') { + this.parentMesh.rotation.setFrom(this.rotation); + this.parentMesh.updateInstanceRotation(); + } + + if (property === 'scale') { + this.parentMesh.scale.setFrom(this.scale); + this.parentMesh.updateInstanceScale(); + } + + if (property === 'particlesPerSecond') { + + console.log('particles per second or max distance'); + + this.meshes.map( + function(mesh) { + GameLib.Event.Emit( + GameLib.Event.REMOVE_COMPONENT, + { + component : mesh + } + ) + } + ); + + this.meshes = []; + + this.createInstance(); + } + + if (property === 'minDistance' || property === 'maxDistance') { + this.updateDistances(); + } + + //GameLib.Event.Emit(GameLib.Event.PARTICLE_INSTANCE_UPDATED, {component:this}); }; /** @@ -202,6 +332,8 @@ GameLib.D3.ParticleEngine.prototype.toApiObject = function() { } ), this.position.toApiObject(), + this.rotation.toApiObject(), + this.scale.toApiObject(), this.direction.toApiObject(), this.lookAt.toApiObject(), this.particlesPerSecond, diff --git a/src/game-lib-quaternion.js b/src/game-lib-quaternion.js index 656fd4f..658335b 100644 --- a/src/game-lib-quaternion.js +++ b/src/game-lib-quaternion.js @@ -101,7 +101,7 @@ GameLib.Quaternion.prototype.createInstance = function() { /** * Updates the instance vector, calls updateInstance on the parent object */ -GameLib.Quaternion.prototype.updateInstance = function() { +GameLib.Quaternion.prototype.updateInstance = function(property) { this.instance.x = this.x; this.instance.y = this.y; @@ -110,7 +110,7 @@ GameLib.Quaternion.prototype.updateInstance = function() { if (this.parentObject && this.parentObject.updateInstance) { - this.parentObject.updateInstance(); + this.parentObject.updateInstance(property); } }; diff --git a/src/game-lib-system-gui.js b/src/game-lib-system-gui.js index 7df23a9..99e67ae 100644 --- a/src/game-lib-system-gui.js +++ b/src/game-lib-system-gui.js @@ -202,11 +202,11 @@ GameLib.System.GUI.prototype.onChange = function(property, subProperty, affected } if (typeof component[property].updateInstance === 'function') { - component[property].updateInstance(); + component[property].updateInstance(property); } else if (typeof component[property][subProperty].updateInstance === 'function') { - component[property][subProperty].updateInstance(); + component[property][subProperty].updateInstance(subProperty); } else { - component.updateInstance(); + component.updateInstance(property); } }); @@ -1118,7 +1118,8 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, } else if ( property === 'widthSegments' || property === 'radiusSegments' || - property === 'heightSegments' + property === 'heightSegments' || + property === 'particlesPerSecond' ) { controllers.push(folder.add(object, property, 1, 1000, 1)); } else if ( @@ -1166,7 +1167,7 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, ) { controllers.push(folder.add(object, property, -Math.PI * 2, Math.PI * 2, 0.01)); } else { - controllers.push(folder.add(object, property, -10000, 10000, grain)); + controllers.push(folder.add(object, property, -1000, 1000, 0.1)); } } } @@ -1182,7 +1183,7 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, componentTemplate.affected.map( function(component){ component[property] = value; - component.updateInstance(); + component.updateInstance(property); } ); @@ -1202,7 +1203,7 @@ GameLib.System.GUI.prototype.buildControl = function(folder, componentTemplate, componentTemplate.affected.map( function(component){ component[property] = value; - component.updateInstance(); + component.updateInstance(property); } ); } diff --git a/src/game-lib-vector2.js b/src/game-lib-vector2.js index aad03f6..5f34d73 100644 --- a/src/game-lib-vector2.js +++ b/src/game-lib-vector2.js @@ -17,6 +17,7 @@ GameLib.Vector2 = function ( if (GameLib.Utils.UndefinedOrNull(apiVector2)) { apiVector2 = {}; + apiVector2 = {}; } if (apiVector2 instanceof GameLib.Vector2) { @@ -57,14 +58,14 @@ GameLib.Vector2.prototype.createInstance = function() { /** * Updates the instance vector, calls updateInstance on the parent object */ -GameLib.Vector2.prototype.updateInstance = function() { +GameLib.Vector2.prototype.updateInstance = function(property) { this.instance.x = this.x; this.instance.y = this.y; if (this.parentObject && this.parentObject.updateInstance) { - this.parentObject.updateInstance(); + this.parentObject.updateInstance(property); } }; diff --git a/src/game-lib-vector3.js b/src/game-lib-vector3.js index 57adaa2..8f19a78 100644 --- a/src/game-lib-vector3.js +++ b/src/game-lib-vector3.js @@ -83,7 +83,7 @@ GameLib.Vector3.prototype.createInstance = function() { /** * Updates the instance vector, calls updateInstance on the parent object */ -GameLib.Vector3.prototype.updateInstance = function() { +GameLib.Vector3.prototype.updateInstance = function(property) { this.instance.x = this.x; this.instance.y = this.y; @@ -92,7 +92,7 @@ GameLib.Vector3.prototype.updateInstance = function() { if (this.parentObject && this.parentObject !== this && this.parentObject.updateInstance) { - this.parentObject.updateInstance(); + this.parentObject.updateInstance(property); } }; @@ -123,6 +123,19 @@ GameLib.Vector3.prototype.copy = function() { ) }; +GameLib.Vector3.prototype.clone = function() { + return new GameLib.Vector3( + this.implementation, + new GameLib.API.Vector3( + this.x, + this.y, + this.z + ), + this.parentObject, + this.grain + ) +}; + /** * Create a negative version of this vector * @returns {GameLib.Vector3} diff --git a/src/game-lib-vector4.js b/src/game-lib-vector4.js index 02eb117..d1e26f9 100644 --- a/src/game-lib-vector4.js +++ b/src/game-lib-vector4.js @@ -64,7 +64,7 @@ GameLib.Vector4.prototype.createInstance = function() { /** * Updates the instance vector, calls updateInstance on the parent object */ -GameLib.Vector4.prototype.updateInstance = function() { +GameLib.Vector4.prototype.updateInstance = function(property) { this.instance.x = this.x; this.instance.y = this.y; @@ -73,7 +73,7 @@ GameLib.Vector4.prototype.updateInstance = function() { if (this.parentObject && this.parentObject.updateInstance) { - this.parentObject.updateInstance(); + this.parentObject.updateInstance(property); } };