2017-11-06 13:57:57 +01:00
|
|
|
/**
|
|
|
|
* Creates a Particle object
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param apiParticle GameLib.D3.API.Particle
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Particle = function(
|
|
|
|
graphics,
|
|
|
|
apiParticle
|
|
|
|
) {
|
|
|
|
|
|
|
|
this.graphics = graphics;
|
|
|
|
this.graphics.isNotThreeThrow();
|
|
|
|
|
|
|
|
if (GameLib.Utils.UndefinedOrNull(apiParticle)) {
|
|
|
|
apiParticle = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (apiParticle instanceof GameLib.D3.Particle) {
|
|
|
|
return apiParticle;
|
|
|
|
}
|
|
|
|
|
|
|
|
GameLib.D3.API.Particle.call(
|
|
|
|
this,
|
|
|
|
apiParticle.id,
|
|
|
|
apiParticle.name,
|
|
|
|
apiParticle.lifeTime,
|
|
|
|
apiParticle.elapsed,
|
|
|
|
apiParticle.mesh,
|
2017-11-13 15:22:08 +01:00
|
|
|
apiParticle.opacityType,
|
|
|
|
apiParticle.opacityFactor,
|
2017-11-06 13:57:57 +01:00
|
|
|
apiParticle.positionOffsetType,
|
|
|
|
apiParticle.positionOffset,
|
|
|
|
apiParticle.positionOffsetFn,
|
|
|
|
apiParticle.directionType,
|
|
|
|
apiParticle.direction,
|
|
|
|
apiParticle.directionFn,
|
2017-11-13 08:39:07 +01:00
|
|
|
apiParticle.speed,
|
2017-11-06 13:57:57 +01:00
|
|
|
apiParticle.scaleType,
|
|
|
|
apiParticle.scale,
|
|
|
|
apiParticle.scaleFn,
|
|
|
|
apiParticle.rotationType,
|
|
|
|
apiParticle.rotation,
|
|
|
|
apiParticle.rotationFn,
|
|
|
|
apiParticle.parentEngine,
|
|
|
|
apiParticle.parentEntity
|
|
|
|
);
|
|
|
|
|
|
|
|
if (this.mesh instanceof GameLib.D3.API.Mesh) {
|
|
|
|
this.mesh = new GameLib.D3.Mesh(
|
|
|
|
graphics,
|
|
|
|
this.mesh
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.positionOffset instanceof GameLib.API.Vector3) {
|
|
|
|
this.positionOffset = new GameLib.Vector3(
|
|
|
|
graphics,
|
|
|
|
this.positionOffset,
|
|
|
|
this
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
console.warn('positionOffset not instance of API.Vector3');
|
|
|
|
throw new Error('positionOffset not instance of API.Vector3');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.direction instanceof GameLib.API.Vector3) {
|
|
|
|
this.direction = new GameLib.Vector3(
|
|
|
|
graphics,
|
|
|
|
this.direction,
|
|
|
|
this
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
console.warn('direction not instance of API.Vector3');
|
|
|
|
throw new Error('direction 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.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');
|
|
|
|
}
|
|
|
|
|
|
|
|
GameLib.Component.call(
|
|
|
|
this,
|
|
|
|
GameLib.Component.COMPONENT_PARTICLE,
|
|
|
|
{
|
|
|
|
mesh : GameLib.D3.Mesh,
|
|
|
|
parentEngine : GameLib.D3.ParticleEngine
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
GameLib.D3.Particle.prototype = Object.create(GameLib.D3.API.Particle.prototype);
|
|
|
|
GameLib.D3.Particle.prototype.constructor = GameLib.D3.Particle;
|
|
|
|
|
2017-11-13 15:22:08 +01:00
|
|
|
GameLib.D3.Particle.OPACITY_TYPE_CONSTANT = 0x1;
|
|
|
|
GameLib.D3.Particle.OPACITY_TYPE_DECREASE_LINEAR = 0x2;
|
|
|
|
GameLib.D3.Particle.OPACITY_TYPE_INCREASE_LINEAR = 0x3;
|
|
|
|
|
2017-11-06 13:57:57 +01:00
|
|
|
GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT = 0x1;
|
|
|
|
GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM = 0x2;
|
|
|
|
GameLib.D3.Particle.POSITION_OFFSET_TYPE_FUNCTION = 0x3;
|
|
|
|
|
|
|
|
GameLib.D3.Particle.DIRECTION_TYPE_CONSTANT = 0x1;
|
|
|
|
GameLib.D3.Particle.DIRECTION_TYPE_RANDOM = 0x2;
|
|
|
|
GameLib.D3.Particle.DIRECTION_TYPE_FUNCTION = 0x3;
|
|
|
|
|
|
|
|
GameLib.D3.Particle.SCALE_TYPE_CONSTANT = 0x1;
|
|
|
|
GameLib.D3.Particle.SCALE_TYPE_LINEAR = 0x2;
|
|
|
|
GameLib.D3.Particle.SCALE_TYPE_EXPONENTIAL = 0x3;
|
|
|
|
GameLib.D3.Particle.SCALE_TYPE_RANDOM = 0x4;
|
2017-11-13 15:06:59 +01:00
|
|
|
GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y = 0x6;
|
|
|
|
GameLib.D3.Particle.SCALE_TYPE_FUNCTION = 0x7;
|
2017-11-06 13:57:57 +01:00
|
|
|
|
|
|
|
GameLib.D3.Particle.ROTATION_TYPE_CONSTANT = 0x1;
|
|
|
|
GameLib.D3.Particle.ROTATION_TYPE_RANDOM = 0x2;
|
|
|
|
GameLib.D3.Particle.ROTATION_TYPE_FUNCTION = 0x3;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Particle create instance
|
|
|
|
*/
|
|
|
|
GameLib.D3.Particle.prototype.createInstance = function() {
|
|
|
|
|
|
|
|
if (!this.mesh) {
|
|
|
|
console.warn('no mesh to clone from - failed dependency check?');
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-11-06 14:45:05 +01:00
|
|
|
this.instance = this.mesh.instance;
|
2017-11-06 13:57:57 +01:00
|
|
|
|
|
|
|
GameLib.Component.prototype.createInstance.call(this);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Updates the instance with the current state
|
|
|
|
*/
|
|
|
|
GameLib.D3.Particle.prototype.updateInstance = function(property) {
|
2017-11-13 15:06:59 +01:00
|
|
|
|
2017-11-15 11:43:46 +01:00
|
|
|
if (property === 'positionOffset') {
|
|
|
|
this.positionOffset.instance.x = this.positionOffset.x;
|
|
|
|
this.positionOffset.instance.y = this.positionOffset.y;
|
|
|
|
this.positionOffset.instance.z = this.positionOffset.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (property === 'direction') {
|
|
|
|
this.direction.instance.x = this.direction.x;
|
|
|
|
this.direction.instance.y = this.direction.y;
|
|
|
|
this.direction.instance.z = this.direction.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (property === 'scale') {
|
|
|
|
this.scale.instance.x = this.scale.x;
|
|
|
|
this.scale.instance.y = this.scale.y;
|
|
|
|
this.scale.instance.z = this.scale.z;
|
2017-11-13 15:06:59 +01:00
|
|
|
}
|
2017-11-15 11:43:46 +01:00
|
|
|
|
|
|
|
if (property === 'rotation') {
|
|
|
|
this.rotation.instance.x = this.rotation.x;
|
|
|
|
this.rotation.instance.y = this.rotation.y;
|
|
|
|
this.rotation.instance.z = this.rotation.z;
|
|
|
|
}
|
|
|
|
|
2017-11-06 13:57:57 +01:00
|
|
|
};
|
|
|
|
|
2017-11-06 14:45:05 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clones a particle - this only clones 3rd party instances, so we have less overhead of creating these types of objects
|
|
|
|
*/
|
2017-11-15 11:43:46 +01:00
|
|
|
GameLib.D3.Particle.prototype.cloneInstance = function() {
|
|
|
|
|
|
|
|
this.updateInstance('positionOffset');
|
|
|
|
this.updateInstance('direction');
|
|
|
|
this.updateInstance('scale');
|
|
|
|
this.updateInstance('rotation');
|
|
|
|
|
|
|
|
var clone = GameLib.Component.prototype.cloneInstance.call(this);
|
|
|
|
|
|
|
|
clone.position = this.parentEngine.position.instance.clone();
|
|
|
|
|
|
|
|
clone.material = this.mesh.materials[0].instance.clone();
|
|
|
|
|
|
|
|
clone.visible = true;
|
|
|
|
|
|
|
|
if (this.positionOffsetType === GameLib.D3.Particle.POSITION_OFFSET_TYPE_CONSTANT) {
|
|
|
|
clone.position.add(this.positionOffset.instance);
|
|
|
|
}
|
|
|
|
|
|
|
|
var add = 1;
|
|
|
|
|
|
|
|
if (this.positionOffsetType === GameLib.D3.Particle.POSITION_OFFSET_TYPE_RANDOM) {
|
|
|
|
|
|
|
|
add = GameLib.Utils.GetRandomIntInclusive(1,2);
|
|
|
|
|
|
|
|
if (add === 1) {
|
|
|
|
clone.position.x += Math.random() * this.positionOffset.x;
|
|
|
|
clone.position.y += Math.random() * this.positionOffset.y;
|
|
|
|
clone.position.z += Math.random() * this.positionOffset.z;
|
|
|
|
} else {
|
|
|
|
clone.position.x -= Math.random() * this.positionOffset.x;
|
|
|
|
clone.position.y -= Math.random() * this.positionOffset.y;
|
|
|
|
clone.position.z -= Math.random() * this.positionOffset.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_CONSTANT) {
|
|
|
|
clone.scale.x += this.scale.x;
|
|
|
|
clone.scale.y += this.scale.y;
|
|
|
|
clone.scale.z += this.scale.z;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_RANDOM) {
|
|
|
|
|
|
|
|
add = GameLib.Utils.GetRandomIntInclusive(1,2);
|
|
|
|
|
|
|
|
if (add === 1) {
|
|
|
|
clone.scale.x += Math.random() * this.scale.x;
|
|
|
|
clone.scale.y += Math.random() * this.scale.y;
|
|
|
|
clone.scale.z += Math.random() * this.scale.z;
|
|
|
|
} else {
|
|
|
|
clone.scale.x -= Math.random() * this.scale.x;
|
|
|
|
clone.scale.y -= Math.random() * this.scale.y;
|
|
|
|
clone.scale.z -= Math.random() * this.scale.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.scaleType === GameLib.D3.Particle.SCALE_TYPE_RANDOM_X_EQUALS_Y) {
|
|
|
|
|
|
|
|
add = GameLib.Utils.GetRandomIntInclusive(1,2);
|
|
|
|
|
|
|
|
var factor = Math.random() * this.scale.x;
|
|
|
|
|
|
|
|
if (add === 1) {
|
|
|
|
clone.scale.x += factor;
|
|
|
|
clone.scale.y += factor;
|
|
|
|
clone.scale.z += Math.random() * this.scale.z;
|
|
|
|
} else {
|
|
|
|
clone.scale.x -= factor;
|
|
|
|
clone.scale.y -= factor;
|
|
|
|
clone.scale.z -= Math.random() * this.scale.z;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clone.userData.direction = this.direction.clone();
|
|
|
|
clone.userData.scale = this.scale.clone();
|
|
|
|
clone.userData.lifeTime = this.lifeTime;
|
|
|
|
clone.userData.speed = this.speed;
|
|
|
|
clone.userData.scene = this.mesh.parentScene.instance;
|
|
|
|
|
|
|
|
clone.userData.elapsed = 0;
|
|
|
|
|
|
|
|
clone.userData.scene.add(clone);
|
|
|
|
|
|
|
|
return clone;
|
|
|
|
};
|
2017-11-06 14:45:05 +01:00
|
|
|
|
2017-11-06 13:57:57 +01:00
|
|
|
/**
|
|
|
|
* Converts a GameLib.D3.Particle to a new GameLib.D3.API.Particle
|
|
|
|
* @returns {GameLib.D3.API.Particle}
|
|
|
|
*/
|
|
|
|
GameLib.D3.Particle.prototype.toApiObject = function() {
|
|
|
|
|
|
|
|
return new GameLib.D3.API.Particle(
|
|
|
|
this.id,
|
|
|
|
this.name,
|
|
|
|
this.lifeTime,
|
|
|
|
this.elapsed,
|
|
|
|
GameLib.Utils.IdOrNull(this.mesh),
|
2017-11-13 15:22:08 +01:00
|
|
|
this.opacityType,
|
|
|
|
this.opacityFactor,
|
2017-11-06 13:57:57 +01:00
|
|
|
this.positionOffsetType,
|
|
|
|
this.positionOffset.toApiObject(),
|
|
|
|
this.positionOffsetFn,
|
|
|
|
this.directionType,
|
|
|
|
this.direction.toApiObject(),
|
|
|
|
this.directionFn,
|
2017-11-13 08:39:07 +01:00
|
|
|
this.speed,
|
2017-11-06 13:57:57 +01:00
|
|
|
this.scaleType,
|
|
|
|
this.scale.toApiObject(),
|
|
|
|
this.scaleFn,
|
|
|
|
this.rotationType,
|
|
|
|
this.rotation.toApiObject(),
|
|
|
|
this.rotationFn,
|
|
|
|
GameLib.Utils.IdOrNull(this.parentEngine),
|
|
|
|
GameLib.Utils.IdOrNull(this.parentEntity)
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts from an Object Particle to a GameLib.D3.Particle
|
|
|
|
* @param graphics GameLib.D3.Graphics
|
|
|
|
* @param objectParticle Object
|
|
|
|
* @returns {GameLib.D3.Particle}
|
|
|
|
* @constructor
|
|
|
|
*/
|
|
|
|
GameLib.D3.Particle.FromObject = function(graphics, objectParticle) {
|
|
|
|
|
|
|
|
var apiParticle = GameLib.D3.API.Particle.FromObject(objectParticle);
|
|
|
|
|
|
|
|
return new GameLib.D3.Particle(
|
|
|
|
graphics,
|
|
|
|
apiParticle
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|