three
Version:
JavaScript 3D library
160 lines (94 loc) • 3.31 kB
JavaScript
/**
* @author sunag / http://www.sunag.com.br/
* @thanks bhouston / https://clara.io/
*/
THREE.FunctionNode = function( src, includes, extensions ) {
THREE.GLNode.call( this );
this.parse( src || '', includes, extensions );
};
THREE.FunctionNode.prototype = Object.create( THREE.GLNode.prototype );
THREE.FunctionNode.prototype.constructor = THREE.FunctionNode;
THREE.FunctionNode.prototype.parseReference = function( name ) {
switch ( name ) {
case 'uv': return new THREE.UVNode().name;
case 'uv2': return new THREE.UVNode( 1 ).name;
case 'position': return new THREE.PositionNode().name;
case 'worldPosition': return new THREE.PositionNode( THREE.PositionNode.WORLD ).name;
case 'normal': return new THREE.NormalNode().name;
case 'normalPosition': return new THREE.NormalNode( THREE.NormalNode.WORLD ).name;
case 'viewPosition': return new THREE.PositionNode( THREE.NormalNode.VIEW ).name;
case 'viewNormal': return new THREE.NormalNode( THREE.NormalNode.VIEW ).name;
}
return name;
};
THREE.FunctionNode.prototype.getTypeNode = function( builder, type ) {
return builder.getTypeByFormat( type ) || type;
};
THREE.FunctionNode.prototype.getInputByName = function( name ) {
var i = this.inputs.length;
while ( i -- ) {
if ( this.inputs[ i ].name === name )
return this.inputs[ i ];
}
};
THREE.FunctionNode.prototype.getType = function( builder ) {
return this.getTypeNode( builder, this.type );
};
THREE.FunctionNode.prototype.getInclude = function( name ) {
var i = this.includes.length;
while ( i -- ) {
if ( this.includes[ i ].name === name )
return this.includes[ i ];
}
return undefined;
};
THREE.FunctionNode.prototype.parse = function( src, includes, extensions ) {
var rDeclaration = /^([a-z_0-9]+)\s([a-z_0-9]+)\s?\((.*?)\)/i;
var rProperties = /[a-z_0-9]+/ig;
this.includes = includes || [];
this.extensions = extensions || {};
var match = src.match( rDeclaration );
this.inputs = [];
if ( match && match.length == 4 ) {
this.type = match[ 1 ];
this.name = match[ 2 ];
var inputs = match[ 3 ].match( rProperties );
if ( inputs ) {
var i = 0;
while ( i < inputs.length ) {
var qualifier = inputs[ i ++ ];
var type, name;
if ( qualifier == 'in' || qualifier == 'out' || qualifier == 'inout' ) {
type = inputs[ i ++ ];
}
else {
type = qualifier;
qualifier = '';
}
name = inputs[ i ++ ];
this.inputs.push( {
name : name,
type : type,
qualifier : qualifier
} );
}
}
var match, offset = 0;
while ( match = rProperties.exec( src ) ) {
var prop = match[ 0 ];
var reference = this.parseReference( prop );
if ( prop != reference ) {
src = src.substring( 0, match.index + offset ) + reference + src.substring( match.index + prop.length + offset );
offset += reference.length - prop.length;
}
if ( this.getInclude( reference ) === undefined && THREE.NodeLib.contains( reference ) ) {
this.includes.push( THREE.NodeLib.get( reference ) );
}
}
this.src = src;
}
else {
this.type = '';
this.name = '';
}
};