import { Utils } from '../common/Utils';
import { ParticleEmitter } from './ParticleEmitter';
const __ = {
private: Symbol('private'),
}
/**
* @class ParticleGroup
* The particle group.
* @memberof THING
* @public
* @example
* const group = new THING.ParticleGroup();
* group.maxParticleCount = 200;
* group.useMesh = false;
* group.meshUrl = "BuildIn/Box";
* group.texture = {
* url:"./particle.png"
* };
* group.blendingMode = "normal";
* group.isTransparent = true;
* group.alphaTest = true;
* group.depthWrite = false;
* group.depthTest = false;
* group.url = "./particle.png";
*/
class ParticleGroup {
constructor(param = {}) {
this.node = param['node'] || Utils.createObject('ParticleGroup');
}
/**
* Get attribute.
* @param {ParticleGroupAttributeType} key The key.
* @returns {any}
* @public
*/
getAttribute(key) {
return this.node.getAttribute(key);
}
/**
* Set attribute.
* @param {ParticleGroupAttributeType} key The key.
* @param {any} value The value.
* @public
*/
setAttribute(key, value) {
if (key === "Texture") {
this.node.setAttribute(key, value.getTextureResource());
}
else {
this.node.setAttribute(key, value);
}
}
/**
* Add emitter.
* @param {ParticleEmitter} emitter The emitter.
* @returns {ParticleEmitter}
* @public
* @example
* const emitter = new THING.ParticelEmitter();
* group.addEmitter(emitter);
*/
addEmitter(emitter) {
let node = emitter.node;
if (!this.node) {
return;
}
this.node.addEmitter(node);
this._updateEmitters();
return this.emitters[this.emitters.length - 1];
}
/**
* Remove emitter by ParticleEmitter.
* @param {ParticleEmitter} emitter The emitter.
* @public
* @example
* const emitter = group.getEmitters();
* group.removeEmitter(emitter);
*/
removeEmitter(emitter) {
if (!this.node) {
return;
}
if (this.emitters.length == 0) {
return;
}
this.node.removeEmitter(emitter.node);
this._updateEmitters();
}
_updateEmitters() {
this._emitters = [];
const that = this;
this.getEmitters().forEach(node => {
const _emitter = new ParticleEmitter({ node });
that._emitters.push(_emitter);
})
}
/**
* Get emitters.
* @returns {Array<ParticleEmitter>}
* @private
* @example
* const emitter = group.getEmitters();
*/
getEmitters() {
return this.node.getEmitters();
}
// #region Accessor
/**
* Get emitters.
* @type {Array<ParticleEmitter>}
* @public
*/
get emitters() {
if (!this._emitters) {
this._updateEmitters();
}
return this._emitters;
}
/**
* Get/Set maxParticleCount.The max count of these particle.
* @type {Number}
* @public
*/
get maxParticleCount() {
return this.getAttribute('MaxParticleCount');
}
set maxParticleCount(value) {
return this.setAttribute('MaxParticleCount', value);
}
/**
* Get/Set useMesh.True indicates these particle use mesh but not points.
* @type {Boolean}
* @public
*/
get useMesh() {
return this.getAttribute('UseMesh');
}
set useMesh(value) {
this.setAttribute('UseMesh', value);
for (let i = 0; i < this.emitters.length; i++) {
this.emitters[i].node = this.node._emitters[i];
}
}
/**
* Get/Set mesh url.It takes effect when UseMesh is true, and indicates particle mesh type.The options are 'BuildIn/Box', 'BuildIn/Plane', 'BuildIn/Sphere'.
* @type {String}
* @public
*/
get meshUrl() {
return this.getAttribute('MeshUrl');
}
set meshUrl(value) {
this.setAttribute('MeshUrl', value);
}
/**
* Get/Set mesh parmas.It takes effect when UseMesh is true, and indicates particle mesh type's attribute.
* @type {Array}
* @public
*/
get meshParams() {
return this.getAttribute('MeshParams');
}
set meshParams(value) {
this.setAttribute('MeshParams', value);
}
/**
* Get/Set texture.The image value of particle.
* @type {ImageTextureResource}
* @public
*/
get texture() {
return this.getAttribute('Texture');
}
set texture(value) {
this.setAttribute('Texture', value);
}
/**
* The texture's animation attribute.
* @typedef {Object} TextureAnimation
* @property {Array<Number>} frames The number of frames on the x- and y-axis of the given texture.
* @property {Number} frameCount The total number of frames in the sprite-sheet.
* @property {Number} loop The number of loops through the sprite-sheet that should be performed over the course of a single particle's lifetime.
*/
/**
* Get/Set textureAnimation.
* @type {TextureAnimation}
* @public
*/
get textureAnimation() {
return this.getAttribute('TextureAnimation');
}
set textureAnimation(value) {
this.setAttribute('TextureAnimation', value);
}
/**
* Get/Set blend mode.The blend mode of these particle.The options are 'none', 'normal', 'add', 'sub', 'mul', 'custom'.
* @type {String}
* @public
*/
get blendingMode() {
return this.getAttribute('BlendingMode');
}
set blendingMode(value) {
this.setAttribute('BlendingMode', value);
}
/**
* Get/Set isTransparent.True indicates these particle's should be rendered with transparency.
* @type {Boolean}
* @public
*/
get isTransparent() {
return this.getAttribute('IsTransparent');
}
set isTransparent(value) {
this.setAttribute('IsTransparent', value);
}
/**
* Get/Set isColorize.True indicates these particles should be rendered with color, or the only color of particles will come from the provided texture.
* @type {Boolean}
* @public
*/
get isColorize() {
return this.getAttribute('IsColorize');
}
set isColorize(value) {
this.setAttribute('IsColorize', value);
}
/**
* Get/Set alphaTest.Sets the alpha value to particle. Value between 0 and 1.
* @type {Number}
* @public
*/
get alphaTest() {
return this.getAttribute('AlphaTest');
}
set alphaTest(value) {
this.setAttribute('AlphaTest', value);
}
/**
* Get/Set depthWrite.Sets the depthWrite to particle.
* @type {Boolean}
* @public
*/
get depthWrite() {
return this.getAttribute('DepthWrite');
}
set depthWrite(value) {
this.setAttribute('DepthWrite', value);
}
/**
* Get/Set depthTest.Sets the depthTest to particle.
* @type {Boolean}
* @public
*/
get depthTest() {
return this.getAttribute('DepthTest');
}
set depthTest(value) {
this.setAttribute('DepthTest', value);
}
/**
* Get/Set texture url.The image url of particle.
* @type {String}
* @public
*/
get url() {
return this.getAttribute('Url');
}
set url(value) {
this.setAttribute('Url', value);
}
/**
* Get/Set fog.True indicates these particles should be affected by their scene's fog.
* @type {Boolean}
* @public
*/
get fog() {
return this.getAttribute('Fog');
}
set fog(value) {
this.setAttribute('Fog', value);
}
// #endregion
}
export { ParticleGroup }