David Catuhe преди 5 години
родител
ревизия
7ba93bb682
променени са 3 файла, в които са добавени 51 реда и са изтрити 6 реда
  1. 25 5
      src/Culling/ray.ts
  2. 10 1
      src/Meshes/abstractMesh.ts
  3. 16 0
      src/scene.ts

+ 25 - 5
src/Culling/ray.ts

@@ -584,7 +584,7 @@ declare module "../scene" {
         _pickWithRayInverseMatrix: Matrix;
 
         /** @hidden */
-        _internalPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo>;
+        _internalPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, fastCheck?: boolean, onlyBoundingInfo?: boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo>;
 
         /** @hidden */
         _internalMultiPick(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean, trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo[]>;
@@ -658,6 +658,7 @@ Scene.prototype.createPickingRayInCameraSpaceToRef = function(x: number, y: numb
 
 Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, predicate?: (mesh: AbstractMesh) => boolean,
     fastCheck?: boolean,
+    onlyBoundingInfo?: boolean,
     trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
     if (!PickingInfo) {
         return null;
@@ -676,10 +677,10 @@ Scene.prototype._internalPick = function(rayFunction: (world: Matrix) => Ray, pr
             continue;
         }
 
-        var world = mesh.getWorldMatrix();
+        var world = mesh.skeleton && mesh.skeleton.overrideMesh ? mesh.skeleton.overrideMesh.getWorldMatrix() : mesh.getWorldMatrix();
         var ray = rayFunction(world);
 
-        var result = mesh.intersects(ray, fastCheck, trianglePredicate);
+        var result = mesh.intersects(ray, fastCheck, trianglePredicate, onlyBoundingInfo);
         if (!result || !result.hit) {
             continue;
         }
@@ -731,6 +732,25 @@ Scene.prototype._internalMultiPick = function(rayFunction: (world: Matrix) => Ra
     return pickingInfos;
 };
 
+Scene.prototype.pickWithBoundingInfo = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean,
+    fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {
+    if (!PickingInfo) {
+        return null;
+    }
+    var result = this._internalPick((world) => {
+        if (!this._tempPickingRay) {
+            this._tempPickingRay = Ray.Zero();
+        }
+
+        this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
+        return this._tempPickingRay;
+    }, predicate, fastCheck, true);
+    if (result) {
+        result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
+    }
+    return result;
+};
+
 Scene.prototype.pick = function(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean,
     fastCheck?: boolean, camera?: Nullable<Camera>,
     trianglePredicate?: TrianglePickingPredicate): Nullable<PickingInfo> {
@@ -744,7 +764,7 @@ Scene.prototype.pick = function(x: number, y: number, predicate?: (mesh: Abstrac
 
         this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
         return this._tempPickingRay;
-    }, predicate, fastCheck, trianglePredicate);
+    }, predicate, fastCheck, false, trianglePredicate);
     if (result) {
         result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
     }
@@ -765,7 +785,7 @@ Scene.prototype.pickWithRay = function(ray: Ray, predicate?: (mesh: AbstractMesh
 
         Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
         return this._cachedRayForTransform;
-    }, predicate, fastCheck, trianglePredicate);
+    }, predicate, fastCheck, false, trianglePredicate);
     if (result) {
         result.ray = ray;
     }

+ 10 - 1
src/Meshes/abstractMesh.ts

@@ -1485,10 +1485,11 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
      * @param ray defines the ray to use
      * @param fastCheck defines if fast mode (but less precise) must be used (false by default)
      * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
+     * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)
      * @returns the picking info
      * @see http://doc.babylonjs.com/babylon101/intersect_collisions_-_mesh
      */
-    public intersects(ray: Ray, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate): PickingInfo {
+    public intersects(ray: Ray, fastCheck?: boolean, trianglePredicate?: TrianglePickingPredicate, onlyBoundingInfo = false): PickingInfo {
         var pickingInfo = new PickingInfo();
         const intersectionThreshold = this.getClassName() === "InstancedLinesMesh" || this.getClassName() === "LinesMesh" ? (this as any).intersectionThreshold : 0;
         const boundingInfo = this._boundingInfo;
@@ -1496,6 +1497,14 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
             return pickingInfo;
         }
 
+        if (onlyBoundingInfo) {
+            pickingInfo.hit = true;
+            pickingInfo.pickedMesh = this;
+            pickingInfo.distance = Vector3.Distance(ray.origin, boundingInfo.boundingSphere.center);
+            pickingInfo.subMeshId = 0;
+            return pickingInfo;
+        }
+
         if (!this._generatePointsArray()) {
             return pickingInfo;
         }

+ 16 - 0
src/scene.ts

@@ -4434,6 +4434,22 @@ export class Scene extends AbstractScene implements IAnimatable {
         return pi;
     }
 
+    /** Launch a ray to try to pick a mesh in the scene using only bounding information of the main mesh (not using submeshes)
+     * @param x position on screen
+     * @param y position on screen
+     * @param 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 fastCheck Launch a fast check only using the bounding boxes. Can be set to null.
+     * @param camera to use for computing the picking ray. Can be set to null. In this case, the scene.activeCamera will be used
+     * @returns a PickingInfo (Please note that some info will not be set like distance, bv, bu and everything that cannot be capture by only using bounding infos)
+     */
+    public pickWithBoundingInfo(x: number, y: number, predicate?: (mesh: AbstractMesh) => boolean,
+        fastCheck?: boolean, camera?: Nullable<Camera>): Nullable<PickingInfo> {
+        // Dummy info if picking as not been imported
+        const pi = new PickingInfo();
+        pi._pickingUnavailable = true;
+        return pi;
+    }
+
     /** Use the given ray to pick a mesh in the scene
      * @param ray The ray to use to pick meshes
      * @param predicate Predicate function used to determine eligible meshes. Can be set to null. In this case, a mesh must have isPickable set to true