import { ObjectProxy } from '@uino/base-thing';
import { Utils } from '../common/Utils'
import { BaseLight } from './BaseLight';
import { ShadowLightTransformComponent } from '../components/ShadowLightTransformComponent';
import { ShadowQualityType } from '../const';
const __ = {
private: Symbol('private'),
}
const registerComponentParam = { isResident: true };
/**
* @class BaseShadowLight
* 可产生阴影的光
* @memberof THING
* @extends THING.BaseLight
* @public
*/
class BaseShadowLight extends BaseLight {
/**
* 基础阴影光源类,负责管理可产生阴影的光源属性和行为
* @param {object} param 初始化参数列表
* @param {number|string|Array<number>} param.color 光的颜色
* @param {number} param.intensity 光的强度
* @param {boolean} param.castShadow 开启/关闭阴影效果
* @param {number} param.shadowQuality 阴影效果品质(2的n次幂的一个数值,数值越大质量越高)
* @param {number} param.shadowBias 阴影偏移量
* @param {ShadowRangeInfo} param.shadowRange 阴影范围
* @param {number[]} param.position 灯光位置
* @param {number[]} param.target 灯光的目标位置 根据position和target可确定平行光方向
*/
constructor(param = {}) {
super(param);
this[__.private] = {};
// Set the default values
if (Utils.isNull(param['shadowQuality'])) {
this.shadowQuality = ShadowQualityType.High;
}
// Sync options
Utils.syncOptions(this, [
'enableShadow',
'castShadow',
'shadowQuality',
'shadowBias',
'shadowNormalBias',
'shadowRadius',
'shadowRange',
'target'
], param, param['extras'] || param['external']);
// Refresh
this.onRefresh();
}
// #region Object3D Overrides
onSetupAttributes(param) {
super.onSetupAttributes(param);
this._shadowRange = new ObjectProxy({
data: {
width: 64,
height: 64,
near: 0.5,
far: 1000
},
onChange: (ev) => {
this.bodyNode.setShadowRange(ev.data);
}
});
}
onDestroy() {
this._shadowRange.dispose();
this._shadowRange = null;
super.onDestroy();
}
onCopy(object) {
super.onCopy(object);
this.castShadow = object.castShadow;
this.shadowQuality = object.shadowQuality;
this.shadowBias = object.shadowBias;
this.shadowNormalBias = object.shadowNormalBias;
this.shadowRadius = object.shadowRadius;
this.shadowRange = object.shadowRange;
this.target = object.target;
}
onRefresh() {
super.onRefresh();
this._shadowRange.notifyChange();
this.bodyNode.setShadowNormalBias(this.shadowNormalBias);
}
onSetupComponent(param) {
super.onSetupComponent(param);
this.addComponent(ShadowLightTransformComponent, 'transform', registerComponentParam);
}
onUpdate(deltaTime) {
super.onUpdate(deltaTime);
this.bodyNode.updateShadow();
}
onImportExternalData(external, options) {
super.onImportExternalData(external, options);
this.castShadow = Utils.parseValue(external['castShadow'], this.castShadow);
this.shadowQuality = Utils.parseValue(external['shadowQuality'], this.shadowQuality);
this.shadowBias = Utils.parseValue(external['shadowBias'], this.shadowBias);
this.shadowNormalBias = Utils.parseValue(external['shadowNormalBias'], this.shadowNormalBias);
this.shadowRadius = Utils.parseValue(external['shadowRadius'], this.shadowRadius);
this.shadowRange = Utils.parseValue(external['shadowRange'], this.shadowRange);
}
onExportExternalData() {
let external = Object.assign({}, super.onExportExternalData());
Utils.setAttributeIfExist(external, 'castShadow', this);
Utils.setAttributeIfExist(external, 'shadowQuality', this);
Utils.setAttributeIfExist(external, 'shadowBias', this);
Utils.setAttributeIfExist(external, 'shadowNormalBias', this);
Utils.setAttributeIfExist(external, 'shadowRadius', this);
Utils.setAttributeIfExist(external, 'shadowRange', this);
return external;
}
// #endregion
// #region Accessor
/**
* Enable/Disable shadow.
* @type {boolean}
* @deprecated 2.7
* @private
*/
get enableShadow() {
Utils.warn('Please use castShadow instead');
return this.castShadow;
}
set enableShadow(value) {
Utils.warn('Please use castShadow instead');
this.castShadow = value;
}
/**
* 是否开启阴影
* @type {boolean}
* @public
*/
get castShadow() {
return this.bodyNode.getCastShadow();
}
set castShadow(value) {
if (this.castShadow == value) {
return;
}
this.bodyNode.setCastShadow(value);
}
/**
* 获取/设置阴影效果品质
* @type {ShadowQualityType|Number}
* @public
*/
get shadowQuality() {
return this.bodyNode.getShadowQuality();
}
set shadowQuality(value) {
this.bodyNode.setShadowQuality(value);
}
/**
* 获取/设置阴影偏移量
* @type {number}
* @public
*/
get shadowBias() {
return this.bodyNode.getShadowBias();
}
set shadowBias(value) {
this.bodyNode.setShadowBias(value);
}
/**
* 获取/设置阴影范围
* @type {ShadowRangeInfo}
* @public
*/
get shadowNormalBias() {
return this.bodyNode.getShadowNormalBias();
}
set shadowNormalBias(value) {
this.bodyNode.setShadowNormalBias(value);
}
/**
* Get/Set shadow radius, default is 1 (not working yet).
* @type {number}
* @private
*/
get shadowRadius() {
return this.bodyNode.getShadowRadius();
}
set shadowRadius(value) {
this.bodyNode.setShadowRadius(value);
}
/**
* 阴影范围
* @typedef {object} ShadowRangeInfo
* @property {number} width 宽度
* @property {number} height 高度
* @property {number} near 近
* @property {number} far 远
* @public
*/
/**
* 获取/设置阴影范围。
* @type {ShadowRangeInfo}
* @public
*/
get shadowRange() {
return this._shadowRange.dataProxy;
}
set shadowRange(value) {
this._shadowRange.merge(value);
}
// #endregion
// #region Internal components attributes and functions
// #region Component - animation
/**
* 平行光看向的位置,根据target和自身的position可以确定朝向
* @public
* @type {number[]}
*/
get target() { return this.transform.target; }
set target(value) { this.transform.target = value; }
// #endregion
// #endregion
/**
* 检查是否为BaseShadowLight类型或继承自它。
* @type {boolean}
* @public
*/
get isBaseShadowLight() {
return true;
}
}
export { BaseShadowLight }