SplitNode.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { vectorComponents } from '../core/constants.js';
  3. const stringVectorComponents = vectorComponents.join( '' );
  4. class SplitNode extends Node {
  5. constructor( node, components = 'x' ) {
  6. super();
  7. this.node = node;
  8. this.components = components;
  9. this.isSplitNode = true;
  10. }
  11. getVectorLength() {
  12. let vectorLength = this.components.length;
  13. for ( const c of this.components ) {
  14. vectorLength = Math.max( vectorComponents.indexOf( c ) + 1, vectorLength );
  15. }
  16. return vectorLength;
  17. }
  18. getComponentType( builder ) {
  19. return builder.getComponentType( this.node.getNodeType( builder ) );
  20. }
  21. getNodeType( builder ) {
  22. return builder.getTypeFromLength( this.components.length, this.getComponentType( builder ) );
  23. }
  24. generate( builder, output ) {
  25. const node = this.node;
  26. const nodeTypeLength = builder.getTypeLength( node.getNodeType( builder ) );
  27. let snippet = null;
  28. if ( nodeTypeLength > 1 ) {
  29. let type = null;
  30. const componentsLength = this.getVectorLength();
  31. if ( componentsLength >= nodeTypeLength ) {
  32. // needed expand the input node
  33. type = builder.getTypeFromLength( this.getVectorLength(), this.getComponentType( builder ) );
  34. }
  35. const nodeSnippet = node.build( builder, type );
  36. if ( this.components.length === nodeTypeLength && this.components === stringVectorComponents.slice( 0, this.components.length ) ) {
  37. // unnecessary swizzle
  38. snippet = builder.format( nodeSnippet, type, output );
  39. } else {
  40. snippet = builder.format( `${nodeSnippet}.${this.components}`, this.getNodeType( builder ), output );
  41. }
  42. } else {
  43. // ignore .components if .node returns float/integer
  44. snippet = node.build( builder, output );
  45. }
  46. return snippet;
  47. }
  48. serialize( data ) {
  49. super.serialize( data );
  50. data.components = this.components;
  51. }
  52. deserialize( data ) {
  53. super.deserialize( data );
  54. this.components = data.components;
  55. }
  56. }
  57. export default SplitNode;
  58. addNodeClass( 'SplitNode', SplitNode );