ReferenceNode.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. import Node, { addNodeClass } from '../core/Node.js';
  2. import { NodeUpdateType } from '../core/constants.js';
  3. import { uniform } from '../core/UniformNode.js';
  4. import { texture } from './TextureNode.js';
  5. import { buffer } from './BufferNode.js';
  6. import { nodeObject } from '../shadernode/ShaderNode.js';
  7. import { uniforms } from './UniformsNode.js';
  8. import ArrayElementNode from '../utils/ArrayElementNode.js';
  9. class ReferenceElementNode extends ArrayElementNode {
  10. constructor( referenceNode, indexNode ) {
  11. super( referenceNode, indexNode );
  12. this.referenceNode = referenceNode;
  13. this.isReferenceElementNode = true;
  14. }
  15. getNodeType() {
  16. return this.referenceNode.uniformType;
  17. }
  18. generate( builder ) {
  19. const snippet = super.generate( builder );
  20. const arrayType = this.referenceNode.getNodeType();
  21. const elementType = this.getNodeType();
  22. return builder.format( snippet, arrayType, elementType );
  23. }
  24. }
  25. class ReferenceNode extends Node {
  26. constructor( property, uniformType, object = null, count = null ) {
  27. super();
  28. this.property = property;
  29. this.uniformType = uniformType;
  30. this.object = object;
  31. this.count = count;
  32. this.properties = property.split( '.' );
  33. this.reference = null;
  34. this.node = null;
  35. this.updateType = NodeUpdateType.OBJECT;
  36. }
  37. element( indexNode ) {
  38. return nodeObject( new ReferenceElementNode( this, nodeObject( indexNode ) ) );
  39. }
  40. setNodeType( uniformType ) {
  41. let node = null;
  42. if ( this.count !== null ) {
  43. node = buffer( null, uniformType, this.count );
  44. } else if ( Array.isArray( this.getValueFromReference() ) ) {
  45. node = uniforms( null, uniformType );
  46. } else if ( uniformType === 'texture' ) {
  47. node = texture( null );
  48. } else {
  49. node = uniform( null, uniformType );
  50. }
  51. this.node = node;
  52. }
  53. getNodeType( builder ) {
  54. if ( this.node === null ) {
  55. this.updateValue();
  56. }
  57. return this.node.getNodeType( builder );
  58. }
  59. getValueFromReference( object = this.reference ) {
  60. const { properties } = this;
  61. let value = object[ properties[ 0 ] ];
  62. for ( let i = 1; i < properties.length; i ++ ) {
  63. value = value[ properties[ i ] ];
  64. }
  65. return value;
  66. }
  67. updateReference( state ) {
  68. this.reference = this.object !== null ? this.object : state.object;
  69. return this.reference;
  70. }
  71. setup() {
  72. this.updateValue();
  73. return this.node;
  74. }
  75. update( /*frame*/ ) {
  76. this.updateValue();
  77. }
  78. updateValue() {
  79. if ( this.node === null ) this.setNodeType( this.uniformType );
  80. const value = this.getValueFromReference();
  81. if ( Array.isArray( value ) ) {
  82. this.node.array = value;
  83. } else {
  84. this.node.value = value;
  85. }
  86. }
  87. }
  88. export default ReferenceNode;
  89. export const reference = ( name, type, object ) => nodeObject( new ReferenceNode( name, type, object ) );
  90. export const referenceBuffer = ( name, type, count, object ) => nodeObject( new ReferenceNode( name, type, object, count ) );
  91. addNodeClass( 'ReferenceNode', ReferenceNode );