Archived
Private
Public Access
1
0

Initial commit

This commit is contained in:
2022-09-04 12:45:01 +02:00
commit f4a01d6a69
11601 changed files with 4206660 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
import Node from '../core/Node.js';
import PropertyNode from '../core/PropertyNode.js';
import ContextNode from '../core/ContextNode.js';
class CondNode extends Node {
constructor( node, ifNode, elseNode ) {
super();
this.node = node;
this.ifNode = ifNode;
this.elseNode = elseNode;
}
getNodeType( builder ) {
const ifType = this.ifNode.getNodeType( builder );
const elseType = this.elseNode.getNodeType( builder );
if ( builder.getTypeLength( elseType ) > builder.getTypeLength( ifType ) ) {
return elseType;
}
return ifType;
}
generate( builder ) {
const type = this.getNodeType( builder );
const context = { temp: false };
const nodeProperty = new PropertyNode( null, type ).build( builder );
const nodeSnippet = new ContextNode( this.node/*, context*/ ).build( builder, 'bool' ),
ifSnippet = new ContextNode( this.ifNode, context ).build( builder, type ),
elseSnippet = new ContextNode( this.elseNode, context ).build( builder, type );
builder.addFlowCode( `if ( ${nodeSnippet} ) {
\t\t${nodeProperty} = ${ifSnippet};
\t} else {
\t\t${nodeProperty} = ${elseSnippet};
\t}` );
return nodeProperty;
}
}
export default CondNode;

View File

@@ -0,0 +1,258 @@
import TempNode from '../core/TempNode.js';
import ExpressionNode from '../core/ExpressionNode.js';
import JoinNode from '../utils/JoinNode.js';
import SplitNode from '../utils/SplitNode.js';
import OperatorNode from './OperatorNode.js';
class MathNode extends TempNode {
// 1 input
static RAD = 'radians';
static DEG = 'degrees';
static EXP = 'exp';
static EXP2 = 'exp2';
static LOG = 'log';
static LOG2 = 'log2';
static SQRT = 'sqrt';
static INV_SQRT = 'inversesqrt';
static FLOOR = 'floor';
static CEIL = 'ceil';
static NORMALIZE = 'normalize';
static FRACT = 'fract';
static SIN = 'sin';
static COS = 'cos';
static TAN = 'tan';
static ASIN = 'asin';
static ACOS = 'acos';
static ATAN = 'atan';
static ABS = 'abs';
static SIGN = 'sign';
static LENGTH = 'length';
static NEGATE = 'negate';
static INVERT = 'invert';
static DFDX = 'dFdx';
static DFDY = 'dFdy';
static SATURATE = 'saturate';
static ROUND = 'round';
// 2 inputs
static MIN = 'min';
static MAX = 'max';
static MOD = 'mod';
static STEP = 'step';
static REFLECT = 'reflect';
static DISTANCE = 'distance';
static DOT = 'dot';
static CROSS = 'cross';
static POW = 'pow';
static TRANSFORM_DIRECTION = 'transformDirection';
// 3 inputs
static MIX = 'mix';
static CLAMP = 'clamp';
static REFRACT = 'refract';
static SMOOTHSTEP = 'smoothstep';
static FACEFORWARD = 'faceforward';
constructor( method, aNode, bNode = null, cNode = null ) {
super();
this.method = method;
this.aNode = aNode;
this.bNode = bNode;
this.cNode = cNode;
}
getInputType( builder ) {
const aType = this.aNode.getNodeType( builder );
const bType = this.bNode ? this.bNode.getNodeType( builder ) : null;
const cType = this.cNode ? this.cNode.getNodeType( builder ) : null;
const aLen = builder.getTypeLength( aType );
const bLen = builder.getTypeLength( bType );
const cLen = builder.getTypeLength( cType );
if ( aLen > bLen && aLen > cLen ) {
return aType;
} else if ( bLen > cLen ) {
return bType;
} else if ( cLen > aLen ) {
return cType;
}
return aType;
}
getNodeType( builder ) {
const method = this.method;
if ( method === MathNode.LENGTH || method === MathNode.DISTANCE || method === MathNode.DOT ) {
return 'float';
} else if ( method === MathNode.CROSS ) {
return 'vec3';
} else {
return this.getInputType( builder );
}
}
generate( builder, output ) {
const method = this.method;
const type = this.getNodeType( builder );
const inputType = this.getInputType( builder );
const a = this.aNode;
const b = this.bNode;
const c = this.cNode;
const isWebGL = builder.renderer.isWebGLRenderer === true;
if ( isWebGL && ( method === MathNode.DFDX || method === MathNode.DFDY ) && output === 'vec3' ) {
// Workaround for Adreno 3XX dFd*( vec3 ) bug. See #9988
return new JoinNode( [
new MathNode( method, new SplitNode( a, 'x' ) ),
new MathNode( method, new SplitNode( a, 'y' ) ),
new MathNode( method, new SplitNode( a, 'z' ) )
] ).build( builder );
} else if ( method === MathNode.TRANSFORM_DIRECTION ) {
// dir can be either a direction vector or a normal vector
// upper-left 3x3 of matrix is assumed to be orthogonal
let tA = a;
let tB = b;
if ( builder.isMatrix( tA.getNodeType( builder ) ) ) {
tB = new ExpressionNode( `${ builder.getType( 'vec4' ) }( ${ tB.build( builder, 'vec3' ) }, 0.0 )`, 'vec4' );
} else {
tA = new ExpressionNode( `${ builder.getType( 'vec4' ) }( ${ tA.build( builder, 'vec3' ) }, 0.0 )`, 'vec4' );
}
const mulNode = new SplitNode( new OperatorNode( '*', tA, tB ), 'xyz' );
return new MathNode( MathNode.NORMALIZE, mulNode ).build( builder );
} else if ( method === MathNode.SATURATE ) {
return builder.format( `clamp( ${ a.build( builder, inputType ) }, 0.0, 1.0 )`, type, output );
} else if ( method === MathNode.NEGATE ) {
return builder.format( '( -' + a.build( builder, inputType ) + ' )', type, output );
} else if ( method === MathNode.INVERT ) {
return builder.format( '( 1.0 - ' + a.build( builder, inputType ) + ' )', type, output );
} else {
const params = [];
if ( method === MathNode.CROSS ) {
params.push(
a.build( builder, type ),
b.build( builder, type )
);
} else if ( method === MathNode.STEP ) {
params.push(
a.build( builder, builder.getTypeLength( a.getNodeType( builder ) ) === 1 ? 'float' : inputType ),
b.build( builder, inputType )
);
} else if ( ( isWebGL && ( method === MathNode.MIN || method === MathNode.MAX ) ) || method === MathNode.MOD ) {
params.push(
a.build( builder, inputType ),
b.build( builder, builder.getTypeLength( b.getNodeType( builder ) ) === 1 ? 'float' : inputType )
);
} else if ( method === MathNode.REFRACT ) {
params.push(
a.build( builder, inputType ),
b.build( builder, inputType ),
c.build( builder, 'float' )
);
} else if ( method === MathNode.MIX ) {
params.push(
a.build( builder, inputType ),
b.build( builder, inputType ),
c.build( builder, builder.getTypeLength( c.getNodeType( builder ) ) === 1 ? 'float' : inputType )
);
} else {
params.push( a.build( builder, inputType ) );
if ( c !== null ) {
params.push( b.build( builder, inputType ), c.build( builder, inputType ) );
} else if ( b !== null ) {
params.push( b.build( builder, inputType ) );
}
}
return builder.format( `${ builder.getMethod( method ) }( ${params.join( ', ' )} )`, type, output );
}
}
serialize( data ) {
super.serialize( data );
data.method = this.method;
}
deserialize( data ) {
super.deserialize( data );
this.method = data.method;
}
}
export default MathNode;

View File

@@ -0,0 +1,194 @@
import TempNode from '../core/TempNode.js';
class OperatorNode extends TempNode {
constructor( op, aNode, bNode, ...params ) {
super();
this.op = op;
if ( params.length > 0 ) {
let finalBNode = bNode;
for ( let i = 0; i < params.length; i ++ ) {
finalBNode = new OperatorNode( op, finalBNode, params[ i ] );
}
bNode = finalBNode;
}
this.aNode = aNode;
this.bNode = bNode;
}
getNodeType( builder, output ) {
const op = this.op;
const aNode = this.aNode;
const bNode = this.bNode;
const typeA = aNode.getNodeType( builder );
const typeB = bNode.getNodeType( builder );
if ( typeA === 'void' || typeB === 'void' ) {
return 'void';
} else if ( op === '=' || op === '%' ) {
return typeA;
} else if ( op === '&' || op === '|' || op === '^' || op === '>>' || op === '<<' ) {
return 'int';
} else if ( op === '==' || op === '&&' || op === '||' || op === '^^' ) {
return 'bool';
} else if ( op === '<=' || op === '>=' || op === '<' || op === '>' ) {
const length = builder.getTypeLength( output );
return length > 1 ? `bvec${ length }` : 'bool';
} else {
if ( typeA === 'float' && builder.isMatrix( typeB ) ) {
return typeB;
} else if ( builder.isMatrix( typeA ) && builder.isVector( typeB ) ) {
// matrix x vector
return builder.getVectorFromMatrix( typeA );
} else if ( builder.isVector( typeA ) && builder.isMatrix( typeB ) ) {
// vector x matrix
return builder.getVectorFromMatrix( typeB );
} else if ( builder.getTypeLength( typeB ) > builder.getTypeLength( typeA ) ) {
// anytype x anytype: use the greater length vector
return typeB;
}
return typeA;
}
}
generate( builder, output ) {
const op = this.op;
const aNode = this.aNode;
const bNode = this.bNode;
const type = this.getNodeType( builder, output );
let typeA = null;
let typeB = null;
if ( type !== 'void' ) {
typeA = aNode.getNodeType( builder );
typeB = bNode.getNodeType( builder );
if ( op === '=' ) {
typeB = typeA;
} else if ( builder.isMatrix( typeA ) && builder.isVector( typeB ) ) {
// matrix x vector
typeB = builder.getVectorFromMatrix( typeA );
} else if ( builder.isVector( typeA ) && builder.isMatrix( typeB ) ) {
// vector x matrix
typeA = builder.getVectorFromMatrix( typeB );
} else {
// anytype x anytype
typeA = typeB = type;
}
} else {
typeA = typeB = type;
}
const a = aNode.build( builder, typeA );
const b = bNode.build( builder, typeB );
const outputLength = builder.getTypeLength( output );
if ( output !== 'void' ) {
if ( op === '=' ) {
builder.addFlowCode( `${a} ${this.op} ${b}` );
return a;
} else if ( op === '>' && outputLength > 1 ) {
return builder.format( `${ builder.getMethod( 'greaterThan' ) }( ${a}, ${b} )`, type, output );
} else if ( op === '<=' && outputLength > 1 ) {
return builder.format( `${ builder.getMethod( 'lessThanEqual' ) }( ${a}, ${b} )`, type, output );
} else {
return builder.format( `( ${a} ${this.op} ${b} )`, type, output );
}
} else if ( typeA !== 'void' ) {
return builder.format( `${a} ${this.op} ${b}`, type, output );
}
}
serialize( data ) {
super.serialize( data );
data.op = this.op;
}
deserialize( data ) {
super.deserialize( data );
this.op = data.op;
}
}
export default OperatorNode;