Browse Source

TSL: Add `increment` and `decrement` and fix unsual `for()` expression syntax for transpiler (#30912)

* TSLEncoder: Remove `While` usage.

* Revert "TSLEncoder: Remove `While` usage."

This reverts commit 28957ed87bd0de2057cd5807f6af7f4827420ab0.

* fix afterthought for operators

* fix While -> Loop

* fix `++` operator after code block

* optimize increment and decrement

* add increment and decrement

* Update OperatorNode.js

---------

Co-authored-by: sunag <sunagbrasil@gmail.com>
Michael Herzog 9 months ago
parent
commit
bd9ac7da73

+ 1 - 2
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' ) {
 

+ 27 - 6
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;
 
 	}

+ 4 - 0
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;

+ 68 - 1
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

粤ICP备19079148号