import { ObjectProxy } from '@uino/base-thing';
import { Utils } from '../common/Utils'
import { BaseLight } from './BaseLight';
import { ShadowLightTransformComponent } from '../components/ShadowLightTransformComponent';
import { ShadowLightAdapterComponent } from '../components/ShadowLightAdapterComponent';
import { ShadowQualityType } from '../const';
const __ = {
private: Symbol('private'),
}
const registerComponentParam = { isResident: true };
/**
* @class BaseShadowLight
* The base shadow light object.
* @memberof THING
* @extends THING.BaseLight
* @public
*/
class BaseShadowLight extends BaseLight {
/**
* The base light object that can cast shadow.
* @param {Object} param The initial parameters.
*/
constructor(param = {}) {
super(param);
this[__.private] = {};
let _private = this[__.private];
_private.shadowRange = new ObjectProxy({
data: {
width: 64,
height: 64,
near: 0.5,
far: 1000
},
onChange: (ev) => {
this.bodyNode.setShadowRange(ev.data);
}
});
// Set the default values
if (Utils.isNull(param['shadowQuality'])) {
this.shadowQuality = ShadowQualityType.High;
}
// Sync options
Utils.syncOptions(this, [
'enableShadow',
'shadowQuality',
'shadowBias',
'shadowNormalBias',
'shadowRadius',
'shadowRange',
'target'
], param, param['extras'] || param['external']);
// Refresh
this.onRefresh();
}
// #region Object3D Overrides
onDestroy() {
let _private = this[__.private];
_private.shadowRange.dispose();
_private.shadowRange = null;
super.onDestroy();
}
onCopy(object) {
super.onCopy(object);
this.enableShadow = object.enableShadow;
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();
let _private = this[__.private];
_private.shadowRange.notifyChange();
}
onSetupComponent(param) {
super.onSetupComponent(param);
this.addComponent(ShadowLightTransformComponent, 'transform', registerComponentParam);
this.addComponent(ShadowLightAdapterComponent, 'adapter', registerComponentParam);
}
onUpdate(deltaTime) {
super.onUpdate(deltaTime);
this.bodyNode.updateShadow();
}
onExportExternalData() {
let external = Object.assign({}, super.onExportExternalData());
Utils.setAttributeIfExist(external, 'enableShadow', 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);
Utils.setAttributeIfExist(external, 'target', 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;
}
/**
* Enable/Disable cast shadow.
* @type {Boolean}
* @public
*/
get castShadow() {
return this.bodyNode.getCastShadow();
}
set castShadow(value) {
if (this.castShadow == value) {
return;
}
this.bodyNode.setCastShadow(value);
this.adapter.needRefresh = true;
}
/**
* Get/Set shadow quality.
* @type {ShadowQualityType|Number}
* @public
*/
get shadowQuality() {
return this.bodyNode.getShadowQuality();
}
set shadowQuality(value) {
this.bodyNode.setShadowQuality(value);
}
/**
* Get/Set shadow bias.
* @type {Number}
* @public
*/
get shadowBias() {
return this.bodyNode.getShadowBias();
}
set shadowBias(value) {
this.bodyNode.setShadowBias(value);
}
/**
* Get/Set shadow normal bias.
* @type {Number}
* @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 The width.
* @property {Number} height The height.
* @property {Number} near The near.
* @property {Number} far The far.
*/
/**
* Get/Set shadow range.
* @type {ShadowRangeInfo}
* @public
*/
get shadowRange() {
let _private = this[__.private];
return _private.shadowRange.dataProxy;
}
set shadowRange(value) {
let _private = this[__.private];
_private.shadowRange.merge(value);
}
// #endregion
// #region Internal components attributes and functions
// #region Component - animation
get target() { return this.transform.target; }
set target(value) { this.transform.target = value; }
// #endregion
// #endregion
/**
* Check whether it's BaseShadowLight type or inherit from it.
* @type {Boolean}
* @public
*/
get isBaseShadowLight() {
return true;
}
}
export { BaseShadowLight }