Browse Source

Merge pull request #5258 from barroij/SPS_optimization

SPS optimization
David Catuhe 6 years ago
parent
commit
91e343d331

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

@@ -11,6 +11,7 @@
 
 ### Core Engine
 
+- Refactor of the SolidParticleSystem code for performance and code quality improvement ([barroij](https://github.com/barroij))
 - Added utility function `Tools.BuildArray` for array initialisation ([barroij](https://github.com/barroij))
 
 ### glTF Loader

+ 76 - 92
src/Culling/babylon.boundingBox.ts

@@ -1,4 +1,4 @@
-module BABYLON {
+module BABYLON {
     /**
      * Class used to store bounding box information
      */
@@ -59,9 +59,10 @@ module BABYLON {
          * Creates a new bounding box
          * @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
          */
-        constructor(min: Vector3, max: Vector3) {
-            this.reConstruct(min, max);
+        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+            this.reConstruct(min, max, worldMatrix);
         }
 
         // Methods
@@ -70,46 +71,28 @@ module BABYLON {
          * Recreates the entire bounding box from scratch
          * @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) {
-            this.minimum.copyFrom(min);
-            this.maximum.copyFrom(max);
-
-            // Bounding vectors
-            this.vectors[0].copyFrom(this.minimum);
-            this.vectors[1].copyFrom(this.maximum);
-            this.vectors[2].copyFrom(this.minimum);
-            this.vectors[3].copyFrom(this.minimum);
-            this.vectors[4].copyFrom(this.minimum);
-            this.vectors[5].copyFrom(this.maximum);
-            this.vectors[6].copyFrom(this.maximum);
-            this.vectors[7].copyFrom(this.maximum);
-
-            this.vectors[2].x = this.maximum.x;
-            this.vectors[3].y = this.maximum.y;
-            this.vectors[4].z = this.maximum.z;
-            this.vectors[5].z = this.minimum.z;
-            this.vectors[6].x = this.minimum.x;
-            this.vectors[7].y = this.minimum.y;
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+            const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
+            const vectors = this.vectors;
+
+            this.minimum.copyFromFloats(minX, minY, minZ);
+            this.maximum.copyFromFloats(maxX, maxY, maxZ);
+            vectors[0].copyFromFloats(minX, minY, minZ);
+            vectors[1].copyFromFloats(maxX, maxY, maxZ);
+            vectors[2].copyFromFloats(maxX, minY, minZ);
+            vectors[3].copyFromFloats(minX, maxY, minZ);
+            vectors[4].copyFromFloats(minX, minY, maxZ);
+            vectors[5].copyFromFloats(maxX, maxY, minZ);
+            vectors[6].copyFromFloats(minX, maxY, maxZ);
+            vectors[7].copyFromFloats(maxX, minY, maxZ);
 
             // OBB
-            this.center.copyFrom(this.maximum).addInPlace(this.minimum).scaleInPlace(0.5);
-            this.extendSize.copyFrom(this.maximum).subtractInPlace(this.minimum).scaleInPlace(0.5);
-            for (var index = 0; index < 3; index++) {
-                this.directions[index].copyFromFloats(0, 0, 0);
-            }
-
-            // World
-            for (var index = 0; index < 8; index++) {
-                this.vectorsWorld[index].copyFromFloats(0, 0, 0);
-            }
-
-            this.minimumWorld.copyFromFloats(0, 0, 0);
-            this.maximumWorld.copyFromFloats(0, 0, 0);
-            this.centerWorld.copyFromFloats(0, 0, 0);
-            this.extendSizeWorld.copyFromFloats(0, 0, 0);
+            this.maximum.addToRef(min, this.center).scaleInPlace(0.5);
+            this.maximum.subtractToRef(max, this.extendSize).scaleInPlace(0.5);
 
-            this._update(this._worldMatrix || Matrix.Identity());
+            this._update(worldMatrix || this._worldMatrix || Matrix.Identity());
         }
 
         /**
@@ -118,13 +101,15 @@ module BABYLON {
          * @returns the current bounding box
          */
         public scale(factor: number): BoundingBox {
-            const diff = Tmp.Vector3[0].copyFrom(this.maximum).subtractInPlace(this.minimum);
-            let distance = diff.length() * factor;
-            diff.normalize();
-            let newRadius = diff.scaleInPlace(distance * 0.5);
+            const tmpVectors = Tmp.Vector3;
+            const diff = this.maximum.subtractToRef(this.minimum, tmpVectors[0]);
+            const len = diff.length();
+            diff.normalizeFromLength(len);
+            const distance = len * factor;
+            const newRadius = diff.scaleInPlace(distance * 0.5);
 
-            const min = Tmp.Vector3[1].copyFrom(this.center).subtractInPlace(newRadius);
-            const max = Tmp.Vector3[2].copyFrom(this.center).addInPlace(newRadius);
+            const min = this.center.subtractToRef(newRadius, tmpVectors[1]);
+            const max = this.center.addToRef(newRadius, tmpVectors[2]);
 
             this.reConstruct(min, max);
 
@@ -151,27 +136,30 @@ module BABYLON {
 
         /** @hidden */
         public _update(world: Matrix): void {
-            Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this.minimumWorld);
-            Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this.maximumWorld);
-
-            for (var index = 0; index < 8; index++) {
-                var v = this.vectorsWorld[index];
-                Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
-                this.minimumWorld.minimizeInPlace(v);
-                this.maximumWorld.maximizeInPlace(v);
+            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);
             }
 
             // Extend
-            this.maximumWorld.subtractToRef(this.minimumWorld, this.extendSizeWorld);
-            this.extendSizeWorld.scaleInPlace(0.5);
+            maxWorld.subtractToRef(minWorld, this.extendSizeWorld).scaleInPlace(0.5);
+            // OOBB
+            maxWorld.addToRef(minWorld, this.centerWorld).scaleInPlace(0.5);
 
-            // OBB
-            this.maximumWorld.addToRef(this.minimumWorld, this.centerWorld);
-            this.centerWorld.scaleInPlace(0.5);
-
-            Vector3.FromFloatArrayToRef(world.m, 0, this.directions[0]);
-            Vector3.FromFloatArrayToRef(world.m, 4, this.directions[1]);
-            Vector3.FromFloatArrayToRef(world.m, 8, this.directions[2]);
+            Vector3.FromArrayToRef(world.m, 0, directions[0]);
+            Vector3.FromArrayToRef(world.m, 4, directions[1]);
+            Vector3.FromArrayToRef(world.m, 8, directions[2]);
 
             this._worldMatrix = world;
         }
@@ -200,17 +188,21 @@ module BABYLON {
          * @returns true if the point is inside the bounding box
          */
         public intersectsPoint(point: Vector3): boolean {
+            const min = this.minimumWorld;
+            const max = this.maximumWorld;
+            const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
+            const pointX = point.x, pointY = point.y, pointZ = point.z;
             var delta = -Epsilon;
 
-            if (this.maximumWorld.x - point.x < delta || delta > point.x - this.minimumWorld.x) {
+            if (maxX - pointX < delta || delta > pointX - minX) {
                 return false;
             }
 
-            if (this.maximumWorld.y - point.y < delta || delta > point.y - this.minimumWorld.y) {
+            if (maxY - pointY < delta || delta > pointY - minY) {
                 return false;
             }
 
-            if (this.maximumWorld.z - point.z < delta || delta > point.z - this.minimumWorld.z) {
+            if (maxZ - pointZ < delta || delta > pointZ - minZ) {
                 return false;
             }
 
@@ -233,15 +225,19 @@ module BABYLON {
          * @returns true if there is an intersection
          */
         public intersectsMinMax(min: Vector3, max: Vector3): boolean {
-            if (this.maximumWorld.x < min.x || this.minimumWorld.x > max.x) {
+            const myMin = this.minimumWorld;
+            const myMax = this.maximumWorld;
+            const myMinX = myMin.x, myMinY = myMin.y, myMinZ = myMin.z, myMaxX = myMax.x, myMaxY = myMax.y, myMaxZ = myMax.z;
+            const minX = min.x, minY = min.y, minZ = min.z, maxX = max.x, maxY = max.y, maxZ = max.z;
+            if (myMaxX < minX || myMinX > maxX) {
                 return false;
             }
 
-            if (this.maximumWorld.y < min.y || this.minimumWorld.y > max.y) {
+            if (myMaxY < minY || myMinY > maxY) {
                 return false;
             }
 
-            if (this.maximumWorld.z < min.z || this.minimumWorld.z > max.z) {
+            if (myMaxZ < minZ || myMinZ > maxZ) {
                 return false;
             }
 
@@ -257,19 +253,7 @@ module BABYLON {
          * @returns true if there is an intersection
          */
         public static Intersects(box0: BoundingBox, box1: BoundingBox): boolean {
-            if (box0.maximumWorld.x < box1.minimumWorld.x || box0.minimumWorld.x > box1.maximumWorld.x) {
-                return false;
-            }
-
-            if (box0.maximumWorld.y < box1.minimumWorld.y || box0.minimumWorld.y > box1.maximumWorld.y) {
-                return false;
-            }
-
-            if (box0.maximumWorld.z < box1.minimumWorld.z || box0.minimumWorld.z > box1.maximumWorld.z) {
-                return false;
-            }
-
-            return true;
+            return box0.intersectsMinMax(box1.minimumWorld, box1.maximumWorld);
         }
 
         /**
@@ -293,9 +277,10 @@ module BABYLON {
          * @return true if there is an inclusion
          */
         public static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
-            for (var p = 0; p < 6; p++) {
-                for (var i = 0; i < 8; i++) {
-                    if (frustumPlanes[p].dotCoordinate(boundingVectors[i]) < 0) {
+            for (var p = 0; p < 6; ++p) {
+                const frustumPlane = frustumPlanes[p];
+                for (var i = 0; i < 8; ++i) {
+                    if (frustumPlane.dotCoordinate(boundingVectors[i]) < 0) {
                         return false;
                     }
                 }
@@ -310,17 +295,16 @@ module BABYLON {
          * @return true if there is an intersection
          */
         public static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean {
-            for (var p = 0; p < 6; p++) {
-                var inCount = 8;
-
-                for (var i = 0; i < 8; i++) {
-                    if (frustumPlanes[p].dotCoordinate(boundingVectors[i]) < 0) {
-                        --inCount;
-                    } else {
+            for (var p = 0; p < 6; ++p) {
+                let canReturnFalse = true;
+                const frustumPlane = frustumPlanes[p];
+                for (var i = 0; i < 8; ++i) {
+                    if (frustumPlane.dotCoordinate(boundingVectors[i]) >= 0) {
+                        canReturnFalse = false;
                         break;
                     }
                 }
-                if (inCount === 0) {
+                if (canReturnFalse) {
                     return false;
                 }
             }

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

@@ -56,14 +56,27 @@ module BABYLON {
         public boundingSphere: BoundingSphere;
 
         private _isLocked = false;
+
         /**
          * Constructs bounding info
          * @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
+         */
+        constructor(minimum: Vector3, maximum: Vector3, worldMatrix?: Matrix) {
+            this.boundingBox = new BoundingBox(minimum, maximum, worldMatrix);
+            this.boundingSphere = new BoundingSphere(minimum, maximum, worldMatrix);
+        }
+
+        /**
+         * Recreates the entire bounding info from scratch
+         * @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
          */
-        constructor(minimum: Vector3, maximum: Vector3) {
-            this.boundingBox = new BoundingBox(minimum, maximum);
-            this.boundingSphere = new BoundingSphere(minimum, maximum);
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+            this.boundingBox.reConstruct(min, max, worldMatrix);
+            this.boundingSphere.reConstruct(min, max, worldMatrix);
         }
 
         /**

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

@@ -35,17 +35,19 @@ module BABYLON {
          * Creates a new bounding sphere
          * @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
          */
-        constructor(min: Vector3, max: Vector3) {
-            this.reConstruct(min, max);
+        constructor(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
+            this.reConstruct(min, max, worldMatrix);
         }
 
         /**
          * Recreates the entire bounding sphere from scratch
          * @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) {
+        public reConstruct(min: Vector3, max: Vector3, worldMatrix?: Matrix) {
             this.minimum.copyFrom(min);
             this.maximum.copyFrom(max);
 
@@ -54,8 +56,7 @@ module BABYLON {
             Vector3.LerpToRef(min, max, 0.5, this.center);
             this.radius = distance * 0.5;
 
-            this.centerWorld.set(0, 0, 0);
-            this._update(_identityMatrix);
+            this._update(worldMatrix || _identityMatrix);
         }
 
         /**
@@ -65,9 +66,10 @@ module BABYLON {
          */
         public scale(factor: number): BoundingSphere {
             let newRadius = this.radius * factor;
-            const tempRadiusVector = Tmp.Vector3[0].set(newRadius, newRadius, newRadius);
-            let min = Tmp.Vector3[1].copyFrom(this.center).subtractInPlace(tempRadiusVector);
-            let max = Tmp.Vector3[2].copyFrom(this.center).addInPlace(tempRadiusVector);
+            const tmpVectors = Tmp.Vector3;
+            const tempRadiusVector = tmpVectors[0].copyFromFloats(newRadius, newRadius, newRadius);
+            let min = this.center.subtractToRef(tempRadiusVector, tmpVectors[1]);
+            let max = this.center.addToRef(tempRadiusVector, tmpVectors[2]);
 
             this.reConstruct(min, max);
 
@@ -91,7 +93,7 @@ module BABYLON {
         public isInFrustum(frustumPlanes: Plane[]): boolean {
             for (var i = 0; i < 6; i++) {
                 if (frustumPlanes[i].dotCoordinate(this.centerWorld) <= -this.radiusWorld) {
-                    return false;
+                    return false;
                 }
             }
 
@@ -111,7 +113,7 @@ module BABYLON {
             var distance = Math.sqrt((x * x) + (y * y) + (z * z));
 
             if (this.radiusWorld < distance) {
-                return false;
+                return false;
             }
 
             return true;
@@ -132,7 +134,7 @@ module BABYLON {
             var distance = Math.sqrt((x * x) + (y * y) + (z * z));
 
             if (sphere0.radiusWorld + sphere1.radiusWorld < distance) {
-                return false;
+                return false;
             }
 
             return true;

+ 90 - 100
src/Math/babylon.math.ts

@@ -534,10 +534,7 @@ module BABYLON {
          * @param index defines an optional index in the target array to define where to start storing values
          * @returns the current Color4 object
          */
-        public toArray(array: number[], index?: number): Color4 {
-            if (index === undefined) {
-                index = 0;
-            }
+        public toArray(array: number[], index: number = 0): Color4 {
             array[index] = this.r;
             array[index + 1] = this.g;
             array[index + 2] = this.b;
@@ -1454,8 +1451,9 @@ module BABYLON {
          * @param result defines the target vector
          */
         public static TransformToRef(vector: Vector2, transformation: Matrix, result: Vector2) {
-            var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + transformation.m[12];
-            var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + transformation.m[13];
+            const m = transformation.m;
+            var x = (vector.x * m[0]) + (vector.y * m[4]) + m[12];
+            var y = (vector.x * m[1]) + (vector.y * m[5]) + m[13];
             result.x = x;
             result.y = y;
         }
@@ -1625,9 +1623,20 @@ module BABYLON {
          * @returns the current updated Vector3
          */
         public addInPlace(otherVector: Vector3): Vector3 {
-            this.x += otherVector.x;
-            this.y += otherVector.y;
-            this.z += otherVector.z;
+            return this.addInPlaceFromFloats(otherVector.x, otherVector.y, otherVector.z);
+        }
+
+        /**
+         * Adds the given coordinates to the current Vector3
+         * @param x defines the x coordinate of the operand
+         * @param y defines the y coordinate of the operand
+         * @param z defines the z coordinate of the operand
+         * @returns the current updated Vector3
+         */
+        public addInPlaceFromFloats(x: number, y: number, z: number): Vector3 {
+            this.x += x;
+            this.y += y;
+            this.z += z;
             return this;
         }
 
@@ -1647,10 +1656,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public addToRef(otherVector: Vector3, result: Vector3): Vector3 {
-            result.x = this.x + otherVector.x;
-            result.y = this.y + otherVector.y;
-            result.z = this.z + otherVector.z;
-            return this;
+            return result.copyFromFloats(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
         }
 
         /**
@@ -1681,10 +1687,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public subtractToRef(otherVector: Vector3, result: Vector3): Vector3 {
-            result.x = this.x - otherVector.x;
-            result.y = this.y - otherVector.y;
-            result.z = this.z - otherVector.z;
-            return this;
+            return this.subtractFromFloatsToRef(otherVector.x, otherVector.y, otherVector.z, result);
         }
 
         /**
@@ -1707,10 +1710,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public subtractFromFloatsToRef(x: number, y: number, z: number, result: Vector3): Vector3 {
-            result.x = this.x - x;
-            result.y = this.y - y;
-            result.z = this.z - z;
-            return this;
+            return result.copyFromFloats(this.x - x, this.y - y, this.z - z);
         }
 
         /**
@@ -1749,10 +1749,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public scaleToRef(scale: number, result: Vector3): Vector3 {
-            result.x = this.x * scale;
-            result.y = this.y * scale;
-            result.z = this.z * scale;
-            return this;
+            return result.copyFromFloats(this.x * scale, this.y * scale, this.z * scale);
         }
 
         /**
@@ -1762,10 +1759,7 @@ module BABYLON {
          * @returns the unmodified current Vector3
          */
         public scaleAndAddToRef(scale: number, result: Vector3): Vector3 {
-            result.x += this.x * scale;
-            result.y += this.y * scale;
-            result.z += this.z * scale;
-            return this;
+            return result.addInPlaceFromFloats(this.x * scale, this.y * scale, this.z * scale);
         }
 
         /**
@@ -1816,7 +1810,7 @@ module BABYLON {
          * @returns the new Vector3
          */
         public multiply(otherVector: Vector3): Vector3 {
-            return new Vector3(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
+            return this.multiplyByFloats(otherVector.x, otherVector.y, otherVector.z);
         }
 
         /**
@@ -1826,10 +1820,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public multiplyToRef(otherVector: Vector3, result: Vector3): Vector3 {
-            result.x = this.x * otherVector.x;
-            result.y = this.y * otherVector.y;
-            result.z = this.z * otherVector.z;
-            return this;
+            return result.copyFromFloats(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
         }
 
         /**
@@ -1859,10 +1850,7 @@ module BABYLON {
          * @returns the current Vector3
          */
         public divideToRef(otherVector: Vector3, result: Vector3): Vector3 {
-            result.x = this.x / otherVector.x;
-            result.y = this.y / otherVector.y;
-            result.z = this.z / otherVector.z;
-            return this;
+            return result.copyFromFloats(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z);
         }
 
         /**
@@ -1981,16 +1969,21 @@ module BABYLON {
          * @returns the current updated Vector3
          */
         public normalize(): Vector3 {
-            var len = this.length();
+            return this.normalizeFromLength(this.length());
+        }
+
+        /**
+         * Normalize the current Vector3 with the given input length.
+         * Please note that this is an in place operation.
+         * @param len the length of the vector
+         * @returns the current updated Vector3
+         */
+        public normalizeFromLength(len : number): Vector3 {
             if (len === 0 || len === 1.0) {
                 return this;
             }
 
-            var num = 1.0 / len;
-            this.x *= num;
-            this.y *= num;
-            this.z *= num;
-            return this;
+            return this.scaleInPlace(1.0 / len);
         }
 
         /**
@@ -2011,13 +2004,10 @@ module BABYLON {
         public normalizeToRef(reference: Vector3): Vector3 {
             var len = this.length();
             if (len === 0 || len === 1.0) {
-                reference.set(this.x, this.y, this.z);
-                return reference;
+                return reference.copyFromFloats(this.x, this.y, this.z);
             }
 
-            const scale = 1.0 / len;
-            this.scaleToRef(scale, reference);
-            return reference;
+            return this.scaleToRef(1.0 / len, reference);
         }
 
         /**
@@ -2034,10 +2024,7 @@ module BABYLON {
          * @returns the current updated Vector3
          */
         public copyFrom(source: Vector3): Vector3 {
-            this.x = source.x;
-            this.y = source.y;
-            this.z = source.z;
-            return this;
+            return this.copyFromFloats(source.x, source.y, source.z);
         }
 
         /**
@@ -2065,6 +2052,16 @@ module BABYLON {
             return this.copyFromFloats(x, y, z);
         }
 
+        /**
+         * Copies the given float to the current Vector3 coordinates
+         * @param v defines the x, y and z coordinates of the operand
+         * @returns the current updated Vector3
+         */
+        public setAll(v: number): Vector3 {
+            this.x = this.y = this.z = v;
+            return this;
+        }
+
         // Statics
 
         /**
@@ -2092,10 +2089,10 @@ module BABYLON {
          * @return the angle between vector0 and vector1
          */
         public static GetAngleBetweenVectors(vector0: Vector3, vector1: Vector3, normal: Vector3): number {
-            const v0: Vector3 = MathTmp.Vector3[1].copyFrom(vector0).normalize();
-            const v1: Vector3 = MathTmp.Vector3[2].copyFrom(vector1).normalize();
+            const v0: Vector3 = vector0.normalizeToRef(MathTmp.Vector3[0]);
+            const v1: Vector3 = vector1.normalizeToRef(MathTmp.Vector3[1]);
             const dot: number = Vector3.Dot(v0, v1);
-            const n = MathTmp.Vector3[3];
+            const n = MathTmp.Vector3[2];
             Vector3.CrossToRef(v0, v1, n);
             if (Vector3.Dot(n, normal) > 0) {
                 return Math.acos(dot);
@@ -2158,9 +2155,7 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static FromFloatsToRef(x: number, y: number, z: number, result: Vector3): void {
-            result.x = x;
-            result.y = y;
-            result.z = z;
+            result.copyFromFloats(x, y, z);
         }
 
         /**
@@ -2241,14 +2236,7 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static TransformCoordinatesToRef(vector: Vector3, transformation: Matrix, result: Vector3): void {
-            var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]) + transformation.m[12];
-            var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]) + transformation.m[13];
-            var z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]) + transformation.m[14];
-            var w = (vector.x * transformation.m[3]) + (vector.y * transformation.m[7]) + (vector.z * transformation.m[11]) + transformation.m[15];
-
-            result.x = x / w;
-            result.y = y / w;
-            result.z = z / w;
+            return Vector3.TransformCoordinatesFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
         }
 
         /**
@@ -2261,14 +2249,15 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static TransformCoordinatesFromFloatsToRef(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void {
-            var rx = (x * transformation.m[0]) + (y * transformation.m[4]) + (z * transformation.m[8]) + transformation.m[12];
-            var ry = (x * transformation.m[1]) + (y * transformation.m[5]) + (z * transformation.m[9]) + transformation.m[13];
-            var rz = (x * transformation.m[2]) + (y * transformation.m[6]) + (z * transformation.m[10]) + transformation.m[14];
-            var rw = (x * transformation.m[3]) + (y * transformation.m[7]) + (z * transformation.m[11]) + transformation.m[15];
+            const m = transformation.m;
+            var rx = x * m[0] + y * m[4] + z * m[8] + m[12];
+            var ry = x * m[1] + y * m[5] + z * m[9] + m[13];
+            var rz = x * m[2] + y * m[6] + z * m[10] + m[14];
+            var rw = 1 / (x * m[3] + y * m[7] + z * m[11] + m[15]);
 
-            result.x = rx / rw;
-            result.y = ry / rw;
-            result.z = rz / rw;
+            result.x = rx * rw;
+            result.y = ry * rw;
+            result.z = rz * rw;
         }
 
         /**
@@ -2292,12 +2281,7 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static TransformNormalToRef(vector: Vector3, transformation: Matrix, result: Vector3): void {
-            var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]);
-            var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]);
-            var z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]);
-            result.x = x;
-            result.y = y;
-            result.z = z;
+            this.TransformNormalFromFloatsToRef(vector.x, vector.y, vector.z, transformation, result);
         }
 
         /**
@@ -2310,9 +2294,10 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, transformation: Matrix, result: Vector3): void {
-            result.x = (x * transformation.m[0]) + (y * transformation.m[4]) + (z * transformation.m[8]);
-            result.y = (x * transformation.m[1]) + (y * transformation.m[5]) + (z * transformation.m[9]);
-            result.z = (x * transformation.m[2]) + (y * transformation.m[6]) + (z * transformation.m[10]);
+            const m = transformation.m;
+            result.x = x * m[0] + y * m[4] + z * m[8];
+            result.y = x * m[1] + y * m[5] + z * m[9];
+            result.z = x * m[2] + y * m[6] + z * m[10];
         }
 
         /**
@@ -2471,8 +2456,7 @@ module BABYLON {
          * @param result defines the Vector3 where to store the result
          */
         public static NormalizeToRef(vector: Vector3, result: Vector3): void {
-            result.copyFrom(vector);
-            result.normalize();
+            vector.normalizeToRef(result);
         }
 
         private static _viewportMatrixCache: Matrix;
@@ -3103,14 +3087,7 @@ module BABYLON {
                 return this;
             }
 
-            var num = 1.0 / len;
-
-            this.x *= num;
-            this.y *= num;
-            this.z *= num;
-            this.w *= num;
-
-            return this;
+            return this.scaleInPlace(1.0 / len);
         }
 
         /**
@@ -3166,6 +3143,16 @@ module BABYLON {
             return this.copyFromFloats(x, y, z, w);
         }
 
+        /**
+         * Copies the given float to the current Vector3 coordinates
+         * @param v defines the x, y, z and w coordinates of the operand
+         * @returns the current updated Vector3
+         */
+        public setAll(v: number): Vector4 {
+            this.x = this.y = this.z = this.w = v;
+            return this;
+        }
+
         // Statics
         /**
          * Returns a new Vector4 set from the starting index of the given array.
@@ -3327,9 +3314,10 @@ module BABYLON {
          * @param result the vector to store the result in
          */
         public static TransformNormalToRef(vector: Vector4, transformation: Matrix, result: Vector4): void {
-            var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]);
-            var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]);
-            var z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]);
+            const m = transformation.m;
+            var x = (vector.x * m[0]) + (vector.y * m[4]) + (vector.z * m[8]);
+            var y = (vector.x * m[1]) + (vector.y * m[5]) + (vector.z * m[9]);
+            var z = (vector.x * m[2]) + (vector.y * m[6]) + (vector.z * m[10]);
             result.x = x;
             result.y = y;
             result.z = z;
@@ -3347,9 +3335,10 @@ module BABYLON {
          * @param result the vector to store the results in
          */
         public static TransformNormalFromFloatsToRef(x: number, y: number, z: number, w: number, transformation: Matrix, result: Vector4): void {
-            result.x = (x * transformation.m[0]) + (y * transformation.m[4]) + (z * transformation.m[8]);
-            result.y = (x * transformation.m[1]) + (y * transformation.m[5]) + (z * transformation.m[9]);
-            result.z = (x * transformation.m[2]) + (y * transformation.m[6]) + (z * transformation.m[10]);
+            const m = transformation.m;
+            result.x = (x * m[0]) + (y * m[4]) + (z * m[8]);
+            result.y = (x * m[1]) + (y * m[5]) + (z * m[9]);
+            result.z = (x * m[2]) + (y * m[6]) + (z * m[10]);
             result.w = w;
         }
     }
@@ -7179,10 +7168,11 @@ module BABYLON {
      * @hidden
      */
     export class Tmp {
+
         public static Color3: Color3[] = Tools.BuildArray(3, Color3.Black);
         public static Color4: Color4[] = Tools.BuildArray(3, () => new Color4(0, 0, 0, 0));
         public static Vector2: Vector2[] = Tools.BuildArray(3, Vector2.Zero); // 3 temp Vector2 at once should be enough
-        public static Vector3: Vector3[] = Tools.BuildArray(9, Vector3.Zero); // 9 temp Vector3 at once should be enough
+        public static Vector3: Vector3[] = Tools.BuildArray(13, Vector3.Zero); // 13 temp Vector3 at once should be enough
         public static Vector4: Vector4[] = Tools.BuildArray(3, Vector4.Zero); // 3 temp Vector4 at once should be enough
         public static Quaternion: Quaternion[] = Tools.BuildArray(2, Quaternion.Zero); // 2 temp Quaternion at once should be enough
         public static Matrix: Matrix[] = Tools.BuildArray(6, Matrix.Identity); // 6 temp Matrices at once should be enough

+ 6 - 2
src/Mesh/babylon.abstractMesh.ts

@@ -1031,8 +1031,12 @@ module BABYLON {
 
         /** @hidden */
         public _updateBoundingInfo(): AbstractMesh {
-            this._boundingInfo = this._boundingInfo || new BoundingInfo(this.absolutePosition, this.absolutePosition);
-            this._boundingInfo.update(this.worldMatrixFromCache);
+            if (this._boundingInfo) {
+                this._boundingInfo.update(this.worldMatrixFromCache);
+            }
+            else {
+                this._boundingInfo = new BoundingInfo(this.absolutePosition, this.absolutePosition, this.worldMatrixFromCache);
+            }
             this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);
             return this;
         }

+ 27 - 38
src/Mesh/babylon.meshBuilder.ts

@@ -162,48 +162,32 @@ module BABYLON {
             if (instance) {   // existing ribbon instance update
                 // positionFunction : ribbon case
                 // only pathArray and sideOrientation parameters are taken into account for positions update
-                Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, Tmp.Vector3[0]);         // minimum
-                Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, Tmp.Vector3[1]);
+                const minimum = Tmp.Vector3[0].setAll(Number.MAX_VALUE);
+                const maximum = Tmp.Vector3[1].setAll(-Number.MAX_VALUE);
                 var positionFunction = (positions: FloatArray) => {
                     var minlg = pathArray[0].length;
                     var mesh = (<Mesh>instance);
                     var i = 0;
                     var ns = (mesh._originalBuilderSideOrientation === Mesh.DOUBLESIDE) ? 2 : 1;
-                    for (var si = 1; si <= ns; si++) {
-                        for (var p = 0; p < pathArray.length; p++) {
+                    for (var si = 1; si <= ns; ++si) {
+                        for (var p = 0; p < pathArray.length; ++p) {
                             var path = pathArray[p];
                             var l = path.length;
                             minlg = (minlg < l) ? minlg : l;
-                            var j = 0;
-                            while (j < minlg) {
-                                positions[i] = path[j].x;
-                                positions[i + 1] = path[j].y;
-                                positions[i + 2] = path[j].z;
-                                if (path[j].x < Tmp.Vector3[0].x) {
-                                    Tmp.Vector3[0].x = path[j].x;
-                                }
-                                if (path[j].x > Tmp.Vector3[1].x) {
-                                    Tmp.Vector3[1].x = path[j].x;
-                                }
-                                if (path[j].y < Tmp.Vector3[0].y) {
-                                    Tmp.Vector3[0].y = path[j].y;
-                                }
-                                if (path[j].y > Tmp.Vector3[1].y) {
-                                    Tmp.Vector3[1].y = path[j].y;
-                                }
-                                if (path[j].z < Tmp.Vector3[0].z) {
-                                    Tmp.Vector3[0].z = path[j].z;
-                                }
-                                if (path[j].z > Tmp.Vector3[1].z) {
-                                    Tmp.Vector3[1].z = path[j].z;
-                                }
-                                j++;
+                            for (let j = 0; j < minlg; ++j) {
+                                const pathPoint = path[j];
+                                positions[i] = pathPoint.x;
+                                positions[i + 1] = pathPoint.y;
+                                positions[i + 2] = pathPoint.z;
+                                minimum.minimizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);
+                                maximum.maximizeInPlaceFromFloats(pathPoint.x, pathPoint.y, pathPoint.z);
                                 i += 3;
                             }
                             if (mesh._creationDataStorage && mesh._creationDataStorage.closePath) {
-                                positions[i] = path[0].x;
-                                positions[i + 1] = path[0].y;
-                                positions[i + 2] = path[0].z;
+                                const pathPoint = path[0];
+                                positions[i] = pathPoint.x;
+                                positions[i + 1] = pathPoint.y;
+                                positions[i + 2] = pathPoint.z;
                                 i += 3;
                             }
                         }
@@ -211,16 +195,21 @@ module BABYLON {
                 };
                 var positions = <FloatArray>instance.getVerticesData(VertexBuffer.PositionKind);
                 positionFunction(positions);
-                instance._boundingInfo = new BoundingInfo(Tmp.Vector3[2], Tmp.Vector3[3]);
-                instance._boundingInfo.update(instance._worldMatrix);
+                if (instance._boundingInfo) {
+                    instance._boundingInfo.reConstruct(minimum, maximum, instance._worldMatrix);
+                }
+                else {
+                    instance._boundingInfo = new BoundingInfo(minimum, maximum, instance._worldMatrix);
+                }
                 instance.updateVerticesData(VertexBuffer.PositionKind, positions, false, false);
                 if (options.colors) {
                     var colors = <FloatArray>instance.getVerticesData(VertexBuffer.ColorKind);
-                    for (var c = 0; c < options.colors.length; c++) {
-                        colors[c * 4] = options.colors[c].r;
-                        colors[c * 4 + 1] = options.colors[c].g;
-                        colors[c * 4 + 2] = options.colors[c].b;
-                        colors[c * 4 + 3] = options.colors[c].a;
+                    for (var c = 0, colorIndex = 0; c < options.colors.length; c++, colorIndex += 4) {
+                        const color = options.colors[c];
+                        colors[colorIndex] = color.r;
+                        colors[colorIndex + 1] = color.g;
+                        colors[colorIndex + 2] = color.b;
+                        colors[colorIndex + 3] = color.a;
                     }
                     instance.updateVerticesData(VertexBuffer.ColorKind, colors, false, false);
                 }

+ 18 - 0
src/Particles/babylon.solidParticle.ts

@@ -172,6 +172,24 @@ module BABYLON {
             }
             return this._boundingInfo.intersects(target._boundingInfo, false);
         }
+
+        /**
+         * get the rotation matrix of the particle
+         * @hidden
+         */
+        public getRotationMatrix(m : Matrix) {
+            let quaternion: Quaternion;
+            if (this.rotationQuaternion) {
+                quaternion = this.rotationQuaternion;
+            }
+            else {
+                quaternion = Tmp.Quaternion[0];
+                const rotation = this.rotation;
+                Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
+            }
+
+            quaternion.toRotationMatrix(m);
+        }
     }
 
     /**

+ 294 - 425
src/Particles/babylon.solidParticleSystem.ts

@@ -1,4 +1,6 @@
 module BABYLON {
+    const depthSortFunction = (p1: DepthSortedParticle, p2: DepthSortedParticle) => p2.sqDistance - p1.sqDistance;
+
     /**
      * The SPS is a single updatable mesh. The solid particles are simply separate parts or faces fo this big mesh.
      *As it is just a mesh, the SPS has all the same properties than any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.
@@ -89,8 +91,6 @@ module BABYLON {
         private _depthSort: boolean = false;
         private _shapeCounter: number = 0;
         private _copy: SolidParticle = new SolidParticle(0, 0, 0, null, 0, 0, this);
-        private _shape: Vector3[];
-        private _shapeUV: number[];
         private _color: Color4 = new Color4(0, 0, 0, 0);
         private _computeParticleColor: boolean = true;
         private _computeParticleTexture: boolean = true;
@@ -98,47 +98,10 @@ module BABYLON {
         private _computeParticleVertex: boolean = false;
         private _computeBoundingBox: boolean = false;
         private _depthSortParticles: boolean = true;
-        private _cam_axisZ: Vector3 = Vector3.Zero();
-        private _cam_axisY: Vector3 = Vector3.Zero();
-        private _cam_axisX: Vector3 = Vector3.Zero();
-        private _axisZ: Vector3 = Axis.Z;
         private _camera: TargetCamera;
-        private _particle: SolidParticle;
-        private _camDir: Vector3 = Vector3.Zero();
-        private _camInvertedPosition: Vector3 = Vector3.Zero();
-        private _rotMatrix: Matrix = new Matrix();
-        private _invertMatrix: Matrix = new Matrix();
-        private _rotated: Vector3 = Vector3.Zero();
-        private _quaternion: Quaternion = new Quaternion();
-        private _vertex: Vector3 = Vector3.Zero();
-        private _normal: Vector3 = Vector3.Zero();
-        private _yaw: number = 0.0;
-        private _pitch: number = 0.0;
-        private _roll: number = 0.0;
-        private _halfroll: number = 0.0;
-        private _halfpitch: number = 0.0;
-        private _halfyaw: number = 0.0;
-        private _sinRoll: number = 0.0;
-        private _cosRoll: number = 0.0;
-        private _sinPitch: number = 0.0;
-        private _cosPitch: number = 0.0;
-        private _sinYaw: number = 0.0;
-        private _cosYaw: number = 0.0;
         private _mustUnrotateFixedNormals = false;
-        private _minimum: Vector3 = Vector3.Zero();
-        private _maximum: Vector3 = Vector3.Zero();
-        private _minBbox: Vector3 = Vector3.Zero();
-        private _maxBbox: Vector3 = Vector3.Zero();
         private _particlesIntersect: boolean = false;
-        private _depthSortFunction: (p1: DepthSortedParticle, p2: DepthSortedParticle) => number =
-            function(p1, p2) {
-                return (p2.sqDistance - p1.sqDistance);
-            };
         private _needs32Bits: boolean = false;
-        private _pivotBackTranslation: Vector3 = Vector3.Zero();
-        private _scaledPivot: Vector3 = Vector3.Zero();
-        private _particleHasParent: boolean = false;
-        private _parent: SolidParticle;
 
         /**
          * Creates a SPS (Solid Particle System) object.
@@ -337,27 +300,19 @@ module BABYLON {
         private _unrotateFixedNormals() {
             var index = 0;
             var idx = 0;
+            const tmpNormal = Tmp.Vector3[0];
+            const rotMatrix = Tmp.Matrix[0];
+            const invertedRotMatrix = Tmp.Matrix[1];
             for (var p = 0; p < this.particles.length; p++) {
-                this._particle = this.particles[p];
-                this._shape = this._particle._model._shape;
-                if (this._particle.rotationQuaternion) {
-                    this._quaternion.copyFrom(this._particle.rotationQuaternion);
-                }
-                else {
-                    this._yaw = this._particle.rotation.y;
-                    this._pitch = this._particle.rotation.x;
-                    this._roll = this._particle.rotation.z;
-                    this._quaternionRotationYPR();
-                }
-                this._quaternionToRotationMatrix();
-                this._rotMatrix.invertToRef(this._invertMatrix);
+                const particle = this.particles[p];
+                const shape = particle._model._shape;
+                particle.getRotationMatrix(rotMatrix);
+                rotMatrix.invertToRef(invertedRotMatrix);
 
-                for (var pt = 0; pt < this._shape.length; pt++) {
+                for (var pt = 0; pt < shape.length; pt++) {
                     idx = index + pt * 3;
-                    Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], this._invertMatrix, this._normal);
-                    this._fixedNormal32[idx] = this._normal.x;
-                    this._fixedNormal32[idx + 1] = this._normal.y;
-                    this._fixedNormal32[idx + 2] = this._normal.z;
+                    Vector3.TransformNormalFromFloatsToRef(this._normals32[idx], this._normals32[idx + 1], this._normals32[idx + 2], invertedRotMatrix, tmpNormal);
+                    tmpNormal.toArray(this._fixedNormal32, idx);
                 }
                 index = idx + 3;
             }
@@ -365,22 +320,14 @@ module BABYLON {
 
         //reset copy
         private _resetCopy() {
-            this._copy.position.x = 0;
-            this._copy.position.y = 0;
-            this._copy.position.z = 0;
-            this._copy.rotation.x = 0;
-            this._copy.rotation.y = 0;
-            this._copy.rotation.z = 0;
-            this._copy.rotationQuaternion = null;
-            this._copy.scaling.x = 1.0;
-            this._copy.scaling.y = 1.0;
-            this._copy.scaling.z = 1.0;
-            this._copy.uvs.x = 0;
-            this._copy.uvs.y = 0;
-            this._copy.uvs.z = 1.0;
-            this._copy.uvs.w = 1.0;
-            this._copy.color = null;
-            this._copy.translateFromPivot = false;
+            const copy = this._copy;
+            copy.position.setAll(0);
+            copy.rotation.setAll(0);
+            copy.rotationQuaternion = null;
+            copy.scaling.setAll(1);
+            copy.uvs.copyFromFloats(0.0, 0.0, 1.0, 1.0);
+            copy.color = null;
+            copy.translateFromPivot = false;
         }
 
         // _meshBuilder : inserts the shape model in the global SPS mesh
@@ -391,80 +338,69 @@ module BABYLON {
             var n = 0;
 
             this._resetCopy();
+            const copy = this._copy;
             if (options && options.positionFunction) {        // call to custom positionFunction
-                options.positionFunction(this._copy, idx, idxInShape);
+                options.positionFunction(copy, idx, idxInShape);
                 this._mustUnrotateFixedNormals = true;
             }
 
-            if (this._copy.rotationQuaternion) {
-                this._quaternion.copyFrom(this._copy.rotationQuaternion);
-            } else {
-                this._yaw = this._copy.rotation.y;
-                this._pitch = this._copy.rotation.x;
-                this._roll = this._copy.rotation.z;
-                this._quaternionRotationYPR();
-            }
-            this._quaternionToRotationMatrix();
+            const rotMatrix = Tmp.Matrix[0];
+            const tmpVertex = Tmp.Vector3[0];
+            const tmpRotated = Tmp.Vector3[1];
+            const pivotBackTranslation = Tmp.Vector3[2];
+            const scaledPivot  = Tmp.Vector3[3];
+            copy.getRotationMatrix(rotMatrix);
 
-            this._scaledPivot.x = this._copy.pivot.x * this._copy.scaling.x;
-            this._scaledPivot.y = this._copy.pivot.y * this._copy.scaling.y;
-            this._scaledPivot.z = this._copy.pivot.z * this._copy.scaling.z;
+            copy.pivot.multiplyToRef(copy.scaling, scaledPivot);
 
-            if (this._copy.translateFromPivot) {
-                this._pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);
+            if (copy.translateFromPivot) {
+                pivotBackTranslation.setAll(0.0);
             }
             else {
-                this._pivotBackTranslation.copyFrom(this._scaledPivot);
+                pivotBackTranslation.copyFrom(scaledPivot);
             }
 
             for (i = 0; i < shape.length; i++) {
-                this._vertex.x = shape[i].x;
-                this._vertex.y = shape[i].y;
-                this._vertex.z = shape[i].z;
-
+                tmpVertex.copyFrom(shape[i]);
                 if (options && options.vertexFunction) {
-                    options.vertexFunction(this._copy, this._vertex, i);
+                    options.vertexFunction(copy, tmpVertex, i);
                 }
 
-                this._vertex.x *= this._copy.scaling.x;
-                this._vertex.y *= this._copy.scaling.y;
-                this._vertex.z *= this._copy.scaling.z;
-
-                this._vertex.x -= this._scaledPivot.x;
-                this._vertex.y -= this._scaledPivot.y;
-                this._vertex.z -= this._scaledPivot.z;
-
-                Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
-
-                this._rotated.addInPlace(this._pivotBackTranslation);
-                positions.push(this._copy.position.x + this._rotated.x, this._copy.position.y + this._rotated.y, this._copy.position.z + this._rotated.z);
+                tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);
+                Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);
+                tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position);
+                positions.push(tmpRotated.x, tmpRotated.y, tmpRotated.z);
                 if (meshUV) {
-                    uvs.push((this._copy.uvs.z - this._copy.uvs.x) * meshUV[u] + this._copy.uvs.x, (this._copy.uvs.w - this._copy.uvs.y) * meshUV[u + 1] + this._copy.uvs.y);
+                    const copyUvs = copy.uvs;
+                    uvs.push((copyUvs.z - copyUvs.x) * meshUV[u] + copyUvs.x, (copyUvs.w - copyUvs.y) * meshUV[u + 1] + copyUvs.y);
                     u += 2;
                 }
 
-                if (this._copy.color) {
-                    this._color = this._copy.color;
-                } else if (meshCol && meshCol[c] !== undefined) {
-                    this._color.r = meshCol[c];
-                    this._color.g = meshCol[c + 1];
-                    this._color.b = meshCol[c + 2];
-                    this._color.a = meshCol[c + 3];
+                if (copy.color) {
+                    this._color = copy.color;
                 } else {
-                    this._color.r = 1.0;
-                    this._color.g = 1.0;
-                    this._color.b = 1.0;
-                    this._color.a = 1.0;
+                    const color = this._color;
+                    if (meshCol && meshCol[c] !== undefined) {
+                        color.r = meshCol[c];
+                        color.g = meshCol[c + 1];
+                        color.b = meshCol[c + 2];
+                        color.a = meshCol[c + 3];
+                    } else {
+                        color.r = 1.0;
+                        color.g = 1.0;
+                        color.b = 1.0;
+                        color.a = 1.0;
+                    }
                 }
                 colors.push(this._color.r, this._color.g, this._color.b, this._color.a);
                 c += 4;
 
                 if (!this.recomputeNormals && meshNor) {
-                    this._normal.x = meshNor[n];
-                    this._normal.y = meshNor[n + 1];
-                    this._normal.z = meshNor[n + 2];
-                    Vector3.TransformNormalToRef(this._normal, this._rotMatrix, this._normal);
-                    normals.push(this._normal.x, this._normal.y, this._normal.z);
+                    tmpVertex.x = meshNor[n];
+                    tmpVertex.y = meshNor[n + 1];
+                    tmpVertex.z = meshNor[n + 2];
+                    Vector3.TransformNormalToRef(tmpVertex, rotMatrix, tmpVertex);
+                    normals.push(tmpVertex.x, tmpVertex.y, tmpVertex.z);
                     n += 3;
                 }
 
@@ -489,14 +425,14 @@ module BABYLON {
                 this.depthSortedParticles.push(new DepthSortedParticle());
             }
 
-            return this._copy;
+            return copy;
         }
 
         // returns a shape array from positions array
         private _posToShape(positions: number[] | Float32Array): Vector3[] {
             var shape = [];
             for (var i = 0; i < positions.length; i += 3) {
-                shape.push(new Vector3(positions[i], positions[i + 1], positions[i + 2]));
+                shape.push(Vector3.FromArray(positions, i));
             }
             return shape;
         }
@@ -506,7 +442,7 @@ module BABYLON {
             var shapeUV = [];
             if (uvs) {
                 for (var i = 0; i < uvs.length; i++) {
-                    shapeUV.push(uvs[i]);
+                    shapeUV.push(uvs[i]);
                 }
             }
             return shapeUV;
@@ -579,73 +515,46 @@ module BABYLON {
         // rebuilds a particle back to its just built status : if needed, recomputes the custom positions and vertices
         private _rebuildParticle(particle: SolidParticle): void {
             this._resetCopy();
+            const copy = this._copy;
             if (particle._model._positionFunction) {        // recall to stored custom positionFunction
-                particle._model._positionFunction(this._copy, particle.idx, particle.idxInShape);
+                particle._model._positionFunction(copy, particle.idx, particle.idxInShape);
             }
 
-            if (this._copy.rotationQuaternion) {
-                this._quaternion.copyFrom(this._copy.rotationQuaternion);
-            } else {
-                this._yaw = this._copy.rotation.y;
-                this._pitch = this._copy.rotation.x;
-                this._roll = this._copy.rotation.z;
-                this._quaternionRotationYPR();
-            }
-            this._quaternionToRotationMatrix();
+            const rotMatrix = Tmp.Matrix[0];
+            const tmpVertex = Tmp.Vector3[0];
+            const tmpRotated = Tmp.Vector3[1];
+            const pivotBackTranslation = Tmp.Vector3[2];
+            const scaledPivot  = Tmp.Vector3[3];
+
+            copy.getRotationMatrix(rotMatrix);
 
-            this._scaledPivot.x = this._particle.pivot.x * this._particle.scaling.x;
-            this._scaledPivot.y = this._particle.pivot.y * this._particle.scaling.y;
-            this._scaledPivot.z = this._particle.pivot.z * this._particle.scaling.z;
+            particle.pivot.multiplyToRef(particle.scaling, scaledPivot);
 
-            if (this._copy.translateFromPivot) {
-                this._pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);
+            if (copy.translateFromPivot) {
+                pivotBackTranslation.copyFromFloats(0.0, 0.0, 0.0);
             }
             else {
-                this._pivotBackTranslation.copyFrom(this._scaledPivot);
+                pivotBackTranslation.copyFrom(scaledPivot);
             }
 
-            this._shape = particle._model._shape;
-            for (var pt = 0; pt < this._shape.length; pt++) {
-                this._vertex.x = this._shape[pt].x;
-                this._vertex.y = this._shape[pt].y;
-                this._vertex.z = this._shape[pt].z;
+            const shape = particle._model._shape;
 
+            for (var pt = 0; pt < shape.length; pt++) {
+                tmpVertex.copyFrom(shape[pt]);
                 if (particle._model._vertexFunction) {
-                    particle._model._vertexFunction(this._copy, this._vertex, pt); // recall to stored vertexFunction
+                    particle._model._vertexFunction(copy, tmpVertex, pt); // recall to stored vertexFunction
                 }
 
-                this._vertex.x *= this._copy.scaling.x;
-                this._vertex.y *= this._copy.scaling.y;
-                this._vertex.z *= this._copy.scaling.z;
-
-                this._vertex.x -= this._scaledPivot.x;
-                this._vertex.y -= this._scaledPivot.y;
-                this._vertex.z -= this._scaledPivot.z;
-
-                Vector3.TransformCoordinatesToRef(this._vertex, this._rotMatrix, this._rotated);
-                this._rotated.addInPlace(this._pivotBackTranslation);
-
-                this._positions32[particle._pos + pt * 3] = this._copy.position.x + this._rotated.x;
-                this._positions32[particle._pos + pt * 3 + 1] = this._copy.position.y + this._rotated.y;
-                this._positions32[particle._pos + pt * 3 + 2] = this._copy.position.z + this._rotated.z;
+                tmpVertex.multiplyInPlace(copy.scaling).subtractInPlace(scaledPivot);
+                Vector3.TransformCoordinatesToRef(tmpVertex, rotMatrix, tmpRotated);
+                tmpRotated.addInPlace(pivotBackTranslation).addInPlace(copy.position).toArray(this._positions32, particle._pos + pt * 3);
             }
-            particle.position.x = 0.0;
-            particle.position.y = 0.0;
-            particle.position.z = 0.0;
-            particle.rotation.x = 0.0;
-            particle.rotation.y = 0.0;
-            particle.rotation.z = 0.0;
+            particle.position.setAll(0.0);
+            particle.rotation.setAll(0.0);
             particle.rotationQuaternion = null;
-            particle.scaling.x = 1.0;
-            particle.scaling.y = 1.0;
-            particle.scaling.z = 1.0;
-            particle.uvs.x = 0.0;
-            particle.uvs.y = 0.0;
-            particle.uvs.z = 1.0;
-            particle.uvs.w = 1.0;
-            particle.pivot.x = 0.0;
-            particle.pivot.y = 0.0;
-            particle.pivot.z = 0.0;
+            particle.scaling.setAll(1.0);
+            particle.uvs.setAll(0.0);
+            particle.pivot.setAll(0.0);
             particle.translateFromPivot = false;
             particle.parentId = null;
         }
@@ -679,43 +588,51 @@ module BABYLON {
             // custom beforeUpdate
             this.beforeUpdateParticles(start, end, update);
 
-            this._cam_axisX.x = 1.0;
-            this._cam_axisX.y = 0.0;
-            this._cam_axisX.z = 0.0;
-
-            this._cam_axisY.x = 0.0;
-            this._cam_axisY.y = 1.0;
-            this._cam_axisY.z = 0.0;
-
-            this._cam_axisZ.x = 0.0;
-            this._cam_axisZ.y = 0.0;
-            this._cam_axisZ.z = 1.0;
+            const rotMatrix = Tmp.Matrix[0];
+            const invertedMatrix = Tmp.Matrix[1];
+            const mesh = this.mesh;
+            const colors32 = this._colors32;
+            const positions32 = this._positions32;
+            const normals32 = this._normals32;
+            const uvs32 = this._uvs32;
+            const indices32 = this._indices32;
+            const indices = this._indices;
+            const fixedNormal32 = this._fixedNormal32;
+
+            const tempVectors = Tmp.Vector3;
+            const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);
+            const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);
+            const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);
+            const minimum = tempVectors[8].setAll(Number.MAX_VALUE);
+            const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);
+            const camInvertedPosition = tempVectors[10].setAll(0);
 
             // cases when the World Matrix is to be computed first
             if (this.billboard || this._depthSort) {
                 this.mesh.computeWorldMatrix(true);
-                this.mesh._worldMatrix.invertToRef(this._invertMatrix);
+                this.mesh._worldMatrix.invertToRef(invertedMatrix);
             }
             // if the particles will always face the camera
             if (this.billboard) {
                 // compute the camera position and un-rotate it by the current mesh rotation
-                this._camera.getDirectionToRef(this._axisZ, this._camDir);
-                Vector3.TransformNormalToRef(this._camDir, this._invertMatrix, this._cam_axisZ);
-                this._cam_axisZ.normalize();
+                const tmpVertex = tempVectors[0];
+                this._camera.getDirectionToRef(Axis.Z, tmpVertex);
+                Vector3.TransformNormalToRef(tmpVertex, invertedMatrix, camAxisZ);
+                camAxisZ.normalize();
                 // same for camera up vector extracted from the cam view matrix
                 var view = this._camera.getViewMatrix(true);
-                Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], this._invertMatrix, this._cam_axisY);
-                Vector3.CrossToRef(this._cam_axisY, this._cam_axisZ, this._cam_axisX);
-                this._cam_axisY.normalize();
-                this._cam_axisX.normalize();
+                Vector3.TransformNormalFromFloatsToRef(view.m[1], view.m[5], view.m[9], invertedMatrix, camAxisY);
+                Vector3.CrossToRef(camAxisY, camAxisZ, camAxisX);
+                camAxisY.normalize();
+                camAxisX.normalize();
             }
 
             // if depthSort, compute the camera global position in the mesh local system
             if (this._depthSort) {
-                Vector3.TransformCoordinatesToRef(this._camera.globalPosition, this._invertMatrix, this._camInvertedPosition); // then un-rotate the camera
+                Vector3.TransformCoordinatesToRef(this._camera.globalPosition, invertedMatrix, camInvertedPosition); // then un-rotate the camera
             }
 
-            Matrix.IdentityToRef(this._rotMatrix);
+            Matrix.IdentityToRef(rotMatrix);
             var idx = 0;            // current position index in the global array positions32
             var index = 0;          // position start index in the global array positions32 of the current particle
             var colidx = 0;         // current color index in the global array colors32
@@ -730,267 +647,252 @@ module BABYLON {
 
             end = (end >= this.nbParticles) ? this.nbParticles - 1 : end;
             if (this._computeBoundingBox) {
-                if (start == 0 && end == this.nbParticles - 1) {        // all the particles are updated, then recompute the BBox from scratch
-                    Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this._minimum);
-                    Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this._maximum);
-                }
-                else {      // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
-                    if (this.mesh._boundingInfo) {
-                        this._minimum.copyFrom(this.mesh._boundingInfo.boundingBox.minimum);
-                        this._maximum.copyFrom(this.mesh._boundingInfo.boundingBox.maximum);
+                if (start != 0 || end != this.nbParticles - 1) { // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
+                    const boundingInfo = this.mesh._boundingInfo;
+                    if (boundingInfo) {
+                        minimum.copyFrom(boundingInfo.minimum);
+                        maximum.copyFrom(boundingInfo.maximum);
                     }
                 }
             }
 
             // particle loop
             index = this.particles[start]._pos;
-            var vpos = (index / 3) | 0;
+            const vpos = (index / 3) | 0;
             colorIndex = vpos * 4;
             uvIndex = vpos * 2;
+
             for (var p = start; p <= end; p++) {
-                this._particle = this.particles[p];
-                this._shape = this._particle._model._shape;
-                this._shapeUV = this._particle._model._shapeUV;
+                const particle = this.particles[p];
 
                 // call to custom user function to update the particle properties
-                this.updateParticle(this._particle);
+                this.updateParticle(particle);
+
+                const shape = particle._model._shape;
+                const shapeUV = particle._model._shapeUV;
+                const particleRotationMatrix = particle._rotationMatrix;
+                const particlePosition = particle.position;
+                const particleRotation = particle.rotation;
+                const particleScaling = particle.scaling;
+                const particleGlobalPosition = particle._globalPosition;
 
                 // camera-particle distance for depth sorting
                 if (this._depthSort && this._depthSortParticles) {
                     var dsp = this.depthSortedParticles[p];
-                    dsp.ind = this._particle._ind;
-                    dsp.indicesLength = this._particle._model._indicesLength;
-                    dsp.sqDistance = Vector3.DistanceSquared(this._particle.position, this._camInvertedPosition);
+                    dsp.ind = particle._ind;
+                    dsp.indicesLength = particle._model._indicesLength;
+                    dsp.sqDistance = Vector3.DistanceSquared(particle.position, camInvertedPosition);
                 }
 
                 // skip the computations for inactive or already invisible particles
-                if (!this._particle.alive || (this._particle._stillInvisible && !this._particle.isVisible)) {
+                if (!particle.alive || (particle._stillInvisible && !particle.isVisible)) {
                     // increment indexes for the next particle
-                    pt = this._shape.length;
+                    pt = shape.length;
                     index += pt * 3;
                     colorIndex += pt * 4;
                     uvIndex += pt * 2;
                     continue;
                 }
 
-                if (this._particle.isVisible) {
-                    this._particle._stillInvisible = false; // un-mark permanent invisibility
-                    this._particleHasParent = (this._particle.parentId !== null);
+                if (particle.isVisible) {
+                    particle._stillInvisible = false; // un-mark permanent invisibility
 
-                    this._scaledPivot.x = this._particle.pivot.x * this._particle.scaling.x;
-                    this._scaledPivot.y = this._particle.pivot.y * this._particle.scaling.y;
-                    this._scaledPivot.z = this._particle.pivot.z * this._particle.scaling.z;
+                    const scaledPivot = tempVectors[12];
+                    particle.pivot.multiplyToRef(particleScaling, scaledPivot);
 
                     // particle rotation matrix
                     if (this.billboard) {
-                        this._particle.rotation.x = 0.0;
-                        this._particle.rotation.y = 0.0;
+                        particleRotation.x = 0.0;
+                        particleRotation.y = 0.0;
                     }
                     if (this._computeParticleRotation || this.billboard) {
-                        if (this._particle.rotationQuaternion) {
-                            this._quaternion.copyFrom(this._particle.rotationQuaternion);
-                        } else {
-                            this._yaw = this._particle.rotation.y;
-                            this._pitch = this._particle.rotation.x;
-                            this._roll = this._particle.rotation.z;
-                            this._quaternionRotationYPR();
-                        }
-                        this._quaternionToRotationMatrix();
+                        particle.getRotationMatrix(rotMatrix);
                     }
 
-                    if (this._particleHasParent) {
-                        this._parent = this.particles[this._particle.parentId!];
-                        this._rotated.x = this._particle.position.x * this._parent._rotationMatrix[0] + this._particle.position.y * this._parent._rotationMatrix[3] + this._particle.position.z * this._parent._rotationMatrix[6];
-                        this._rotated.y = this._particle.position.x * this._parent._rotationMatrix[1] + this._particle.position.y * this._parent._rotationMatrix[4] + this._particle.position.z * this._parent._rotationMatrix[7];
-                        this._rotated.z = this._particle.position.x * this._parent._rotationMatrix[2] + this._particle.position.y * this._parent._rotationMatrix[5] + this._particle.position.z * this._parent._rotationMatrix[8];
+                    const particleHasParent = (particle.parentId !== null);
+                    if (particleHasParent) {
+                        const parent = this.particles[particle.parentId!];
+                        const parentRotationMatrix = parent._rotationMatrix;
+                        const parentGlobalPosition = parent._globalPosition;
 
-                        this._particle._globalPosition.x = this._parent._globalPosition.x + this._rotated.x;
-                        this._particle._globalPosition.y = this._parent._globalPosition.y + this._rotated.y;
-                        this._particle._globalPosition.z = this._parent._globalPosition.z + this._rotated.z;
+                        const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];
+                        const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];
+                        const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];
+
+                        particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;
+                        particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;
+                        particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;
 
                         if (this._computeParticleRotation || this.billboard) {
-                            this._particle._rotationMatrix[0] = this._rotMatrix.m[0] * this._parent._rotationMatrix[0] + this._rotMatrix.m[1] * this._parent._rotationMatrix[3] + this._rotMatrix.m[2] * this._parent._rotationMatrix[6];
-                            this._particle._rotationMatrix[1] = this._rotMatrix.m[0] * this._parent._rotationMatrix[1] + this._rotMatrix.m[1] * this._parent._rotationMatrix[4] + this._rotMatrix.m[2] * this._parent._rotationMatrix[7];
-                            this._particle._rotationMatrix[2] = this._rotMatrix.m[0] * this._parent._rotationMatrix[2] + this._rotMatrix.m[1] * this._parent._rotationMatrix[5] + this._rotMatrix.m[2] * this._parent._rotationMatrix[8];
-                            this._particle._rotationMatrix[3] = this._rotMatrix.m[4] * this._parent._rotationMatrix[0] + this._rotMatrix.m[5] * this._parent._rotationMatrix[3] + this._rotMatrix.m[6] * this._parent._rotationMatrix[6];
-                            this._particle._rotationMatrix[4] = this._rotMatrix.m[4] * this._parent._rotationMatrix[1] + this._rotMatrix.m[5] * this._parent._rotationMatrix[4] + this._rotMatrix.m[6] * this._parent._rotationMatrix[7];
-                            this._particle._rotationMatrix[5] = this._rotMatrix.m[4] * this._parent._rotationMatrix[2] + this._rotMatrix.m[5] * this._parent._rotationMatrix[5] + this._rotMatrix.m[6] * this._parent._rotationMatrix[8];
-                            this._particle._rotationMatrix[6] = this._rotMatrix.m[8] * this._parent._rotationMatrix[0] + this._rotMatrix.m[9] * this._parent._rotationMatrix[3] + this._rotMatrix.m[10] * this._parent._rotationMatrix[6];
-                            this._particle._rotationMatrix[7] = this._rotMatrix.m[8] * this._parent._rotationMatrix[1] + this._rotMatrix.m[9] * this._parent._rotationMatrix[4] + this._rotMatrix.m[10] * this._parent._rotationMatrix[7];
-                            this._particle._rotationMatrix[8] = this._rotMatrix.m[8] * this._parent._rotationMatrix[2] + this._rotMatrix.m[9] * this._parent._rotationMatrix[5] + this._rotMatrix.m[10] * this._parent._rotationMatrix[8];
+                            const rotMatrixValues = rotMatrix.m;
+                            particleRotationMatrix[0] = rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];
+                            particleRotationMatrix[1] = rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];
+                            particleRotationMatrix[2] = rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];
+                            particleRotationMatrix[3] = rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];
+                            particleRotationMatrix[4] = rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];
+                            particleRotationMatrix[5] = rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];
+                            particleRotationMatrix[6] = rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];
+                            particleRotationMatrix[7] = rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];
+                            particleRotationMatrix[8] = rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];
                         }
                     }
                     else {
-                        this._particle._globalPosition.x = this._particle.position.x;
-                        this._particle._globalPosition.y = this._particle.position.y;
-                        this._particle._globalPosition.z = this._particle.position.z;
+                        particleGlobalPosition.x = particlePosition.x;
+                        particleGlobalPosition.y = particlePosition.y;
+                        particleGlobalPosition.z = particlePosition.z;
 
                         if (this._computeParticleRotation || this.billboard) {
-                            this._particle._rotationMatrix[0] = this._rotMatrix.m[0];
-                            this._particle._rotationMatrix[1] = this._rotMatrix.m[1];
-                            this._particle._rotationMatrix[2] = this._rotMatrix.m[2];
-                            this._particle._rotationMatrix[3] = this._rotMatrix.m[4];
-                            this._particle._rotationMatrix[4] = this._rotMatrix.m[5];
-                            this._particle._rotationMatrix[5] = this._rotMatrix.m[6];
-                            this._particle._rotationMatrix[6] = this._rotMatrix.m[8];
-                            this._particle._rotationMatrix[7] = this._rotMatrix.m[9];
-                            this._particle._rotationMatrix[8] = this._rotMatrix.m[10];
+                            const rotMatrixValues = rotMatrix.m;
+                            particleRotationMatrix[0] = rotMatrixValues[0];
+                            particleRotationMatrix[1] = rotMatrixValues[1];
+                            particleRotationMatrix[2] = rotMatrixValues[2];
+                            particleRotationMatrix[3] = rotMatrixValues[4];
+                            particleRotationMatrix[4] = rotMatrixValues[5];
+                            particleRotationMatrix[5] = rotMatrixValues[6];
+                            particleRotationMatrix[6] = rotMatrixValues[8];
+                            particleRotationMatrix[7] = rotMatrixValues[9];
+                            particleRotationMatrix[8] = rotMatrixValues[10];
                         }
                     }
 
-                    if (this._particle.translateFromPivot) {
-                        this._pivotBackTranslation.x = 0.0;
-                        this._pivotBackTranslation.y = 0.0;
-                        this._pivotBackTranslation.z = 0.0;
+                    const pivotBackTranslation = tempVectors[11];
+                    if (particle.translateFromPivot) {
+                        pivotBackTranslation.setAll(0.0);
                     }
                     else {
-                        this._pivotBackTranslation.x = this._scaledPivot.x;
-                        this._pivotBackTranslation.y = this._scaledPivot.y;
-                        this._pivotBackTranslation.z = this._scaledPivot.z;
+                        pivotBackTranslation.copyFrom(scaledPivot);
                     }
+
                     // particle vertex loop
-                    for (pt = 0; pt < this._shape.length; pt++) {
+                    for (pt = 0; pt < shape.length; pt++) {
                         idx = index + pt * 3;
                         colidx = colorIndex + pt * 4;
                         uvidx = uvIndex + pt * 2;
 
-                        this._vertex.x = this._shape[pt].x;
-                        this._vertex.y = this._shape[pt].y;
-                        this._vertex.z = this._shape[pt].z;
-
+                        const tmpVertex = tempVectors[0];
+                        tmpVertex.copyFrom(shape[pt]);
                         if (this._computeParticleVertex) {
-                            this.updateParticleVertex(this._particle, this._vertex, pt);
+                            this.updateParticleVertex(particle, tmpVertex, pt);
                         }
 
                         // positions
-                        this._vertex.x *= this._particle.scaling.x;
-                        this._vertex.y *= this._particle.scaling.y;
-                        this._vertex.z *= this._particle.scaling.z;
-
-                        this._vertex.x -= this._scaledPivot.x;
-                        this._vertex.y -= this._scaledPivot.y;
-                        this._vertex.z -= this._scaledPivot.z;
+                        const vertexX = tmpVertex.x * particleScaling.x - scaledPivot.x;
+                        const vertexY = tmpVertex.y * particleScaling.y - scaledPivot.y;
+                        const vertexZ = tmpVertex.z * particleScaling.z - scaledPivot.z;
 
-                        this._rotated.x = this._vertex.x * this._particle._rotationMatrix[0] + this._vertex.y * this._particle._rotationMatrix[3] + this._vertex.z * this._particle._rotationMatrix[6];
-                        this._rotated.y = this._vertex.x * this._particle._rotationMatrix[1] + this._vertex.y * this._particle._rotationMatrix[4] + this._vertex.z * this._particle._rotationMatrix[7];
-                        this._rotated.z = this._vertex.x * this._particle._rotationMatrix[2] + this._vertex.y * this._particle._rotationMatrix[5] + this._vertex.z * this._particle._rotationMatrix[8];
+                        let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];
+                        let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];
+                        let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];
 
-                        this._rotated.x += this._pivotBackTranslation.x;
-                        this._rotated.y += this._pivotBackTranslation.y;
-                        this._rotated.z += this._pivotBackTranslation.z;
+                        rotatedX += pivotBackTranslation.x;
+                        rotatedY += pivotBackTranslation.y;
+                        rotatedZ += pivotBackTranslation.z;
 
-                        this._positions32[idx] = this._particle._globalPosition.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
-                        this._positions32[idx + 1] = this._particle._globalPosition.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
-                        this._positions32[idx + 2] = this._particle._globalPosition.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
+                        const px = positions32[idx] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;
+                        const py = positions32[idx + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;
+                        const pz = positions32[idx + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;
 
                         if (this._computeBoundingBox) {
-                            if (this._positions32[idx] < this._minimum.x) {
-                                this._minimum.x = this._positions32[idx];
-                            }
-                            if (this._positions32[idx] > this._maximum.x) {
-                                this._maximum.x = this._positions32[idx];
-                            }
-                            if (this._positions32[idx + 1] < this._minimum.y) {
-                                this._minimum.y = this._positions32[idx + 1];
-                            }
-                            if (this._positions32[idx + 1] > this._maximum.y) {
-                                this._maximum.y = this._positions32[idx + 1];
-                            }
-                            if (this._positions32[idx + 2] < this._minimum.z) {
-                                this._minimum.z = this._positions32[idx + 2];
-                            }
-                            if (this._positions32[idx + 2] > this._maximum.z) {
-                                this._maximum.z = this._positions32[idx + 2];
-                            }
+                            minimum.minimizeInPlaceFromFloats(px, py, pz);
+                            maximum.maximizeInPlaceFromFloats(px, py, pz);
                         }
 
                         // normals : if the particles can't be morphed then just rotate the normals, what is much more faster than ComputeNormals()
                         if (!this._computeParticleVertex) {
-                            this._normal.x = this._fixedNormal32[idx];
-                            this._normal.y = this._fixedNormal32[idx + 1];
-                            this._normal.z = this._fixedNormal32[idx + 2];
+                            const normalx = fixedNormal32[idx];
+                            const normaly = fixedNormal32[idx + 1];
+                            const normalz = fixedNormal32[idx + 2];
 
-                            this._rotated.x = this._normal.x * this._particle._rotationMatrix[0] + this._normal.y * this._particle._rotationMatrix[3] + this._normal.z * this._particle._rotationMatrix[6];
-                            this._rotated.y = this._normal.x * this._particle._rotationMatrix[1] + this._normal.y * this._particle._rotationMatrix[4] + this._normal.z * this._particle._rotationMatrix[7];
-                            this._rotated.z = this._normal.x * this._particle._rotationMatrix[2] + this._normal.y * this._particle._rotationMatrix[5] + this._normal.z * this._particle._rotationMatrix[8];
+                            const rotatedx = normalx * particleRotationMatrix[0] + normaly * particleRotationMatrix[3] + normalz * particleRotationMatrix[6];
+                            const rotatedy = normalx * particleRotationMatrix[1] + normaly * particleRotationMatrix[4] + normalz * particleRotationMatrix[7];
+                            const rotatedz = normalx * particleRotationMatrix[2] + normaly * particleRotationMatrix[5] + normalz * particleRotationMatrix[8];
 
-                            this._normals32[idx] = this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
-                            this._normals32[idx + 1] = this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
-                            this._normals32[idx + 2] = this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
+                            normals32[idx] = camAxisX.x * rotatedx + camAxisY.x * rotatedy + camAxisZ.x * rotatedz;
+                            normals32[idx + 1] = camAxisX.y * rotatedx + camAxisY.y * rotatedy + camAxisZ.y * rotatedz;
+                            normals32[idx + 2] = camAxisX.z * rotatedx + camAxisY.z * rotatedy + camAxisZ.z * rotatedz;
                         }
 
-                        if (this._computeParticleColor && this._particle.color) {
-                            this._colors32[colidx] = this._particle.color.r;
-                            this._colors32[colidx + 1] = this._particle.color.g;
-                            this._colors32[colidx + 2] = this._particle.color.b;
-                            this._colors32[colidx + 3] = this._particle.color.a;
+                        if (this._computeParticleColor && particle.color) {
+                            const color = particle.color;
+                            const colors32 = this._colors32;
+                            colors32[colidx] = color.r;
+                            colors32[colidx + 1] = color.g;
+                            colors32[colidx + 2] = color.b;
+                            colors32[colidx + 3] = color.a;
                         }
 
                         if (this._computeParticleTexture) {
-                            this._uvs32[uvidx] = this._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
-                            this._uvs32[uvidx + 1] = this._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
+                            const uvs = particle.uvs;
+                            uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;
+                            uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;
                         }
                     }
                 }
                 // particle just set invisible : scaled to zero and positioned at the origin
                 else {
-                    this._particle._stillInvisible = true;      // mark the particle as invisible
-                    for (pt = 0; pt < this._shape.length; pt++) {
+                    particle._stillInvisible = true;      // mark the particle as invisible
+                    for (pt = 0; pt < shape.length; pt++) {
                         idx = index + pt * 3;
                         colidx = colorIndex + pt * 4;
                         uvidx = uvIndex + pt * 2;
 
-                        this._positions32[idx] = 0.0;
-                        this._positions32[idx + 1] = 0.0;
-                        this._positions32[idx + 2] = 0.0;
-                        this._normals32[idx] = 0.0;
-                        this._normals32[idx + 1] = 0.0;
-                        this._normals32[idx + 2] = 0.0;
-                        if (this._computeParticleColor && this._particle.color) {
-                            this._colors32[colidx] = this._particle.color.r;
-                            this._colors32[colidx + 1] = this._particle.color.g;
-                            this._colors32[colidx + 2] = this._particle.color.b;
-                            this._colors32[colidx + 3] = this._particle.color.a;
+                        positions32[idx] = positions32[idx + 1] = positions32[idx + 2] = 0;
+                        normals32[idx] = normals32[idx + 1] = normals32[idx + 2] = 0;
+                        if (this._computeParticleColor && particle.color) {
+                            const color = particle.color;
+                            colors32[colidx] = color.r;
+                            colors32[colidx + 1] = color.g;
+                            colors32[colidx + 2] = color.b;
+                            colors32[colidx + 3] = color.a;
                         }
                         if (this._computeParticleTexture) {
-                            this._uvs32[uvidx] = this._shapeUV[pt * 2] * (this._particle.uvs.z - this._particle.uvs.x) + this._particle.uvs.x;
-                            this._uvs32[uvidx + 1] = this._shapeUV[pt * 2 + 1] * (this._particle.uvs.w - this._particle.uvs.y) + this._particle.uvs.y;
+                            const uvs = particle.uvs;
+                            uvs32[uvidx] = shapeUV[pt * 2] * (uvs.z - uvs.x) + uvs.x;
+                            uvs32[uvidx + 1] = shapeUV[pt * 2 + 1] * (uvs.w - uvs.y) + uvs.y;
                         }
                     }
                 }
 
                 // if the particle intersections must be computed : update the bbInfo
                 if (this._particlesIntersect) {
-                    var bInfo = this._particle._boundingInfo;
-                    var bBox = bInfo.boundingBox;
-                    var bSphere = bInfo.boundingSphere;
+                    const bInfo = particle._boundingInfo;
+                    const bBox = bInfo.boundingBox;
+                    const bSphere = bInfo.boundingSphere;
+                    const modelBoundingInfo = particle._modelBoundingInfo;
                     if (!this._bSphereOnly) {
                         // place, scale and rotate the particle bbox within the SPS local system, then update it
-                        for (var b = 0; b < bBox.vectors.length; b++) {
-                            this._vertex.x = this._particle._modelBoundingInfo.boundingBox.vectors[b].x * this._particle.scaling.x;
-                            this._vertex.y = this._particle._modelBoundingInfo.boundingBox.vectors[b].y * this._particle.scaling.y;
-                            this._vertex.z = this._particle._modelBoundingInfo.boundingBox.vectors[b].z * this._particle.scaling.z;
-                            this._rotated.x = this._vertex.x * this._particle._rotationMatrix[0] + this._vertex.y * this._particle._rotationMatrix[3] + this._vertex.z * this._particle._rotationMatrix[6];
-                            this._rotated.y = this._vertex.x * this._particle._rotationMatrix[1] + this._vertex.y * this._particle._rotationMatrix[4] + this._vertex.z * this._particle._rotationMatrix[7];
-                            this._rotated.z = this._vertex.x * this._particle._rotationMatrix[2] + this._vertex.y * this._particle._rotationMatrix[5] + this._vertex.z * this._particle._rotationMatrix[8];
-                            bBox.vectors[b].x = this._particle.position.x + this._cam_axisX.x * this._rotated.x + this._cam_axisY.x * this._rotated.y + this._cam_axisZ.x * this._rotated.z;
-                            bBox.vectors[b].y = this._particle.position.y + this._cam_axisX.y * this._rotated.x + this._cam_axisY.y * this._rotated.y + this._cam_axisZ.y * this._rotated.z;
-                            bBox.vectors[b].z = this._particle.position.z + this._cam_axisX.z * this._rotated.x + this._cam_axisY.z * this._rotated.y + this._cam_axisZ.z * this._rotated.z;
+                        const modelBoundingInfoVectors = modelBoundingInfo.boundingBox.vectors;
+
+                        const tempMin = tempVectors[1];
+                        const tempMax = tempVectors[2];
+                        tempMin.setAll(Number.MAX_VALUE);
+                        tempMax.setAll(-Number.MAX_VALUE);
+                        for (var b = 0; b < 8; b++) {
+                            const scaledX = modelBoundingInfoVectors[b].x * particleScaling.x;
+                            const scaledY = modelBoundingInfoVectors[b].y * particleScaling.y;
+                            const scaledZ = modelBoundingInfoVectors[b].z * particleScaling.z;
+                            const rotatedX = scaledX * particleRotationMatrix[0] + scaledY * particleRotationMatrix[3] + scaledZ * particleRotationMatrix[6];
+                            const rotatedY = scaledX * particleRotationMatrix[1] + scaledY * particleRotationMatrix[4] + scaledZ * particleRotationMatrix[7];
+                            const rotatedZ = scaledX * particleRotationMatrix[2] + scaledY * particleRotationMatrix[5] + scaledZ * particleRotationMatrix[8];
+                            const x = particlePosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ;
+                            const y = particlePosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ;
+                            const z = particlePosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ;
+                            tempMin.minimizeInPlaceFromFloats(x, y, z);
+                            tempMax.maximizeInPlaceFromFloats(x, y, z);
                         }
-                        bBox._update(this.mesh._worldMatrix);
+
+                        bBox.reConstruct(tempMin, tempMax, mesh._worldMatrix);
                     }
+
                     // place and scale the particle bouding sphere in the SPS local system, then update it
-                    this._minBbox.x = this._particle._modelBoundingInfo.minimum.x * this._particle.scaling.x;
-                    this._minBbox.y = this._particle._modelBoundingInfo.minimum.y * this._particle.scaling.y;
-                    this._minBbox.z = this._particle._modelBoundingInfo.minimum.z * this._particle.scaling.z;
-                    this._maxBbox.x = this._particle._modelBoundingInfo.maximum.x * this._particle.scaling.x;
-                    this._maxBbox.y = this._particle._modelBoundingInfo.maximum.y * this._particle.scaling.y;
-                    this._maxBbox.z = this._particle._modelBoundingInfo.maximum.z * this._particle.scaling.z;
-                    bSphere.center.x = this._particle._globalPosition.x + (this._minBbox.x + this._maxBbox.x) * 0.5;
-                    bSphere.center.y = this._particle._globalPosition.y + (this._minBbox.y + this._maxBbox.y) * 0.5;
-                    bSphere.center.z = this._particle._globalPosition.z + (this._minBbox.z + this._maxBbox.z) * 0.5;
-                    bSphere.radius = this._bSphereRadiusFactor * 0.5 * Math.sqrt((this._maxBbox.x - this._minBbox.x) * (this._maxBbox.x - this._minBbox.x) + (this._maxBbox.y - this._minBbox.y) * (this._maxBbox.y - this._minBbox.y) + (this._maxBbox.z - this._minBbox.z) * (this._maxBbox.z - this._minBbox.z));
-                    bSphere._update(this.mesh._worldMatrix);
+                    const minBbox = modelBoundingInfo.minimum.multiplyToRef(particleScaling, tempVectors[1]);
+                    const maxBbox = modelBoundingInfo.maximum.multiplyToRef(particleScaling, tempVectors[2]);
+
+                    const bSphereCenter = maxBbox.addToRef(minBbox, tempVectors[3]).scaleInPlace(0.5);
+                    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);
                 }
 
                 // increment indexes for the next particle
@@ -1002,86 +904,53 @@ module BABYLON {
             // if the VBO must be updated
             if (update) {
                 if (this._computeParticleColor) {
-                    this.mesh.updateVerticesData(VertexBuffer.ColorKind, this._colors32, false, false);
+                    mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);
                 }
                 if (this._computeParticleTexture) {
-                    this.mesh.updateVerticesData(VertexBuffer.UVKind, this._uvs32, false, false);
+                    mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);
                 }
-                this.mesh.updateVerticesData(VertexBuffer.PositionKind, this._positions32, false, false);
-                if (!this.mesh.areNormalsFrozen || this.mesh.isFacetDataEnabled) {
-                    if (this._computeParticleVertex || this.mesh.isFacetDataEnabled) {
+                mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);
+                if (!mesh.areNormalsFrozen || mesh.isFacetDataEnabled) {
+                    if (this._computeParticleVertex || mesh.isFacetDataEnabled) {
                         // recompute the normals only if the particles can be morphed, update then also the normal reference array _fixedNormal32[]
-                        var params = this.mesh.isFacetDataEnabled ? this.mesh.getFacetDataParameters() : null;
-                        VertexData.ComputeNormals(this._positions32, this._indices32, this._normals32, params);
-                        for (var i = 0; i < this._normals32.length; i++) {
-                            this._fixedNormal32[i] = this._normals32[i];
+                        var params = mesh.isFacetDataEnabled ? mesh.getFacetDataParameters() : null;
+                        VertexData.ComputeNormals(positions32, indices32, normals32, params);
+                        for (var i = 0; i < normals32.length; i++) {
+                            fixedNormal32[i] = normals32[i];
                         }
                     }
-                    if (!this.mesh.areNormalsFrozen) {
-                        this.mesh.updateVerticesData(VertexBuffer.NormalKind, this._normals32, false, false);
+                    if (!mesh.areNormalsFrozen) {
+                        mesh.updateVerticesData(VertexBuffer.NormalKind, normals32, false, false);
                     }
                 }
                 if (this._depthSort && this._depthSortParticles) {
-                    this.depthSortedParticles.sort(this._depthSortFunction);
-                    var dspl = this.depthSortedParticles.length;
-                    var sorted = 0;
-                    var lind = 0;
-                    var sind = 0;
-                    var sid = 0;
-                    for (sorted = 0; sorted < dspl; sorted++) {
-                        lind = this.depthSortedParticles[sorted].indicesLength;
-                        sind = this.depthSortedParticles[sorted].ind;
+                    const depthSortedParticles = this.depthSortedParticles;
+                    depthSortedParticles.sort(depthSortFunction);
+                    const dspl = depthSortedParticles.length;
+                    let sid = 0;
+                    for (let sorted = 0; sorted < dspl; sorted++) {
+                        const lind = depthSortedParticles[sorted].indicesLength;
+                        const sind = depthSortedParticles[sorted].ind;
                         for (var i = 0; i < lind; i++) {
-                            this._indices32[sid] = this._indices[sind + i];
+                            indices32[sid] = indices[sind + i];
                             sid++;
                         }
                     }
-                    this.mesh.updateIndices(this._indices32);
+                    mesh.updateIndices(indices32);
                 }
             }
             if (this._computeBoundingBox) {
-                this.mesh._boundingInfo = new BoundingInfo(this._minimum, this._maximum);
-                this.mesh._boundingInfo.update(this.mesh._worldMatrix);
+                if (mesh._boundingInfo) {
+                    mesh._boundingInfo.reConstruct(minimum, maximum, mesh._worldMatrix);
+                }
+                else {
+                    mesh._boundingInfo = new BoundingInfo(minimum, maximum, mesh._worldMatrix);
+                }
             }
             this.afterUpdateParticles(start, end, update);
             return this;
         }
 
-        private _quaternionRotationYPR(): void {
-            this._halfroll = this._roll * 0.5;
-            this._halfpitch = this._pitch * 0.5;
-            this._halfyaw = this._yaw * 0.5;
-            this._sinRoll = Math.sin(this._halfroll);
-            this._cosRoll = Math.cos(this._halfroll);
-            this._sinPitch = Math.sin(this._halfpitch);
-            this._cosPitch = Math.cos(this._halfpitch);
-            this._sinYaw = Math.sin(this._halfyaw);
-            this._cosYaw = Math.cos(this._halfyaw);
-            this._quaternion.x = this._cosYaw * this._sinPitch * this._cosRoll + this._sinYaw * this._cosPitch * this._sinRoll;
-            this._quaternion.y = this._sinYaw * this._cosPitch * this._cosRoll - this._cosYaw * this._sinPitch * this._sinRoll;
-            this._quaternion.z = this._cosYaw * this._cosPitch * this._sinRoll - this._sinYaw * this._sinPitch * this._cosRoll;
-            this._quaternion.w = this._cosYaw * this._cosPitch * this._cosRoll + this._sinYaw * this._sinPitch * this._sinRoll;
-        }
-
-        private _quaternionToRotationMatrix(): void {
-            this._rotMatrix.m[0] = 1.0 - (2.0 * (this._quaternion.y * this._quaternion.y + this._quaternion.z * this._quaternion.z));
-            this._rotMatrix.m[1] = 2.0 * (this._quaternion.x * this._quaternion.y + this._quaternion.z * this._quaternion.w);
-            this._rotMatrix.m[2] = 2.0 * (this._quaternion.z * this._quaternion.x - this._quaternion.y * this._quaternion.w);
-            this._rotMatrix.m[3] = 0;
-            this._rotMatrix.m[4] = 2.0 * (this._quaternion.x * this._quaternion.y - this._quaternion.z * this._quaternion.w);
-            this._rotMatrix.m[5] = 1.0 - (2.0 * (this._quaternion.z * this._quaternion.z + this._quaternion.x * this._quaternion.x));
-            this._rotMatrix.m[6] = 2.0 * (this._quaternion.y * this._quaternion.z + this._quaternion.x * this._quaternion.w);
-            this._rotMatrix.m[7] = 0;
-            this._rotMatrix.m[8] = 2.0 * (this._quaternion.z * this._quaternion.x + this._quaternion.y * this._quaternion.w);
-            this._rotMatrix.m[9] = 2.0 * (this._quaternion.y * this._quaternion.z - this._quaternion.x * this._quaternion.w);
-            this._rotMatrix.m[10] = 1.0 - (2.0 * (this._quaternion.y * this._quaternion.y + this._quaternion.x * this._quaternion.x));
-            this._rotMatrix.m[11] = 0;
-            this._rotMatrix.m[12] = 0;
-            this._rotMatrix.m[13] = 0;
-            this._rotMatrix.m[14] = 0;
-            this._rotMatrix.m[15] = 1.0;
-        }
-
         /**
         * Disposes the SPS.
         */