|
@@ -2,6 +2,16 @@ import { WebGLCoordinateSystem } from '../../constants.js';
|
|
|
import TempNode from '../core/TempNode.js';
|
|
import TempNode from '../core/TempNode.js';
|
|
|
import { addMethodChaining, Fn, int, nodeProxy } from '../tsl/TSLCore.js';
|
|
import { addMethodChaining, Fn, int, nodeProxy } from '../tsl/TSLCore.js';
|
|
|
|
|
|
|
|
|
|
+const _vectorOperators = {
|
|
|
|
|
+ '==': 'equal',
|
|
|
|
|
+ '!=': 'notEqual',
|
|
|
|
|
+ '<': 'lessThan',
|
|
|
|
|
+ '>': 'greaterThan',
|
|
|
|
|
+ '<=': 'lessThanEqual',
|
|
|
|
|
+ '>=': 'greaterThanEqual',
|
|
|
|
|
+ '%': 'mod'
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* This node represents basic mathematical and logical operations like addition,
|
|
* This node represents basic mathematical and logical operations like addition,
|
|
|
* subtraction or comparisons (e.g. `equal()`).
|
|
* subtraction or comparisons (e.g. `equal()`).
|
|
@@ -75,15 +85,27 @@ class OperatorNode extends TempNode {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Returns the operator method name.
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param {NodeBuilder} builder - The current node builder.
|
|
|
|
|
+ * @param {string} output - The output type.
|
|
|
|
|
+ * @returns {string} The operator method name.
|
|
|
|
|
+ */
|
|
|
|
|
+ getOperatorMethod( builder, output ) {
|
|
|
|
|
+
|
|
|
|
|
+ return builder.getMethod( _vectorOperators[ this.op ], output );
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* This method is overwritten since the node type is inferred from the operator
|
|
* This method is overwritten since the node type is inferred from the operator
|
|
|
* and the input node types.
|
|
* and the input node types.
|
|
|
*
|
|
*
|
|
|
* @param {NodeBuilder} builder - The current node builder.
|
|
* @param {NodeBuilder} builder - The current node builder.
|
|
|
- * @param {string} output - The current output string.
|
|
|
|
|
* @return {string} The node type.
|
|
* @return {string} The node type.
|
|
|
*/
|
|
*/
|
|
|
- getNodeType( builder, output ) {
|
|
|
|
|
|
|
+ getNodeType( builder ) {
|
|
|
|
|
|
|
|
const op = this.op;
|
|
const op = this.op;
|
|
|
|
|
|
|
@@ -105,13 +127,13 @@ class OperatorNode extends TempNode {
|
|
|
|
|
|
|
|
return builder.getIntegerType( typeA );
|
|
return builder.getIntegerType( typeA );
|
|
|
|
|
|
|
|
- } else if ( op === '!' || op === '==' || op === '!=' || op === '&&' || op === '||' || op === '^^' ) {
|
|
|
|
|
|
|
+ } else if ( op === '!' || op === '&&' || op === '||' || op === '^^' ) {
|
|
|
|
|
|
|
|
return 'bool';
|
|
return 'bool';
|
|
|
|
|
|
|
|
- } else if ( op === '<' || op === '>' || op === '<=' || op === '>=' ) {
|
|
|
|
|
|
|
+ } else if ( op === '==' || op === '!=' || op === '<' || op === '>' || op === '<=' || op === '>=' ) {
|
|
|
|
|
|
|
|
- const typeLength = output ? builder.getTypeLength( output ) : Math.max( builder.getTypeLength( typeA ), builder.getTypeLength( typeB ) );
|
|
|
|
|
|
|
+ const typeLength = Math.max( builder.getTypeLength( typeA ), builder.getTypeLength( typeB ) );
|
|
|
|
|
|
|
|
return typeLength > 1 ? `bvec${ typeLength }` : 'bool';
|
|
return typeLength > 1 ? `bvec${ typeLength }` : 'bool';
|
|
|
|
|
|
|
@@ -172,7 +194,7 @@ class OperatorNode extends TempNode {
|
|
|
const aNode = this.aNode;
|
|
const aNode = this.aNode;
|
|
|
const bNode = this.bNode;
|
|
const bNode = this.bNode;
|
|
|
|
|
|
|
|
- const type = this.getNodeType( builder, output );
|
|
|
|
|
|
|
+ const type = this.getNodeType( builder );
|
|
|
|
|
|
|
|
let typeA = null;
|
|
let typeA = null;
|
|
|
let typeB = null;
|
|
let typeB = null;
|
|
@@ -188,6 +210,10 @@ class OperatorNode extends TempNode {
|
|
|
|
|
|
|
|
typeB = typeA;
|
|
typeB = typeA;
|
|
|
|
|
|
|
|
|
|
+ } else if ( builder.isVector( typeB ) ) {
|
|
|
|
|
+
|
|
|
|
|
+ typeA = typeB;
|
|
|
|
|
+
|
|
|
} else if ( typeA !== typeB ) {
|
|
} else if ( typeA !== typeB ) {
|
|
|
|
|
|
|
|
typeA = typeB = 'float';
|
|
typeA = typeB = 'float';
|
|
@@ -264,20 +290,19 @@ class OperatorNode extends TempNode {
|
|
|
const a = aNode.build( builder, typeA );
|
|
const a = aNode.build( builder, typeA );
|
|
|
const b = typeof bNode !== 'undefined' ? bNode.build( builder, typeB ) : null;
|
|
const b = typeof bNode !== 'undefined' ? bNode.build( builder, typeB ) : null;
|
|
|
|
|
|
|
|
- const outputLength = builder.getTypeLength( output );
|
|
|
|
|
const fnOpSnippet = builder.getFunctionOperator( op );
|
|
const fnOpSnippet = builder.getFunctionOperator( op );
|
|
|
|
|
|
|
|
if ( output !== 'void' ) {
|
|
if ( output !== 'void' ) {
|
|
|
|
|
|
|
|
const isGLSL = builder.renderer.coordinateSystem === WebGLCoordinateSystem;
|
|
const isGLSL = builder.renderer.coordinateSystem === WebGLCoordinateSystem;
|
|
|
|
|
|
|
|
- if ( op === '==' ) {
|
|
|
|
|
|
|
+ if ( op === '==' || op === '!=' || op === '<' || op === '>' || op === '<=' || op === '>=' ) {
|
|
|
|
|
|
|
|
if ( isGLSL ) {
|
|
if ( isGLSL ) {
|
|
|
|
|
|
|
|
- if ( outputLength > 1 ) {
|
|
|
|
|
|
|
+ if ( builder.isVector( typeA ) ) {
|
|
|
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'equal', output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
|
|
+ return builder.format( `${ this.getOperatorMethod( builder, output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
|
@@ -289,71 +314,7 @@ class OperatorNode extends TempNode {
|
|
|
|
|
|
|
|
// WGSL
|
|
// WGSL
|
|
|
|
|
|
|
|
- if ( outputLength > 1 || ! builder.isVector( typeA ) ) {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `( ${ a } == ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- } else {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `all( ${ a } == ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- } else if ( op === '<' && outputLength > 1 ) {
|
|
|
|
|
-
|
|
|
|
|
- if ( isGLSL ) {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'lessThan', output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- } else {
|
|
|
|
|
-
|
|
|
|
|
- // WGSL
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `( ${ a } < ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- } else if ( op === '<=' && outputLength > 1 ) {
|
|
|
|
|
-
|
|
|
|
|
- if ( isGLSL ) {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'lessThanEqual', output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- } else {
|
|
|
|
|
-
|
|
|
|
|
- // WGSL
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `( ${ a } <= ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- } else if ( op === '>' && outputLength > 1 ) {
|
|
|
|
|
-
|
|
|
|
|
- if ( isGLSL ) {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'greaterThan', output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- } else {
|
|
|
|
|
-
|
|
|
|
|
- // WGSL
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `( ${ a } > ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- } else if ( op === '>=' && outputLength > 1 ) {
|
|
|
|
|
-
|
|
|
|
|
- if ( isGLSL ) {
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'greaterThanEqual', output ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
-
|
|
|
|
|
- } else {
|
|
|
|
|
-
|
|
|
|
|
- // WGSL
|
|
|
|
|
-
|
|
|
|
|
- return builder.format( `( ${ a } >= ${ b } )`, type, output );
|
|
|
|
|
|
|
+ return builder.format( `( ${ a } ${ op } ${ b } )`, type, output );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -365,7 +326,7 @@ class OperatorNode extends TempNode {
|
|
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
|
|
- return builder.format( `${ builder.getMethod( 'mod', type ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
|
|
+ return builder.format( `${ this.getOperatorMethod( builder, type ) }( ${ a }, ${ b } )`, type, output );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|