MCP 3D Printer Server

by DMontgomery40
Verified
import DataMap from './DataMap.js'; import { AttributeType } from './Constants.js'; /** * This renderer module manages the bindings of the renderer. * * @private * @augments DataMap */ class Bindings extends DataMap { /** * Constructs a new bindings management component. * * @param {Backend} backend - The renderer's backend. * @param {Nodes} nodes - Renderer component for managing nodes related logic. * @param {Textures} textures - Renderer component for managing textures. * @param {Attributes} attributes - Renderer component for managing attributes. * @param {Pipelines} pipelines - Renderer component for managing pipelines. * @param {Info} info - Renderer component for managing metrics and monitoring data. */ constructor( backend, nodes, textures, attributes, pipelines, info ) { super(); /** * The renderer's backend. * * @type {Backend} */ this.backend = backend; /** * Renderer component for managing textures. * * @type {Textures} */ this.textures = textures; /** * Renderer component for managing pipelines. * * @type {Pipelines} */ this.pipelines = pipelines; /** * Renderer component for managing attributes. * * @type {Attributes} */ this.attributes = attributes; /** * Renderer component for managing nodes related logic. * * @type {Nodes} */ this.nodes = nodes; /** * Renderer component for managing metrics and monitoring data. * * @type {Info} */ this.info = info; this.pipelines.bindings = this; // assign bindings to pipelines } /** * Returns the bind groups for the given render object. * * @param {RenderObject} renderObject - The render object. * @return {Array<BindGroup>} The bind groups. */ getForRender( renderObject ) { const bindings = renderObject.getBindings(); for ( const bindGroup of bindings ) { const groupData = this.get( bindGroup ); if ( groupData.bindGroup === undefined ) { // each object defines an array of bindings (ubos, textures, samplers etc.) this._init( bindGroup ); this.backend.createBindings( bindGroup, bindings, 0 ); groupData.bindGroup = bindGroup; } } return bindings; } /** * Returns the bind groups for the given compute node. * * @param {Node} computeNode - The compute node. * @return {Array<BindGroup>} The bind groups. */ getForCompute( computeNode ) { const bindings = this.nodes.getForCompute( computeNode ).bindings; for ( const bindGroup of bindings ) { const groupData = this.get( bindGroup ); if ( groupData.bindGroup === undefined ) { this._init( bindGroup ); this.backend.createBindings( bindGroup, bindings, 0 ); groupData.bindGroup = bindGroup; } } return bindings; } /** * Updates the bindings for the given compute node. * * @param {Node} computeNode - The compute node. */ updateForCompute( computeNode ) { this._updateBindings( this.getForCompute( computeNode ) ); } /** * Updates the bindings for the given render object. * * @param {RenderObject} renderObject - The render object. */ updateForRender( renderObject ) { this._updateBindings( this.getForRender( renderObject ) ); } /** * Updates the given array of bindings. * * @param {Array<BindGroup>} bindings - The bind groups. */ _updateBindings( bindings ) { for ( const bindGroup of bindings ) { this._update( bindGroup, bindings ); } } /** * Initializes the given bind group. * * @param {BindGroup} bindGroup - The bind group to initialize. */ _init( bindGroup ) { for ( const binding of bindGroup.bindings ) { if ( binding.isSampledTexture ) { this.textures.updateTexture( binding.texture ); } else if ( binding.isStorageBuffer ) { const attribute = binding.attribute; const attributeType = attribute.isIndirectStorageBufferAttribute ? AttributeType.INDIRECT : AttributeType.STORAGE; this.attributes.update( attribute, attributeType ); } } } /** * Updates the given bind group. * * @param {BindGroup} bindGroup - The bind group to update. * @param {Array<BindGroup>} bindings - The bind groups. */ _update( bindGroup, bindings ) { const { backend } = this; let needsBindingsUpdate = false; let cacheBindings = true; let cacheIndex = 0; let version = 0; // iterate over all bindings and check if buffer updates or a new binding group is required for ( const binding of bindGroup.bindings ) { if ( binding.isNodeUniformsGroup ) { const updated = this.nodes.updateGroup( binding ); // every uniforms group is a uniform buffer. So if no update is required, // we move one with the next binding. Otherwise the next if block will update the group. if ( updated === false ) continue; } if ( binding.isUniformBuffer ) { const updated = binding.update(); if ( updated ) { backend.updateBinding( binding ); } } else if ( binding.isSampler ) { binding.update(); } else if ( binding.isSampledTexture ) { const texturesTextureData = this.textures.get( binding.texture ); if ( binding.needsBindingsUpdate( texturesTextureData.generation ) ) needsBindingsUpdate = true; const updated = binding.update(); const texture = binding.texture; if ( updated ) { this.textures.updateTexture( texture ); } const textureData = backend.get( texture ); if ( textureData.externalTexture !== undefined || texturesTextureData.isDefaultTexture ) { cacheBindings = false; } else { cacheIndex = cacheIndex * 10 + texture.id; version += texture.version; } if ( backend.isWebGPUBackend === true && textureData.texture === undefined && textureData.externalTexture === undefined ) { // TODO: Remove this once we found why updated === false isn't bound to a texture in the WebGPU backend console.error( 'Bindings._update: binding should be available:', binding, updated, texture, binding.textureNode.value, needsBindingsUpdate ); this.textures.updateTexture( texture ); needsBindingsUpdate = true; } if ( texture.isStorageTexture === true ) { const textureData = this.get( texture ); if ( binding.store === true ) { textureData.needsMipmap = true; } else if ( this.textures.needsMipmaps( texture ) && textureData.needsMipmap === true ) { this.backend.generateMipmaps( texture ); textureData.needsMipmap = false; } } } } if ( needsBindingsUpdate === true ) { this.backend.updateBindings( bindGroup, bindings, cacheBindings ? cacheIndex : 0, version ); } } } export default Bindings;