import { Utils } from '../common/Utils';
import { ParticleEmitter } from './ParticleEmitter';
/**
* @class ParticleGroup
* 粒子组。
* @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');
}
/**
* 获取属性值。
* @param {THING.ADAPTER.ParticleGroupAttributeType} key 属性键。
* @returns {any} 返回属性值。
* @public
*/
getAttribute(key) {
return this.node.getAttribute(key);
}
/**
* 设置属性值。
* @param {THING.ADAPTER.ParticleGroupAttributeType} key 属性键。
* @param {any} value 属性值。
* @public
*/
setAttribute(key, value) {
if (key === "Texture") {
this.node.setAttribute(key, value.getTextureResource());
}
else {
this.node.setAttribute(key, value);
}
if (key === "UseMesh" || key === "MeshUrl" || key === "MeshParams") {
this._updateEmitters()
}
}
/**
* 添加发射器。
* @param {ParticleEmitter} emitter 发射器。
* @returns {ParticleEmitter|null} 返回添加的发射器,如果节点不存在则返回 null。
* @public
* @example
* const emitter = new THING.ParticelEmitter();
* group.addEmitter(emitter);
*/
addEmitter(emitter) {
let node = emitter.node;
if (!this.node) {
return null;
}
this.node.addEmitter(node);
this._updateEmitters();
return this.emitters[this.emitters.length - 1];
}
/**
* 根据发射器移除发射器。
* @param {ParticleEmitter} 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
/**
* 获取发射器。
* @type {Array<ParticleEmitter>}
* @public
*/
get emitters() {
if (!this._emitters) {
this._updateEmitters();
}
return this._emitters;
}
/**
* 获取/设置最大粒子数。这些粒子的最大数量。
* @type {number}
* @public
*/
get maxParticleCount() {
return this.getAttribute('MaxParticleCount');
}
set maxParticleCount(value) {
return this.setAttribute('MaxParticleCount', value);
}
/**
* 获取/设置是否使用网格。当为true时,表示粒子使用网格而不是点。
* @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];
}
}
/**
* 获取/设置网格URL。当UseMesh为true时生效,表示粒子网格类型的属性。可选值为'BuildIn/Box'、'BuildIn/Plane'、'BuildIn/Sphere'。
* @type {string}
* @public
*/
get meshUrl() {
return this.getAttribute('MeshUrl');
}
set meshUrl(value) {
this.setAttribute('MeshUrl', value);
}
/**
* 获取/设置网格参数。当UseMesh为true时生效,表示粒子网格类型的属性。
* @type {Array}
* @public
*/
get meshParams() {
return this.getAttribute('MeshParams');
}
set meshParams(value) {
this.setAttribute('MeshParams', value);
}
/**
* 获取/设置纹理。粒子的图像值。
* @type {THING.ImageTexture}
* @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.
*/
/**
* 获取/设置纹理动画。
* @type {TextureAnimation}
* @public
*/
get textureAnimation() {
return this.getAttribute('TextureAnimation');
}
set textureAnimation(value) {
this.setAttribute('TextureAnimation', value);
}
/**
* 获取/设置混合模式。粒子的混合模式。可选值为'none'、'normal'、'add'、'sub'、'mul'、'custom'。
* @type {string}
* @public
*/
get blendingMode() {
return this.getAttribute('BlendingMode');
}
set blendingMode(value) {
this.setAttribute('BlendingMode', value);
}
/**
* 获取/设置是否透明。表示这些粒子是否应该以透明方式渲染。
* @type {boolean}
* @public
*/
get isTransparent() {
return this.getAttribute('IsTransparent');
}
set isTransparent(value) {
this.setAttribute('IsTransparent', value);
}
/**
* 获取/设置是否着色。表示这些粒子是否应该以颜色渲染,或者粒子的颜色仅来自提供的纹理。
* @type {boolean}
* @public
*/
get isColorize() {
return this.getAttribute('IsColorize');
}
set isColorize(value) {
this.setAttribute('IsColorize', value);
}
/**
* 获取/设置alpha测试。设置粒子的alpha值。取值范围为0到1。
* @type {number}
* @public
*/
get alphaTest() {
return this.getAttribute('AlphaTest');
}
set alphaTest(value) {
this.setAttribute('AlphaTest', value);
}
/**
* 获取/设置深度写入。设置粒子的深度写入。
* @type {boolean}
* @public
*/
get depthWrite() {
return this.getAttribute('DepthWrite');
}
set depthWrite(value) {
this.setAttribute('DepthWrite', value);
}
/**
* 获取/设置深度测试。设置粒子的深度测试。
* @type {boolean}
* @public
*/
get depthTest() {
return this.getAttribute('DepthTest');
}
set depthTest(value) {
this.setAttribute('DepthTest', value);
}
/**
* 获取/设置纹理URL。粒子的图像URL。
* @type {string}
* @public
*/
get url() {
return this.getAttribute('Url');
}
set url(value) {
this.setAttribute('Url', value);
}
/**
* 获取/设置雾效。表示这些粒子是否受到场景雾效的影响。
* @type {boolean}
* @public
*/
get fog() {
return this.getAttribute('Fog');
}
set fog(value) {
this.setAttribute('Fog', value);
}
// #endregion
}
export { ParticleGroup }