Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/flo-bit/shapecraft. flo-bit.dev/shapecraft
Something went wrong. Try again.
7.9 kB · 319 lines
JavaScript
at commit da69385e
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320import TempNode from '../core/TempNode.js';import { addMethodChaining, nodeProxy } from '../tsl/TSLCore.js';
class OperatorNode extends TempNode {
static get type() {
return 'OperatorNode';
}
constructor( op, aNode, bNode, ...params ) {
super();
if ( params.length > 0 ) {
let finalOp = new OperatorNode( op, aNode, bNode );
for ( let i = 0; i < params.length - 1; i ++ ) {
finalOp = new OperatorNode( op, finalOp, params[ i ] );
}
aNode = finalOp; bNode = params[ params.length - 1 ];
}
this.op = op; 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 = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
if ( typeA === 'void' || typeB === 'void' ) {
return 'void';
} else if ( op === '%' ) {
return typeA;
} else if ( op === '~' || op === '&' || op === '|' || op === '^' || op === '>>' || op === '<<' ) {
return builder.getIntegerType( typeA );
} else if ( op === '!' || op === '==' || op === '&&' || op === '||' || op === '^^' ) {
return 'bool';
} else if ( op === '<' || op === '>' || op === '<=' || op === '>=' ) {
const typeLength = output ? builder.getTypeLength( output ) : Math.max( builder.getTypeLength( typeA ), builder.getTypeLength( typeB ) );
return typeLength > 1 ? `bvec${ typeLength }` : '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 = typeof bNode !== 'undefined' ? bNode.getNodeType( builder ) : null;
if ( op === '<' || op === '>' || op === '<=' || op === '>=' || op === '==' ) {
if ( builder.isVector( typeA ) ) {
typeB = typeA;
} else if ( typeA !== typeB ) {
typeA = typeB = 'float';
}
} else if ( op === '>>' || op === '<<' ) {
typeA = type; typeB = builder.changeComponentType( typeB, 'uint' );
} 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 = typeof bNode !== 'undefined' ? bNode.build( builder, typeB ) : null;
const outputLength = builder.getTypeLength( output ); const fnOpSnippet = builder.getFunctionOperator( op );
if ( output !== 'void' ) {
if ( op === '<' && outputLength > 1 ) {
if ( builder.useComparisonMethod ) {
return builder.format( `${ builder.getMethod( 'lessThan', output ) }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `( ${ a } < ${ b } )`, type, output );
}
} else if ( op === '<=' && outputLength > 1 ) {
if ( builder.useComparisonMethod ) {
return builder.format( `${ builder.getMethod( 'lessThanEqual', output ) }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `( ${ a } <= ${ b } )`, type, output );
}
} else if ( op === '>' && outputLength > 1 ) {
if ( builder.useComparisonMethod ) {
return builder.format( `${ builder.getMethod( 'greaterThan', output ) }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `( ${ a } > ${ b } )`, type, output );
}
} else if ( op === '>=' && outputLength > 1 ) {
if ( builder.useComparisonMethod ) {
return builder.format( `${ builder.getMethod( 'greaterThanEqual', output ) }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `( ${ a } >= ${ b } )`, type, output );
}
} else if ( op === '!' || op === '~' ) {
return builder.format( `(${op}${a})`, typeA, output );
} else if ( fnOpSnippet ) {
return builder.format( `${ fnOpSnippet }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `( ${ a } ${ op } ${ b } )`, type, output );
}
} else if ( typeA !== 'void' ) {
if ( fnOpSnippet ) {
return builder.format( `${ fnOpSnippet }( ${ a }, ${ b } )`, type, output );
} else {
return builder.format( `${ a } ${ 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;
export const add = /*@__PURE__*/ nodeProxy( OperatorNode, '+' );export const sub = /*@__PURE__*/ nodeProxy( OperatorNode, '-' );export const mul = /*@__PURE__*/ nodeProxy( OperatorNode, '*' );export const div = /*@__PURE__*/ nodeProxy( OperatorNode, '/' );export const modInt = /*@__PURE__*/ nodeProxy( OperatorNode, '%' );export const equal = /*@__PURE__*/ nodeProxy( OperatorNode, '==' );export const notEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '!=' );export const lessThan = /*@__PURE__*/ nodeProxy( OperatorNode, '<' );export const greaterThan = /*@__PURE__*/ nodeProxy( OperatorNode, '>' );export const lessThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '<=' );export const greaterThanEqual = /*@__PURE__*/ nodeProxy( OperatorNode, '>=' );export const and = /*@__PURE__*/ nodeProxy( OperatorNode, '&&' );export const or = /*@__PURE__*/ nodeProxy( OperatorNode, '||' );export const not = /*@__PURE__*/ nodeProxy( OperatorNode, '!' );export const xor = /*@__PURE__*/ nodeProxy( OperatorNode, '^^' );export const bitAnd = /*@__PURE__*/ nodeProxy( OperatorNode, '&' );export const bitNot = /*@__PURE__*/ nodeProxy( OperatorNode, '~' );export const bitOr = /*@__PURE__*/ nodeProxy( OperatorNode, '|' );export const bitXor = /*@__PURE__*/ nodeProxy( OperatorNode, '^' );export const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' );export const shiftRight = /*@__PURE__*/ nodeProxy( OperatorNode, '>>' );
addMethodChaining( 'add', add );addMethodChaining( 'sub', sub );addMethodChaining( 'mul', mul );addMethodChaining( 'div', div );addMethodChaining( 'modInt', modInt );addMethodChaining( 'equal', equal );addMethodChaining( 'notEqual', notEqual );addMethodChaining( 'lessThan', lessThan );addMethodChaining( 'greaterThan', greaterThan );addMethodChaining( 'lessThanEqual', lessThanEqual );addMethodChaining( 'greaterThanEqual', greaterThanEqual );addMethodChaining( 'and', and );addMethodChaining( 'or', or );addMethodChaining( 'not', not );addMethodChaining( 'xor', xor );addMethodChaining( 'bitAnd', bitAnd );addMethodChaining( 'bitNot', bitNot );addMethodChaining( 'bitOr', bitOr );addMethodChaining( 'bitXor', bitXor );addMethodChaining( 'shiftLeft', shiftLeft );addMethodChaining( 'shiftRight', shiftRight );
export const remainder = ( ...params ) => { // @deprecated, r168
console.warn( 'TSL.OperatorNode: .remainder() has been renamed to .modInt().' ); return modInt( ...params );
};
addMethodChaining( 'remainder', remainder );