Allow controlling traverse flow

Make traverse and the rest of the family respect special return values. The most important (in my opinion) would be the ability to ignore the children. For example:

// Somewhere in Three.js code. Could be replaced with an enum-style definition 
const IGNORE_CHILDREN = new Symbol('ignore_children');
const HALT_TRAVERSE = new Symbol('halt_traverse');

// I didn't check this for mistakes, but the idea should become clear
	traverse( callback ) {

		const controlFlowResult = callback( this );

                if (controlFlowResult === IGNORE_CHILDREN || controlFlowResult === HALT_TRAVERSE ) {

                      return controlFlowResult;

                } 

		const children = this.children;

		for ( let i = 0, l = children.length; i < l; i ++ ) {

			const childFlowResult = children[ i ].traverse( callback );

                        if (childFlowResult === HALT_TRAVERSE) {

                             return HALT_TRAVERSE;

                        }

		}

	}

Examples how a user might use it:

Find a specific node with some property. Then stop.

// 
let oneSpecimenB;
myModel.traverse(node => {
           if (node.userData.isB) {
               oneSpecimentB = node;
                return HALT_TRAVERSE;
           }
});

Run code for all nodes except for all the descendants (and the node itself) of the nodes we want to ignore

myModel.traverse(node => {
           if (node.userData.ignoreChildren) {
                // Optionally run operations here before returning
                return IGNORE_CHILDREN;
           }

          // Do operations for others
});

Leave a comment

Your email address will not be published. Required fields are marked *