diff --git a/examples/jsm/transpiler/GLSLDecoder.js b/examples/jsm/transpiler/GLSLDecoder.js index 31490af779079b..a66491bbf1c9aa 100644 --- a/examples/jsm/transpiler/GLSLDecoder.js +++ b/examples/jsm/transpiler/GLSLDecoder.js @@ -414,7 +414,6 @@ class GLSLDecoder { } - // unary operators (after) if ( lastToken.isOperator ) { @@ -894,7 +893,7 @@ class GLSLDecoder { // - if ( token.isLiteral ) { + if ( token.isLiteral || token.isOperator ) { if ( token.str === 'const' ) { diff --git a/examples/jsm/transpiler/TSLEncoder.js b/examples/jsm/transpiler/TSLEncoder.js index 39278796bddb2f..b9d27969ca46e4 100644 --- a/examples/jsm/transpiler/TSLEncoder.js +++ b/examples/jsm/transpiler/TSLEncoder.js @@ -61,6 +61,8 @@ class TSLEncoder { this.uniqueNames = false; this.reference = false; + this._currentVarible = null; + this._currentProperties = {}; this._lastStatement = null; @@ -321,9 +323,22 @@ class TSLEncoder { let type = unaryLib[ node.type ]; - if ( node.after === false && ( node.type === '++' || node.type === '--' ) ) { + if ( node.type === '++' || node.type === '--' ) { + + if ( this._currentVarible === null ) { + + // optimize increment/decrement operator + // to avoid creating a new variable + + node.after = false; + + } + + if ( node.after === false ) { + + type += 'Before'; - type += 'Before'; + } } @@ -476,8 +491,10 @@ ${ this.tab }} )`; if ( ( initialization && initialization.isVariableDeclaration && initialization.next === null ) && ( condition && condition.left.isAccessor && condition.left.property === initialization.name ) && - ( afterthought && afterthought.isUnary ) && - ( initialization.name === afterthought.expression.property ) + ( afterthought && ( + ( afterthought.isUnary && ( initialization.name === afterthought.expression.property ) ) || + ( afterthought.isOperator && ( initialization.name === afterthought.left.property ) ) + ) ) ) { return this.emitLoop( node ); @@ -497,7 +514,7 @@ ${ this.tab }} )`; this.tab += '\t'; let forStr = '{\n\n' + this.tab + initialization + ';\n\n'; - forStr += `${ this.tab }While( ${ condition }, () => {\n\n`; + forStr += `${ this.tab }Loop( ${ condition }, () => {\n\n`; forStr += this.emitBody( node.body ) + '\n\n'; @@ -509,7 +526,7 @@ ${ this.tab }} )`; forStr += this.tab + '}'; - this.imports.add( 'While' ); + this.imports.add( 'Loop' ); return forStr; @@ -519,6 +536,8 @@ ${ this.tab }} )`; const { name, type, value, next } = node; + this._currentVarible = node; + const valueStr = value ? this.emitExpression( value ) : ''; let varStr = isRoot ? 'const ' : ''; @@ -556,6 +575,8 @@ ${ this.tab }} )`; this.addImport( type ); + this._currentVarible = null; + return varStr; } diff --git a/src/Three.TSL.js b/src/Three.TSL.js index d1282296aab8c9..cefec7c04b45c2 100644 --- a/src/Three.TSL.js +++ b/src/Three.TSL.js @@ -130,6 +130,8 @@ export const dFdx = TSL.dFdx; export const dFdy = TSL.dFdy; export const dashSize = TSL.dashSize; export const debug = TSL.debug; +export const decrement = TSL.decrement; +export const decrementBefore = TSL.decrementBefore; export const defaultBuildStages = TSL.defaultBuildStages; export const defaultShaderStages = TSL.defaultShaderStages; export const defined = TSL.defined; @@ -194,6 +196,8 @@ export const hash = TSL.hash; export const highpModelNormalViewMatrix = TSL.highpModelNormalViewMatrix; export const highpModelViewMatrix = TSL.highpModelViewMatrix; export const hue = TSL.hue; +export const increment = TSL.increment; +export const incrementBefore = TSL.incrementBefore; export const instance = TSL.instance; export const instanceIndex = TSL.instanceIndex; export const instancedArray = TSL.instancedArray; diff --git a/src/nodes/math/OperatorNode.js b/src/nodes/math/OperatorNode.js index dce01aab50d435..62e044384c73b8 100644 --- a/src/nodes/math/OperatorNode.js +++ b/src/nodes/math/OperatorNode.js @@ -1,6 +1,6 @@ import { WebGLCoordinateSystem } from '../../constants.js'; import TempNode from '../core/TempNode.js'; -import { addMethodChaining, int, nodeProxy } from '../tsl/TSLCore.js'; +import { addMethodChaining, Fn, int, nodeProxy } from '../tsl/TSLCore.js'; /** * This node represents basic mathematical and logical operations like addition, @@ -681,6 +681,68 @@ export const shiftLeft = /*@__PURE__*/ nodeProxy( OperatorNode, '<<' ).setParame */ export const shiftRight = /*@__PURE__*/ nodeProxy( OperatorNode, '>>' ).setParameterLength( 2 ).setName( 'shiftRight' ); +/** + * Increments a node by 1. + * + * @tsl + * @function + * @param {Node} a - The node to increment. + * @returns {OperatorNode} + */ +export const incrementBefore = Fn( ( [ a ] ) => { + + a.addAssign( 1 ); + return a; + +} ); + +/** + * Decrements a node by 1. + * + * @tsl + * @function + * @param {Node} a - The node to decrement. + * @returns {OperatorNode} + */ +export const decrementBefore = Fn( ( [ a ] ) => { + + a.subAssign( 1 ); + return a; + +} ); + +/** + * Increments a node by 1 and returns the previous value. + * + * @tsl + * @function + * @param {Node} a - The node to increment. + * @returns {OperatorNode} + */ +export const increment = /*@__PURE__*/ Fn( ( [ a ] ) => { + + const temp = int( a ).toConst(); + a.addAssign( 1 ); + return temp; + +} ); + +/** + * Decrements a node by 1 and returns the previous value. + * + * @tsl + * @function + * @param {Node} a - The node to decrement. + * @returns {OperatorNode} + */ +export const decrement = /*@__PURE__*/ Fn( ( [ a ] ) => { + + const temp = int( a ).toConst(); + a.subAssign( 1 ); + return temp; + +} ); + addMethodChaining( 'add', add ); addMethodChaining( 'sub', sub ); addMethodChaining( 'mul', mul ); @@ -703,6 +765,11 @@ addMethodChaining( 'bitXor', bitXor ); addMethodChaining( 'shiftLeft', shiftLeft ); addMethodChaining( 'shiftRight', shiftRight ); +addMethodChaining( 'incrementBefore', incrementBefore ); +addMethodChaining( 'decrementBefore', decrementBefore ); +addMethodChaining( 'increment', increment ); +addMethodChaining( 'decrement', decrement ); + /** * @tsl * @function