@@ -611,7 +611,13 @@ const ConvertType = function ( type, cacheMap = null ) {
611611
612612 return ( ...params ) => {
613613
614- if ( params . length === 0 || ( ! [ 'bool' , 'float' , 'int' , 'uint' ] . includes ( type ) && params . every ( param => typeof param !== 'object' ) ) ) {
614+ if ( params . length === 0 || ( ! [ 'bool' , 'float' , 'int' , 'uint' ] . includes ( type ) && params . every ( param => {
615+
616+ const paramType = typeof param ;
617+
618+ return paramType !== 'object' && paramType !== 'function' ;
619+
620+ } ) ) ) {
615621
616622 params = [ getValueFromType ( type , ...params ) ] ;
617623
@@ -664,37 +670,90 @@ export const nodeProxyIntent = ( NodeClass, scope = null, factor = null, setting
664670
665671let fnId = 0 ;
666672
667- export const Fn = ( jsFunc , layout = null ) => {
673+ class FnNode extends Node {
668674
669- let nodeType = null ;
675+ constructor ( jsFunc , layout = null ) {
670676
671- if ( layout !== null ) {
672-
673- if ( typeof layout === 'object' ) {
677+ super ( ) ;
674678
675- nodeType = layout . return ;
679+ let nodeType = null ;
676680
677- } else {
681+ if ( layout !== null ) {
678682
679- if ( typeof layout === 'string ' ) {
683+ if ( typeof layout === 'object ' ) {
680684
681- nodeType = layout ;
685+ nodeType = layout . return ;
682686
683687 } else {
684688
685- console . error ( 'THREE.TSL: Invalid layout type.' ) ;
689+ if ( typeof layout === 'string' ) {
690+
691+ nodeType = layout ;
692+
693+ } else {
694+
695+ console . error ( 'THREE.TSL: Invalid layout type.' ) ;
696+
697+ }
698+
699+ layout = null ;
700+
701+ }
702+
703+ }
704+
705+ this . shaderNode = new ShaderNode ( jsFunc , nodeType ) ;
706+
707+ if ( layout !== null ) {
708+
709+ this . setLayout ( layout ) ;
710+
711+ }
712+
713+ this . isFn = true ;
714+
715+ }
716+
717+ setLayout ( layout ) {
718+
719+ const nodeType = this . shaderNode . nodeType ;
720+
721+ if ( typeof layout . inputs !== 'object' ) {
722+
723+ const fullLayout = {
724+ name : 'fn' + fnId ++ ,
725+ type : nodeType ,
726+ inputs : [ ]
727+ } ;
728+
729+ for ( const name in layout ) {
730+
731+ if ( name === 'return' ) continue ;
732+
733+ fullLayout . inputs . push ( {
734+ name : name ,
735+ type : layout [ name ]
736+ } ) ;
686737
687738 }
688739
689- layout = null ;
740+ layout = fullLayout ;
690741
691742 }
692743
744+ this . shaderNode . setLayout ( layout ) ;
745+
746+ return this ;
747+
693748 }
694749
695- const shaderNode = new ShaderNode ( jsFunc , nodeType ) ;
750+ getNodeType ( builder ) {
751+
752+ return this . shaderNode . getNodeType ( builder ) || 'float' ;
753+
754+ }
696755
697- const fn = ( ...params ) => {
756+ call ( ...params ) {
698757
699758 let inputs ;
700759
@@ -712,71 +771,62 @@ export const Fn = ( jsFunc, layout = null ) => {
712771
713772 }
714773
715- const fnCall = shaderNode . call ( inputs ) ;
774+ const fnCall = this . shaderNode . call ( inputs ) ;
716775
717- if ( nodeType === 'void' ) fnCall . toStack ( ) ;
776+ if ( this . shaderNode . nodeType === 'void' ) fnCall . toStack ( ) ;
718777
719778 return fnCall . toVarIntent ( ) ;
720779
721- } ;
780+ }
722781
723- fn . shaderNode = shaderNode ;
724- fn . id = shaderNode . id ;
782+ once ( subBuilds = null ) {
725783
726- fn . isFn = true ;
784+ this . shaderNode . once = true ;
785+ this . shaderNode . subBuilds = subBuilds ;
727786
728- fn . getNodeType = ( ...params ) => shaderNode . getNodeType ( ...params ) ;
729- fn . getCacheKey = ( ...params ) => shaderNode . getCacheKey ( ...params ) ;
787+ return this ;
730788
731- fn . setLayout = ( layout ) => {
789+ }
732790
733- shaderNode . setLayout ( layout ) ;
791+ generate ( builder ) {
734792
735- return fn ;
793+ const type = this . getNodeType ( builder ) ;
736794
737- } ;
795+ console . warn ( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' ) ;
738796
739- fn . once = ( subBuilds = null ) => {
797+ return builder . generateConst ( type ) ;
740798
741- shaderNode . once = true ;
742- shaderNode . subBuilds = subBuilds ;
799+ }
743800
744- return fn ;
801+ }
745802
746- } ;
803+ export function Fn ( jsFunc , layout = null ) {
747804
748- if ( layout !== null ) {
805+ const instance = new FnNode ( jsFunc , layout ) ;
749806
750- if ( typeof layout . inputs !== 'object' ) {
807+ return new Proxy ( ( ) => { } , {
751808
752- const fullLayout = {
753- name : 'fn' + fnId ++ ,
754- type : nodeType ,
755- inputs : [ ]
756- } ;
809+ apply ( target , thisArg , params ) {
757810
758- for ( const name in layout ) {
811+ return instance . call ( ... params ) ;
759812
760- if ( name === 'return' ) continue ;
813+ } ,
761814
762- fullLayout . inputs . push ( {
763- name : name ,
764- type : layout [ name ]
765- } ) ;
815+ get ( target , prop , receiver ) {
766816
767- }
817+ return Reflect . get ( instance , prop , receiver ) ;
768818
769- layout = fullLayout ;
819+ } ,
770820
771- }
821+ set ( target , prop , value , receiver ) {
772822
773- fn . setLayout ( layout ) ;
823+ return Reflect . set ( instance , prop , value , receiver ) ;
774824
775- }
825+ }
776826
777- return fn ;
827+ } ) ;
778828
779- } ;
829+ }
780830
781831//
782832
0 commit comments