MCP 3D Printer Server

by DMontgomery40
Verified
import TempNode from '../core/TempNode.js'; import { NodeUpdateType } from '../core/constants.js'; import { nodeProxy } from '../tsl/TSLBase.js'; import { CubeTexture } from '../../textures/CubeTexture.js'; import { cubeTexture } from '../accessors/CubeTextureNode.js'; import CubeRenderTarget from '../../renderers/common/CubeRenderTarget.js'; import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../constants.js'; /** @module CubeMapNode **/ 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 { 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 = cubeTexture(); const defaultTexture = new 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 = 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 === EquirectangularReflectionMapping || mapping === 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( 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; } } export 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 === EquirectangularReflectionMapping ) { texture.mapping = CubeReflectionMapping; } else if ( mapping === EquirectangularRefractionMapping ) { texture.mapping = CubeRefractionMapping; } } /** * TSL function for creating a cube map node. * * @function * @param {Node} envNode - The node representing the environment map. * @returns {CubeMapNode} */ export const cubeMapNode = /*@__PURE__*/ nodeProxy( CubeMapNode );