import { Utils } from '../common/Utils';
import { BaseComponent } from './BaseComponent';
import { DirectionalLight } from '../objects/DirectionalLight';
import { HemisphereLight } from '../objects/HemisphereLight';
import { AmbientLight } from '../objects/AmbientLight';
/**
* @class AppRenderConfigComponent
* The global renderSettings component.
* @memberof THING
* @extends THING.BaseComponent
*/
class AppRenderConfigComponent extends BaseComponent {
/**
* The RenderSettings helper
*/
constructor() {
super();
}
onAdd(object) {
super.onAdd(object);
}
onRemove() {
super.onRemove();
}
/**
* Configuration about app renderSettings.
* @typedef {Object} RenderSettingsInfo
* @property {background} background The camera's background.
* @property {environment} environment The scene's global environmentMap.
* @property {lights} light The lights config(lights under app.root.children).
* @property {postEffects} PostEffectInfo The camera postEffect info.
* @property {cameraEffects} cameraEffectInfo The camera effect info.
*/
/**
* Configuration about background
* @typedef {ImageTexture| CubeTexture | Array<Number>} background
*/
/**
* Configuration about environment
* @typedef {Object} environment
* @property {ImageTexture | CubeTexture} envMap The scene's envMap.
* @property {Number} diffuseIntensity The envMap light Intensity
*/
/**
* Configuration about lights
* @typedef {Object} lights
* @property {Array<AmbientLightInfo>} ambientLights The ambientLights config.
* @property {Array<DirectionalLightInfo>} directionalLights The directionalLights config.
* @property {Array<HemisphereLightInfo>} hemisphereLights The hemisphereLights config.
* @private
*/
/**
* Configuration about ambientLight
* @typedef {Object} AmbientLightInfo
* @property {Number} intensity The ambientLight intensity.
* @property {Array<Number>} color The ambientLight color.
* @property {String} uuid The ambientLight uuid.
* @property {Boolean} isMainLight Whether the ambientLight is main light.
* @private
*/
/**
* Configuration about directionalLight
* @typedef {Object} DirectionalLightInfo
* @property {Boolean} enableShadow Whether the directionalLight enable shadow.
* @property {Number} intensity The directionalLight intensity.
* @property {Array<Number>} color The directionalLight color.
* @property {Number} shadowBias The directionalLight shadow bias.
* @property {Number} shadowQuality The directionalLight shadow quality.
* @property {Number} horzAngle The directionalLight horizontal angles.
* @property {Number} vertAngle The directionalLight vertical angles.
* @property {Boolean} visible The directionalLight visible.
* @property {String} uuid The directionalLight uuid.
* @property {Boolean} isMainLight Whether the directionalLight is main light.
* @private
*/
/**
* Configuration about hemisphereLight
* @typedef {Object} HemisphereLightInfo
* @property {Number} intensity The hemisphereLight intensity.
* @property {Array<Number>} color The hemisphereLight color.
* @property {Array<Number>} groundColor The hemisphereLight ground color.
* @property {String} uuid The hemisphereLight uuid.
* @private
*/
/**
* get/set global renderSettings.(Can only control the lights under app.root.children)
* @type {RenderSettingsInfo}
*/
get renderSettings() {
const app = this._object;
const config = {
'background': app.background,
'environment': {
'envMap': app.envMap,
'diffuseIntensity': app.scene.envMapLightIntensity
},
'lights': {
'ambientLights': [],
'directionalLights': [],
'hemisphereLights': []
}
};
// fog
config.fog = Utils.cloneObject(app.camera.fog.config, false);
app.root.children.query('.AmbientLight').forEach(ambientLight => {
const ambientLightConfig = {
"intensity": ambientLight.intensity,
"color": ambientLight.color
};
if (app.scene.ambientLight === ambientLight) {
ambientLightConfig.isMainLight = true;
}
else {
ambientLightConfig.uuid = ambientLight.uuid;
}
config.lights.ambientLights.push(ambientLightConfig)
});
app.root.children.query('.DirectionalLight').forEach(directionalLight => {
const directionalLightConfig = {
"enableShadow": directionalLight.enableShadow,
"intensity": directionalLight.intensity,
"color": directionalLight.color,
"shadowBias": directionalLight.shadowBias,
"shadowQuality": directionalLight.shadowQuality,
"horzAngle": directionalLight.adapter.horzAngle,
"vertAngle": directionalLight.adapter.vertAngle,
"visible": directionalLight.visible
};
if (app.scene.mainLight === directionalLight) {
directionalLightConfig.isMainLight = true;
}
else {
directionalLightConfig.uuid = directionalLight.uuid;
}
config.lights.directionalLights.push(directionalLightConfig);
});
app.root.children.query('.HemisphereLight').forEach(hemisphereLight => {
const hemisphereLightConfig = {
'intensity': hemisphereLight.intensity,
'color': hemisphereLight.color,
'groundColor': hemisphereLight.groundColor,
'uuid': hemisphereLight.uuid
};
config.lights.hemisphereLights.push(hemisphereLightConfig);
});
config.postEffects = Utils.cloneObject(app.camera.postEffect.config, false);
config.cameraEffects = Utils.cloneObject(app.camera.effect.config, false);
return config;
}
set renderSettings(config) {
const app = this._object;
app.root.children.query('.BaseLight').forEach(light => {
light.destroy();
});
if (config.background) {
if (!!app.background && (app.background.isImageTexture || app.background.isCubeTexture)) {
app.background.release();
}
app.background = config.background;
if (config.background.isImageTexture || app.background.isCubeTexture) {
config.background.addRef();
}
}
const environment = config.environment;
if (environment) {
if (environment.envMap) {
if (!!app.envMap && (app.envMap.isImageTexture || app.envMap.isCubeTexture)) {
app.envMap.release();
}
app.envMap = environment.envMap;
if (environment.isImageTexture || environment.isCubeTexture) {
environment.addRef();
}
}
app.scene.envMapLightIntensity = environment.diffuseIntensity;
}
// fog
const fog = config.fog;
if (fog) {
app.camera.fog.config = fog;
}
const lights = config.lights;
const ambientLightConfigs = lights.ambientLights;
ambientLightConfigs.forEach(ambientLightConfig => {
let ambientLight;
if (ambientLightConfig.isMainLight) {
ambientLight = app.scene.ambientLight;
}
else {
ambientLight = new AmbientLight();
}
for (let key in ambientLightConfig) {
ambientLight[key] = ambientLightConfig[key];
}
})
const directionalLightConfigs = lights.directionalLights;
directionalLightConfigs.forEach(directionalLightConfig => {
let directionalLight;
if (directionalLightConfig.isMainLight) {
directionalLight = app.scene.mainLight;
}
else {
directionalLight = new DirectionalLight();
}
for (let key in directionalLightConfig) {
if (key == 'adapter') {
const adapterValue = directionalLightConfig[key];
for (let _key in adapterValue) {
directionalLight[key][_key] = adapterValue[_key];
}
}
else if (key == 'helperVisible') {
directionalLight.helper.visible = directionalLightConfig[key];
}
else if (key == 'horzAngle') { // @compatible remove adapter
const adapter = directionalLight.adapter;
adapter.horzAngle = directionalLightConfig[key];
}
else if (key == 'vertAngle') { // @compatible remove adapter
const adapter = directionalLight.adapter;
adapter.vertAngle = directionalLightConfig[key];
}
else {
directionalLight[key] = directionalLightConfig[key];
}
}
});
const hemisphereLightConfigs = lights.hemisphereLights;
hemisphereLightConfigs.forEach(hemisphereLightConfig => {
const hemisphereLight = new HemisphereLight();
for (let key in hemisphereLightConfig) {
hemisphereLight[key] = hemisphereLightConfig[key];
}
});
app.camera.postEffect.config = config.postEffects;
app.camera.effect.config = config.cameraEffects;
}
}
AppRenderConfigComponent.exportProperties = [
'renderSettings'
];
export { AppRenderConfigComponent }