Node.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { NodeUpdateType } from './constants.js';
  2. import { getNodesKeys } from './NodeUtils.js';
  3. import { MathUtils } from 'three';
  4. let _nodeId = 0;
  5. class Node {
  6. constructor( nodeType = null ) {
  7. this.nodeType = nodeType;
  8. this.updateType = NodeUpdateType.None;
  9. this.uuid = MathUtils.generateUUID();
  10. Object.defineProperty( this, 'id', { value: _nodeId ++ } );
  11. }
  12. get type() {
  13. return this.constructor.name;
  14. }
  15. getHash( /*builder*/ ) {
  16. return this.uuid;
  17. }
  18. getUpdateType( /*builder*/ ) {
  19. return this.updateType;
  20. }
  21. getNodeType( /*builder*/ ) {
  22. return this.nodeType;
  23. }
  24. update( /*frame*/ ) {
  25. console.warn( 'Abstract function.' );
  26. }
  27. generate( /*builder, output*/ ) {
  28. console.warn( 'Abstract function.' );
  29. }
  30. analyze( builder ) {
  31. const hash = this.getHash( builder );
  32. const sharedNode = builder.getNodeFromHash( hash );
  33. if ( sharedNode !== undefined && this !== sharedNode ) {
  34. return sharedNode.analyze( builder );
  35. }
  36. const nodeData = builder.getDataFromNode( this );
  37. nodeData.dependenciesCount = nodeData.dependenciesCount === undefined ? 1 : nodeData.dependenciesCount + 1;
  38. const nodeKeys = getNodesKeys( this );
  39. for ( const property of nodeKeys ) {
  40. this[ property ].analyze( builder );
  41. }
  42. }
  43. build( builder, output = null ) {
  44. const hash = this.getHash( builder );
  45. const sharedNode = builder.getNodeFromHash( hash );
  46. if ( sharedNode !== undefined && this !== sharedNode ) {
  47. return sharedNode.build( builder, output );
  48. }
  49. builder.addNode( this );
  50. builder.addStack( this );
  51. const nodeData = builder.getDataFromNode( this );
  52. const isGenerateOnce = this.generate.length === 1;
  53. let snippet = null;
  54. if ( isGenerateOnce ) {
  55. const type = this.getNodeType( builder );
  56. snippet = nodeData.snippet;
  57. if ( snippet === undefined ) {
  58. snippet = this.generate( builder ) || '';
  59. nodeData.snippet = snippet;
  60. }
  61. snippet = builder.format( snippet, type, output );
  62. } else {
  63. snippet = this.generate( builder, output ) || '';
  64. }
  65. builder.removeStack( this );
  66. return snippet;
  67. }
  68. serialize( json ) {
  69. const nodeKeys = getNodesKeys( this );
  70. if ( nodeKeys.length > 0 ) {
  71. const inputNodes = {};
  72. for ( const property of nodeKeys ) {
  73. inputNodes[ property ] = this[ property ].toJSON( json.meta ).uuid;
  74. }
  75. json.inputNodes = inputNodes;
  76. }
  77. }
  78. deserialize( json ) {
  79. if ( json.inputNodes !== undefined ) {
  80. const nodes = json.meta.nodes;
  81. for ( const property in json.inputNodes ) {
  82. const uuid = json.inputNodes[ property ];
  83. this[ property ] = nodes[ uuid ];
  84. }
  85. }
  86. }
  87. toJSON( meta ) {
  88. const { uuid, type } = this;
  89. const isRoot = ( meta === undefined || typeof meta === 'string' );
  90. if ( isRoot ) {
  91. meta = {
  92. textures: {},
  93. images: {},
  94. nodes: {}
  95. };
  96. }
  97. // serialize
  98. let data = meta.nodes[ uuid ];
  99. if ( data === undefined ) {
  100. data = {
  101. uuid,
  102. type,
  103. meta,
  104. metadata: {
  105. version: 4.5,
  106. type: 'Node',
  107. generator: 'Node.toJSON'
  108. }
  109. };
  110. meta.nodes[ data.uuid ] = data;
  111. this.serialize( data );
  112. delete data.meta;
  113. }
  114. // TODO: Copied from Object3D.toJSON
  115. function extractFromCache( cache ) {
  116. const values = [];
  117. for ( const key in cache ) {
  118. const data = cache[ key ];
  119. delete data.metadata;
  120. values.push( data );
  121. }
  122. return values;
  123. }
  124. if ( isRoot ) {
  125. const textures = extractFromCache( meta.textures );
  126. const images = extractFromCache( meta.images );
  127. const nodes = extractFromCache( meta.nodes );
  128. if ( textures.length > 0 ) data.textures = textures;
  129. if ( images.length > 0 ) data.images = images;
  130. if ( nodes.length > 0 ) data.nodes = nodes;
  131. }
  132. return data;
  133. }
  134. }
  135. Node.prototype.isNode = true;
  136. export default Node;