import { TempNode } from '../core/TempNode.js'; import { NodeLib } from '../core/NodeLib.js'; class PositionNode extends TempNode { constructor( scope ) { super( 'v3' ); this.scope = scope || PositionNode.LOCAL; } getType( ) { switch ( this.scope ) { case PositionNode.PROJECTION: return 'v4'; } return this.type; } getShared( /* builder */ ) { switch ( this.scope ) { case PositionNode.LOCAL: case PositionNode.WORLD: return false; } return true; } generate( builder, output ) { let result; switch ( this.scope ) { case PositionNode.LOCAL: if ( builder.isShader( 'vertex' ) ) { result = 'transformed'; } else { builder.requires.position = true; result = 'vPosition'; } break; case PositionNode.WORLD: if ( builder.isShader( 'vertex' ) ) { return '( modelMatrix * vec4( transformed, 1.0 ) ).xyz'; } else { builder.requires.worldPosition = true; result = 'vWPosition'; } break; case PositionNode.VIEW: result = builder.isShader( 'vertex' ) ? '-mvPosition.xyz' : 'vViewPosition'; break; case PositionNode.PROJECTION: result = builder.isShader( 'vertex' ) ? '( projectionMatrix * modelViewMatrix * vec4( position, 1.0 ) )' : 'vec4( 0.0 )'; break; } return builder.format( result, this.getType( builder ), output ); } copy( source ) { super.copy( source ); this.scope = source.scope; return this; } toJSON( meta ) { let data = this.getJSONNode( meta ); if ( ! data ) { data = this.createJSONNode( meta ); data.scope = this.scope; } return data; } } PositionNode.LOCAL = 'local'; PositionNode.WORLD = 'world'; PositionNode.VIEW = 'view'; PositionNode.PROJECTION = 'projection'; PositionNode.prototype.nodeType = 'Position'; NodeLib.addKeyword( 'position', function () { return new PositionNode(); } ); NodeLib.addKeyword( 'worldPosition', function () { return new PositionNode( PositionNode.WORLD ); } ); NodeLib.addKeyword( 'viewPosition', function () { return new PositionNode( PositionNode.VIEW ); } ); export { PositionNode };