UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

188 lines (171 loc) 5.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.cubeMapNode = void 0; var _TempNode = _interopRequireDefault(require("../core/TempNode.js")); var _constants = require("../core/constants.js"); var _TSLBase = require("../tsl/TSLBase.js"); var _CubeTexture = require("../../textures/CubeTexture.js"); var _CubeTextureNode = require("../accessors/CubeTextureNode.js"); var _CubeRenderTarget = _interopRequireDefault(require("../../renderers/common/CubeRenderTarget.js")); var _constants2 = require("../../constants.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const _cache = new WeakMap(); /** * This node can be used to automatically convert environment maps in the * equirectangular format into the cube map format. * * @augments TempNode */ class CubeMapNode extends _TempNode.default { static get type() { return 'CubeMapNode'; } /** * Constructs a new cube map node. * * @param {Node} envNode - The node representing the environment map. */ constructor(envNode) { super('vec3'); /** * The node representing the environment map. * * @type {Node} */ this.envNode = envNode; /** * A reference to the internal cube texture. * * @private * @type {?CubeTexture} * @default null */ this._cubeTexture = null; /** * A reference to the internal cube texture node. * * @private * @type {CubeTextureNode} */ this._cubeTextureNode = (0, _CubeTextureNode.cubeTexture)(null); const defaultTexture = new _CubeTexture.CubeTexture(); defaultTexture.isRenderTargetTexture = true; /** * A default cube texture that acts as a placeholder. * It is used when the conversion from equirectangular to cube * map has not finished yet for a given texture. * * @private * @type {CubeTexture} */ this._defaultTexture = defaultTexture; /** * The `updateBeforeType` is set to `NodeUpdateType.RENDER` since the node updates * the texture once per render in its {@link CubeMapNode#updateBefore} method. * * @type {string} * @default 'render' */ this.updateBeforeType = _constants.NodeUpdateType.RENDER; } updateBefore(frame) { const { renderer, material } = frame; const envNode = this.envNode; if (envNode.isTextureNode || envNode.isMaterialReferenceNode) { const texture = envNode.isTextureNode ? envNode.value : material[envNode.property]; if (texture && texture.isTexture) { const mapping = texture.mapping; if (mapping === _constants2.EquirectangularReflectionMapping || mapping === _constants2.EquirectangularRefractionMapping) { // check for converted cubemap map if (_cache.has(texture)) { const cubeMap = _cache.get(texture); mapTextureMapping(cubeMap, texture.mapping); this._cubeTexture = cubeMap; } else { // create cube map from equirectangular map const image = texture.image; if (isEquirectangularMapReady(image)) { const renderTarget = new _CubeRenderTarget.default(image.height); renderTarget.fromEquirectangularTexture(renderer, texture); mapTextureMapping(renderTarget.texture, texture.mapping); this._cubeTexture = renderTarget.texture; _cache.set(texture, renderTarget.texture); texture.addEventListener('dispose', onTextureDispose); } else { // default cube texture as fallback when equirectangular texture is not yet loaded this._cubeTexture = this._defaultTexture; } } // this._cubeTextureNode.value = this._cubeTexture; } else { // envNode already refers to a cube map this._cubeTextureNode = this.envNode; } } } } setup(builder) { this.updateBefore(builder); return this._cubeTextureNode; } } var _default = exports.default = CubeMapNode; /** * Returns true if the given equirectangular image has been fully loaded * and is ready for further processing. * * @private * @param {Image} image - The equirectangular image to check. * @return {boolean} Whether the image is ready or not. */ function isEquirectangularMapReady(image) { if (image === null || image === undefined) return false; return image.height > 0; } /** * This function is executed when `dispose()` is called on the equirectangular * texture. In this case, the generated cube map with its render target * is deleted as well. * * @private * @param {Object} event - The event object. */ function onTextureDispose(event) { const texture = event.target; texture.removeEventListener('dispose', onTextureDispose); const renderTarget = _cache.get(texture); if (renderTarget !== undefined) { _cache.delete(texture); renderTarget.dispose(); } } /** * This function makes sure the generated cube map uses the correct * texture mapping that corresponds to the equirectangular original. * * @private * @param {Texture} texture - The cube texture. * @param {number} mapping - The original texture mapping. */ function mapTextureMapping(texture, mapping) { if (mapping === _constants2.EquirectangularReflectionMapping) { texture.mapping = _constants2.CubeReflectionMapping; } else if (mapping === _constants2.EquirectangularRefractionMapping) { texture.mapping = _constants2.CubeRefractionMapping; } } /** * TSL function for creating a cube map node. * * @tsl * @function * @param {Node} envNode - The node representing the environment map. * @returns {CubeMapNode} */ const cubeMapNode = exports.cubeMapNode = /*@__PURE__*/(0, _TSLBase.nodeProxy)(CubeMapNode).setParameterLength(1);