|
1 | 1 | import Node from '../core/Node.js'; |
2 | 2 | import { expression } from '../code/ExpressionNode.js'; |
3 | | -import { nodeObject, nodeArray } from '../tsl/TSLBase.js'; |
| 3 | +import { nodeObject, nodeArray, Fn } from '../tsl/TSLBase.js'; |
4 | 4 |
|
5 | 5 | /** |
6 | 6 | * This module offers a variety of ways to implement loops in TSL. In it's basic form it's: |
@@ -101,9 +101,15 @@ class LoopNode extends Node { |
101 | 101 |
|
102 | 102 | const stack = builder.addStack(); // TODO: cache() it |
103 | 103 |
|
104 | | - properties.returnsNode = this.params[ this.params.length - 1 ]( inputs, stack, builder ); |
| 104 | + properties.returnsNode = this.params[ this.params.length - 1 ]( inputs, builder ); |
105 | 105 | properties.stackNode = stack; |
106 | 106 |
|
| 107 | + if ( typeof this.params[ 0 ].update === 'function' ) { |
| 108 | + |
| 109 | + properties.updateNode = Fn( this.params[ 0 ].update )( inputs ); |
| 110 | + |
| 111 | + } |
| 112 | + |
107 | 113 | builder.removeStack(); |
108 | 114 |
|
109 | 115 | return properties; |
@@ -222,30 +228,67 @@ class LoopNode extends Node { |
222 | 228 | const startSnippet = internalParam.start; |
223 | 229 | const endSnippet = internalParam.end; |
224 | 230 |
|
225 | | - let declarationSnippet = ''; |
226 | | - let conditionalSnippet = ''; |
227 | | - let updateSnippet = ''; |
| 231 | + let updateSnippet; |
228 | 232 |
|
229 | | - if ( ! update ) { |
| 233 | + const deltaOperator = () => condition.includes( '<' ) ? '+=' : '-='; |
230 | 234 |
|
231 | | - if ( type === 'int' || type === 'uint' ) { |
| 235 | + switch ( typeof update ) { |
232 | 236 |
|
233 | | - if ( condition.includes( '<' ) ) update = '++'; |
234 | | - else update = '--'; |
| 237 | + case 'undefined': |
235 | 238 |
|
236 | | - } else { |
| 239 | + if ( type === 'int' || type === 'uint' ) { |
237 | 240 |
|
238 | | - if ( condition.includes( '<' ) ) update = '+= 1.'; |
239 | | - else update = '-= 1.'; |
| 241 | + update = condition.includes( '<' ) ? '++' : '--'; |
240 | 242 |
|
241 | | - } |
| 243 | + } else { |
242 | 244 |
|
243 | | - } |
| 245 | + update = deltaOperator() + ' 1.'; |
| 246 | + |
| 247 | + } |
| 248 | + |
| 249 | + updateSnippet = name + ' ' + update; |
| 250 | + |
| 251 | + break; |
| 252 | + |
| 253 | + case 'function': |
| 254 | + |
| 255 | + const flow = builder.flowStagesNode( properties.updateNode, 'void' ); |
| 256 | + const snippet = flow.code.replace( /\t|;/g, '' ); |
| 257 | + |
| 258 | + updateSnippet = snippet; |
| 259 | + |
| 260 | + break; |
244 | 261 |
|
245 | | - declarationSnippet += builder.getVar( type, name ) + ' = ' + startSnippet; |
| 262 | + case 'number': |
| 263 | + |
| 264 | + updateSnippet = name + ' ' + deltaOperator() + ' ' + builder.generateConst( type, update ); |
| 265 | + |
| 266 | + break; |
| 267 | + |
| 268 | + case 'string': |
| 269 | + |
| 270 | + updateSnippet = name + ' ' + update; |
| 271 | + |
| 272 | + break; |
| 273 | + |
| 274 | + default: |
| 275 | + |
| 276 | + if ( update && update.isNode ) { |
| 277 | + |
| 278 | + updateSnippet = name + ' ' + deltaOperator() + ' ' + update.build( builder ); |
| 279 | + |
| 280 | + } else { |
| 281 | + |
| 282 | + console.error( 'THREE.TSL: \'Loop( { update: ... } )\' is not a function, string or number.' ); |
| 283 | + |
| 284 | + updateSnippet = 'break /* invalid update */'; |
| 285 | + |
| 286 | + } |
| 287 | + |
| 288 | + } |
246 | 289 |
|
247 | | - conditionalSnippet += name + ' ' + condition + ' ' + endSnippet; |
248 | | - updateSnippet += name + ' ' + update; |
| 290 | + const declarationSnippet = builder.getVar( type, name ) + ' = ' + startSnippet; |
| 291 | + const conditionalSnippet = name + ' ' + condition + ' ' + endSnippet; |
249 | 292 |
|
250 | 293 | loopSnippet = `for ( ${ declarationSnippet }; ${ conditionalSnippet }; ${ updateSnippet } )`; |
251 | 294 |
|
|
0 commit comments