Jelajahi Sumber

intro ExpressionNode instead of FunctionNode as expression

sunag 7 tahun lalu
induk
melakukan
9bace7816d

+ 1 - 0
examples/js/nodes/Nodes.js

@@ -10,6 +10,7 @@ export { VarNode } from './core/VarNode.js';
 export { StructNode } from './core/StructNode.js';
 export { StructNode } from './core/StructNode.js';
 export { AttributeNode } from './core/AttributeNode.js';
 export { AttributeNode } from './core/AttributeNode.js';
 export { FunctionNode } from './core/FunctionNode.js';
 export { FunctionNode } from './core/FunctionNode.js';
+export { ExpressionNode } from './core/ExpressionNode.js';
 export { FunctionCallNode } from './core/FunctionCallNode.js';
 export { FunctionCallNode } from './core/FunctionCallNode.js';
 export { NodeLib } from './core/NodeLib.js';
 export { NodeLib } from './core/NodeLib.js';
 export { NodeUtils } from './core/NodeUtils.js';
 export { NodeUtils } from './core/NodeUtils.js';

+ 2 - 0
examples/js/nodes/THREE.Nodes.js

@@ -10,6 +10,7 @@ import {
 	StructNode,
 	StructNode,
 	AttributeNode,
 	AttributeNode,
 	FunctionNode,
 	FunctionNode,
+	ExpressionNode,
 	FunctionCallNode,
 	FunctionCallNode,
 	NodeLib,
 	NodeLib,
 	NodeUtils,
 	NodeUtils,
@@ -113,6 +114,7 @@ THREE.VarNode = VarNode;
 THREE.StructNode = StructNode;
 THREE.StructNode = StructNode;
 THREE.AttributeNode = AttributeNode;
 THREE.AttributeNode = AttributeNode;
 THREE.FunctionNode = FunctionNode;
 THREE.FunctionNode = FunctionNode;
+THREE.ExpressionNode = ExpressionNode;
 THREE.FunctionCallNode = FunctionCallNode;
 THREE.FunctionCallNode = FunctionCallNode;
 THREE.NodeLib = NodeLib;
 THREE.NodeLib = NodeLib;
 THREE.NodeUtils = NodeUtils;
 THREE.NodeUtils = NodeUtils;

+ 3 - 3
examples/js/nodes/core/ConstNode.js

@@ -4,6 +4,8 @@
 
 
 import { TempNode } from './TempNode.js';
 import { TempNode } from './TempNode.js';
 
 
+var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i;
+
 function ConstNode( src, useDefine ) {
 function ConstNode( src, useDefine ) {
 
 
 	TempNode.call( this );
 	TempNode.call( this );
@@ -19,8 +21,6 @@ ConstNode.RECIPROCAL_PI2 = 'RECIPROCAL_PI2';
 ConstNode.LOG2 = 'LOG2';
 ConstNode.LOG2 = 'LOG2';
 ConstNode.EPSILON = 'EPSILON';
 ConstNode.EPSILON = 'EPSILON';
 
 
-ConstNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\=?\s?(.*?)(\;|$)/i;
-
 ConstNode.prototype = Object.create( TempNode.prototype );
 ConstNode.prototype = Object.create( TempNode.prototype );
 ConstNode.prototype.constructor = ConstNode;
 ConstNode.prototype.constructor = ConstNode;
 ConstNode.prototype.nodeType = "Const";
 ConstNode.prototype.nodeType = "Const";
@@ -37,7 +37,7 @@ ConstNode.prototype.eval = function ( src, useDefine ) {
 
 
 	var name, type, value = "";
 	var name, type, value = "";
 
 
-	var match = this.src.match( ConstNode.rDeclaration );
+	var match = this.src.match( declarationRegexp );
 
 
 	this.useDefine = useDefine || this.src.charAt(0) === '#';
 	this.useDefine = useDefine || this.src.charAt(0) === '#';
 
 

+ 17 - 0
examples/js/nodes/core/ExpressionNode.js

@@ -0,0 +1,17 @@
+/**
+ * @author sunag / http://www.sunag.com.br/
+ */
+
+import { FunctionNode } from './FunctionNode.js';
+
+function ExpressionNode( src, type, keywords, extensions, includes ) {
+
+	FunctionNode.call( this, src, includes, extensions, keywords, type  );
+	
+};
+
+ExpressionNode.prototype = Object.create( FunctionNode.prototype );
+ExpressionNode.prototype.constructor = ExpressionNode;
+ExpressionNode.prototype.nodeType = "Expression";
+
+export { ExpressionNode };

+ 19 - 20
examples/js/nodes/core/FunctionNode.js

@@ -6,32 +6,25 @@
 import { TempNode } from './TempNode.js';
 import { TempNode } from './TempNode.js';
 import { NodeLib } from './NodeLib.js';
 import { NodeLib } from './NodeLib.js';
 
 
-function FunctionNode( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions, includes ) {
+var declarationRegexp = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i,
+	propertiesRegexp = /[a-z_0-9]+/ig;
 
 
-	this.isMethod = typeof includesOrType !== "string";
-	this.useKeywords = true;
+function FunctionNode( src, includes, extensions, keywords, type ) {
 
 
-	TempNode.call( this, this.isMethod ? null : includesOrType );
+	this.isMethod = type === undefined;
 
 
-	if ( this.isMethod ) {
-		
-		this.eval( src, includesOrType, extensionsOrKeywords, keywordsOrExtensions );
-		
-	} else {
-		
-		this.eval( src, includes, keywordsOrExtensions, extensionsOrKeywords );
+	TempNode.call( this, type );
 
 
-	}
+	this.eval( src, includes, extensions, keywords );
 
 
 };
 };
 
 
-FunctionNode.rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s*\((.*?)\)/i;
-FunctionNode.rProperties = /[a-z_0-9]+/ig;
-
 FunctionNode.prototype = Object.create( TempNode.prototype );
 FunctionNode.prototype = Object.create( TempNode.prototype );
 FunctionNode.prototype.constructor = FunctionNode;
 FunctionNode.prototype.constructor = FunctionNode;
 FunctionNode.prototype.nodeType = "Function";
 FunctionNode.prototype.nodeType = "Function";
 
 
+FunctionNode.prototype.useKeywords = true;
+
 FunctionNode.prototype.isShared = function ( builder, output ) {
 FunctionNode.prototype.isShared = function ( builder, output ) {
 
 
 	return ! this.isMethod;
 	return ! this.isMethod;
@@ -50,8 +43,11 @@ FunctionNode.prototype.getInputByName = function ( name ) {
 
 
 	while ( i -- ) {
 	while ( i -- ) {
 
 
-		if ( this.inputs[ i ].name === name )
+		if ( this.inputs[ i ].name === name ) {
+			
 			return this.inputs[ i ];
 			return this.inputs[ i ];
+			
+		}
 
 
 	}
 	}
 
 
@@ -63,8 +59,11 @@ FunctionNode.prototype.getIncludeByName = function ( name ) {
 
 
 	while ( i -- ) {
 	while ( i -- ) {
 
 
-		if ( this.includes[ i ].name === name )
+		if ( this.includes[ i ].name === name ) {
+			
 			return this.includes[ i ];
 			return this.includes[ i ];
+			
+		}
 
 
 	}
 	}
 
 
@@ -86,7 +85,7 @@ FunctionNode.prototype.generate = function ( builder, output ) {
 
 
 	}
 	}
 
 
-	while ( match = FunctionNode.rProperties.exec( this.src ) ) {
+	while ( match = propertiesRegexp.exec( this.src ) ) {
 
 
 		var prop = match[ 0 ], 
 		var prop = match[ 0 ], 
 			isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true,
 			isGlobal = this.isMethod ? ! this.getInputByName( prop ) : true,
@@ -156,7 +155,7 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) {
 
 
 	if ( this.isMethod ) {
 	if ( this.isMethod ) {
 
 
-		var match = this.src.match( FunctionNode.rDeclaration );
+		var match = this.src.match( declarationRegexp );
 
 
 		this.inputs = [];
 		this.inputs = [];
 
 
@@ -165,7 +164,7 @@ FunctionNode.prototype.eval = function ( src, includes, extensions, keywords ) {
 			this.type = match[ 1 ];
 			this.type = match[ 1 ];
 			this.name = match[ 2 ];
 			this.name = match[ 2 ];
 
 
-			var inputs = match[ 3 ].match( FunctionNode.rProperties );
+			var inputs = match[ 3 ].match( propertiesRegexp );
 
 
 			if ( inputs ) {
 			if ( inputs ) {
 
 

+ 13 - 12
examples/js/nodes/core/StructNode.js

@@ -5,6 +5,9 @@
 import { TempNode } from './TempNode.js';
 import { TempNode } from './TempNode.js';
 import { FunctionNode } from './FunctionNode.js';
 import { FunctionNode } from './FunctionNode.js';
 
 
+var declarationRegexp = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img,
+	propertiesRegexp = /\s*(\w*?)\s*(\w*?)(\=|\;)/img;
+
 function StructNode( src ) {
 function StructNode( src ) {
 
 
 	TempNode.call( this);
 	TempNode.call( this);
@@ -13,9 +16,6 @@ function StructNode( src ) {
 
 
 };
 };
 
 
-StructNode.rDeclaration = /^struct\s*([a-z_0-9]+)\s*{\s*((.|\n)*?)}/img;
-StructNode.rProperties = /\s*(\w*?)\s*(\w*?)(\=|\;)/img;
-
 StructNode.prototype = Object.create( TempNode.prototype );
 StructNode.prototype = Object.create( TempNode.prototype );
 StructNode.prototype.constructor = StructNode;
 StructNode.prototype.constructor = StructNode;
 StructNode.prototype.nodeType = "Struct";
 StructNode.prototype.nodeType = "Struct";
@@ -32,8 +32,11 @@ StructNode.prototype.getInputByName = function ( name ) {
 
 
 	while ( i -- ) {
 	while ( i -- ) {
 
 
-		if ( this.inputs[ i ].name === name )
+		if ( this.inputs[ i ].name === name ) {
+			
 			return this.inputs[ i ];
 			return this.inputs[ i ];
+			
+		}
 
 
 	}
 	}
 
 
@@ -47,7 +50,7 @@ StructNode.prototype.generate = function ( builder, output ) {
 
 
 	} else {
 	} else {
 
 
-		return builder.format( "(" + src + ")", this.getType( builder ), output );
+		return builder.format( '( ' + src + ' )', this.getType( builder ), output );
 
 
 	}
 	}
 
 
@@ -59,19 +62,17 @@ StructNode.prototype.eval = function ( src ) {
 	
 	
 	this.inputs = [];
 	this.inputs = [];
 	
 	
-	var declaration = StructNode.rDeclaration.exec( this.src );
+	var declaration = declarationRegexp.exec( this.src );
 	
 	
 	if (declaration) {
 	if (declaration) {
 		
 		
-		var properties = declaration[2], matchType, matchName;
+		var properties = declaration[2], match;
 		
 		
-		while ( matchType = FunctionNode.rProperties.exec( properties ) ) {
-			
-			matchName = FunctionNode.rProperties.exec( properties )[0];
+		while ( match = propertiesRegexp.exec( properties ) ) {
 			
 			
 			this.inputs.push( {
 			this.inputs.push( {
-				name: matchName,
-				type: matchType
+				type: match[1],
+				name: match[2]
 			} );
 			} );
 			
 			
 		}
 		}

+ 3 - 0
examples/js/nodes/utils/TimerNode.js

@@ -26,6 +26,8 @@ TimerNode.prototype.nodeType = "Timer";
 
 
 TimerNode.prototype.isReadonly = function () {
 TimerNode.prototype.isReadonly = function () {
 
 
+	// never use TimerNode as readonly but aways as "uniform"
+	
 	return false;
 	return false;
 
 
 };
 };
@@ -33,6 +35,7 @@ TimerNode.prototype.isReadonly = function () {
 TimerNode.prototype.isUnique = function () {
 TimerNode.prototype.isUnique = function () {
 
 
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
 	// share TimerNode "uniform" input if is used on more time with others TimerNode
+
 	return this.timeScale && ( this.scope === TimerNode.GLOBAL || this.scope === TimerNode.DELTA );
 	return this.timeScale && ( this.scope === TimerNode.GLOBAL || this.scope === TimerNode.DELTA );
 
 
 };
 };

+ 5 - 5
examples/js/nodes/utils/UVTransformNode.js

@@ -2,20 +2,20 @@
  * @author sunag / http://www.sunag.com.br/
  * @author sunag / http://www.sunag.com.br/
  */
  */
 
 
-import { FunctionNode } from '../core/FunctionNode.js';
+import { ExpressionNode } from '../core/ExpressionNode.js';
 import { Matrix3Node } from '../inputs/Matrix3Node.js';
 import { Matrix3Node } from '../inputs/Matrix3Node.js';
 import { UVNode } from '../accessors/UVNode.js';
 import { UVNode } from '../accessors/UVNode.js';
  
  
 function UVTransformNode( uv, transform ) {
 function UVTransformNode( uv, transform ) {
 
 
-	FunctionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" );
+	ExpressionNode.call( this, "( uvTransform * vec3( uvNode, 1 ) ).xy", "vec2" );
 
 
 	this.uv = uv || new UVNode();
 	this.uv = uv || new UVNode();
 	this.transform = transform || new Matrix3Node();
 	this.transform = transform || new Matrix3Node();
 
 
 };
 };
 
 
-UVTransformNode.prototype = Object.create( FunctionNode.prototype );
+UVTransformNode.prototype = Object.create( ExpressionNode.prototype );
 UVTransformNode.prototype.constructor = UVTransformNode;
 UVTransformNode.prototype.constructor = UVTransformNode;
 UVTransformNode.prototype.nodeType = "UVTransform";
 UVTransformNode.prototype.nodeType = "UVTransform";
 
 
@@ -24,7 +24,7 @@ UVTransformNode.prototype.generate = function ( builder, output ) {
 	this.keywords[ "uvNode" ] = this.uv;
 	this.keywords[ "uvNode" ] = this.uv;
 	this.keywords[ "uvTransform" ] = this.transform;
 	this.keywords[ "uvTransform" ] = this.transform;
 
 
-	return FunctionNode.prototype.generate.call( this, builder, output );
+	return ExpressionNode.prototype.generate.call( this, builder, output );
 
 
 };
 };
 
 
@@ -39,7 +39,7 @@ UVTransformNode.prototype.setUvTransform = function ( tx, ty, sx, sy, rotation,
 
 
 UVTransformNode.prototype.copy = function ( source ) {
 UVTransformNode.prototype.copy = function ( source ) {
 			
 			
-	FunctionNode.prototype.copy.call( this, source );
+	ExpressionNode.prototype.copy.call( this, source );
 	
 	
 	this.uv = source.uv;
 	this.uv = source.uv;
 	this.transform = source.transform;
 	this.transform = source.transform;

+ 2 - 2
examples/webgl_materials_compile.html

@@ -207,10 +207,10 @@
 			mtl.emissive = cos;
 			mtl.emissive = cos;
 			
 			
 			
 			
-			var transformer = new THREE.FunctionNode( "position + 0.0 * " + Math.random(), "vec3", [ ]);
+			var transformer = new THREE.ExpressionNode( "position + 0.0 * " + Math.random(), "vec3", [ ]);
 			mtl.transform = transformer;
 			mtl.transform = transformer;
 
 
-			// build shader
+			// build shader ( ignore auto build )
 			mtl.build();
 			mtl.build();
 
 
 			// set material
 			// set material

+ 5 - 5
examples/webgl_materials_nodes.html

@@ -1942,10 +1942,10 @@
 
 
 					var speed = new THREE.FloatNode( .5 );
 					var speed = new THREE.FloatNode( .5 );
 
 
-					mtl.color = new THREE.FunctionNode( "myCustomUv + (sin(time*speed)*.5) + (position * .05)", "vec3" );
+					mtl.color = new THREE.ExpressionNode( "myCustomUv + (sin(time*speed)*.5) + (position * .05)", "vec3" );
 					mtl.color.keywords[ "speed" ] = speed;
 					mtl.color.keywords[ "speed" ] = speed;
 
 
-					mtl.transform = new THREE.FunctionNode( "mod(time*speed,1.0) < 0.5 ? position + (worldNormal*(1.0+sin(time*speed*1.0))*3.0) : position + sin( position.x * sin(time*speed*2.0))", "vec3" );
+					mtl.transform = new THREE.ExpressionNode( "mod(time*speed,1.0) < 0.5 ? position + (worldNormal*(1.0+sin(time*speed*1.0))*3.0) : position + sin( position.x * sin(time*speed*2.0))", "vec3" );
 					mtl.transform.keywords[ "speed" ] = speed;
 					mtl.transform.keywords[ "speed" ] = speed;
 
 
 					// add global keyword ( variable or const )
 					// add global keyword ( variable or const )
@@ -2018,8 +2018,8 @@
 					mtl.color = varying;
 					mtl.color = varying;
 					
 					
 					// you can also set a independent value in .transform slot using BypassNode
 					// you can also set a independent value in .transform slot using BypassNode
-					// such this expression using FunctionNode
-					mtl.transform.value = new THREE.FunctionNode("position * ( .1 + abs( sin( time ) ) )", "vec3");
+					// such this expression using ExpressionNode
+					mtl.transform.value = new THREE.ExpressionNode("position * ( .1 + abs( sin( time ) ) )", "vec3");
 
 
 					break;
 					break;
 					
 					
@@ -2045,7 +2045,7 @@
 					// add keyword
 					// add keyword
 					setMyVar.keywords[ "myVar" ] = varying;
 					setMyVar.keywords[ "myVar" ] = varying;
 
 
-					var transform = new THREE.FunctionNode( "setMyVar( position * .1 )", "vec3" );
+					var transform = new THREE.ExpressionNode( "setMyVar( position * .1 )", "vec3" );
 					transform.includes = [ setMyVar ];
 					transform.includes = [ setMyVar ];
 					transform.keywords[ "tex" ] = new THREE.TextureNode( getTexture( "brick" ) );
 					transform.keywords[ "tex" ] = new THREE.TextureNode( getTexture( "brick" ) );
 
 

+ 1 - 1
examples/webgl_mirror_nodes.html

@@ -138,7 +138,7 @@
 
 
 			var blurMirror = new THREE.BlurNode( mirror );
 			var blurMirror = new THREE.BlurNode( mirror );
 			blurMirror.size = new THREE.Vector2( WIDTH, HEIGHT );
 			blurMirror.size = new THREE.Vector2( WIDTH, HEIGHT );
-			blurMirror.uv = new THREE.FunctionNode( "projCoord.xyz / projCoord.q", "vec3" );
+			blurMirror.uv = new THREE.ExpressionNode( "projCoord.xyz / projCoord.q", "vec3" );
 			blurMirror.uv.keywords[ "projCoord" ] = new THREE.OperatorNode( mirror.offset, mirror.uv, THREE.OperatorNode.ADD );
 			blurMirror.uv.keywords[ "projCoord" ] = new THREE.OperatorNode( mirror.offset, mirror.uv, THREE.OperatorNode.ADD );
 			blurMirror.radius.x = blurMirror.radius.y = 0;
 			blurMirror.radius.x = blurMirror.radius.y = 0;