particle system, materials, position, stable

beta.r3js.org
-=yb4f310 2017-11-05 09:36:09 +01:00
parent 424ac0169d
commit 0d579f9f13
5 changed files with 237 additions and 25 deletions

View File

@ -281,6 +281,7 @@ GameLib.Component.COMPONENT_SYSTEM_VISUALIZATION = 0x49;
GameLib.Component.COMPONENT_FOG = 0x50;
GameLib.Component.COMPONENT_MESH_LINE = 0x51;
GameLib.Component.COMPONENT_PARTICLE_ENGINE = 0x52;
GameLib.Component.COMPONENT_SYSTEM_PARTICLE = 0x53;
/**
* Returns string name for component number
@ -366,6 +367,7 @@ GameLib.Component.GetComponentName = function(number) {
case 0x50 : return 'GameLib.D3.Fog';
case 0x51 : return 'GameLib.D3.Mesh.Line';
case 0x52 : return 'GameLib.D3.ParticleEngine';
case 0x53 : return 'GameLib.D3.System.Particle';
break;
}

View File

@ -2,7 +2,8 @@
* Raw ParticleEngine API object - should always correspond with the ParticleEngine Schema
* @param id
* @param name
* @param images
* @param materials
* @param position
* @param direction
* @param particlesPerSecond
* @param distanceType
@ -20,7 +21,8 @@
GameLib.D3.API.ParticleEngine = function(
id,
name,
images,
materials,
position,
direction,
particlesPerSecond,
distanceType,
@ -45,10 +47,15 @@ GameLib.D3.API.ParticleEngine = function(
}
this.name = name;
if (GameLib.Utils.UndefinedOrNull(images)) {
images = [];
if (GameLib.Utils.UndefinedOrNull(materials)) {
materials = [];
}
this.images = images;
this.materials = materials;
if (GameLib.Utils.UndefinedOrNull(position)) {
position = new GameLib.API.Vector3(0, 0, 0);
}
this.position = position;
if (GameLib.Utils.UndefinedOrNull(direction)) {
direction = new GameLib.API.Vector3(0, 0, 1);
@ -122,14 +129,14 @@ GameLib.D3.API.ParticleEngine.prototype.constructor = GameLib.D3.API.ParticleEng
*/
GameLib.D3.API.ParticleEngine.FromObject = function(objectParticleEngine) {
var apiImages = [];
if (objectParticleEngine.images) {
apiImages = objectParticleEngine.images.map(
function (objectImage) {
if (objectImage instanceof Object) {
return GameLib.D3.API.Image.FromObject(objectImage);
var apiMaterials = [];
if (objectParticleEngine.materials) {
apiMaterials = objectParticleEngine.materials.map(
function (objectMaterial) {
if (objectMaterial instanceof Object) {
return GameLib.D3.API.Material.FromObject(objectMaterial);
} else {
return objectImage
return objectMaterial
}
}
)
@ -138,7 +145,8 @@ GameLib.D3.API.ParticleEngine.FromObject = function(objectParticleEngine) {
return new GameLib.D3.API.ParticleEngine(
objectParticleEngine.id,
objectParticleEngine.name,
apiImages,
apiMaterials,
GameLib.API.Vector3.FromObject(objectParticleEngine.position),
GameLib.API.Vector3.FromObject(objectParticleEngine.direction),
objectParticleEngine.particlesPerSecond,
objectParticleEngine.distanceType,

View File

@ -24,7 +24,8 @@ GameLib.D3.ParticleEngine = function(
this,
apiParticleEngine.id,
apiParticleEngine.name,
apiParticleEngine.images,
apiParticleEngine.materials,
apiParticleEngine.position,
apiParticleEngine.direction,
apiParticleEngine.particlesPerSecond,
apiParticleEngine.distanceType,
@ -39,17 +40,28 @@ GameLib.D3.ParticleEngine = function(
apiParticleEngine.parentEntity
);
this.images = this.images.map(
function(image) {
if (image instanceof GameLib.D3.API.Image) {
return new GameLib.D3.Image(
this.materials = this.materials.map(
function(material) {
if (material instanceof GameLib.D3.API.Material) {
return new GameLib.D3.Material(
graphics,
image
material
)
}
}
);
if (this.position instanceof GameLib.API.Vector3) {
this.position = new GameLib.Vector3(
graphics,
this.position,
this
);
} else {
console.warn('position not instance of API.Vector3');
throw new Error('position not instance of API.Vector3');
}
if (this.direction instanceof GameLib.API.Vector3) {
this.direction = new GameLib.Vector3(
graphics,
@ -65,7 +77,7 @@ GameLib.D3.ParticleEngine = function(
this,
GameLib.Component.COMPONENT_PARTICLE_ENGINE,
{
images : [GameLib.D3.Image]
materials : [GameLib.D3.Material]
}
);
@ -83,9 +95,7 @@ GameLib.D3.ParticleEngine.ROTATION_TYPE_CONSTANT = 0x1;
* @returns true
*/
GameLib.D3.ParticleEngine.prototype.createInstance = function() {
this.instance = true;
GameLib.Component.prototype.createInstance.call(this);
};
@ -106,11 +116,12 @@ GameLib.D3.ParticleEngine.prototype.toApiObject = function() {
this.id,
this.name,
this.images.map(
function(image){
return GameLib.Utils.IdOrNull(image);
this.materials.map(
function(material){
return GameLib.Utils.IdOrNull(material);
}
),
this.position.toApiObject(),
this.direction.toApiObject(),
this.particlesPerSecond,
this.distanceType,

View File

@ -66,10 +66,15 @@ GameLib.System = function(
if (apiSystem.systemType === GameLib.System.SYSTEM_TYPE_STORAGE) {
componentType = GameLib.Component.COMPONENT_SYSTEM_STORAGE;
}
if (apiSystem.systemType === GameLib.System.SYSTEM_TYPE_VISUALIZATION) {
componentType = GameLib.Component.COMPONENT_SYSTEM_VISUALIZATION;
}
if (apiSystem.systemType === GameLib.System.SYSTEM_TYPE_PARTICLE) {
componentType = GameLib.Component.COMPONENT_SYSTEM_PARTICLE;
}
GameLib.Component.call(
this,
componentType
@ -90,6 +95,7 @@ GameLib.System.SYSTEM_TYPE_PHYSICS = 0x20;
GameLib.System.SYSTEM_TYPE_LINKING = 0x40;
GameLib.System.SYSTEM_TYPE_CUSTOM = 0x80;
GameLib.System.SYSTEM_TYPE_VISUALIZATION = 0x100;
GameLib.System.SYSTEM_TYPE_PARTICLE = 0x200;
GameLib.System.SYSTEM_TYPE_ALL = 0xFFFF;
GameLib.System.prototype.createInstance = function() {

View File

@ -0,0 +1,185 @@
/**
* System takes care of updating all the entities (based on their component data)
* @param graphics
* @param apiSystem GameLib.API.System
* @constructor
*/
GameLib.System.Particle = function(
graphics,
apiSystem
) {
this.graphics = graphics;
this.graphics.isNotThreeThrow();
GameLib.System.call(
this,
apiSystem
);
/**
* this holds a reference to engine components and does some initial setup work so we don't have to do it during render
* like calculate frequency etc..
* @type {Array}
*/
this.engines = [];
this.beforeRenderSubscription = null;
};
GameLib.System.Particle.prototype = Object.create(GameLib.System.prototype);
GameLib.System.Particle.prototype.constructor = GameLib.System.Particle;
/**
* Start this system (add all event listeners)
*/
GameLib.System.Particle.prototype.start = function() {
GameLib.System.prototype.start.call(this);
this.particleObjects = GameLib.EntityManager.Instance.queryComponents(GameLib.D3.ParticleEngine);
this.particleObjects.map(this.initialize.bind(this));
this.instanceCreatedSubscription = GameLib.Event.Subscribe(
GameLib.Event.INSTANCE_CREATED,
this.instanceCreated.bind(this)
);
this.removeComponentSubscription = GameLib.Event.Subscribe(
GameLib.Event.REMOVE_COMPONENT,
this.removeComponent.bind(this)
);
this.beforeRenderSubscription = GameLib.Event.Subscribe(
GameLib.Event.BEFORE_RENDER,
this.beforeRender.bind(this)
);
};
/**
* This function does alot of work we want do have done, but we don't want to do it during 'before render' - since we
* don't want to waste cpu power
* @param component
*/
GameLib.System.Particle.prototype.initialize = function(component) {
var lookAt = GameLib.EntityManager.Instance.defaultRenderer.camera.lookAt.instance.clone().negate();
var frequency = Number(1 / component.particlesPerSecond);
var meshes = [];
for (var i = 0; i < frequency; i++) {
var apiMesh = new GameLib.D3.API.Mesh(
null,
GameLib.D3.Mesh.MESH_TYPE_PLANE,
'Particle Mesh',
null,
null,
component.materials
);
var mesh = new GameLib.D3.Mesh.Plane(
this.graphics,
apiMesh,
1,
1,
1,
1
);
meshes.push(mesh);
}
var engine = {
component : component,
elapsed : 0,
frequency : frequency,
lookAt : lookAt,
meshes : meshes
};
this.engines.push(engine);
};
/**
* From now on we want to track everything about a component, only from the systems that are active
* @param data
*/
GameLib.System.Particle.prototype.instanceCreated = function(data) {
if (data.component instanceof GameLib.D3.ParticleEngine) {
console.log('new particle engine');
this.particleObjects.push(data.component);
this.initialize(data.component);
}
};
/**
* Removes a particle engine from this system
* @param data
*/
GameLib.System.Particle.prototype.removeComponent = function(data) {
if (data.component instanceof GameLib.D3.ParticleEngine) {
var index = this.particleObjects.indexOf(data.component);
if (index !== -1) {
console.log('removing particle engine from system');
this.particleObjects.splice(index, 1);
this.engines = this.engines.reduce(
function(result, engine){
if (engine.component !== data.component) {
result.push(engine);
}
return result;
},
[]
);
} else {
console.log('failed to find the particle engine in the system : ' + data.component.name);
}
}
};
/**
* This is what actually happens to all particles before render
* @param data
*/
GameLib.System.Particle.prototype.beforeRender = function(data) {
this.totalTime += data.delta;
this.engines.map(
function(engine) {
engine.elapsed += data.delta;
if (engine.elapsed > engine.frequency) {
engine.elapsed = 0;
console.log('spawn time');
}
}.bind(this)
)
};
/**
* Stop this system (remove all event listeners)
*/
GameLib.System.Particle.prototype.stop = function() {
GameLib.System.prototype.stop.call(this);
this.instanceCreatedSubscription.remove();
this.removeComponentSubscription.remove();
this.beforeRenderSubscription.remove();
};