import { CubeTexture, DirectionalLight, HemisphereLight, ImageWrapType, MathUtils, Utils } from "../main";
import { BaseComponent } from "./BaseComponent";
const __ = {
private: Symbol('private'),
}
let _tempArray = [];
/**
* @class DynamicSky
* The dynamic sky.
* @memberof THING
* @extends THING.BaseComponent
*/
class CameraDynamicSkyComponent extends BaseComponent {
constructor() {
super();
this[__.private] = {};
let _private = this[__.private];
_private.enable = false;
}
// #region Private Functions
/**
* Load the stars data
* @param {String | Float32Array} data
* @private
*/
async _loadStarsData(data) {
if (Utils.isString(data)) {
let _buffer = await Utils.loadBinaryFile(data);
let starsData = new Float32Array(_buffer);
return starsData;
}
if (!(data instanceof Float32Array)) {
return null;
}
}
/**
* Update the lights.
* @param {String | Float32Array} data
* @private
*/
_updateLights() {
let _private = this[__.private];
_private._dynamicSky.getSunPhiAndTheta(_tempArray);
_private.sunLight.adapter.vertAngle = MathUtils.radToDeg(_tempArray[1]);
_private.sunLight.adapter.horzAngle = MathUtils.radToDeg(_tempArray[0]);
_private.sunLight.color = _private._dynamicSky.getSunLightColor(_tempArray);
_private._dynamicSky.getMoonPhiAndTheta(_tempArray);
_private.moonLight.adapter.vertAngle = MathUtils.radToDeg(_tempArray[1]);
_private.moonLight.adapter.horzAngle = MathUtils.radToDeg(_tempArray[0]);
_private.moonLight.color = _private._dynamicSky.getMoonLightColor(_tempArray);
_private.hemisphereLight.color = _private._dynamicSky.getHemisphereLightColor(_tempArray);
_private.hemisphereLight.groundColor = _private._dynamicSky.getHemisphereLightGroundColor(_tempArray);
}
// #endregion
// #region BaseComponent Overrides
onRemove() {
let _private = this[__.private];
if (_private._dynamicSky) {
_private._dynamicSky.dispose();
}
super.onRemove();
}
onUpdate(deltaTime) {
let _private = this[__.private];
if (_private._dynamicSky && this.enable) {
_private._dynamicSky.update(deltaTime);
}
}
/**
* Get/Set enable of sky.
* @type {Boolean}
* @public
*/
async init(options) {
let _private = this[__.private];
if (!_private._dynamicSky) {
_private.envMap = new CubeTexture();
_private.sunLight = THING.App.current.scene.mainLight;
_private.moonLight = new DirectionalLight({
intensity: 0.2
});
_private.moonLight.adapter.bind(THING.App.current.scene.mainLight.adapter.bindingObject);
_private.hemisphereLight = new HemisphereLight({
intensity: 0.2
});
_private._dynamicSky = Utils.createObject('DynamicSky', {
sunLight: _private.sunLight.node,
moonLight: _private.moonLight.node,
hemisphereLight: _private.hemisphereLight.node,
cubeTexture: _private.envMap.getTextureResource()
});
}
let nightSkyTexture = options.nightSkyTexture;
if (nightSkyTexture) {
_private._dynamicSky.setNightSkyTexture(nightSkyTexture.getTextureResource());
}
let moonTexture = options.moonTexture;
if (moonTexture) {
moonTexture.wrapTypeT = ImageWrapType.ClampToEdge;
moonTexture.wrapTypeS = ImageWrapType.ClampToEdge;
_private._dynamicSky.setMoonTexture(moonTexture.getTextureResource());
}
let cloudsTexture = options.cloudsTexture;
if (cloudsTexture) {
_private._dynamicSky.setCloudsTexture(cloudsTexture.getTextureResource());
}
let starsData = await this._loadStarsData(options.starsData);
_private._dynamicSky.setStarsData(starsData);
if (_private.enable) {
this.object.background = _private.envMap;
}
}
// #endregion
/**
* Get/Set enable of sky.
* @type {Boolean}
* @public
*/
get enable() {
let _private = this[__.private];
return _private.enable;
}
set enable(value) {
let _private = this[__.private];
if (_private.enable == value) {
return;
}
if (value) {
this.object.background = _private.envMap;
}
else {
if (_private.enable) {
this.object.background = null;
}
}
_private.enable = value;
}
/**
* Set map of sky.
* @type {CubeTextureResource}
* @public
*/
set map(value) {
if (!value) {
return;
}
let _private = this[__.private];
_private._dynamicSky.setNightSkyTexture(value.getTextureResource());
}
/**
* Set clouds texture of sky.
* @type {ImageTextureResource}
* @public
*/
set cloudsTexture(value) {
if (!value) {
return;
}
let _private = this[__.private];
_private._dynamicSky.setCloudsTexture(value.getTextureResource());
}
/**
* Set moon texture of sky.
* @type {ImageTextureResource}
* @public
*/
set moonTexture(value) {
if (!value) {
return;
}
let _private = this[__.private];
_private._dynamicSky.setMoonTexture(value.getTextureResource());
}
/**
* Set stars data of sky.
* @type {String | Float32Array}
* @public
*/
set starsData(value) {
if (!value) {
return;
}
let _private = this[__.private];
this._loadStarsData(value).then((data) => {
_private._dynamicSky.setStarsData(data);
})
}
/**
* Get the texture of sky.
* @type {CubeTextureResource}
* @public
*/
get envMap() {
let _private = this[__.private];
return _private.envMap;
}
/**
* Set/Get size of texture.
* @type {Array<Number>}
* @default - [1024,1024]
* @public
*/
set textureSize(value) {
let _private = this[__.private];
return _private._dynamicSky.setTextureSize(value);
}
get textureSize() {
let _private = this[__.private];
return _private._dynamicSky.getTextureSize(_tempArray);
}
/**
* Set/Get exposure of sky.
* @type {Number}
* @default 0.8
* @public
*/
get exposure() {
let _private = this[__.private];
return _private._dynamicSky.getExposure();
}
set exposure(value) {
let _private = this[__.private];
_private._dynamicSky.setExposure(value);
}
/**
* Set/Get light exposure of sky.
* @type {Number}
* @default 1.0
* @public
*/
get lightExposure() {
let _private = this[__.private];
return _private._dynamicSky.getLightExposure();
}
set lightExposure(value) {
let _private = this[__.private];
_private._dynamicSky.setLightExposure(value);
}
/**
* Set/Get timeline.
* @type {Number}
* @default 13
* @public
*/
get timeline() {
let _private = this[__.private];
return _private._dynamicSky.getTimeline();
}
set timeline(value) {
let _private = this[__.private];
_private._dynamicSky.setTimeline(value);
this._updateLights();
}
/**
* Set/Get sun equator offset.
* @type {Number}
* @default -40
* @public
*/
get sunEquatorOffset() {
let _private = this[__.private];
return _private._dynamicSky.getSunEquatorOffset();
}
set sunEquatorOffset(value) {
let _private = this[__.private];
_private._dynamicSky.setSunEquatorOffset(value);
this._updateLights();
}
/**
* Get moon light.
* @type {DirectionalLight}
* @public
*/
get moonLight() {
let _private = this[__.private];
return _private.moonLight;
}
/**
* Get hemisphere light.
* @type {HemisphereLight}
* @public
*/
get hemisphereLight() {
let _private = this[__.private];
return _private.hemisphereLight;
}
}
export { CameraDynamicSkyComponent }