浏览代码

Added `scene.multiPick` and `scene.multiPickWithRay` to return an array of pickedMesh objects

David Catuhe 8 年之前
父节点
当前提交
6f2232a9d7

文件差异内容过多而无法显示
+ 14 - 14
dist/preview release/babylon.core.js


文件差异内容过多而无法显示
+ 795 - 792
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 24 - 24
dist/preview release/babylon.js


+ 55 - 12
dist/preview release/babylon.max.js

@@ -18714,6 +18714,27 @@ var BABYLON;
             }
             return pickingInfo || new BABYLON.PickingInfo();
         };
+        Scene.prototype._internalMultiPick = function (rayFunction, predicate) {
+            var pickingInfos = new Array();
+            for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
+                var mesh = this.meshes[meshIndex];
+                if (predicate) {
+                    if (!predicate(mesh)) {
+                        continue;
+                    }
+                }
+                else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
+                    continue;
+                }
+                var world = mesh.getWorldMatrix();
+                var ray = rayFunction(world);
+                var result = mesh.intersects(ray, false);
+                if (!result || !result.hit)
+                    continue;
+                pickingInfos.push(result);
+            }
+            return pickingInfos;
+        };
         Scene.prototype._internalPickSprites = function (ray, predicate, fastCheck, camera) {
             var pickingInfo = null;
             camera = camera || this.activeCamera;
@@ -18736,23 +18757,23 @@ var BABYLON;
             }
             return pickingInfo || new BABYLON.PickingInfo();
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         Scene.prototype.pick = function (x, y, predicate, fastCheck, camera) {
             var _this = this;
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPick(function (world) { return _this.createPickingRay(x, y, world, camera); }, predicate, fastCheck);
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         Scene.prototype.pickSprite = function (x, y, predicate, fastCheck, camera) {
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPickSprites(this.createPickingRayInCameraSpace(x, y, camera), predicate, fastCheck, camera);
         };
         Scene.prototype.pickWithRay = function (ray, predicate, fastCheck) {
@@ -18765,6 +18786,28 @@ var BABYLON;
                 return BABYLON.Ray.Transform(ray, _this._pickWithRayInverseMatrix);
             }, predicate, fastCheck);
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
+        Scene.prototype.multiPick = function (x, y, predicate, camera) {
+            var _this = this;
+            return this._internalMultiPick(function (world) { return _this.createPickingRay(x, y, world, camera); }, predicate);
+        };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="ray">Ray to use</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        Scene.prototype.multiPickWithRay = function (ray, predicate) {
+            var _this = this;
+            return this._internalMultiPick(function (world) {
+                if (!_this._pickWithRayInverseMatrix) {
+                    _this._pickWithRayInverseMatrix = BABYLON.Matrix.Identity();
+                }
+                world.invertToRef(_this._pickWithRayInverseMatrix);
+                return BABYLON.Ray.Transform(ray, _this._pickWithRayInverseMatrix);
+            }, predicate);
+        };
         Scene.prototype.setPointerOverMesh = function (mesh) {
             if (this._pointerOverMesh === mesh) {
                 return;

文件差异内容过多而无法显示
+ 24 - 24
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/what's new.md

@@ -10,6 +10,7 @@
 - New BoneLookController [Demo](http://www.babylonjs-playground.com/#1B1PUZ#13) - ([abow](https://github.com/abow))
 
 ### Updates
+- Added `scene.multiPick` and `scene.multiPickWithRay` to return an array of pickedMesh objects ([deltakosh](https://github.com/deltakosh))
 - Added `Effect.GetVertexShaderSource()` and `Effect.GetFragmentShaderSource()` ([deltakosh](https://github.com/deltakosh))
 - New `Texture.LoadFromDataString()` to help loading base64 encoded textures ([deltakosh](https://github.com/deltakosh))
 - You can now specify an array of string when loading a texture (they will be considered as fallbacks) ([deltakosh](https://github.com/deltakosh))

+ 55 - 12
src/babylon.scene.js

@@ -2401,6 +2401,27 @@ var BABYLON;
             }
             return pickingInfo || new BABYLON.PickingInfo();
         };
+        Scene.prototype._internalMultiPick = function (rayFunction, predicate) {
+            var pickingInfos = new Array();
+            for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
+                var mesh = this.meshes[meshIndex];
+                if (predicate) {
+                    if (!predicate(mesh)) {
+                        continue;
+                    }
+                }
+                else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
+                    continue;
+                }
+                var world = mesh.getWorldMatrix();
+                var ray = rayFunction(world);
+                var result = mesh.intersects(ray, false);
+                if (!result || !result.hit)
+                    continue;
+                pickingInfos.push(result);
+            }
+            return pickingInfos;
+        };
         Scene.prototype._internalPickSprites = function (ray, predicate, fastCheck, camera) {
             var pickingInfo = null;
             camera = camera || this.activeCamera;
@@ -2423,23 +2444,23 @@ var BABYLON;
             }
             return pickingInfo || new BABYLON.PickingInfo();
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         Scene.prototype.pick = function (x, y, predicate, fastCheck, camera) {
             var _this = this;
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPick(function (world) { return _this.createPickingRay(x, y, world, camera); }, predicate, fastCheck);
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         Scene.prototype.pickSprite = function (x, y, predicate, fastCheck, camera) {
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPickSprites(this.createPickingRayInCameraSpace(x, y, camera), predicate, fastCheck, camera);
         };
         Scene.prototype.pickWithRay = function (ray, predicate, fastCheck) {
@@ -2452,6 +2473,28 @@ var BABYLON;
                 return BABYLON.Ray.Transform(ray, _this._pickWithRayInverseMatrix);
             }, predicate, fastCheck);
         };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
+        Scene.prototype.multiPick = function (x, y, predicate, camera) {
+            var _this = this;
+            return this._internalMultiPick(function (world) { return _this.createPickingRay(x, y, world, camera); }, predicate);
+        };
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="ray">Ray to use</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        Scene.prototype.multiPickWithRay = function (ray, predicate) {
+            var _this = this;
+            return this._internalMultiPick(function (world) {
+                if (!_this._pickWithRayInverseMatrix) {
+                    _this._pickWithRayInverseMatrix = BABYLON.Matrix.Identity();
+                }
+                world.invertToRef(_this._pickWithRayInverseMatrix);
+                return BABYLON.Ray.Transform(ray, _this._pickWithRayInverseMatrix);
+            }, predicate);
+        };
         Scene.prototype.setPointerOverMesh = function (mesh) {
             if (this._pointerOverMesh === mesh) {
                 return;

+ 62 - 13
src/babylon.scene.ts

@@ -2872,6 +2872,33 @@
             return pickingInfo || new PickingInfo();
         }
 
+        private _internalMultiPick(rayFunction: (world: Matrix) => Ray, predicate: (mesh: AbstractMesh) => boolean): PickingInfo[] {
+            var pickingInfos = new Array<PickingInfo>();
+
+            for (var meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
+                var mesh = this.meshes[meshIndex];
+
+                if (predicate) {
+                    if (!predicate(mesh)) {
+                        continue;
+                    }
+                } else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
+                    continue;
+                }
+
+                var world = mesh.getWorldMatrix();
+                var ray = rayFunction(world);
+
+                var result = mesh.intersects(ray, false);
+                if (!result || !result.hit)
+                    continue;
+
+                pickingInfos.push(result);
+            }
+
+            return pickingInfos;
+        }
+
 
         private _internalPickSprites(ray: Ray, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean, camera?: Camera): PickingInfo {
             var pickingInfo = null;
@@ -2904,27 +2931,27 @@
             return pickingInfo || new PickingInfo();
         }
 
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         public pick(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, camera?: Camera): PickingInfo {
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPick(world => this.createPickingRay(x, y, world, camera), predicate, fastCheck);
         }
 
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
+        /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
         public pickSprite(x: number, y: number, predicate?: (sprite: Sprite) => boolean, fastCheck?: boolean, camera?: Camera): PickingInfo {
-            /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
-            /// <param name="x">X position on screen</param>
-            /// <param name="y">Y position on screen</param>
-            /// <param name="predicate">Predicate function used to determine eligible sprites. Can be set to null. In this case, a sprite must have isPickable set to true</param>
-            /// <param name="fastCheck">Launch a fast check only using the bounding boxes. Can be set to null.</param>
-            /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
             return this._internalPickSprites(this.createPickingRayInCameraSpace(x, y, camera), predicate, fastCheck, camera);
         }
 
-        public pickWithRay(ray: Ray, predicate: (mesh: Mesh) => boolean, fastCheck?: boolean) {
+        public pickWithRay(ray: Ray, predicate: (mesh: Mesh) => boolean, fastCheck?: boolean): PickingInfo {
             return this._internalPick(world => {
                 if (!this._pickWithRayInverseMatrix) {
                     this._pickWithRayInverseMatrix = Matrix.Identity();
@@ -2934,6 +2961,28 @@
             }, predicate, fastCheck);
         }
 
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="x">X position on screen</param>
+        /// <param name="y">Y position on screen</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        /// <param name="camera">camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used</param>
+        public multiPick(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean, camera?: Camera): PickingInfo[] {
+            return this._internalMultiPick(world => this.createPickingRay(x, y, world, camera), predicate);
+        }
+
+        /// <summary>Launch a ray to try to pick a mesh in the scene</summary>
+        /// <param name="ray">Ray to use</param>
+        /// <param name="predicate">Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must be enabled, visible and with isPickable set to true</param>
+        public multiPickWithRay(ray: Ray, predicate: (mesh: Mesh) => boolean): PickingInfo[] {
+            return this._internalMultiPick(world => {
+                if (!this._pickWithRayInverseMatrix) {
+                    this._pickWithRayInverseMatrix = Matrix.Identity();
+                }
+                world.invertToRef(this._pickWithRayInverseMatrix);
+                return Ray.Transform(ray, this._pickWithRayInverseMatrix);
+            }, predicate);
+        }
+
         public setPointerOverMesh(mesh: AbstractMesh): void {
             if (this._pointerOverMesh === mesh) {
                 return;