Explorar o código

Merge pull request #1018 from nockawa/master

Added an optional predicate on Node.getDescendants, Node.getChildren to filter out Node based on a callback execution.
David Catuhe %!s(int64=9) %!d(string=hai) anos
pai
achega
0dbdfd0ab6
Modificáronse 2 ficheiros con 41 adicións e 21 borrados
  1. 21 11
      src/babylon.node.js
  2. 20 10
      src/babylon.node.ts

+ 21 - 11
src/babylon.node.js

@@ -131,39 +131,49 @@ var BABYLON;
             }
             return false;
         };
-        Node.prototype._getDescendants = function (list, results, directDecendantsOnly) {
+        /**
+         * Evaluate a list of nodes and determine if they should be considered as descendants considering the given criterias
+         * @param {BABYLON.Node[]} list the input array of nodes to evaluate
+         * @param {BABYLON.Node[]} results the result array containing the nodes matching the given criterias
+         * @param {boolean} directDecendantsOnly if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered.
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
+         */
+        Node.prototype._getDescendants = function (list, results, directDecendantsOnly, predicate) {
             if (directDecendantsOnly === void 0) { directDecendantsOnly = false; }
             for (var index = 0; index < list.length; index++) {
                 var item = list[index];
-                if ((directDecendantsOnly && item.parent === this) || (!directDecendantsOnly && item.isDescendantOf(this))) {
+                if (((directDecendantsOnly && item.parent === this) || (!directDecendantsOnly && item.isDescendantOf(this))) && (predicate == null || predicate(item))) {
                     results.push(item);
                 }
             }
         };
         /**
          * Will return all nodes that have this node as parent.
+         * @param {boolean} directDecendantsOnly if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered.
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
          * @return {BABYLON.Node[]} all children nodes of all types.
          */
-        Node.prototype.getDescendants = function (directDecendantsOnly) {
+        Node.prototype.getDescendants = function (directDecendantsOnly, predicate) {
             var results = [];
-            this._getDescendants(this._scene.meshes, results, directDecendantsOnly);
-            this._getDescendants(this._scene.lights, results, directDecendantsOnly);
-            this._getDescendants(this._scene.cameras, results, directDecendantsOnly);
+            this._getDescendants(this._scene.meshes, results, directDecendantsOnly, predicate);
+            this._getDescendants(this._scene.lights, results, directDecendantsOnly, predicate);
+            this._getDescendants(this._scene.cameras, results, directDecendantsOnly, predicate);
             return results;
         };
         /**
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
          * @Deprecated, legacy support.
          * use getDecendants instead.
          */
-        Node.prototype.getChildren = function () {
-            return this.getDescendants(true);
+        Node.prototype.getChildren = function (predicate) {
+            return this.getDescendants(true, predicate);
         };
         /**
          * Get all child-meshes of this node.
          */
-        Node.prototype.getChildMeshes = function (directDecendantsOnly) {
+        Node.prototype.getChildMeshes = function (directDecendantsOnly, predicate) {
             var results = [];
-            this._getDescendants(this._scene.meshes, results, directDecendantsOnly);
+            this._getDescendants(this._scene.meshes, results, directDecendantsOnly, predicate);
             return results;
         };
         Node.prototype._setReady = function (state) {
@@ -250,6 +260,6 @@ var BABYLON;
             BABYLON.serialize()
         ], Node.prototype, "state", void 0);
         return Node;
-    })();
+    }());
     BABYLON.Node = Node;
 })(BABYLON || (BABYLON = {}));

+ 20 - 10
src/babylon.node.ts

@@ -176,10 +176,17 @@
             return false;
         }
 
-        public _getDescendants(list: Node[], results: Node[], directDecendantsOnly: boolean = false): void {
+        /**
+         * Evaluate a list of nodes and determine if they should be considered as descendants considering the given criterias
+         * @param {BABYLON.Node[]} list the input array of nodes to evaluate
+         * @param {BABYLON.Node[]} results the result array containing the nodes matching the given criterias
+         * @param {boolean} directDecendantsOnly if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered.
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
+         */
+        public _getDescendants(list: Node[], results: Node[], directDecendantsOnly: boolean = false, predicate?: (node: Node) => boolean): void {
             for (var index = 0; index < list.length; index++) {
                 var item = list[index];
-                if ((directDecendantsOnly && item.parent === this) || (!directDecendantsOnly && item.isDescendantOf(this))) {
+                if (((directDecendantsOnly && item.parent === this) || (!directDecendantsOnly && item.isDescendantOf(this))) && (predicate==null || predicate(item))) {
                     results.push(item);
                 }
             }
@@ -187,31 +194,34 @@
 
         /**
          * Will return all nodes that have this node as parent.
+         * @param {boolean} directDecendantsOnly if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered.
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
          * @return {BABYLON.Node[]} all children nodes of all types.
          */
-        public getDescendants(directDecendantsOnly?: boolean): Node[] {
+        public getDescendants(directDecendantsOnly?: boolean, predicate?: (node: Node) => boolean): Node[] {
             var results = [];
-            this._getDescendants(this._scene.meshes, results, directDecendantsOnly);
-            this._getDescendants(this._scene.lights, results, directDecendantsOnly);
-            this._getDescendants(this._scene.cameras, results, directDecendantsOnly);
+            this._getDescendants(this._scene.meshes, results, directDecendantsOnly, predicate);
+            this._getDescendants(this._scene.lights, results, directDecendantsOnly, predicate);
+            this._getDescendants(this._scene.cameras, results, directDecendantsOnly, predicate);
 
             return results;
         }
         
         /**
+         * @param predicate: an optional predicate that will be called on every evaluated children, the predicate must return true for a given child to be part of the result, otherwise it will be ignored.
          * @Deprecated, legacy support.
          * use getDecendants instead.
          */
-        public getChildren(): Node[] {
-            return this.getDescendants(true);
+        public getChildren(predicate?: (node: Node) => boolean): Node[] {
+            return this.getDescendants(true, predicate);
         }
         
         /**
          * Get all child-meshes of this node.
          */
-        public getChildMeshes(directDecendantsOnly?: boolean): AbstractMesh[] {
+        public getChildMeshes(directDecendantsOnly?: boolean, predicate?: (node: Node) => boolean): AbstractMesh[] {
             var results: Array<AbstractMesh> = [];
-            this._getDescendants(this._scene.meshes, results, directDecendantsOnly);
+            this._getDescendants(this._scene.meshes, results, directDecendantsOnly, predicate);
             return results;
         }