Browse Source

NodeUtils: `getNodesKeys` -> `getNodeChildren` (#25581)

* Ray: Clean up

* Don't move t0

* Update Ray.js

* Update NodeUtils.js

* Update NodeMaterial.js

* Update Node.js

* Revert "Merge branch 'patch-2' of https://github.com/LeviPesin/three.js-1 into pr/25581"

This reverts commit bcf3af839dad20b1484fd9582cbf37fed8b9db47, reversing
changes made to c70a5673a373d72ce3625c59b6d1e256f99b5cc3.

* Revert "Revert "Merge branch 'patch-2' of https://github.com/LeviPesin/three.js-1 into pr/25581""

This reverts commit 08e1c556df94f60313784e40ab8d0f2aae0512aa.

* Update Node.js

* Update NodeUtils.js

* Update Node.js

* Fix

* Fix

* Fix

* cleanup

---------

Co-authored-by: mrdoob <[email protected]>
Co-authored-by: sunag <[email protected]>
Levi Pesin 2 years ago
parent
commit
98d3030079

+ 22 - 46
examples/jsm/nodes/core/Node.js

@@ -1,5 +1,5 @@
 import { NodeUpdateType } from './constants.js';
-import { getNodesKeys, getCacheKey } from './NodeUtils.js';
+import { getNodeChildren, getCacheKey } from './NodeUtils.js';
 import { MathUtils } from 'three';
 
 const NodeClasses = new Map();
@@ -36,42 +36,17 @@ class Node {
 
 	* getChildren() {
 
-		for ( const property in this ) {
+		const self = this;
 
-			const object = this[ property ];
+		for ( const { property, index, childNode } of getNodeChildren( this ) ) {
 
-			if ( Array.isArray( object ) === true ) {
+			if ( index !== undefined ) {
 
-				for ( let i = 0; i < object.length; i++ ) {
+				yield { childNode, replaceNode( node ) { self[ property ][ index ] = node; } };
 
-					const child = object[ i ];
-
-					if ( child && child.isNode === true ) {
-
-						yield { childNode: child, replaceNode( node ) { object[ i ] = node; } };
-
-					}
-
-				}
-
-			} else if ( object && object.isNode === true ) {
-
-				const self = this;
-				yield { childNode: object, replaceNode( node ) { self[ property ] = node; } };
-
-			} else if ( typeof object === 'object' ) {
-
-				for ( const property in object ) {
-
-					const child = object[ property ];
-
-					if ( child && child.isNode === true ) {
-
-						yield { childNode: child, replaceNode( node ) { object[ property ] = node; } };
-
-					}
+			} else {
 
-				}
+				yield { childNode, replaceNode( node ) { self[ property ] = node; } };
 
 			}
 
@@ -82,6 +57,7 @@ class Node {
 	traverse( callback, replaceNode = null ) {
 
 		callback( this, replaceNode );
+
 		for ( const { childNode, replaceNode } of this.getChildren() ) {
 
 			childNode.traverse( callback, replaceNode );
@@ -194,7 +170,7 @@ class Node {
 		builder.addNode( this );
 		builder.addStack( this );
 
-		/* expected return:
+		/* Build stages expected results:
 			- "construct"	-> Node
 			- "analyze"		-> null
 			- "generate"	-> String
@@ -265,31 +241,31 @@ class Node {
 
 	serialize( json ) {
 
-		const nodeKeys = getNodesKeys( this );
+		const nodeChildren = getNodeChildren( this );
 
-		if ( nodeKeys.length > 0 ) {
+		const inputNodes = {};
 
-			const inputNodes = {};
+		for ( const { property, index, childNode } of nodeChildren ) {
 
-			for ( const property of nodeKeys ) {
+			if ( index !== undefined ) {
 
-				if ( Array.isArray( this[ property ] ) ) {
+				if ( inputNodes[ property ] === undefined ) {
 
-					inputNodes[ property ] = [];
+					inputNodes[ property ] = Number.isInteger( index ) ? [] : {};
 
-					for ( const node of this[ property ] ) {
+				}
 
-						inputNodes[ property ].push( node.toJSON( json.meta ).uuid );
+				inputNodes[ property ][ index ] = childNode.toJSON( json.meta ).uuid;
 
-					}
+			} else {
 
-				} else {
+				inputNodes[ property ] = childNode.toJSON( json.meta ).uuid;
 
-					inputNodes[ property ] = this[ property ].toJSON( json.meta ).uuid;
+			}
 
-				}
+		}
 
-			}
+		if ( Object.keys( inputNodes ).length > 0 ) {
 
 			json.inputNodes = inputNodes;
 

+ 37 - 33
examples/jsm/nodes/core/NodeUtils.js

@@ -1,72 +1,76 @@
 import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three';
 
-export const getCacheKey = ( object ) => {
+export function getCacheKey( object )  {
 
 	let cacheKey = '{';
 
 	if ( object.isNode === true ) {
 
-		cacheKey += `uuid:"${ object.uuid }",`;
+		cacheKey += `uuid:"${ object.uuid }"`;
 
 	}
 
-	for ( const property of getNodesKeys( object ) ) {
-
-		const node = object[ property ];
+	for ( const { property, index, childNode } of getNodeChildren( object ) ) {
 
 		// @TODO: Think about implement NodeArray and NodeObject.
 
-		if ( Array.isArray( node ) ) {
+		let childCacheKey = getCacheKey( childNode );
+		if ( ! childCacheKey.includes( ',' ) ) childCacheKey = childCacheKey.slice( childCacheKey.indexOf( '"' ), childCacheKey.indexOf( '}' ) );
+		cacheKey += `,${ property }${ index !== undefined ? '/' + index : '' }:${ childCacheKey }`;
 
-			for ( const subNode of node ) {
+	}
 
-				cacheKey += `${ property }:${ subNode.getCacheKey() },`;
+	cacheKey += '}';
 
-			}
+	return cacheKey;
 
-		} else {
+}
 
-			cacheKey += `${ property }:${ node.getCacheKey() },`;
+export function* getNodeChildren( node ) {
 
-		}
+	for ( const property in node ) {
 
-	}
+		const object = node[ property ];
 
-	cacheKey += '}';
+		if ( Array.isArray( object ) === true ) {
 
-	return cacheKey;
+			for ( let i = 0; i < object.length; i++ ) {
+
+				const child = object[ i ];
 
-};
+				if ( child && child.isNode === true ) {
 
-export const getNodesKeys = ( object ) => {
+					yield { property, index: i, childNode: child };
 
-	const props = [];
+				}
 
-	for ( const name in object ) {
+			}
 
-		const value = object[ name ];
+		} else if ( object && object.isNode === true ) {
 
-		if ( Array.isArray( value ) ) {
+			yield { property, childNode: object };
 
-			if ( value[ 0 ] && value[ 0 ].isNode === true ) {
+		} else if ( typeof object === 'object' ) {
 
-				props.push( name );
+			for ( const subProperty in object ) {
 
-			}
+				const child = object[ subProperty ];
 
-		} else if ( value && value.isNode === true ) {
+				if ( child && child.isNode === true ) {
 
-			props.push( name );
+					yield { property, index: subProperty, childNode: child };
+
+				}
+
+			}
 
 		}
 
 	}
 
-	return props;
-
-};
+}
 
-export const getValueType = ( value ) => {
+export function getValueType( value ) {
 
 	if ( typeof value === 'number' ) {
 
@@ -104,9 +108,9 @@ export const getValueType = ( value ) => {
 
 	return null;
 
-};
+}
 
-export const getValueFromType = ( type, ...params ) => {
+export function getValueFromType( type, ...params ) {
 
 	const last4 = type ? type.slice( - 4 ) : undefined;
 
@@ -146,4 +150,4 @@ export const getValueFromType = ( type, ...params ) => {
 
 	return null;
 
-};
+}

+ 4 - 4
examples/jsm/nodes/materials/NodeMaterial.js

@@ -1,5 +1,5 @@
 import { Material, ShaderMaterial, NoToneMapping } from 'three';
-import { getNodesKeys, getCacheKey } from '../core/NodeUtils.js';
+import { getNodeChildren, getCacheKey } from '../core/NodeUtils.js';
 import { attribute } from '../core/AttributeNode.js';
 import { diffuseColor } from '../core/PropertyNode.js';
 import { materialNormal } from '../accessors/ExtendedMaterialNode.js';
@@ -322,13 +322,13 @@ class NodeMaterial extends ShaderMaterial {
 		}
 
 		const data = Material.prototype.toJSON.call( this, meta );
-		const nodeKeys = getNodesKeys( this );
+		const nodeChildren = getNodeChildren( this );
 
 		data.inputNodes = {};
 
-		for ( const name of nodeKeys ) {
+		for ( const { property, childNode } of nodeChildren ) {
 
-			data.inputNodes[ name ] = this[ name ].toJSON( meta ).uuid;
+			data.inputNodes[ property ] = childNode.toJSON( meta ).uuid;
 
 		}