MCP 3D Printer Server

by DMontgomery40
Verified
import Node from '../core/Node.js'; import { normalLocal } from './Normal.js'; import { positionLocal } from './Position.js'; import { nodeProxy, vec3, mat3, mat4, int, ivec2, float, Fn } from '../tsl/TSLBase.js'; import { textureLoad } from './TextureNode.js'; import { textureSize } from './TextureSizeNode.js'; import { tangentLocal } from './Tangent.js'; import { instanceIndex, drawIndex } from '../core/IndexNode.js'; import { varyingProperty } from '../core/PropertyNode.js'; /** @module BatchNode **/ /** * This node implements the vertex shader logic which is required * when rendering 3D objects via batching. `BatchNode` must be used * with instances of {@link BatchedMesh}. * * @augments Node */ class BatchNode extends Node { static get type() { return 'BatchNode'; } /** * Constructs a new batch node. * * @param {BatchedMesh} batchMesh - A reference to batched mesh. */ constructor( batchMesh ) { super( 'void' ); /** * A reference to batched mesh. * * @type {BatchedMesh} */ this.batchMesh = batchMesh; /** * The batching index node. * * @type {IndexNode?} * @default null */ this.batchingIdNode = null; } /** * Setups the internal buffers and nodes and assigns the transformed vertex data * to predefined node variables for accumulation. That follows the same patterns * like with morph and skinning nodes. * * @param {NodeBuilder} builder - The current node builder. */ setup( builder ) { if ( this.batchingIdNode === null ) { if ( builder.getDrawIndex() === null ) { this.batchingIdNode = instanceIndex; } else { this.batchingIdNode = drawIndex; } } const getIndirectIndex = Fn( ( [ id ] ) => { const size = int( textureSize( textureLoad( this.batchMesh._indirectTexture ), 0 ) ); const x = int( id ).modInt( size ); const y = int( id ).div( size ); return textureLoad( this.batchMesh._indirectTexture, ivec2( x, y ) ).x; } ).setLayout( { name: 'getIndirectIndex', type: 'uint', inputs: [ { name: 'id', type: 'int' } ] } ); const indirectId = getIndirectIndex( int( this.batchingIdNode ) ); const matricesTexture = this.batchMesh._matricesTexture; const size = textureSize( textureLoad( matricesTexture ), 0 ); const j = float( indirectId ).mul( 4 ).toInt().toVar(); const x = j.modInt( size ); const y = j.div( int( size ) ); const batchingMatrix = mat4( textureLoad( matricesTexture, ivec2( x, y ) ), textureLoad( matricesTexture, ivec2( x.add( 1 ), y ) ), textureLoad( matricesTexture, ivec2( x.add( 2 ), y ) ), textureLoad( matricesTexture, ivec2( x.add( 3 ), y ) ) ); const colorsTexture = this.batchMesh._colorsTexture; if ( colorsTexture !== null ) { const getBatchingColor = Fn( ( [ id ] ) => { const size = textureSize( textureLoad( colorsTexture ), 0 ).x; const j = id; const x = j.modInt( size ); const y = j.div( size ); return textureLoad( colorsTexture, ivec2( x, y ) ).rgb; } ).setLayout( { name: 'getBatchingColor', type: 'vec3', inputs: [ { name: 'id', type: 'int' } ] } ); const color = getBatchingColor( indirectId ); varyingProperty( 'vec3', 'vBatchColor' ).assign( color ); } const bm = mat3( batchingMatrix ); positionLocal.assign( batchingMatrix.mul( positionLocal ) ); const transformedNormal = normalLocal.div( vec3( bm[ 0 ].dot( bm[ 0 ] ), bm[ 1 ].dot( bm[ 1 ] ), bm[ 2 ].dot( bm[ 2 ] ) ) ); const batchingNormal = bm.mul( transformedNormal ).xyz; normalLocal.assign( batchingNormal ); if ( builder.hasGeometryAttribute( 'tangent' ) ) { tangentLocal.mulAssign( bm ); } } } export default BatchNode; /** * TSL function for creating a batch node. * * @function * @param {BatchedMesh} batchMesh - A reference to batched mesh. * @returns {BatchNode} */ export const batch = /*@__PURE__*/ nodeProxy( BatchNode );