MorphNode.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { NodeUpdateType } from '../core/constants.js';
  3. import { nodeProxy } from '../shadernode/ShaderNode.js';
  4. import { uniform } from '../core/UniformNode.js';
  5. import { reference } from './ReferenceNode.js';
  6. import { bufferAttribute } from './BufferAttributeNode.js';
  7. import { positionLocal } from './PositionNode.js';
  8. class MorphNode extends Node {
  9. constructor( mesh ) {
  10. super( 'void' );
  11. this.mesh = mesh;
  12. this.morphBaseInfluence = uniform( 1 );
  13. this.updateType = NodeUpdateType.OBJECT;
  14. }
  15. setupAttribute( builder, name, assignNode = positionLocal ) {
  16. const mesh = this.mesh;
  17. const attributes = mesh.geometry.morphAttributes[ name ];
  18. builder.stack.assign( assignNode, assignNode.mul( this.morphBaseInfluence ) );
  19. for ( let i = 0; i < attributes.length; i ++ ) {
  20. const attribute = attributes[ i ];
  21. const bufferAttrib = bufferAttribute( attribute.array, 'vec3' );
  22. const influence = reference( i, 'float', mesh.morphTargetInfluences );
  23. builder.stack.assign( assignNode, assignNode.add( bufferAttrib.mul( influence ) ) );
  24. }
  25. }
  26. setup( builder ) {
  27. this.setupAttribute( builder, 'position' );
  28. }
  29. update() {
  30. const morphBaseInfluence = this.morphBaseInfluence;
  31. if ( this.mesh.geometry.morphTargetsRelative ) {
  32. morphBaseInfluence.value = 1;
  33. } else {
  34. morphBaseInfluence.value = 1 - this.mesh.morphTargetInfluences.reduce( ( a, b ) => a + b, 0 );
  35. }
  36. }
  37. }
  38. export default MorphNode;
  39. export const morph = nodeProxy( MorphNode );
  40. addNodeClass( 'MorphNode', MorphNode );