MCP 3D Printer Server

by DMontgomery40
Verified
import NodeMaterial from './NodeMaterial.js'; import { cameraProjectionMatrix } from '../../nodes/accessors/Camera.js'; import { materialRotation } from '../../nodes/accessors/MaterialNode.js'; import { modelViewMatrix, modelWorldMatrix } from '../../nodes/accessors/ModelNode.js'; import { positionGeometry } from '../../nodes/accessors/Position.js'; import { rotate } from '../../nodes/utils/RotateNode.js'; import { float, vec2, vec3, vec4 } from '../../nodes/tsl/TSLBase.js'; import { SpriteMaterial } from '../SpriteMaterial.js'; import { reference } from '../../nodes/accessors/ReferenceBaseNode.js'; const _defaultValues = /*@__PURE__*/ new SpriteMaterial(); /** * Node material version of `SpriteMaterial`. * * @augments NodeMaterial */ class SpriteNodeMaterial extends NodeMaterial { static get type() { return 'SpriteNodeMaterial'; } /** * Constructs a new sprite node material. * * @param {Object?} parameters - The configuration parameter. */ constructor( parameters ) { super(); /** * This flag can be used for type testing. * * @type {Boolean} * @readonly * @default true */ this.isSpriteNodeMaterial = true; this._useSizeAttenuation = true; /** * This property makes it possible to define the position of the sprite with a * node. That can be useful when the material is used with instanced rendering * and node data are defined with an instanced attribute node: * ```js * const positionAttribute = new InstancedBufferAttribute( new Float32Array( positions ), 3 ); * material.positionNode = instancedBufferAttribute( positionAttribute ); * ``` * Another possibility is to compute the instanced data with a compute shader: * ```js * const positionBuffer = instancedArray( particleCount, 'vec3' ); * particleMaterial.positionNode = positionBuffer.toAttribute(); * ``` * * @type {Node<vec2>?} * @default null */ this.positionNode = null; /** * The rotation of sprite materials is by default inferred from the `rotation`, * property. This node property allows to overwrite the default and define * the rotation with a node instead. * * If you don't want to overwrite the rotation but modify the existing * value instead, use {@link module:MaterialNode.materialRotation}. * * @type {Node<float>?} * @default null */ this.rotationNode = null; /** * This node property provides an additional way to scale sprites next to * `Object3D.scale`. The scale transformation based in `Object3D.scale` * is multiplied with the scale value of this node in the vertex shader. * * @type {Node<vec2>?} * @default null */ this.scaleNode = null; this.setDefaultValues( _defaultValues ); this.setValues( parameters ); } /** * Setups the position node in view space. This method implements * the sprite specific vertex shader. * * @param {NodeBuilder} builder - The current node builder. * @return {Node<vec3>} The position in view space. */ setupPositionView( builder ) { const { object, camera } = builder; const sizeAttenuation = this.sizeAttenuation; const { positionNode, rotationNode, scaleNode } = this; const mvPosition = modelViewMatrix.mul( vec3( positionNode || 0 ) ); let scale = vec2( modelWorldMatrix[ 0 ].xyz.length(), modelWorldMatrix[ 1 ].xyz.length() ); if ( scaleNode !== null ) { scale = scale.mul( float( scaleNode ) ); } if ( sizeAttenuation === false ) { if ( camera.isPerspectiveCamera ) { scale = scale.mul( mvPosition.z.negate() ); } else { const orthoScale = float( 2.0 ).div( cameraProjectionMatrix.element( 1 ).element( 1 ) ); scale = scale.mul( orthoScale.mul( 2 ) ); } } let alignedPosition = positionGeometry.xy; if ( object.center && object.center.isVector2 === true ) { const center = reference( 'center', 'vec2', object ); alignedPosition = alignedPosition.sub( center.sub( 0.5 ) ); } alignedPosition = alignedPosition.mul( scale ); const rotation = float( rotationNode || materialRotation ); const rotatedPosition = rotate( alignedPosition, rotation ); return vec4( mvPosition.xy.add( rotatedPosition ), mvPosition.zw ); } copy( source ) { this.positionNode = source.positionNode; this.rotationNode = source.rotationNode; this.scaleNode = source.scaleNode; return super.copy( source ); } /** * Whether to use size attenuation or not. * * @type {Boolean} * @default true */ get sizeAttenuation() { return this._useSizeAttenuation; } set sizeAttenuation( value ) { if ( this._useSizeAttenuation !== value ) { this._useSizeAttenuation = value; this.needsUpdate = true; } } } export default SpriteNodeMaterial;