FunctionOverloadingNode.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import Node from '../core/Node.js';
  2. import { nodeProxy } from '../tsl/TSLCore.js';
  3. /**
  4. * This class allows to define multiple overloaded versions
  5. * of the same function. Depending on the parameters of the function
  6. * call, the node picks the best-fit overloaded version.
  7. *
  8. * @augments Node
  9. */
  10. class FunctionOverloadingNode extends Node {
  11. static get type() {
  12. return 'FunctionOverloadingNode';
  13. }
  14. /**
  15. * Constructs a new function overloading node.
  16. *
  17. * @param {Array<Function>} functionNodes - Array of `Fn` function definitions.
  18. * @param {...Node} parametersNodes - A list of parameter nodes.
  19. */
  20. constructor( functionNodes = [], ...parametersNodes ) {
  21. super();
  22. /**
  23. * Array of `Fn` function definitions.
  24. *
  25. * @type {Array<Function>}
  26. */
  27. this.functionNodes = functionNodes;
  28. /**
  29. * A list of parameter nodes.
  30. *
  31. * @type {Array<Node>}
  32. */
  33. this.parametersNodes = parametersNodes;
  34. /**
  35. * The selected overloaded function call.
  36. *
  37. * @private
  38. * @type {ShaderCallNodeInternal}
  39. */
  40. this._candidateFn = null;
  41. /**
  42. * This node is marked as global.
  43. *
  44. * @type {boolean}
  45. * @default true
  46. */
  47. this.global = true;
  48. }
  49. /**
  50. * This method is overwritten since the node type is inferred from
  51. * the function's return type.
  52. *
  53. * @param {NodeBuilder} builder - The current node builder.
  54. * @return {string} The node type.
  55. */
  56. generateNodeType( builder ) {
  57. const candidateFn = this.getCandidateFn( builder );
  58. return candidateFn.shaderNode.layout.type;
  59. }
  60. /**
  61. * Returns the candidate function for the current parameters.
  62. *
  63. * @param {NodeBuilder} builder - The current node builder.
  64. * @return {FunctionNode} The candidate function.
  65. */
  66. getCandidateFn( builder ) {
  67. const params = this.parametersNodes;
  68. let candidateFn = this._candidateFn;
  69. if ( candidateFn === null ) {
  70. let bestCandidateFn = null;
  71. let bestScore = - 1;
  72. for ( const functionNode of this.functionNodes ) {
  73. const shaderNode = functionNode.shaderNode;
  74. const layout = shaderNode.layout;
  75. if ( layout === null ) {
  76. throw new Error( 'THREE.FunctionOverloadingNode: FunctionNode must be a layout.' );
  77. }
  78. const inputs = layout.inputs;
  79. if ( params.length === inputs.length ) {
  80. let currentScore = 0;
  81. for ( let i = 0; i < params.length; i ++ ) {
  82. const param = params[ i ];
  83. const input = inputs[ i ];
  84. if ( param.getNodeType( builder ) === input.type ) {
  85. currentScore ++;
  86. }
  87. }
  88. if ( currentScore > bestScore ) {
  89. bestCandidateFn = functionNode;
  90. bestScore = currentScore;
  91. }
  92. }
  93. }
  94. this._candidateFn = candidateFn = bestCandidateFn;
  95. }
  96. return candidateFn;
  97. }
  98. /**
  99. * Sets up the node for the current parameters.
  100. *
  101. * @param {NodeBuilder} builder - The current node builder.
  102. * @return {Node} The setup node.
  103. */
  104. setup( builder ) {
  105. const candidateFn = this.getCandidateFn( builder );
  106. return candidateFn( ...this.parametersNodes );
  107. }
  108. }
  109. export default FunctionOverloadingNode;
  110. const overloadingBaseFn = /*@__PURE__*/ nodeProxy( FunctionOverloadingNode );
  111. /**
  112. * TSL function for creating a function overloading node.
  113. *
  114. * @tsl
  115. * @function
  116. * @param {Array<Function>} functionNodes - Array of `Fn` function definitions.
  117. * @returns {FunctionOverloadingNode}
  118. */
  119. export const overloadingFn = ( functionNodes ) => ( ...params ) => overloadingBaseFn( functionNodes, ...params );
粤ICP备19079148号