Bläddra i källkod

Merge pull request #5327 from barroij/LinesMeshIntersection

Handle properly the LinesMesh intersectionThreshold
David Catuhe 6 år sedan
förälder
incheckning
cf786fdc03

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

@@ -48,6 +48,7 @@
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with pointer up being fire twice ([Deltakosh](https://github.com/deltakosh))
 - Fixed a bug with particle systems being update once per camera instead of once per frame ([Deltakosh](https://github.com/deltakosh))
+- Handle properly the `LinesMesh` `intersectionThreshold` by using its value directly when the intersection against a `Ray` is checked, instead of extending the `BoundingInfo` accordingly ([barroij](https://github.com/barroij))
 - Fixed the `LineEdgesRenderer` used for edge rendering of `LinesMesh` handle properly LinesMesh made of disconnected lines + Make it work for instance of `LinesMesh` ([barroij](https://github.com/barroij))
 
 ### Viewer

+ 27 - 15
src/Culling/babylon.boundingBox.ts

@@ -1,4 +1,4 @@
-module BABYLON {
+module BABYLON {
     /**
      * Class used to store bounding box information
      */
@@ -49,7 +49,7 @@
         public maximum: Vector3 = Vector3.Zero();
 
         private _worldMatrix: Matrix;
-        private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
+        private static readonly TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
         /**
          * @hidden
@@ -140,23 +140,35 @@
             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.isIdentity()) {
+                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);
+                }
+
+                // Extend
+                maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
+                maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
             }
+            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);
+                // Extend
+                this.extendSizeWorld.copyFrom(this.extendSize);
+                this.centerWorld.copyFrom(this.center);
+            }
 
             Vector3.FromArrayToRef(world.m, 0, directions[0]);
             Vector3.FromArrayToRef(world.m, 4, directions[1]);

+ 8 - 6
src/Culling/babylon.boundingInfo.ts

@@ -57,6 +57,8 @@ module BABYLON {
 
         private _isLocked = false;
 
+        private static readonly TmpVector3 = Tools.BuildArray(2, Vector3.Zero);
+
         /**
          * Constructs bounding info
          * @param minimum min vector of the bounding box/sphere
@@ -106,7 +108,7 @@ 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) {
@@ -125,8 +127,8 @@ module BABYLON {
          */
         public centerOn(center: Vector3, extend: Vector3): BoundingInfo {
 
-            const minimum = Tmp.Vector3[0].copyFrom(center).subtractInPlace(extend);
-            const maximum = Tmp.Vector3[1].copyFrom(center).addInPlace(extend);
+            const minimum = BoundingInfo.TmpVector3[0].copyFrom(center).subtractInPlace(extend);
+            const maximum = BoundingInfo.TmpVector3[1].copyFrom(center).addInPlace(extend);
 
             this.boundingBox.reConstruct(minimum, maximum);
             this.boundingSphere.reConstruct(minimum, maximum);
@@ -167,9 +169,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, BoundingInfo.TmpVector3[0]);
+            return diag.length();
         }
 
         /**

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

@@ -1,7 +1,4 @@
 module BABYLON {
-    // This matrix is used as a value to reset the bounding box.
-    const _identityMatrix = Matrix.Identity();
-
     /**
      * Class used to store bounding sphere information
      */
@@ -31,7 +28,7 @@ module BABYLON {
          */
         public maximum = Vector3.Zero();
 
-        private static TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
+        private static readonly TmpVector3 = Tools.BuildArray(3, Vector3.Zero);
 
         /**
          * Creates a new bounding sphere
@@ -58,7 +55,7 @@ module BABYLON {
             max.addToRef(min, this.center).scaleInPlace(0.5);
             this.radius = distance * 0.5;
 
-            this._update(worldMatrix || _identityMatrix);
+            this._update(worldMatrix || Matrix.IdentityReadOnly);
         }
 
         /**
@@ -80,11 +77,17 @@ module BABYLON {
 
         // 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): void {
+            if (!worldMatrix.isIdentity()) {
+                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;
+            }
         }
 
         /**
@@ -133,6 +136,5 @@ module BABYLON {
 
             return true;
         }
-
     }
 }

+ 38 - 38
src/Culling/babylon.ray.ts

@@ -3,11 +3,13 @@ module BABYLON {
      * Class representing a ray with position and direction
      */
     export class Ray {
-        private _edge1: Vector3;
-        private _edge2: Vector3;
-        private _pvec: Vector3;
-        private _tvec: Vector3;
-        private _qvec: Vector3;
+        private static readonly _edge1 = Vector3.Zero();
+        private static readonly _edge2 = Vector3.Zero();
+        private static readonly _pvec = Vector3.Zero();
+        private static readonly _tvec = Vector3.Zero();
+        private static readonly _qvec = Vector3.Zero();
+        private static readonly _min = Vector3.Zero();
+        private static readonly _max = Vector3.Zero();
 
         private _tmpRay: Ray;
 
@@ -31,9 +33,12 @@ module BABYLON {
          * Checks if the ray intersects a box
          * @param minimum bound of the box
          * @param maximum bound of the box
+         * @param intersectionTreshold extra extend to be added to the box in all direction
          * @returns if the box was hit
          */
-        public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3): boolean {
+        public intersectsBoxMinMax(minimum: Vector3, maximum: Vector3, intersectionTreshold: number = 0): boolean {
+            const newMinimum = Ray._min.copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
+            const newMaximum = Ray._max.copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
             var d = 0.0;
             var maxValue = Number.MAX_VALUE;
             var inv: number;
@@ -41,14 +46,14 @@ module BABYLON {
             var max: number;
             var temp: number;
             if (Math.abs(this.direction.x) < 0.0000001) {
-                if (this.origin.x < minimum.x || this.origin.x > maximum.x) {
+                if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {
                     return false;
                 }
             }
             else {
                 inv = 1.0 / this.direction.x;
-                min = (minimum.x - this.origin.x) * inv;
-                max = (maximum.x - this.origin.x) * inv;
+                min = (newMinimum.x - this.origin.x) * inv;
+                max = (newMaximum.x - this.origin.x) * inv;
                 if (max === -Infinity) {
                     max = Infinity;
                 }
@@ -68,14 +73,14 @@ module BABYLON {
             }
 
             if (Math.abs(this.direction.y) < 0.0000001) {
-                if (this.origin.y < minimum.y || this.origin.y > maximum.y) {
+                if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {
                     return false;
                 }
             }
             else {
                 inv = 1.0 / this.direction.y;
-                min = (minimum.y - this.origin.y) * inv;
-                max = (maximum.y - this.origin.y) * inv;
+                min = (newMinimum.y - this.origin.y) * inv;
+                max = (newMaximum.y - this.origin.y) * inv;
 
                 if (max === -Infinity) {
                     max = Infinity;
@@ -96,14 +101,14 @@ module BABYLON {
             }
 
             if (Math.abs(this.direction.z) < 0.0000001) {
-                if (this.origin.z < minimum.z || this.origin.z > maximum.z) {
+                if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {
                     return false;
                 }
             }
             else {
                 inv = 1.0 / this.direction.z;
-                min = (minimum.z - this.origin.z) * inv;
-                max = (maximum.z - this.origin.z) * inv;
+                min = (newMinimum.z - this.origin.z) * inv;
+                max = (newMaximum.z - this.origin.z) * inv;
 
                 if (max === -Infinity) {
                     max = Infinity;
@@ -128,23 +133,26 @@ module BABYLON {
         /**
          * Checks if the ray intersects a box
          * @param box the bounding box to check
+         * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
          * @returns if the box was hit
          */
-        public intersectsBox(box: BoundingBox): boolean {
-            return this.intersectsBoxMinMax(box.minimum, box.maximum);
+        public intersectsBox(box: BoundingBox, intersectionTreshold: number = 0): boolean {
+            return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);
         }
 
         /**
          * If the ray hits a sphere
          * @param sphere the bounding sphere to check
+         * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction
          * @returns true if it hits the sphere
          */
-        public intersectsSphere(sphere: BoundingSphere): boolean {
+        public intersectsSphere(sphere: BoundingSphere, intersectionTreshold: number = 0): boolean {
             var x = sphere.center.x - this.origin.x;
             var y = sphere.center.y - this.origin.y;
             var z = sphere.center.z - this.origin.z;
             var pyth = (x * x) + (y * y) + (z * z);
-            var rr = sphere.radius * sphere.radius;
+            const radius = sphere.radius + intersectionTreshold;
+            var rr = radius * radius;
 
             if (pyth <= rr) {
                 return true;
@@ -168,18 +176,10 @@ module BABYLON {
          * @returns intersection information if hit
          */
         public intersectsTriangle(vertex0: Vector3, vertex1: Vector3, vertex2: Vector3): Nullable<IntersectionInfo> {
-            if (!this._edge1) {
-                this._edge1 = Vector3.Zero();
-                this._edge2 = Vector3.Zero();
-                this._pvec = Vector3.Zero();
-                this._tvec = Vector3.Zero();
-                this._qvec = Vector3.Zero();
-            }
-
-            vertex1.subtractToRef(vertex0, this._edge1);
-            vertex2.subtractToRef(vertex0, this._edge2);
-            Vector3.CrossToRef(this.direction, this._edge2, this._pvec);
-            var det = Vector3.Dot(this._edge1, this._pvec);
+            vertex1.subtractToRef(vertex0, Ray._edge1);
+            vertex2.subtractToRef(vertex0, Ray._edge2);
+            Vector3.CrossToRef(this.direction, Ray._edge2, Ray._pvec);
+            var det = Vector3.Dot(Ray._edge1, Ray._pvec);
 
             if (det === 0) {
                 return null;
@@ -187,24 +187,24 @@ module BABYLON {
 
             var invdet = 1 / det;
 
-            this.origin.subtractToRef(vertex0, this._tvec);
+            this.origin.subtractToRef(vertex0, Ray._tvec);
 
-            var bu = Vector3.Dot(this._tvec, this._pvec) * invdet;
+            var bu = Vector3.Dot(Ray._tvec, Ray._pvec) * invdet;
 
             if (bu < 0 || bu > 1.0) {
                 return null;
             }
 
-            Vector3.CrossToRef(this._tvec, this._edge1, this._qvec);
+            Vector3.CrossToRef(Ray._tvec, Ray._edge1, Ray._qvec);
 
-            var bv = Vector3.Dot(this.direction, this._qvec) * invdet;
+            var bv = Vector3.Dot(this.direction, Ray._qvec) * invdet;
 
             if (bv < 0 || bu + bv > 1.0) {
                 return null;
             }
 
             //check if the distance is longer than the predefined length.
-            var distance = Vector3.Dot(this._edge2, this._qvec) * invdet;
+            var distance = Vector3.Dot(Ray._edge2, Ray._qvec) * invdet;
             if (distance > this.length) {
                 return null;
             }
@@ -353,7 +353,7 @@ module BABYLON {
                 if (-d < 0.0) {
                     sN = 0.0;
                 } else if (-d > a) {
-                    sN = sD;
+                    sN = sD;
                        }
                 else {
                     sN = -d;
@@ -441,7 +441,7 @@ module BABYLON {
         * @param world a matrix to transform the ray to. Default is the identity matrix.
         * @returns the new ray
         */
-        public static CreateNewFromTo(origin: Vector3, end: Vector3, world: Matrix = Matrix.Identity()): Ray {
+        public static CreateNewFromTo(origin: Vector3, end: Vector3, world: Matrix = Matrix.IdentityReadOnly): Ray {
             var direction = end.subtract(origin);
             var length = Math.sqrt((direction.x * direction.x) + (direction.y * direction.y) + (direction.z * direction.z));
             direction.normalize();

+ 17 - 4
src/Math/babylon.math.ts

@@ -4250,11 +4250,19 @@ module BABYLON {
             this._isIdentity3x2Dirty = true;
         }
 
+        /** @hidden */
+        private _updateIdentityStatus(isIdentity:boolean) {
+            this.updateFlag = Matrix._updateFlagSeed++;
+            this._isIdentityDirty = false;
+            this._isIdentity = isIdentity;
+        }
+
+
         /**
          * Creates an empty matrix (filled with zeros)
          */
         public constructor() {
-            this._markAsUpdated();
+            this._updateIdentityStatus(false);
         }
 
         // Properties
@@ -4354,7 +4362,7 @@ module BABYLON {
                 this.m[index] = 0.0;
             }
 
-            this._markAsUpdated();
+            this._updateIdentityStatus(false);
             return this;
         }
 
@@ -5099,10 +5107,12 @@ module BABYLON {
          * @returns a new identity matrix
          */
         public static Identity(): Matrix {
-            return Matrix.FromValues(1.0, 0.0, 0.0, 0.0,
+            const identity = Matrix.FromValues(1.0, 0.0, 0.0, 0.0,
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 0.0, 1.0);
+            identity._updateIdentityStatus(true);
+            return identity;
         }
 
         /**
@@ -5114,6 +5124,7 @@ module BABYLON {
                 0.0, 1.0, 0.0, 0.0,
                 0.0, 0.0, 1.0, 0.0,
                 0.0, 0.0, 0.0, 1.0, result);
+            result._updateIdentityStatus(true);
         }
 
         /**
@@ -5121,10 +5132,12 @@ module BABYLON {
          * @returns a new zero matrix
          */
         public static Zero(): Matrix {
-            return Matrix.FromValues(0.0, 0.0, 0.0, 0.0,
+            const zero = Matrix.FromValues(0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0,
                 0.0, 0.0, 0.0, 0.0);
+            zero._updateIdentityStatus(false);
+            return zero;
         }
 
         /**

+ 10 - 11
src/Mesh/babylon.abstractMesh.ts

@@ -266,13 +266,13 @@ module BABYLON {
 
             // remove from material mesh map id needed
             if (this._material && this._material.meshMap) {
-                this._material.meshMap[this.uniqueId] = undefined;
+                this._material.meshMap[this.uniqueId] = undefined;
             }
 
             this._material = value;
 
             if (value && value.meshMap) {
-                value.meshMap[this.uniqueId] = this;
+                value.meshMap[this.uniqueId] = this;
             }
 
             if (this.onMaterialChangedObservable.hasObservers) {
@@ -1298,8 +1298,9 @@ module BABYLON {
          */
         public intersects(ray: Ray, fastCheck?: boolean): PickingInfo {
             var pickingInfo = new PickingInfo();
-
-            if (!this.subMeshes || !this._boundingInfo || !ray.intersectsSphere(this._boundingInfo.boundingSphere) || !ray.intersectsBox(this._boundingInfo.boundingBox)) {
+            const intersectionTreshold = this.getClassName() === "LinesMesh" ? (<LinesMesh>(this as any)).intersectionThreshold : 0;
+            const boundingInfo = this._boundingInfo;
+            if (!this.subMeshes || !boundingInfo || !ray.intersectsSphere(boundingInfo.boundingSphere, intersectionTreshold) || !ray.intersectsBox(boundingInfo.boundingBox, intersectionTreshold)) {
                 return pickingInfo;
             }
 
@@ -1335,13 +1336,11 @@ module BABYLON {
 
             if (intersectInfo) {
                 // Get picked point
-                var world = this.getWorldMatrix();
-                var worldOrigin = Vector3.TransformCoordinates(ray.origin, world);
-                var direction = ray.direction.clone();
-                direction = direction.scale(intersectInfo.distance);
-                var worldDirection = Vector3.TransformNormal(direction, world);
-
-                var pickedPoint = worldOrigin.add(worldDirection);
+                const world = this.getWorldMatrix();
+                const worldOrigin = Vector3.TransformCoordinates(ray.origin, world);
+                const direction = ray.direction.scaleToRef(intersectInfo.distance, Tmp.Vector3[0]);
+                const worldDirection = Vector3.TransformNormal(direction, world);
+                const pickedPoint = worldDirection.addInPlace(worldOrigin);
 
                 // Return result
                 pickingInfo.hit = true;

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

@@ -62,9 +62,6 @@ module BABYLON {
          */
         public set boundingBias(value: Vector2) {
             if (this._boundingBias) {
-                if (this._boundingBias.equals(value)) {
-                    return;
-                }
                 this._boundingBias.copyFrom(value);
             }
             else {
@@ -120,11 +117,6 @@ module BABYLON {
 
             // applyToMesh
             if (mesh) {
-                if (mesh.getClassName() === "LinesMesh") {
-                    this.boundingBias = new Vector2(0, (<LinesMesh>mesh).intersectionThreshold);
-                    this._updateExtend();
-                }
-
                 this.applyToMesh(mesh);
                 mesh.computeWorldMatrix(true);
             }
@@ -317,18 +309,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);
+                    }
+                    else {
+                        mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
+                    }
 
+                    const subMeshes = mesh.subMeshes;
+                    for (const subMesh of subMeshes) {
                         subMesh.refreshBoundingInfo();
                     }
                 }
@@ -681,7 +675,7 @@ module BABYLON {
                 }
                 var buffer = this._vertexBuffers[kind].getBuffer();
                 if (buffer) {
-                    buffer.references = numOfMeshes;
+                    buffer.references = numOfMeshes;
                 }
 
                 if (kind === VertexBuffer.PositionKind) {
@@ -815,7 +809,7 @@ module BABYLON {
         /** @hidden */
         public _generatePointsArray(): boolean {
             if (this._positions) {
-                return true;
+                return true;
             }
 
             var data = this.getVerticesData(VertexBuffer.PositionKind);

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

@@ -214,13 +214,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);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(meshBB.minimum, meshBB.maximum);
+            }
 
             this._updateBoundingInfo();
             return this;

+ 0 - 4
src/Mesh/babylon.linesMesh.ts

@@ -31,11 +31,7 @@ module BABYLON {
             if (this._intersectionThreshold === value) {
                 return;
             }
-
             this._intersectionThreshold = value;
-            if (this.geometry) {
-                this.geometry.boundingBias = new Vector2(0, value);
-            }
         }
 
         private _intersectionThreshold: number;

+ 10 - 4
src/Mesh/babylon.mesh.ts

@@ -871,9 +871,10 @@ module BABYLON {
         /** @hidden */
         public _registerInstanceForRenderId(instance: InstancedMesh, renderId: number): Mesh {
             if (!this._instanceDataStorage.visibleInstances) {
-                this._instanceDataStorage.visibleInstances = {};
-                this._instanceDataStorage.visibleInstances.defaultRenderId = renderId;
-                this._instanceDataStorage.visibleInstances.selfDefaultRenderId = this._renderId;
+                this._instanceDataStorage.visibleInstances = {
+                    defaultRenderId: renderId,
+                    selfDefaultRenderId: this._renderId
+                };
             }
 
             if (!this._instanceDataStorage.visibleInstances[renderId]) {
@@ -903,7 +904,12 @@ module BABYLON {
             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);
+                }
+                else {
+                    this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+                }
             }
 
             if (this.subMeshes) {

+ 9 - 3
src/Mesh/babylon.subMesh.ts

@@ -214,7 +214,13 @@ module BABYLON {
             } else {
                 extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
             }
-            this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+
+            if (this._boundingInfo) {
+                this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(extend.minimum, extend.maximum);
+            }
             return this;
         }
 
@@ -469,10 +475,10 @@ module BABYLON {
                 var vertexIndex = indices[index];
 
                 if (vertexIndex < minVertexIndex) {
-                    minVertexIndex = vertexIndex;
+                    minVertexIndex = vertexIndex;
                 }
                 if (vertexIndex > maxVertexIndex) {
-                    maxVertexIndex = vertexIndex;
+                    maxVertexIndex = vertexIndex;
                 }
             }