Переглянути джерело

update the BoundingInfo/Box/Sphere to integrate a new extraWorldExtent parameter

Julien Barrois 6 роки тому
батько
коміт
2b04f3eeb0

+ 46 - 23
src/Culling/babylon.boundingBox.ts

@@ -1,4 +1,7 @@
-module BABYLON {
+module BABYLON {
+
+    const _identityMatrix = Matrix.Identity();
+
     /**
      * Class used to store bounding box information
      */
@@ -48,6 +51,11 @@
          */
         public maximum: Vector3 = Vector3.Zero();
 
+        /**
+         * an optional extra extent that will be added in all diretionsto the world BoundingBox.
+         * Note that vectorsWorld value is not impacted by this, only minimumWorld, maximumWorld and extendSizeWorld.
+         */
+        public extraWorldExtent: number;
         private _worldMatrix: Matrix;
         private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
@@ -61,20 +69,21 @@
          * @param min defines the minimum vector (in local space)
          * @param max defines the maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
+         * @param extraWorldExtent an extra extent that will be added in all diretionsto the world BoundingBox
          */
-        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
-            this.reConstruct(min, max, worldMatrix);
+        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
+            this.reConstruct(min, max, worldMatrix, extraWorldExtent);
         }
 
         // Methods
 
         /**
-         * Recreates the entire bounding box from scratch
+         * Recreates the entire bounding box from scratch, producing same values as if the constructor was called.
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
             const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
             const vectors = this.vectors;
 
@@ -93,7 +102,7 @@
             max.addToRef(min, this.center).scaleInPlace(0.5);
             max.subtractToRef(max, this.extendSize).scaleInPlace(0.5);
 
-            this._update(worldMatrix || this._worldMatrix || Matrix.Identity());
+            this._update(worldMatrix || _identityMatrix, extraWorldExtent || 0);
         }
 
         /**
@@ -112,13 +121,14 @@
             const min = this.center.subtractToRef(newRadius, tmpVectors[1]);
             const max = this.center.addToRef(newRadius, tmpVectors[2]);
 
-            this.reConstruct(min, max);
+            this.reConstruct(min, max, this._worldMatrix, this.extraWorldExtent);
 
             return this;
         }
 
         /**
-         * Gets the world matrix of the bounding box
+         * Gets the world matrix of the bounding box.
+         * must not be modified
          * @returns a matrix
          */
         public getWorldMatrix(): Matrix {
@@ -131,37 +141,50 @@
          * @returns current bounding box
          */
         public setWorldMatrix(matrix: Matrix): BoundingBox {
-            this._worldMatrix.copyFrom(matrix);
+            this._worldMatrix = matrix;
             return this;
         }
 
         /** @hidden */
-        public _update(world: Matrix): void {
+        public _update(world: Matrix, extraWorldExtent: number): void {
             const minWorld = this.minimumWorld;
             const maxWorld = this.maximumWorld;
             const directions = this.directions;
-
-            minWorld.setAll(Number.MAX_VALUE);
-            maxWorld.setAll(-Number.MAX_VALUE);
-
             const vectorsWorld = this.vectorsWorld;
             const vectors = this.vectors;
-            for (let index = 0; index < 8; ++index) {
-                const v = vectorsWorld[index];
-                Vector3.TransformCoordinatesToRef(vectors[index], world, v);
-                minWorld.minimizeInPlace(v);
-                maxWorld.maximizeInPlace(v);
+
+            if (world !== _identityMatrix) {
+                minWorld.setAll(Number.MAX_VALUE);
+                maxWorld.setAll(-Number.MAX_VALUE);
+
+                for (let index = 0; index < 8; ++index) {
+                    const v = vectorsWorld[index];
+                    Vector3.TransformCoordinatesToRef(vectors[index], world, v);
+                    minWorld.minimizeInPlace(v);
+                    maxWorld.maximizeInPlace(v);
+                }
+            }
+            else {
+                minWorld.copyFrom(this.minimum);
+                maxWorld.copyFrom(this.maximum);
+                for (let index = 0; index < 8; ++index) {
+                    vectorsWorld[index].copyFrom(vectors[index]);
+                }
             }
 
-            // Extend
-            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
-            // OOBB
-            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
+            if (extraWorldExtent) {
+                minWorld.addInPlaceFromFloats(-extraWorldExtent, -extraWorldExtent, -extraWorldExtent);
+                maxWorld.addInPlaceFromFloats(extraWorldExtent, extraWorldExtent, extraWorldExtent);
+            }
 
             Vector3.FromArrayToRef(world.m, 0, directions[0]);
             Vector3.FromArrayToRef(world.m, 4, directions[1]);
             Vector3.FromArrayToRef(world.m, 8, directions[2]);
 
+            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
+            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
+
+            this.extraWorldExtent = extraWorldExtent;
             this._worldMatrix = world;
         }
 

+ 27 - 16
src/Culling/babylon.boundingInfo.ts

@@ -62,21 +62,23 @@ module BABYLON {
          * @param minimum min vector of the bounding box/sphere
          * @param maximum max vector of the bounding box/sphere
          * @param worldMatrix defines the new world matrix
+         * @param extraWorldExtent an extra extent that will be added in all diretionsto the world BoundingInfo only
          */
-        constructor(minimum: Vector3, maximum: Vector3, worldMatrix?: Matrix) {
-            this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix);
-            this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix);
+        constructor(minimum: Vector3, maximum: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
+            this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix, extraWorldExtent);
+            this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix, extraWorldExtent);
         }
 
         /**
-         * Recreates the entire bounding info from scratch
+         * Recreates the entire bounding info from scratch, producing same values as if the constructor was called.
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
-         * @param worldMatrix defines the new world matrix
+         * @param worldMatrix defines the new world matrix.
+         * @param extraWorldExtent an extra extent that will be added in all diretionsto the world BoundingInfo only
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
-            this.boundingBox.reConstruct(min, max, worldMatrix);
-            this.boundingSphere.reConstruct(min, max, worldMatrix);
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
+            this.boundingBox.reConstruct(min, max, worldMatrix, extraWorldExtent);
+            this.boundingSphere.reConstruct(min, max, worldMatrix, extraWorldExtent);
         }
 
         /**
@@ -94,6 +96,13 @@ module BABYLON {
         }
 
         /**
+         * extra extent added to the world BoundingBox and BoundingSphere
+         */
+        public get extraWorldExtent(): number | undefined {
+            return this.boundingBox.extraWorldExtent;
+        }
+
+        /**
          * If the info is locked and won't be updated to avoid perf overhead
          */
         public get isLocked(): boolean {
@@ -106,15 +115,16 @@ module BABYLON {
 
         // Methods
         /**
-         * Updates the boudning sphere and box
+         * Updates the bounding sphere and box
          * @param world world matrix to be used to update
          */
         public update(world: Matrix) {
             if (this._isLocked) {
                 return;
             }
-            this.boundingBox._update(world);
-            this.boundingSphere._update(world);
+            const extraWorldExtent = this.boundingBox.extraWorldExtent;
+            this.boundingBox._update(world, extraWorldExtent);
+            this.boundingSphere._update(world, extraWorldExtent);
         }
 
         /**
@@ -128,8 +138,9 @@ module BABYLON {
             const minimum = Tmp.Vector3[0].copyFrom(center).subtractInPlace(extend);
             const maximum = Tmp.Vector3[1].copyFrom(center).addInPlace(extend);
 
-            this.boundingBox.reConstruct(minimum, maximum);
-            this.boundingSphere.reConstruct(minimum, maximum);
+            const extraWorldExtent = this.boundingBox.extraWorldExtent;
+            this.boundingBox.reConstruct(minimum, maximum, this.boundingBox.getWorldMatrix(), extraWorldExtent);
+            this.boundingSphere.reConstruct(minimum, maximum, this.boundingSphere.getWorldMatrix(), extraWorldExtent);
 
             return this;
         }
@@ -167,9 +178,9 @@ module BABYLON {
 		 * Gets the world distance between the min and max points of the bounding box
 		 */
         public get diagonalLength(): number {
-            let boundingBox = this.boundingBox;
-            let size = boundingBox.maximumWorld.subtract(boundingBox.minimumWorld);
-            return size.length();
+            const boundingBox = this.boundingBox;
+            const diag = boundingBox.maximumWorld.subtractToRef(boundingBox.minimumWorld, Tmp.Vector3[0]);
+            return diag.length();
         }
 
         /**

+ 42 - 11
src/Culling/babylon.boundingSphere.ts

@@ -31,6 +31,13 @@ module BABYLON {
          */
         public maximum = Vector3.Zero();
 
+        /**
+         * an optional extra extent that will be added in all diretionsto the world BoundingBox.
+         * Note that vectorsWorld value is not impacted by this, only minimumWorld, maximumWorld and extendSizeWorld.
+         */
+        private _extraWorldExtent: number | undefined;
+        private _worldMatrix: Matrix;
+
         private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
         /**
@@ -38,18 +45,20 @@ module BABYLON {
          * @param min defines the minimum vector (in local space)
          * @param max defines the maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
+         * @param extraWorldExtent an extra extent that will be added in all diretionsto the world BoundingSphere
          */
-        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
-            this.reConstruct(min, max, worldMatrix);
+        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
+            this.reConstruct(min, max, worldMatrix, extraWorldExtent);
         }
 
         /**
-         * Recreates the entire bounding sphere from scratch
+         * Recreates the entire bounding sphere from scratch, producing same values as if the constructor was called.
          * @param min defines the new minimum vector (in local space)
          * @param max defines the new maximum vector (in local space)
          * @param worldMatrix defines the new world matrix
+         * @param extraWorldExtent an extra extent that will be added in all diretionsto the world BoundingSphere
          */
-        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix, extraWorldExtent?: number) {
             this.minimum.copyFrom(min);
             this.maximum.copyFrom(max);
 
@@ -58,7 +67,7 @@ module BABYLON {
             max.addToRef(min, this.center).scaleInPlace(0.5);
             this.radius = distance * 0.5;
 
-            this._update(worldMatrix || _identityMatrix);
+            this._update(worldMatrix || _identityMatrix, extraWorldExtent);
         }
 
         /**
@@ -73,18 +82,31 @@ module BABYLON {
             const min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
             const max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
 
-            this.reConstruct(min, max);
+            this.reConstruct(min, max, this._worldMatrix, this._extraWorldExtent);
 
             return this;
         }
 
         // Methods
         /** @hidden */
-        public _update(world: Matrix): void {
-            Vector3.TransformCoordinatesToRef(this.center, world, this.centerWorld);
-            const tempVector = BoundingSphere.TmpVector3[0];
-            Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, world, tempVector);
-            this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
+        public _update(worldMatrix: Matrix, extraWorldExtent?: number): void {
+            this._worldMatrix = worldMatrix;
+            this._extraWorldExtent = extraWorldExtent;
+
+            if (this._worldMatrix !== _identityMatrix) {
+                Vector3.TransformCoordinatesToRef(this.center, worldMatrix, this.centerWorld);
+                const tempVector = BoundingSphere.TmpVector3[0];
+                Vector3.TransformNormalFromFloatsToRef(1.0, 1.0, 1.0, worldMatrix, tempVector);
+                this.radiusWorld = Math.max(Math.abs(tempVector.x), Math.abs(tempVector.y), Math.abs(tempVector.z)) * this.radius;
+            }
+            else {
+                this.centerWorld.copyFrom(this.center);
+                this.radiusWorld = this.radius;
+            }
+
+            if (extraWorldExtent) {
+                this.radiusWorld += extraWorldExtent;
+            }
         }
 
         /**
@@ -134,5 +156,14 @@ module BABYLON {
             return true;
         }
 
+        /**
+         * Gets the world matrix of the bounding box.
+         * must not be modified
+         * @returns a matrix
+         */
+        public getWorldMatrix(): Matrix {
+            return this._worldMatrix;
+        }
+
     }
 }

+ 4 - 4
src/Mesh/babylon.abstractMesh.ts

@@ -1196,7 +1196,7 @@ module BABYLON {
         private _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {
             //TODO move this to the collision coordinator!
             if (this.getScene().workerCollisions) {
-                newPosition.multiplyInPlace(this._collider._radius);
+                newPosition.multiplyInPlace(this._collider._radius);
             }
 
             newPosition.subtractToRef(this._oldPositionForCollisions, this._diffPositionForCollisions);
@@ -1250,7 +1250,7 @@ module BABYLON {
 
                 // Bounding test
                 if (len > 1 && !subMesh._checkCollision(collider)) {
-                    continue;
+                    continue;
                 }
 
                 this._collideForSubMesh(subMesh, transformMatrix, collider);
@@ -1262,7 +1262,7 @@ module BABYLON {
         public _checkCollision(collider: Collider): AbstractMesh {
             // Bounding box test
             if (!this._boundingInfo || !this._boundingInfo._checkCollision(collider)) {
-                return this;
+                return this;
             }
 
             // Transformation matrix
@@ -1307,7 +1307,7 @@ module BABYLON {
 
                 // Bounding test
                 if (len > 1 && !subMesh.canIntersects(ray)) {
-                    continue;
+                    continue;
                 }
 
                 var currentIntersectInfo = subMesh.intersects(ray, (<Vector3[]>this._positions), (<IndicesArray>this.getIndices()), fastCheck);

+ 18 - 19
src/Mesh/babylon.geometry.ts

@@ -33,6 +33,7 @@ module BABYLON {
         private _isDisposed = false;
         private _extend: { minimum: Vector3, maximum: Vector3 };
         private _boundingBias: Vector2;
+        public _boundingWorldExtraExtent: number = 0;
         /** @hidden */
         public _delayInfo: Array<string>;
         private _indexBuffer: Nullable<WebGLBuffer>;
@@ -62,9 +63,6 @@ module BABYLON {
          */
         public set boundingBias(value: Vector2) {
             if (this._boundingBias) {
-                if (this._boundingBias.equals(value)) {
-                    return;
-                }
                 this._boundingBias.copyFrom(value);
             }
             else {
@@ -121,8 +119,7 @@ module BABYLON {
             // applyToMesh
             if (mesh) {
                 if (mesh.getClassName() === "LinesMesh") {
-                    this.boundingBias = new Vector2(0, (<LinesMesh>mesh).intersectionThreshold);
-                    this._updateExtend();
+                    this._boundingWorldExtraExtent = (<LinesMesh>mesh).intersectionThreshold;
                 }
 
                 this.applyToMesh(mesh);
@@ -256,7 +253,7 @@ module BABYLON {
 
                 for (var index = 0; index < numOfMeshes; index++) {
                     var mesh = meshes[index];
-                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
+                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum, undefined, this._boundingWorldExtraExtent);
                     mesh._createGlobalSubMesh(false);
                     mesh.computeWorldMatrix(true);
                 }
@@ -317,18 +314,20 @@ module BABYLON {
                 this._updateExtend(data);
             }
 
-            var meshes = this._meshes;
-            var numOfMeshes = meshes.length;
             this._resetPointsArrayCache();
 
-            for (var index = 0; index < numOfMeshes; index++) {
-                var mesh = meshes[index];
-                if (updateExtends) {
-                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
-
-                    for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
-                        var subMesh = mesh.subMeshes[subIndex];
+            if (updateExtends) {
+                var meshes = this._meshes;
+                for (const mesh of meshes) {
+                    if (mesh._boundingInfo) {
+                        mesh._boundingInfo.reConstruct(this._extend.minimum, this._extend.maximum, undefined, this._boundingWorldExtraExtent);
+                    }
+                    else {
+                        mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum, undefined, this._boundingWorldExtraExtent);
+                    }
 
+                    const subMeshes = mesh.subMeshes;
+                    for (const subMesh of subMeshes) {
                         subMesh.refreshBoundingInfo();
                     }
                 }
@@ -681,14 +680,14 @@ module BABYLON {
                 }
                 var buffer = this._vertexBuffers[kind].getBuffer();
                 if (buffer) {
-                    buffer.references = numOfMeshes;
+                    buffer.references = numOfMeshes;
                 }
 
                 if (kind === VertexBuffer.PositionKind) {
                     if (!this._extend) {
                         this._updateExtend();
                     }
-                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
+                    mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum, undefined, this._boundingWorldExtraExtent);
 
                     mesh._createGlobalSubMesh(false);
 
@@ -815,7 +814,7 @@ module BABYLON {
         /** @hidden */
         public _generatePointsArray(): boolean {
             if (this._positions) {
-                return true;
+                return true;
             }
 
             var data = this.getVerticesData(VertexBuffer.PositionKind);
@@ -938,7 +937,7 @@ module BABYLON {
             }
 
             // Bounding info
-            geometry._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
+            geometry._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum, undefined, this._boundingWorldExtraExtent);
 
             return geometry;
         }

+ 7 - 2
src/Mesh/babylon.instancedMesh.ts

@@ -211,13 +211,18 @@ module BABYLON {
         }
 
         /**
-         * Sets a new updated BoundingInfo to the mesh.
+         * reconstructs and updates the BoundingInfo of the mesh.
          * @returns the mesh.
          */
         public refreshBoundingInfo(): InstancedMesh {
             var meshBB = this._sourceMesh.getBoundingInfo();
 
-            this._boundingInfo = new BoundingInfo(meshBB.minimum.clone(), meshBB.maximum.clone());
+            if (this._boundingInfo) {
+                this._boundingInfo.reConstruct(meshBB.minimum, meshBB.maximum, undefined, meshBB.extraWorldExtent);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(meshBB.minimum, meshBB.maximum, undefined, meshBB.extraWorldExtent);
+            }
 
             this._updateBoundingInfo();
             return this;

+ 1 - 1
src/Mesh/babylon.linesMesh.ts

@@ -34,7 +34,7 @@ module BABYLON {
 
             this._intersectionThreshold = value;
             if (this.geometry) {
-                this.geometry.boundingBias = new Vector2(0, value);
+                this.geometry._boundingWorldExtraExtent = value;
             }
         }
 

+ 7 - 1
src/Mesh/babylon.mesh.ts

@@ -889,11 +889,17 @@ module BABYLON {
                 return this;
             }
 
+            let extraWorldExtent = this.geometry ? this.geometry._boundingWorldExtraExtent : undefined;
             var data = this._getPositionData(applySkeleton);
             if (data) {
                 const bias = this.geometry ? this.geometry.boundingBias : null;
                 var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices(), bias);
-                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+                if (this._boundingInfo) {
+                    this._boundingInfo.reConstruct(extend.minimum, extend.maximum, undefined, extraWorldExtent);
+                }
+                else {
+                    this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum, undefined, extraWorldExtent);
+                }
             }
 
             if (this.subMeshes) {

+ 12 - 4
src/Mesh/babylon.subMesh.ts

@@ -214,7 +214,15 @@ module BABYLON {
             } else {
                 extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
             }
-            this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+
+            const extraWorldExtent = this._renderingMesh.geometry ? this._renderingMesh.geometry._boundingWorldExtraExtent : undefined;
+
+            if (this._boundingInfo) {
+                this._boundingInfo.reConstruct(extend.minimum, extend.maximum, undefined, extraWorldExtent);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum, undefined, extraWorldExtent);
+            }
             return this;
         }
 
@@ -426,7 +434,7 @@ module BABYLON {
                     return result;
                 }
 
-                result._boundingInfo = new BoundingInfo(boundingInfo.minimum, boundingInfo.maximum);
+                result._boundingInfo = new BoundingInfo(boundingInfo.minimum, boundingInfo.maximum, undefined, boundingInfo.extraWorldExtent);
             }
 
             return result;
@@ -469,10 +477,10 @@ module BABYLON {
                 var vertexIndex = indices[index];
 
                 if (vertexIndex < minVertexIndex) {
-                    minVertexIndex = vertexIndex;
+                    minVertexIndex = vertexIndex;
                 }
                 if (vertexIndex > maxVertexIndex) {
-                    maxVertexIndex = vertexIndex;
+                    maxVertexIndex = vertexIndex;
                 }
             }
 

+ 1 - 1
src/Particles/babylon.solidParticle.ts

@@ -125,7 +125,7 @@ module BABYLON {
             this._sps = sps;
             if (modelBoundingInfo) {
                 this._modelBoundingInfo = modelBoundingInfo;
-                this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum);
+                this._boundingInfo = new BoundingInfo(modelBoundingInfo.minimum, modelBoundingInfo.maximum, undefined, modelBoundingInfo.extraWorldExtent);
             }
         }
 

+ 2 - 2
src/Particles/babylon.solidParticleSystem.ts

@@ -891,7 +891,7 @@ module BABYLON {
                             tempMax.maximizeInPlaceFromFloats(x, y, z);
                         }
 
-                        bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);
+                        bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix, bInfo.extraWorldExtent);
                     }
 
                     // place and scale the particle bouding sphere in the SPS local system, then update it
@@ -902,7 +902,7 @@ module BABYLON {
                     const halfDiag = maxBbox.subtractToRef(minBbox, tempVectors[4]).scaleInPlace(0.5 * this._bSphereRadiusFactor);
                     const bSphereMinBbox = bSphereCenter.subtractToRef(halfDiag, tempVectors[1]);
                     const bSphereMaxBbox = bSphereCenter.addToRef(halfDiag, tempVectors[2]);
-                    bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix);
+                    bSphere.reConstruct(bSphereMinBbox, bSphereMaxBbox, mesh._worldMatrix, bInfo.extraWorldExtent);
                 }
 
                 // increment indexes for the next particle