import { ObjectProxy } from '@uino/base-thing';
import { Utils } from '../common/Utils';
import { BaseComponent } from './BaseComponent';
import { FogType } from '../const';
const __ = {
private: Symbol('private'),
}
/**
* CameraFogComponent - 相机雾效组件
*
* 用于管理相机的雾效,可设置雾的颜色、密度和衰减范围。
* @class CameraFogComponent
* @memberof THING
* @extends THING.BaseComponent
* @public
* @example
app.camera.fog.enable = true;
app.camera.fog.color = '#cccccc';
app.camera.fog.density = 0.01;
*/
class CameraFogComponent extends BaseComponent {
/**
* 相机雾效组件,用于管理相机的雾效。
*/
constructor() {
super();
this[__.private] = {};
let _private = this[__.private];
_private.needsRefresh = false;
_private.objectProxy = new ObjectProxy({
data: {
enable: false,
type: FogType.Linear,
near: 1,
far: 1000,
color: [1, 1, 1],
density: 0.00025,
sky: {
enable: false,
start: 0,
height: 0.1
}
},
onChange: function (ev) {
_private.needsRefresh = true;
}
});
// Refresh effect by current config
this._refresh();
// Show config always
Object.defineProperty(this, 'customFormatters', {
enumerable: false,
configurable: false,
get: function () {
return ['object', { object: _private.objectProxy.dataProxy }];
}
});
}
// #region Private Functions
_refresh() {
let object = this.object;
if (!object) {
return;
}
let _private = this[__.private];
if (!_private.needsRefresh) {
return;
}
_private.needsRefresh = false;
object.node.setFog(_private.objectProxy.data);
}
// #endregion
// #region BaseComponent Overrides
onAdd(object) {
super.onAdd(object);
// Refresh config before render if needed
this.app.addBeforeRenderCallback(this._onBeforeRenderCallback = () => {
this._refresh();
});
}
onRemove() {
let _private = this[__.private];
_private.objectProxy.dispose();
this.app.removeBeforeRenderCallback(this._onBeforeRenderCallback);
super.onRemove();
}
// #endregion
/**
是否开启雾效
* @type {boolean}
* @public
*/
get enable() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.enable;
}
set enable(value) {
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
if (config.enable == value) {
return;
}
config.enable = value;
this._refresh();
}
/**
设置/获取雾的类型 支持指数雾(THING.FogType.Exp2)和线性雾(THING.FogType.Linear)
* @type {FogType}
* @public
*/
get type() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.type;
}
set type(value) {
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
if (config.type == value) {
return;
}
config.type = value;
this._refresh();
}
/**
指定雾效的起始位置(仅线性雾生效)
* @type {number}
* @public
*/
get near() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.near;
}
set near(value) {
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
if (config.near == value) {
return;
}
config.near = value;
this._refresh();
}
/**
获取/设置远裁剪面。
* @type {number}
* @public
*/
get far() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.far;
}
set far(value) {
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
if (config.far == value) {
return;
}
config.far = value;
this._refresh();
}
/**
雾的浓度(仅指数雾生效)
* @type {number}
* @public
*/
get density() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.density;
}
set density(value) {
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
if (config.density == value) {
return;
}
config.density = value;
this._refresh();
}
/**
雾的颜色
* @type {number|string|Array<string>}
* @public
*/
get color() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.color;
}
set color(value) {
if (!value) {
return;
}
let _private = this[__.private];
let config = _private.objectProxy.dataProxy;
config.color = Utils.parseColor(value);
this._refresh();
}
get sky() {
let _private = this[__.private];
return _private.objectProxy.dataProxy.sky;
}
/**
雾效配置
* @typedef {object} FogInfo
* @property {boolean} enable 是否开启
* @property {FogType} type 雾的类型
* @property {number} near 雾效起始位置(仅线性雾生效)
* @property {number} far 雾效结束位置(仅线性雾生效)
* @property {number} density 雾的强度(仅指数雾生效)
* @property {number|string|Array<string>} color 颜色
* @property {SkyFog} SkyFog 天空盒的雾效
* @public
*/
/**
天空盒的雾效
* @typedef {object} SkyFog
* @property {boolean} enable 是否开启
* @property {number} start 开始位置
* @property {number} height 高度
* @public
*/
/**
雾效的配置
* @type {FogInfo}
* @public
*/
get config() {
return this[__.private].objectProxy.dataProxy;
}
set config(value) {
let _private = this[__.private];
let to = _private.objectProxy.dataProxy;
to.enable = Utils.parseValue(value['enable'], to.enable);
to.type = Utils.parseValue(value['type'], to.type);
to.color = Utils.parseColor(value['color'], to.color);
to.density = Utils.parseValue(value['density'], to.density);
to.near = Utils.parseValue(value['near'], to.near);
to.far = Utils.parseValue(value['far'], to.far);
Utils.mergeObject(to.sky, value.sky, true);
}
}
export { CameraFogComponent }