MCP 3D Printer Server

by DMontgomery40
Verified
import { nodeObject } from '../tsl/TSLBase.js'; import { NodeUpdateType } from '../core/constants.js'; import { getValueType } from '../core/NodeUtils.js'; import ArrayElementNode from '../utils/ArrayElementNode.js'; import BufferNode from './BufferNode.js'; /** @module UniformArrayNode **/ /** * Represents the element access on uniform array nodes. * * @augments ArrayElementNode */ class UniformArrayElementNode extends ArrayElementNode { static get type() { return 'UniformArrayElementNode'; } /** * Constructs a new buffer node. * * @param {UniformArrayNode} uniformArrayNode - The uniform array node to access. * @param {IndexNode} indexNode - The index data that define the position of the accessed element in the array. */ constructor( uniformArrayNode, indexNode ) { super( uniformArrayNode, indexNode ); /** * This flag can be used for type testing. * * @type {Boolean} * @readonly * @default true */ this.isArrayBufferElementNode = true; } generate( builder ) { const snippet = super.generate( builder ); const type = this.getNodeType(); const paddedType = this.node.getPaddedType(); return builder.format( snippet, paddedType, type ); } } /** * Similar to {@link module:BufferNode~BufferNode} this module represents array-like data as * uniform buffers. Unlike {@link module:BufferNode~BufferNode}, it can handle more common * data types in the array (e.g `three.js` primitives) and automatically * manage buffer padding. It should be the first choice when working with * uniforms buffers. * ```js * const tintColors = uniformArray( [ * new Color( 1, 0, 0 ), * new Color( 0, 1, 0 ), * new Color( 0, 0, 1 ) * ], 'color' ); * * const redColor = tintColors.element( 0 ); * * @augments module:BufferNode~BufferNode */ class UniformArrayNode extends BufferNode { static get type() { return 'UniformArrayNode'; } /** * Constructs a new uniform array node. * * @param {Array<Any>} value - Array holding the buffer data. * @param {String?} [elementType=null] - The data type of a buffer element. */ constructor( value, elementType = null ) { super( null ); /** * Array holding the buffer data. Unlike {@link module:BufferNode~BufferNode}, the array can * hold number primitives as well as three.js objects like vectors, matrices * or colors. * * @type {Array<Any>} */ this.array = value; /** * The data type of an array element. * * @type {String} */ this.elementType = elementType === null ? getValueType( value[ 0 ] ) : elementType; /** * The padded type. Uniform buffers must conform to a certain buffer layout * so a separate type is computed to ensure correct buffer size. * * @type {String} */ this.paddedType = this.getPaddedType(); /** * Overwritten since uniform array nodes are updated per render. * * @type {String} * @default 'render' */ this.updateType = NodeUpdateType.RENDER; /** * This flag can be used for type testing. * * @type {Boolean} * @readonly * @default true */ this.isArrayBufferNode = true; } /** * This method is overwritten since the node type is inferred from the * {@link module:UniformArrayNode~UniformArrayNode#paddedType}. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The node type. */ getNodeType( /*builder*/ ) { return this.paddedType; } /** * The data type of the array elements. * * @param {NodeBuilder} builder - The current node builder. * @return {String} The element type. */ getElementType() { return this.elementType; } /** * Returns the padded type based on the element type. * * @return {String} The padded type. */ getPaddedType() { const elementType = this.elementType; let paddedType = 'vec4'; if ( elementType === 'mat2' ) { paddedType = 'mat2'; } else if ( /mat/.test( elementType ) === true ) { paddedType = 'mat4'; } else if ( elementType.charAt( 0 ) === 'i' ) { paddedType = 'ivec4'; } else if ( elementType.charAt( 0 ) === 'u' ) { paddedType = 'uvec4'; } return paddedType; } /** * The update makes sure to correctly transfer the data from the (complex) objects * in the array to the internal, correctly padded value buffer. * * @param {NodeFrame} frame - A reference to the current node frame. */ update( /*frame*/ ) { const { array, value } = this; const elementType = this.elementType; if ( elementType === 'float' || elementType === 'int' || elementType === 'uint' ) { for ( let i = 0; i < array.length; i ++ ) { const index = i * 4; value[ index ] = array[ i ]; } } else if ( elementType === 'color' ) { for ( let i = 0; i < array.length; i ++ ) { const index = i * 4; const vector = array[ i ]; value[ index ] = vector.r; value[ index + 1 ] = vector.g; value[ index + 2 ] = vector.b || 0; //value[ index + 3 ] = vector.a || 0; } } else if ( elementType === 'mat2' ) { for ( let i = 0; i < array.length; i ++ ) { const index = i * 4; const matrix = array[ i ]; value[ index ] = matrix.elements[ 0 ]; value[ index + 1 ] = matrix.elements[ 1 ]; value[ index + 2 ] = matrix.elements[ 2 ]; value[ index + 3 ] = matrix.elements[ 3 ]; } } else if ( elementType === 'mat3' ) { for ( let i = 0; i < array.length; i ++ ) { const index = i * 16; const matrix = array[ i ]; value[ index ] = matrix.elements[ 0 ]; value[ index + 1 ] = matrix.elements[ 1 ]; value[ index + 2 ] = matrix.elements[ 2 ]; value[ index + 4 ] = matrix.elements[ 3 ]; value[ index + 5 ] = matrix.elements[ 4 ]; value[ index + 6 ] = matrix.elements[ 5 ]; value[ index + 8 ] = matrix.elements[ 6 ]; value[ index + 9 ] = matrix.elements[ 7 ]; value[ index + 10 ] = matrix.elements[ 8 ]; value[ index + 15 ] = 1; } } else if ( elementType === 'mat4' ) { for ( let i = 0; i < array.length; i ++ ) { const index = i * 16; const matrix = array[ i ]; for ( let i = 0; i < matrix.elements.length; i ++ ) { value[ index + i ] = matrix.elements[ i ]; } } } else { for ( let i = 0; i < array.length; i ++ ) { const index = i * 4; const vector = array[ i ]; value[ index ] = vector.x; value[ index + 1 ] = vector.y; value[ index + 2 ] = vector.z || 0; value[ index + 3 ] = vector.w || 0; } } } /** * Implement the value buffer creation based on the array data. * * @param {NodeBuilder} builder - A reference to the current node builder. * @return {null} */ setup( builder ) { const length = this.array.length; const elementType = this.elementType; let arrayType = Float32Array; const paddedType = this.paddedType; const paddedElementLength = builder.getTypeLength( paddedType ); if ( elementType.charAt( 0 ) === 'i' ) arrayType = Int32Array; if ( elementType.charAt( 0 ) === 'u' ) arrayType = Uint32Array; this.value = new arrayType( length * paddedElementLength ); this.bufferCount = length; this.bufferType = paddedType; return super.setup( builder ); } /** * Overwrites the default `element()` method to provide element access * based on {@link module:UniformArrayNode~UniformArrayNode}. * * @param {IndexNode} indexNode - The index node. * @return {UniformArrayElementNode} */ element( indexNode ) { return nodeObject( new UniformArrayElementNode( this, nodeObject( indexNode ) ) ); } } export default UniformArrayNode; /** * TSL function for creating an uniform array node. * * @function * @param {Array<Any>} values - Array-like data. * @param {String?} nodeType - The data type of the array elements. * @returns {UniformArrayNode} */ export const uniformArray = ( values, nodeType ) => nodeObject( new UniformArrayNode( values, nodeType ) ); /** * @function * @deprecated since r168. Use {@link uniformArray} instead. * * @param {Array<Any>} values - Array-like data. * @param {String} nodeType - The data type of the array elements. * @returns {UniformArrayNode} */ export const uniforms = ( values, nodeType ) => { // @deprecated, r168 console.warn( 'TSL.UniformArrayNode: uniforms() has been renamed to uniformArray().' ); return nodeObject( new UniformArrayNode( values, nodeType ) ); };