@openhps/core
Version:
Open Hybrid Positioning System - Core component
188 lines (171 loc) • 5.93 kB
JavaScript
;
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);