Browse Source

1.2.0:
- Major rework of the API to remove GC pressure.
- FreeCamera: Support for QWERTY keyboards
- New 3D charting demo

deltakosh 12 years ago
parent
commit
0087abb3ad
33 changed files with 1475 additions and 561 deletions
  1. 2 2
      Babylon/Animations/babylon.animatable.js
  2. 10 0
      Babylon/Animations/babylon.animation.js
  3. 36 2
      Babylon/Cameras/babylon.arcRotateCamera.js
  4. 8 2
      Babylon/Cameras/babylon.camera.js
  5. 49 27
      Babylon/Cameras/babylon.freeCamera.js
  6. 5 2
      Babylon/Cameras/babylon.touchCamera.js
  7. 105 79
      Babylon/Collisions/babylon.collider.js
  8. 18 9
      Babylon/Culling/babylon.boundingBox.js
  9. 3 1
      Babylon/Culling/babylon.boundingSphere.js
  10. 14 6
      Babylon/Lights/Shadows/babylon.shadowGenerator.js
  11. 69 17
      Babylon/Materials/babylon.effect.js
  12. 34 17
      Babylon/Materials/babylon.standardMaterial.js
  13. 24 5
      Babylon/Materials/textures/babylon.dynamicTexture.js
  14. 8 2
      Babylon/Materials/textures/babylon.mirrorTexture.js
  15. 11 4
      Babylon/Materials/textures/babylon.renderTargetTexture.js
  16. 57 48
      Babylon/Materials/textures/babylon.texture.js
  17. 42 29
      Babylon/Mesh/babylon.mesh.js
  18. 6 6
      Babylon/Particles/babylon.particle.js
  19. 50 33
      Babylon/Particles/babylon.particleSystem.js
  20. 43 38
      Babylon/Sprites/babylon.spriteManager.js
  21. 557 123
      Babylon/Tools/babylon.math.js
  22. 42 0
      Babylon/Tools/babylon.tools.js
  23. 28 18
      Babylon/babylon.engine.js
  24. 60 37
      Babylon/babylon.scene.js
  25. 129 0
      Samples/Scenes/Customs/charting.js
  26. 1 1
      Samples/Scenes/Customs/test.js
  27. BIN
      Samples/Screenshots/charting.jpg
  28. 2 2
      Samples/babylon.js
  29. 1 1
      Samples/index.html
  30. 44 37
      Samples/index.js
  31. 0 13
      babylon.1.1.0.js
  32. 13 0
      babylon.1.2.0.js
  33. 4 0
      what's new.txt

+ 2 - 2
Babylon/Animations/babylon.animatable.js

@@ -14,8 +14,8 @@
     BABYLON._Animatable.prototype.target = null;
     BABYLON._Animatable.prototype.target = null;
     BABYLON._Animatable.prototype.animationStarted = false;
     BABYLON._Animatable.prototype.animationStarted = false;
     BABYLON._Animatable.prototype.loopAnimation = false;
     BABYLON._Animatable.prototype.loopAnimation = false;
-    BABYLON._Animatable.prototype.fromFrame = false;
-    BABYLON._Animatable.prototype.toFrame = false;
+    BABYLON._Animatable.prototype.fromFrame = 0;
+    BABYLON._Animatable.prototype.toFrame = 100;
     BABYLON._Animatable.prototype.speedRatio = 1.0;
     BABYLON._Animatable.prototype.speedRatio = 1.0;
     
     
     // Methods
     // Methods

+ 10 - 0
Babylon/Animations/babylon.animation.js

@@ -88,6 +88,16 @@
         if (!this.targetPropertyPath || this.targetPropertyPath.length < 1) {
         if (!this.targetPropertyPath || this.targetPropertyPath.length < 1) {
             return false;
             return false;
         }
         }
+        
+        // Adding a start key at frame 0 if missing
+        if (this._keys[0].frame != 0) {
+            var newKey = {
+                frame: 0,
+                value: this._keys[0].value
+            };
+
+            this._keys.splice(0, 0, newKey);
+        }
 
 
         // Check limits
         // Check limits
         if (from < this._keys[0].frame || from > this._keys[this._keys.length - 1].frame) {
         if (from < this._keys[0].frame || from > this._keys[this._keys.length - 1].frame) {

+ 36 - 2
Babylon/Cameras/babylon.arcRotateCamera.js

@@ -10,6 +10,7 @@
         this.beta = beta;
         this.beta = beta;
         this.radius = radius;
         this.radius = radius;
         this.target = target;
         this.target = target;
+        this.position = BABYLON.Vector3.Zero();
         
         
         this._keys = [];
         this._keys = [];
         this.keysUp = [38];
         this.keysUp = [38];
@@ -25,6 +26,8 @@
             scene.activeCamera = this;
             scene.activeCamera = this;
         }
         }
 
 
+        this._viewMatrix = new BABYLON.Matrix();
+
         this.getViewMatrix();
         this.getViewMatrix();
         
         
         // Animations
         // Animations
@@ -36,6 +39,12 @@
     // Members
     // Members
     BABYLON.ArcRotateCamera.prototype.inertialAlphaOffset = 0;
     BABYLON.ArcRotateCamera.prototype.inertialAlphaOffset = 0;
     BABYLON.ArcRotateCamera.prototype.inertialBetaOffset = 0;
     BABYLON.ArcRotateCamera.prototype.inertialBetaOffset = 0;
+    BABYLON.ArcRotateCamera.prototype.lowerAlphaLimit = null;
+    BABYLON.ArcRotateCamera.prototype.upperAlphaLimit = null;
+    BABYLON.ArcRotateCamera.prototype.lowerBetaLimit = null;
+    BABYLON.ArcRotateCamera.prototype.upperBetaLimit = null;
+    BABYLON.ArcRotateCamera.prototype.lowerRadiusLimit = null;
+    BABYLON.ArcRotateCamera.prototype.upperRadiusLimit = null;
 
 
     // Methods
     // Methods
     BABYLON.ArcRotateCamera.prototype.attachControl = function(canvas) {
     BABYLON.ArcRotateCamera.prototype.attachControl = function(canvas) {
@@ -147,6 +156,9 @@
 
 
         this._onGesture = function(e) {
         this._onGesture = function(e) {
             that.radius *= e.scale;
             that.radius *= e.scale;
+
+            e.preventDefault();
+            e.stopPropagation();
         };
         };
         
         
         canvas.addEventListener(eventPrefix + "down", this._onPointerDown);
         canvas.addEventListener(eventPrefix + "down", this._onPointerDown);
@@ -207,6 +219,26 @@
             if (Math.abs(this.inertialBetaOffset) < BABYLON.Engine.epsilon)
             if (Math.abs(this.inertialBetaOffset) < BABYLON.Engine.epsilon)
                 this.inertialBetaOffset = 0;
                 this.inertialBetaOffset = 0;
         }
         }
+        
+        // Limits
+        if (this.lowerAlphaLimit && this.alpha < this.lowerAlphaLimit) {
+            this.alpha = this.lowerAlphaLimit;
+        }
+        if (this.upperAlphaLimit && this.alpha > this.upperAlphaLimit) {
+            this.alpha = this.upperAlphaLimit;
+        }
+        if (this.lowerBetaLimit && this.beta < this.lowerBetaLimit) {
+            this.beta = this.lowerBetaLimit;
+        }
+        if (this.upperBetaLimit && this.beta > this.upperBetaLimit) {
+            this.beta = this.upperBetaLimit;
+        }
+        if (this.lowerRadiusLimit && this.radius < this.lowerRadiusLimit) {
+            this.radius = this.lowerRadiusLimit;
+        }
+        if (this.upperRadiusLimit && this.radius > this.upperRadiusLimit) {
+            this.radius = this.upperRadiusLimit;
+        }
     };
     };
 
 
     BABYLON.ArcRotateCamera.prototype.setPosition = function(position) {
     BABYLON.ArcRotateCamera.prototype.setPosition = function(position) {
@@ -230,7 +262,9 @@
         var cosb = Math.cos(this.beta);
         var cosb = Math.cos(this.beta);
         var sinb = Math.sin(this.beta);
         var sinb = Math.sin(this.beta);
 
 
-        this.position = this.target.add(new BABYLON.Vector3(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb));
-        return new BABYLON.Matrix.LookAtLH(this.position, this.target, BABYLON.Vector3.Up());
+        this.target.addToRef(new BABYLON.Vector3(this.radius * cosa * sinb, this.radius * cosb, this.radius * sina * sinb), this.position);
+        BABYLON.Matrix.LookAtLHToRef(this.position, this.target, BABYLON.Vector3.Up(), this._viewMatrix);
+
+        return this._viewMatrix;
     };
     };
 })();
 })();

+ 8 - 2
Babylon/Cameras/babylon.camera.js

@@ -46,13 +46,19 @@
     };
     };
 
 
     BABYLON.Camera.prototype.getProjectionMatrix = function () {
     BABYLON.Camera.prototype.getProjectionMatrix = function () {
+        if (!this._projectionMatrix) {
+            this._projectionMatrix = new BABYLON.Matrix();
+        }
+
         var engine = this._scene.getEngine();
         var engine = this._scene.getEngine();
         if (this.mode === BABYLON.Camera.PERSPECTIVE_CAMERA) {
         if (this.mode === BABYLON.Camera.PERSPECTIVE_CAMERA) {
-            return new BABYLON.Matrix.PerspectiveFovLH(this.fov, engine.getAspectRatio(), this.minZ, this.maxZ);
+            BABYLON.Matrix.PerspectiveFovLHToRef(this.fov, engine.getAspectRatio(), this.minZ, this.maxZ, this._projectionMatrix);
+            return this._projectionMatrix;
         }
         }
 
 
         var halfWidth = engine.getRenderWidth() / 2.0;
         var halfWidth = engine.getRenderWidth() / 2.0;
         var halfHeight = engine.getRenderHeight() / 2.0;
         var halfHeight = engine.getRenderHeight() / 2.0;
-        return new BABYLON.Matrix.OrthoOffCenterLH(this.orthoLeft || -halfWidth, this.orthoRight || halfWidth, this.orthoBottom || -halfHeight, this.orthoTop || halfHeight, this.minZ, this.maxZ)
+        BABYLON.Matrix.OrthoOffCenterLHToRef(this.orthoLeft || -halfWidth, this.orthoRight || halfWidth, this.orthoBottom || -halfHeight, this.orthoTop || halfHeight, this.minZ, this.maxZ);
+        return this._projectionMatrix;
     };
     };
 })();
 })();

+ 49 - 27
Babylon/Cameras/babylon.freeCamera.js

@@ -14,10 +14,10 @@
         this.ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5);
         this.ellipsoid = new BABYLON.Vector3(0.5, 1, 0.5);
 
 
         this._keys = [];
         this._keys = [];
-        this.keysUp = [38];
+        this.keysUp = [38, 87];
         this.keysDown = [40];
         this.keysDown = [40];
-        this.keysLeft = [37];
-        this.keysRight = [39];
+        this.keysLeft = [37, 81];
+        this.keysRight = [39, 68];
 
 
         if (!scene.activeCamera) {
         if (!scene.activeCamera) {
             scene.activeCamera = this;
             scene.activeCamera = this;
@@ -25,9 +25,22 @@
         // Collisions
         // Collisions
         this._collider = new BABYLON.Collider();
         this._collider = new BABYLON.Collider();
         this._needMoveForGravity = true;
         this._needMoveForGravity = true;
-        
+
         // Animations
         // Animations
         this.animations = [];
         this.animations = [];
+
+        // Internals
+        this._currentTarget = BABYLON.Vector3.Zero();
+        this._upVector = BABYLON.Vector3.Up();
+        this._viewMatrix = BABYLON.Matrix.Zero();
+        this._camMatrix = BABYLON.Matrix.Zero();
+        this._cameraTransformMatrix = BABYLON.Matrix.Zero();
+        this._cameraRotationMatrix = BABYLON.Matrix.Zero();
+        this._referencePoint = BABYLON.Vector3.Zero();
+        this._transformedReferencePoint = BABYLON.Vector3.Zero();
+        this._oldPosition = BABYLON.Vector3.Zero();
+        this._diffPosition = BABYLON.Vector3.Zero();
+        this._newPosition = BABYLON.Vector3.Zero();
     };
     };
 
 
     BABYLON.FreeCamera.prototype = Object.create(BABYLON.Camera.prototype);
     BABYLON.FreeCamera.prototype = Object.create(BABYLON.Camera.prototype);
@@ -44,10 +57,10 @@
 
 
     // Target
     // Target
     BABYLON.FreeCamera.prototype.setTarget = function (target) {
     BABYLON.FreeCamera.prototype.setTarget = function (target) {
-        var camMatrix = BABYLON.Matrix.LookAtLH(this.position, target, BABYLON.Vector3.Up());
-        camMatrix.invert();
+        BABYLON.Matrix.LookAtLHToRef(this.position, target, BABYLON.Vector3.Up(), this._camMatrix);
+        this._camMatrix.invert();
 
 
-        this.rotation.x = Math.atan(camMatrix.m[6] / camMatrix.m[10]);
+        this.rotation.x = Math.atan(this._camMatrix.m[6] / this._camMatrix.m[10]);
 
 
         var vDir = target.subtract(this.position);
         var vDir = target.subtract(this.position);
 
 
@@ -164,36 +177,41 @@
     };
     };
 
 
     BABYLON.FreeCamera.prototype._collideWithWorld = function (velocity) {
     BABYLON.FreeCamera.prototype._collideWithWorld = function (velocity) {
-        var oldPosition = this.position.subtract(new BABYLON.Vector3(0, this.ellipsoid.y, 0));
+        this.position.subtractFromFloatsToRef(0, this.ellipsoid.y, 0, this._oldPosition);
         this._collider.radius = this.ellipsoid;
         this._collider.radius = this.ellipsoid;
 
 
-        var newPosition = this._scene._getNewPosition(oldPosition, velocity, this._collider, 3);
-        var diffPosition = newPosition.subtract(oldPosition);
+        this._scene._getNewPosition(this._oldPosition, velocity, this._collider, 3, this._newPosition);
+        this._newPosition.subtractToRef(this._oldPosition, this._diffPosition);
 
 
-        if (diffPosition.length() > BABYLON.Engine.collisionsEpsilon) {
-            this.position = this.position.add(diffPosition);
+        if (this._diffPosition.length() > BABYLON.Engine.collisionsEpsilon) {
+            this.position.addInPlace(this._diffPosition);
         }
         }
     };
     };
 
 
     BABYLON.FreeCamera.prototype._checkInputs = function () {
     BABYLON.FreeCamera.prototype._checkInputs = function () {
+        if (!this._localDirection) {
+            this._localDirection = BABYLON.Vector3.Zero();
+            this._transformedDirection = BABYLON.Vector3.Zero();
+        }
+
         // Keyboard
         // Keyboard
         for (var index = 0; index < this._keys.length; index++) {
         for (var index = 0; index < this._keys.length; index++) {
             var keyCode = this._keys[index];
             var keyCode = this._keys[index];
-            var direction;
             var speed = this._computeLocalCameraSpeed();
             var speed = this._computeLocalCameraSpeed();
 
 
             if (this.keysLeft.indexOf(keyCode) !== -1) {
             if (this.keysLeft.indexOf(keyCode) !== -1) {
-                direction = new BABYLON.Vector3(-speed, 0, 0);
+                this._localDirection.copyFromFloats(-speed, 0, 0);
             } else if (this.keysUp.indexOf(keyCode) !== -1) {
             } else if (this.keysUp.indexOf(keyCode) !== -1) {
-                direction = new BABYLON.Vector3(0, 0, speed);
+                this._localDirection.copyFromFloats(0, 0, speed);
             } else if (this.keysRight.indexOf(keyCode) !== -1) {
             } else if (this.keysRight.indexOf(keyCode) !== -1) {
-                direction = new BABYLON.Vector3(speed, 0, 0);
+                this._localDirection.copyFromFloats(speed, 0, 0);
             } else if (this.keysDown.indexOf(keyCode) !== -1) {
             } else if (this.keysDown.indexOf(keyCode) !== -1) {
-                direction = new BABYLON.Vector3(0, 0, -speed);
+                this._localDirection.copyFromFloats(0, 0, -speed);
             }
             }
 
 
-            var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            this.cameraDirection = this.cameraDirection.add(BABYLON.Vector3.TransformCoordinates(direction, cameraTransform));
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, 0, this._cameraTransformMatrix);
+            BABYLON.Vector3.TransformCoordinatesToRef(this._localDirection, this._cameraTransformMatrix, this._transformedDirection);
+            this.cameraDirection.addInPlace(this._transformedDirection);
         }
         }
     };
     };
 
 
@@ -211,10 +229,10 @@
                 if (this.applyGravity) {
                 if (this.applyGravity) {
                     var oldPosition = this.position;
                     var oldPosition = this.position;
                     this._collideWithWorld(this._scene.gravity);
                     this._collideWithWorld(this._scene.gravity);
-                    this._needMoveForGravity = (oldPosition.subtract(this.position).length() != 0);
+                    this._needMoveForGravity = (BABYLON.Vector3.DistanceSquared(oldPosition, this.position) != 0);
                 }
                 }
             } else {
             } else {
-                this.position = this.position.add(this.cameraDirection);
+                this.position.addInPlace(this.cameraDirection);
             }
             }
         }
         }
 
 
@@ -233,20 +251,24 @@
 
 
         // Inertia
         // Inertia
         if (needToMove) {
         if (needToMove) {
-            this.cameraDirection = this.cameraDirection.scale(this.inertia);
+            this.cameraDirection.scaleInPlace(this.inertia);
         }
         }
         if (needToRotate) {
         if (needToRotate) {
-            this.cameraRotation = this.cameraRotation.scale(this.inertia);
+            this.cameraRotation.scaleInPlace(this.inertia);
         }
         }
     };
     };
 
 
     BABYLON.FreeCamera.prototype.getViewMatrix = function () {
     BABYLON.FreeCamera.prototype.getViewMatrix = function () {
+        BABYLON.Vector3.FromFloatsToRef(0, 0, 1, this._referencePoint);
         // Compute
         // Compute
-        var referencePoint = new BABYLON.Vector3(0, 0, 1);
-        var transform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z);
+        BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._cameraRotationMatrix);
+
+        BABYLON.Vector3.TransformCoordinatesToRef(this._referencePoint, this._cameraRotationMatrix, this._transformedReferencePoint);
+
+        this.position.addToRef(this._transformedReferencePoint, this._currentTarget);
 
 
-        var currentTarget = this.position.add(BABYLON.Vector3.TransformCoordinates(referencePoint, transform));
+        BABYLON.Matrix.LookAtLHToRef(this.position, this._currentTarget, this._upVector, this._viewMatrix);
 
 
-        return new BABYLON.Matrix.LookAtLH(this.position, currentTarget, BABYLON.Vector3.Up());
+        return this._viewMatrix;
     };
     };
 })();
 })();

+ 5 - 2
Babylon/Cameras/babylon.touchCamera.js

@@ -30,6 +30,9 @@
         
         
         // Animations
         // Animations
         this.animations = [];
         this.animations = [];
+        
+        // Internals
+        this._cameraRotationMatrix = new BABYLON.Matrix();
     };
     };
 
 
     BABYLON.TouchCamera.prototype = Object.create(BABYLON.FreeCamera.prototype);
     BABYLON.TouchCamera.prototype = Object.create(BABYLON.FreeCamera.prototype);
@@ -121,8 +124,8 @@
             var speed = this._computeLocalCameraSpeed();
             var speed = this._computeLocalCameraSpeed();
             var direction = new BABYLON.Vector3(0, 0, speed * this._offsetY / this.moveSensibility);
             var direction = new BABYLON.Vector3(0, 0, speed * this._offsetY / this.moveSensibility);
 
 
-            var cameraTransform = BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, 0);
-            this.cameraDirection = this.cameraDirection.add(BABYLON.Vector3.TransformCoordinates(direction, cameraTransform));
+            BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, 0, this._cameraRotationMatrix);
+            this.cameraDirection.addInPlace(BABYLON.Vector3.TransformCoordinates(direction, this._cameraRotationMatrix));
         }
         }
     };
     };
 })();
 })();

+ 105 - 79
Babylon/Collisions/babylon.collider.js

@@ -4,16 +4,34 @@
     BABYLON.Collider = function () {
     BABYLON.Collider = function () {
         this.radius = new BABYLON.Vector3(1, 1, 1);
         this.radius = new BABYLON.Vector3(1, 1, 1);
         this.retry = 0;
         this.retry = 0;
+
+        this.basePointWorld = BABYLON.Vector3.Zero();
+        this.velocityWorld = BABYLON.Vector3.Zero();
+        this.normalizedVelocity = BABYLON.Vector3.Zero();
+        
+        // Internals
+        this._trianglePlane = new BABYLON.Plane(0, 0, 0, 0);
+        this._collisionPoint = BABYLON.Vector3.Zero();
+        this._planeIntersectionPoint = BABYLON.Vector3.Zero();
+        this._tempVector = BABYLON.Vector3.Zero();
+        this._tempVector2 = BABYLON.Vector3.Zero();
+        this._tempVector3 = BABYLON.Vector3.Zero();
+        this._tempVector4 = BABYLON.Vector3.Zero();
+        this._edge = BABYLON.Vector3.Zero();
+        this._baseToVertex = BABYLON.Vector3.Zero();
+        this._destinationPoint = BABYLON.Vector3.Zero();
+        this._slidePlaneNormal = BABYLON.Vector3.Zero();
+        this._displacementVector = BABYLON.Vector3.Zero();
     };
     };
 
 
     // Methods
     // Methods
     BABYLON.Collider.prototype._initialize = function (source, dir, e) {
     BABYLON.Collider.prototype._initialize = function (source, dir, e) {
         this.velocity = dir;
         this.velocity = dir;
-        this.normalizedVelocity = BABYLON.Vector3.Normalize(dir);
+        BABYLON.Vector3.NormalizeToRef(dir, this.normalizedVelocity);
         this.basePoint = source;
         this.basePoint = source;
 
 
-        this.basePointWorld = source.multiply(this.radius);
-        this.velocityWorld = dir.multiply(this.radius);
+        source.multiplyToRef(this.radius, this.basePointWorld);
+        dir.multiplyToRef(this.radius, this.velocityWorld);
 
 
         this.velocityWorldLength = this.velocityWorld.length();
         this.velocityWorldLength = this.velocityWorld.length();
 
 
@@ -21,43 +39,43 @@
         this.collisionFound = false;
         this.collisionFound = false;
     };
     };
 
 
-    var checkPointInTriangle = function (point, pa, pb, pc, n) {
-        var e0 = pa.subtract(point);
-        var e1 = pb.subtract(point);
+    BABYLON.Collider.prototype._checkPointInTriangle = function (point, pa, pb, pc, n) {
+        pa.subtractToRef(point, this._tempVector);
+        pb.subtractToRef(point, this._tempVector2);
 
 
-        var d = BABYLON.Vector3.Dot(BABYLON.Vector3.Cross(e0, e1), n);
+        BABYLON.Vector3.CrossToRef(this._tempVector, this._tempVector2, this._tempVector4);
+        var d = BABYLON.Vector3.Dot(this._tempVector4, n);
         if (d < 0)
         if (d < 0)
             return false;
             return false;
 
 
-        var e2 = pc.subtract(point);
-        d = BABYLON.Vector3.Dot(BABYLON.Vector3.Cross(e1, e2), n);
+        pc.subtractToRef(point, this._tempVector3);
+        BABYLON.Vector3.CrossToRef(this._tempVector2, this._tempVector3, this._tempVector4);
+        d = BABYLON.Vector3.Dot(this._tempVector4, n);
         if (d < 0)
         if (d < 0)
             return false;
             return false;
 
 
-        d = BABYLON.Vector3.Dot(BABYLON.Vector3.Cross(e2, e0), n);
+        BABYLON.Vector3.CrossToRef(this._tempVector3, this._tempVector, this._tempVector4);
+        d = BABYLON.Vector3.Dot(this._tempVector4, n);
         return d >= 0;
         return d >= 0;
     };
     };
 
 
     var intersectBoxAASphere = function (boxMin, boxMax, sphereCenter, sphereRadius) {
     var intersectBoxAASphere = function (boxMin, boxMax, sphereCenter, sphereRadius) {
-        var boxMinSphere = new BABYLON.Vector3(sphereCenter.X - sphereRadius, sphereCenter.Y - sphereRadius, sphereCenter.Z - sphereRadius);
-        var boxMaxSphere = new BABYLON.Vector3(sphereCenter.X + sphereRadius, sphereCenter.Y + sphereRadius, sphereCenter.Z + sphereRadius);
-
-        if (boxMin.X > boxMaxSphere.X)
+        if (boxMin.x > sphereCenter.x + sphereRadius)
             return false;
             return false;
 
 
-        if (boxMinSphere.X > boxMax.X)
+        if (sphereCenter.x - sphereRadius > boxMax.x)
             return false;
             return false;
 
 
-        if (boxMin.Y > boxMaxSphere.Y)
+        if (boxMin.y > sphereCenter.y + sphereRadius)
             return false;
             return false;
 
 
-        if (boxMinSphere.Y > boxMax.Y)
+        if (sphereCenter.y - sphereRadius > boxMax.y)
             return false;
             return false;
 
 
-        if (boxMin.Z > boxMaxSphere.Z)
+        if (boxMin.z > sphereCenter.z + sphereRadius)
             return false;
             return false;
 
 
-        if (boxMinSphere.Z > boxMax.Z)
+        if (sphereCenter.z - sphereRadius > boxMax.z)
             return false;
             return false;
 
 
         return true;
         return true;
@@ -96,8 +114,7 @@
     };
     };
 
 
     BABYLON.Collider.prototype._canDoCollision = function (sphereCenter, sphereRadius, vecMin, vecMax) {
     BABYLON.Collider.prototype._canDoCollision = function (sphereCenter, sphereRadius, vecMin, vecMax) {
-        var vecTest = this.basePointWorld.subtract(sphereCenter);
-        var distance = vecTest.length();
+        var distance = BABYLON.Vector3.Distance(this.basePointWorld, sphereCenter);
 
 
         var max = Math.max(this.radius.x, this.radius.y);
         var max = Math.max(this.radius.x, this.radius.y);
         max = Math.max(max, this.radius.z);
         max = Math.max(max, this.radius.z);
@@ -116,13 +133,13 @@
         var t0;
         var t0;
         var embeddedInPlane = false;
         var embeddedInPlane = false;
 
 
-        var trianglePlane = BABYLON.CollisionPlane.CreateFromPoints(p1, p2, p3);
+        this._trianglePlane.copyFromPoints(p1, p2, p3);
 
 
-        if ((!subMesh.getMaterial()) && !trianglePlane.isFrontFacingTo(this.normalizedVelocity, 0))
+        if ((!subMesh.getMaterial()) && !this._trianglePlane.isFrontFacingTo(this.normalizedVelocity, 0))
             return;
             return;
 
 
-        var signedDistToTrianglePlane = trianglePlane.signedDistanceTo(this.basePoint);
-        var normalDotVelocity = BABYLON.Vector3.Dot(trianglePlane.normal, this.velocity);
+        var signedDistToTrianglePlane = this._trianglePlane.signedDistanceTo(this.basePoint);
+        var normalDotVelocity = BABYLON.Vector3.Dot(this._trianglePlane.normal, this.velocity);
 
 
         if (normalDotVelocity == 0) {
         if (normalDotVelocity == 0) {
             if (Math.abs(signedDistToTrianglePlane) >= 1.0)
             if (Math.abs(signedDistToTrianglePlane) >= 1.0)
@@ -149,18 +166,20 @@
                 t0 = 1.0;
                 t0 = 1.0;
         }
         }
 
 
-        var collisionPoint = BABYLON.Vector3.Zero();
+        this._collisionPoint.copyFromFloats(0, 0, 0);
 
 
         var found = false;
         var found = false;
         var t = 1.0;
         var t = 1.0;
 
 
         if (!embeddedInPlane) {
         if (!embeddedInPlane) {
-            var planeIntersectionPoint = (this.basePoint.subtract(trianglePlane.normal)).add(this.velocity.scale(t0));
+            this.basePoint.subtractToRef(this._trianglePlane.normal, this._planeIntersectionPoint);
+            this.velocity.scaleToRef(t0, this._tempVector);
+            this._planeIntersectionPoint.addInPlace(this._tempVector);
 
 
-            if (checkPointInTriangle(planeIntersectionPoint, p1, p2, p3, trianglePlane.normal)) {
+            if (this._checkPointInTriangle(this._planeIntersectionPoint, p1, p2, p3, this._trianglePlane.normal)) {
                 found = true;
                 found = true;
                 t = t0;
                 t = t0;
-                collisionPoint = planeIntersectionPoint;
+                this._collisionPoint.copyFrom(this._planeIntersectionPoint);
             }
             }
         }
         }
 
 
@@ -169,45 +188,48 @@
 
 
             var a = velocitySquaredLength;
             var a = velocitySquaredLength;
 
 
-            var b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this.basePoint.subtract(p1)));
-            var c = p1.subtract(this.basePoint).lengthSquared() - 1.0;
+            this.basePoint.subtractToRef(p1, this._tempVector);
+            var b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this._tempVector));
+            var c = this._tempVector.lengthSquared - 1.0;
 
 
             var lowestRoot = getLowestRoot(a, b, c, t);
             var lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
                 t = lowestRoot.root;
                 t = lowestRoot.root;
                 found = true;
                 found = true;
-                collisionPoint = p1;
+                this._collisionPoint.copyFrom(p1);
             }
             }
 
 
-            b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this.basePoint.subtract(p2)));
-            c = p2.subtract(this.basePoint).lengthSquared() - 1.0;
+            this.basePoint.subtractToRef(p2, this._tempVector);
+            b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this._tempVector));
+            c = this._tempVector.lengthSquared - 1.0;
 
 
             lowestRoot = getLowestRoot(a, b, c, t);
             lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
                 t = lowestRoot.root;
                 t = lowestRoot.root;
                 found = true;
                 found = true;
-                collisionPoint = p2;
+                this._collisionPoint.copyFrom(p2);
             }
             }
 
 
-            b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this.basePoint.subtract(p3)));
-            c = p3.subtract(this.basePoint).lengthSquared() - 1.0;
+            this.basePoint.subtractToRef(p3, this._tempVector);
+            b = 2.0 * (BABYLON.Vector3.Dot(this.velocity, this._tempVector));
+            c = this._tempVector.lengthSquared - 1.0;
 
 
             lowestRoot = getLowestRoot(a, b, c, t);
             lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
                 t = lowestRoot.root;
                 t = lowestRoot.root;
                 found = true;
                 found = true;
-                collisionPoint = p3;
+                this._collisionPoint.copyFrom(p3);
             }
             }
 
 
-            var edge = p2.subtract(p1);
-            var baseToVertex = p1.subtract(this.basePoint);
-            var edgeSquaredLength = edge.lengthSquared();
-            var edgeDotVelocity = BABYLON.Vector3.Dot(edge, this.velocity);
-            var edgeDotBaseToVertex = BABYLON.Vector3.Dot(edge, baseToVertex);
+            p2.subtractToRef(p1, this._edge);
+            p1.subtractToRef(this.basePoint, this._baseToVertex);
+            var edgeSquaredLength = this._edge.lengthSquared();
+            var edgeDotVelocity = BABYLON.Vector3.Dot(this._edge, this.velocity);
+            var edgeDotBaseToVertex = BABYLON.Vector3.Dot(this._edge, this._baseToVertex);
 
 
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
-            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
-            c = edgeSquaredLength * (1.0 - baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
+            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
+            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
 
 
             lowestRoot = getLowestRoot(a, b, c, t);
             lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
@@ -216,19 +238,20 @@
                 if (f >= 0.0 && f <= 1.0) {
                 if (f >= 0.0 && f <= 1.0) {
                     t = lowestRoot.root;
                     t = lowestRoot.root;
                     found = true;
                     found = true;
-                    collisionPoint = p1.add(edge.scale(f));
+                    this._edge.scaleInPlace(f);
+                    p1.addToRef(this._edge, this._collisionPoint);
                 }
                 }
             }
             }
 
 
-            edge = p3.subtract(p2);
-            baseToVertex = p2.subtract(this.basePoint);
-            edgeSquaredLength = edge.lengthSquared();
-            edgeDotVelocity = BABYLON.Vector3.Dot(edge, this.velocity);
-            edgeDotBaseToVertex = BABYLON.Vector3.Dot(edge, baseToVertex);
+            p3.subtractToRef(p2, this._edge);
+            p2.subtractToRef(this.basePoint, this._baseToVertex);
+            edgeSquaredLength = this._edge.lengthSquared();
+            edgeDotVelocity = BABYLON.Vector3.Dot(this._edge, this.velocity);
+            edgeDotBaseToVertex = BABYLON.Vector3.Dot(this._edge, this._baseToVertex);
 
 
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
-            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
-            c = edgeSquaredLength * (1.0 - baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
+            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
+            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
             lowestRoot = getLowestRoot(a, b, c, t);
             lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
                 var f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;
                 var f = (edgeDotVelocity * lowestRoot.root - edgeDotBaseToVertex) / edgeSquaredLength;
@@ -236,19 +259,20 @@
                 if (f >= 0.0 && f <= 1.0) {
                 if (f >= 0.0 && f <= 1.0) {
                     t = lowestRoot.root;
                     t = lowestRoot.root;
                     found = true;
                     found = true;
-                    collisionPoint = p2.add(edge.scale(f));
+                    this._edge.scaleInPlace(f);
+                    p2.addToRef(this._edge, this._collisionPoint);
                 }
                 }
             }
             }
 
 
-            edge = p1.subtract(p3);
-            baseToVertex = p3.subtract(this.basePoint);
-            edgeSquaredLength = edge.lengthSquared();
-            edgeDotVelocity = BABYLON.Vector3.Dot(edge, this.velocity);
-            edgeDotBaseToVertex = BABYLON.Vector3.Dot(edge, baseToVertex);
+            p1.subtractToRef(p3, this._edge);
+            p3.subtractToRef(this.basePoint, this._baseToVertex);
+            edgeSquaredLength = this._edge.lengthSquared();
+            edgeDotVelocity = BABYLON.Vector3.Dot(this._edge, this.velocity);
+            edgeDotBaseToVertex = BABYLON.Vector3.Dot(this._edge, this._baseToVertex);
 
 
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
             a = edgeSquaredLength * (-velocitySquaredLength) + edgeDotVelocity * edgeDotVelocity;
-            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
-            c = edgeSquaredLength * (1.0 - baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
+            b = edgeSquaredLength * (2.0 * BABYLON.Vector3.Dot(this.velocity, this._baseToVertex)) - 2.0 * edgeDotVelocity * edgeDotBaseToVertex;
+            c = edgeSquaredLength * (1.0 - this._baseToVertex.lengthSquared()) + edgeDotBaseToVertex * edgeDotBaseToVertex;
 
 
             lowestRoot = getLowestRoot(a, b, c, t);
             lowestRoot = getLowestRoot(a, b, c, t);
             if (lowestRoot.found) {
             if (lowestRoot.found) {
@@ -257,7 +281,8 @@
                 if (f >= 0.0 && f <= 1.0) {
                 if (f >= 0.0 && f <= 1.0) {
                     t = lowestRoot.root;
                     t = lowestRoot.root;
                     found = true;
                     found = true;
-                    collisionPoint = p3.add(edge.scale(f));
+                    this._edge.scaleInPlace(f);
+                    p3.addToRef(this._edge, this._collisionPoint);
                 }
                 }
             }
             }
         }
         }
@@ -266,8 +291,12 @@
             var distToCollision = t * this.velocity.length();
             var distToCollision = t * this.velocity.length();
 
 
             if (!this.collisionFound || distToCollision < this.nearestDistance) {
             if (!this.collisionFound || distToCollision < this.nearestDistance) {
-                this.nearestDistance = distToCollision;
-                this.intersectionPoint = collisionPoint;
+                if (!this.intersectionPoint) {
+                    this.intersectionPoint = this._collisionPoint.clone();
+                } else {
+                    this.intersectionPoint.copyFrom(this._collisionPoint);
+                }
+                this.nearestDistance = distToCollision;                
                 this.collisionFound = true;
                 this.collisionFound = true;
             }
             }
         }
         }
@@ -282,26 +311,23 @@
             this._testTriangle(subMesh, p3, p2, p1);
             this._testTriangle(subMesh, p3, p2, p1);
         }
         }
     };
     };
-
+    
     BABYLON.Collider.prototype._getResponse = function(pos, vel) {
     BABYLON.Collider.prototype._getResponse = function(pos, vel) {
-        var destinationPoint = pos.add(vel);
-        var V = vel.scale((this.nearestDistance / vel.length()));
-
-        var newPos = this.basePoint.add(V);
-        var slidePlaneNormal = newPos.subtract(this.intersectionPoint);
-        slidePlaneNormal.normalize();
-        var displacementVector = slidePlaneNormal.scale(this.epsilon);
+        pos.addToRef(vel, this._destinationPoint);
+        vel.scaleInPlace((this.nearestDistance / vel.length()));
 
 
-        newPos = newPos.add(displacementVector);
-        this.intersectionPoint = this.intersectionPoint.add(displacementVector);
+        this.basePoint.addToRef(vel, pos);
+        pos.subtractToRef(this.intersectionPoint, this._slidePlaneNormal);
+        this._slidePlaneNormal.normalize();
+        this._slidePlaneNormal.scaleToRef(this.epsilon, this._displacementVector);
 
 
-        var slidePlaneOrigin = this.intersectionPoint;
-        var slidingPlane = new BABYLON.CollisionPlane(slidePlaneOrigin, slidePlaneNormal);
-        var newDestinationPoint = destinationPoint.subtract(slidePlaneNormal.scale(slidingPlane.signedDistanceTo(destinationPoint)));
+        pos.addInPlace(this._displacementVector);
+        this.intersectionPoint.addInPlace(this._displacementVector);
 
 
-        var newVel = newDestinationPoint.subtract(this.intersectionPoint);
+        this._slidePlaneNormal.scaleInPlace(BABYLON.Plane.SignedDistanceToPlaneFromPositionAndNormal(this.intersectionPoint, this._slidePlaneNormal, this._destinationPoint));
+        this._destinationPoint.subtractInPlace(this._slidePlaneNormal);
 
 
-        return { position: newPos, velocity: newVel };
+        this._destinationPoint.subtractToRef(this.intersectionPoint, vel);
     };
     };
 
 
 })();
 })();

+ 18 - 9
Babylon/Culling/babylon.boundingBox.js

@@ -40,17 +40,24 @@
         this.center = this.maximum.add(this.minimum).scale(0.5);
         this.center = this.maximum.add(this.minimum).scale(0.5);
         this.extends = this.maximum.subtract(this.minimum).scale(0.5);
         this.extends = this.maximum.subtract(this.minimum).scale(0.5);
         this.directions = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
         this.directions = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
+        
+        // World
+        this.vectorsWorld = [];
+        for (var index = 0; index < this.vectors.length; index++) {
+            this.vectorsWorld[index] = BABYLON.Vector3.Zero();
+        }
+        this.minimumWorld = BABYLON.Vector3.Zero();
+        this.maximumWorld = BABYLON.Vector3.Zero();
     };
     };
     
     
     // Methods
     // Methods
     BABYLON.BoundingBox.prototype._update = function (world) {
     BABYLON.BoundingBox.prototype._update = function (world) {
-        this.vectorsWorld = [];
-        this.minimumWorld = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
-        this.maximumWorld = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
+        BABYLON.Vector3.FromFloatsToRef(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, this.minimumWorld);
+        BABYLON.Vector3.FromFloatsToRef(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE, this.maximumWorld);
 
 
         for (var index = 0; index < this.vectors.length; index++) {
         for (var index = 0; index < this.vectors.length; index++) {
-            var v = BABYLON.Vector3.TransformCoordinates(this.vectors[index], world);
-            this.vectorsWorld.push(v);
+            var v = this.vectorsWorld[index];
+            BABYLON.Vector3.TransformCoordinatesToRef(this.vectors[index], world, v);
 
 
             if (v.x < this.minimumWorld.x)
             if (v.x < this.minimumWorld.x)
                 this.minimumWorld.x = v.x;
                 this.minimumWorld.x = v.x;
@@ -68,10 +75,12 @@
         }
         }
 
 
         // OBB
         // OBB
-        this.center = this.maximumWorld.add(this.minimumWorld).scale(0.5);
-        this.directions[0] = BABYLON.Vector3.FromArray(world.m, 0);
-        this.directions[1] = BABYLON.Vector3.FromArray(world.m, 4);
-        this.directions[2] = BABYLON.Vector3.FromArray(world.m, 8);
+        this.maximumWorld.addToRef(this.minimumWorld, this.center);
+        this.center.scaleInPlace(0.5);
+        
+        BABYLON.Vector3.FromArrayToRef(world.m, 0, this.directions[0]);
+        BABYLON.Vector3.FromArrayToRef(world.m, 4, this.directions[1]);
+        BABYLON.Vector3.FromArrayToRef(world.m, 8, this.directions[2]);
     };
     };
 
 
     BABYLON.BoundingBox.prototype.isInFrustrum = function (frustumPlanes) {
     BABYLON.BoundingBox.prototype.isInFrustrum = function (frustumPlanes) {

+ 3 - 1
Babylon/Culling/babylon.boundingSphere.js

@@ -16,11 +16,13 @@
         
         
         this.center = BABYLON.Vector3.Lerp(minimum, maximum, 0.5);;
         this.center = BABYLON.Vector3.Lerp(minimum, maximum, 0.5);;
         this.radius = distance * 0.5;
         this.radius = distance * 0.5;
+
+        this.centerWorld = BABYLON.Vector3.Zero();
     };
     };
     
     
     // Methods
     // Methods
     BABYLON.BoundingSphere.prototype._update = function (world, scale) {
     BABYLON.BoundingSphere.prototype._update = function (world, scale) {
-        this.centerWorld = BABYLON.Vector3.TransformCoordinates(this.center, world);
+        BABYLON.Vector3.TransformCoordinatesToRef(this.center, world, this.centerWorld);
         this.radiusWorld = this.radius * scale;
         this.radiusWorld = this.radius * scale;
     };
     };
     
     

+ 14 - 6
Babylon/Lights/Shadows/babylon.shadowGenerator.js

@@ -29,8 +29,10 @@
         var renderSubMesh = function (subMesh, effect) {
         var renderSubMesh = function (subMesh, effect) {
             var mesh = subMesh.getMesh();
             var mesh = subMesh.getMesh();
             var world = mesh.getWorldMatrix();
             var world = mesh.getWorldMatrix();
+
+            world.multiplyToRef(that.getTransformMatrix(), that._worldViewProjection);
             
             
-            effect.setMatrix("worldViewProjection", world.multiply(that.getTransformMatrix()));
+            effect.setMatrix("worldViewProjection", that._worldViewProjection);
             
             
             // Bind and draw
             // Bind and draw
             mesh.bindAndDraw(subMesh, effect, false);
             mesh.bindAndDraw(subMesh, effect, false);
@@ -44,13 +46,19 @@
             engine.enableEffect(effect);
             engine.enableEffect(effect);
             
             
             for (index = 0; index < opaqueSubMeshes.length; index++) {
             for (index = 0; index < opaqueSubMeshes.length; index++) {
-                renderSubMesh(opaqueSubMeshes[index], effect);
+                renderSubMesh(opaqueSubMeshes.data[index], effect);
             }
             }
             
             
             for (index = 0; index < alphaTestSubMeshes.length; index++) {
             for (index = 0; index < alphaTestSubMeshes.length; index++) {
-                renderSubMesh(alphaTestSubMeshes[index], effect);
+                renderSubMesh(alphaTestSubMeshes.data[index], effect);
             }
             }
         };
         };
+        
+        // Internals
+        this._viewMatrix = BABYLON.Matrix.Zero();
+        this._projectionMatrix = BABYLON.Matrix.Zero();
+        this._transformMatrix = BABYLON.Matrix.Zero();
+        this._worldViewProjection = BABYLON.Matrix.Zero();
     };
     };
     
     
     // Members
     // Members
@@ -78,10 +86,10 @@
 
 
             var activeCamera = this._scene.activeCamera;
             var activeCamera = this._scene.activeCamera;
 
 
-            var view = new BABYLON.Matrix.LookAtLH(this._light.position, this._light.position.add(this._light.direction), BABYLON.Vector3.Up());
-            var projection = new BABYLON.Matrix.PerspectiveFovLH(Math.PI / 2.0, 1.0, activeCamera.minZ, activeCamera.maxZ);
+            BABYLON.Matrix.LookAtLHToRef(this._light.position, this._light.position.add(this._light.direction), BABYLON.Vector3.Up(), this._viewMatrix);
+            BABYLON.Matrix.PerspectiveFovLHToRef(Math.PI / 2.0, 1.0, activeCamera.minZ, activeCamera.maxZ, this._projectionMatrix);
 
 
-            this._transformMatrix = view.multiply(projection);
+            this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
         }
         }
 
 
         return this._transformMatrix;
         return this._transformMatrix;

+ 69 - 17
Babylon/Materials/babylon.effect.js

@@ -17,7 +17,14 @@
         if (BABYLON.Effect.ShadersStore[baseName + "VertexShader"]) {
         if (BABYLON.Effect.ShadersStore[baseName + "VertexShader"]) {
             this._prepareEffect(BABYLON.Effect.ShadersStore[baseName + "VertexShader"], BABYLON.Effect.ShadersStore[baseName + "PixelShader"], attributesNames, defines);
             this._prepareEffect(BABYLON.Effect.ShadersStore[baseName + "VertexShader"], BABYLON.Effect.ShadersStore[baseName + "PixelShader"], attributesNames, defines);
         } else {
         } else {
-            var shaderUrl = BABYLON.Engine.ShadersRepository + baseName;
+            var shaderUrl;
+
+            if (baseName[0] === ".") {
+                shaderUrl = baseName;
+            } else {
+                shaderUrl = BABYLON.Engine.ShadersRepository + baseName;
+            }
+
             // Vertex shader
             // Vertex shader
             BABYLON.Tools.LoadFile(shaderUrl + ".vertex.fx",
             BABYLON.Tools.LoadFile(shaderUrl + ".vertex.fx",
                 function (vertexSourceCode) {
                 function (vertexSourceCode) {
@@ -97,11 +104,65 @@
         this._engine.setTexture(this._samplers.indexOf(channel), texture);
         this._engine.setTexture(this._samplers.indexOf(channel), texture);
     };
     };
 
 
+    BABYLON.Effect.prototype._cacheMatrix = function (uniformName, matrix) {
+        if (!this._valueCache[uniformName]) {
+            this._valueCache[uniformName] = new BABYLON.Matrix();
+        }
+        
+        for (var index = 0; index < 16; index++) {
+            this._valueCache[uniformName].m[index] = matrix.m[index];
+        }
+    };
+    
+    BABYLON.Effect.prototype._cacheFloat2 = function (uniformName, x, y) {
+        if (!this._valueCache[uniformName]) {
+            this._valueCache[uniformName] = [x, y];
+            return;
+        }
+
+        this._valueCache[uniformName][0] = x;
+        this._valueCache[uniformName][1] = y;
+    };
+    
+    BABYLON.Effect.prototype._cacheFloat3 = function (uniformName, x, y, z) {
+        if (!this._valueCache[uniformName]) {
+            this._valueCache[uniformName] = [x, y, z];
+            return;
+        }
+
+        this._valueCache[uniformName][0] = x;
+        this._valueCache[uniformName][1] = y;
+        this._valueCache[uniformName][2] = z;
+    };
+    
+    BABYLON.Effect.prototype._cacheFloat4 = function (uniformName, x, y, z, w) {
+        if (!this._valueCache[uniformName]) {
+            this._valueCache[uniformName] = [x, y, z, w];
+            return;
+        }
+
+        this._valueCache[uniformName][0] = x;
+        this._valueCache[uniformName][1] = y;
+        this._valueCache[uniformName][2] = z;
+        this._valueCache[uniformName][3] = w;
+    };
+    
+    BABYLON.Effect.prototype._cacheVector3 = function (uniformName, vector) {
+        if (!this._valueCache[uniformName]) {
+            this._valueCache[uniformName] = [vector.x , vector.y, vector.z];
+            return;
+        }
+
+        this._valueCache[uniformName][0] = vector.x;
+        this._valueCache[uniformName][1] = vector.y;
+        this._valueCache[uniformName][2] = vector.z;
+    };
+
     BABYLON.Effect.prototype.setMatrix = function (uniformName, matrix) {
     BABYLON.Effect.prototype.setMatrix = function (uniformName, matrix) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
         if (this._valueCache[uniformName] && this._valueCache[uniformName].equals(matrix))
             return;
             return;
 
 
-        this._valueCache[uniformName] = matrix;
+        this._cacheMatrix(uniformName, matrix);
         this._engine.setMatrix(this.getUniform(uniformName), matrix);
         this._engine.setMatrix(this.getUniform(uniformName), matrix);
     };
     };
 
 
@@ -114,20 +175,11 @@
         this._engine.setBool(this.getUniform(uniformName), bool);
         this._engine.setBool(this.getUniform(uniformName), bool);
     };
     };
 
 
-    BABYLON.Effect.prototype.setVector2 = function (uniformName, x, y) {
-        if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y)
-            return;
-
-        this._valueCache[uniformName] = [x, y];
-
-        this._engine.setVector2(this.getUniform(uniformName), x, y);
-    };
-
     BABYLON.Effect.prototype.setVector3 = function (uniformName, vector3) {
     BABYLON.Effect.prototype.setVector3 = function (uniformName, vector3) {
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector3.x && this._valueCache[uniformName][1] == vector3.y && this._valueCache[uniformName][2] == vector3.z)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == vector3.x && this._valueCache[uniformName][1] == vector3.y && this._valueCache[uniformName][2] == vector3.z)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [vector3.x, vector3.y, vector3.z];
+        this._cacheVector3(uniformName, vector3);
 
 
         this._engine.setVector3(this.getUniform(uniformName), vector3);
         this._engine.setVector3(this.getUniform(uniformName), vector3);
     };
     };
@@ -136,7 +188,7 @@
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [x, y];
+        this._cacheFloat2(uniformName, x, y);
         this._engine.setFloat2(this.getUniform(uniformName), x, y);
         this._engine.setFloat2(this.getUniform(uniformName), x, y);
     };
     };
 
 
@@ -144,7 +196,7 @@
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [x, y, z];
+        this._cacheFloat3(uniformName, x, y, z);
         this._engine.setFloat3(this.getUniform(uniformName), x, y, z);
         this._engine.setFloat3(this.getUniform(uniformName), x, y, z);
     };
     };
 
 
@@ -152,7 +204,7 @@
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z && this._valueCache[uniformName][3] == w)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == x && this._valueCache[uniformName][1] == y && this._valueCache[uniformName][2] == z && this._valueCache[uniformName][3] == w)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [x, y, z, w];
+        this._cacheFloat4(uniformName, x, y, z, w);
         this._engine.setFloat4(this.getUniform(uniformName), x, y, z, w);
         this._engine.setFloat4(this.getUniform(uniformName), x, y, z, w);
     };
     };
 
 
@@ -160,7 +212,7 @@
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [color3.r, color3.g, color3.b];
+        this._cacheFloat3(uniformName, color3.r, color3.g, color3.b);
         this._engine.setColor3(this.getUniform(uniformName), color3);
         this._engine.setColor3(this.getUniform(uniformName), color3);
     };
     };
 
 
@@ -168,7 +220,7 @@
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b && this._valueCache[uniformName][3] == alpha)
         if (this._valueCache[uniformName] && this._valueCache[uniformName][0] == color3.r && this._valueCache[uniformName][1] == color3.g && this._valueCache[uniformName][2] == color3.b && this._valueCache[uniformName][3] == alpha)
             return;
             return;
 
 
-        this._valueCache[uniformName] = [color3.r, color3.g, color3.b, alpha];
+        this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha);
         this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
         this._engine.setColor4(this.getUniform(uniformName), color3, alpha);
     };
     };
 
 

+ 34 - 17
Babylon/Materials/babylon.standardMaterial.js

@@ -28,6 +28,16 @@
         this.emissiveColor = new BABYLON.Color3(0, 0, 0);
         this.emissiveColor = new BABYLON.Color3(0, 0, 0);
 
 
         this._cachedDefines = null;
         this._cachedDefines = null;
+
+        this._renderTargets = new BABYLON.Tools.SmartArray(16);
+        
+        // Internals
+        this._worldViewProjectionMatrix = BABYLON.Matrix.Zero();
+        this._lightMatrix = BABYLON.Matrix.Zero();
+        this._globalAmbientColor = new BABYLON.Color3(0, 0, 0);
+        this._baseColor = new BABYLON.Color3();
+        this._scaledDiffuse = new BABYLON.Color3();
+        this._scaledSpecular = new BABYLON.Color3();
     };
     };
 
 
     BABYLON.StandardMaterial.prototype = Object.create(BABYLON.Material.prototype);
     BABYLON.StandardMaterial.prototype = Object.create(BABYLON.Material.prototype);
@@ -205,13 +215,13 @@
     };
     };
 
 
     BABYLON.StandardMaterial.prototype.getRenderTargetTextures = function () {
     BABYLON.StandardMaterial.prototype.getRenderTargetTextures = function () {
-        var results = [];
+        this._renderTargets.reset();
 
 
         if (this.reflectionTexture && this.reflectionTexture.isRenderTarget) {
         if (this.reflectionTexture && this.reflectionTexture.isRenderTarget) {
-            results.push(this.reflectionTexture);
+            this._renderTargets.push(this.reflectionTexture);
         }
         }
 
 
-        return results;
+        return this._renderTargets;
     };
     };
 
 
     BABYLON.StandardMaterial.prototype.unbind = function () {
     BABYLON.StandardMaterial.prototype.unbind = function () {
@@ -221,29 +231,29 @@
     };
     };
 
 
     BABYLON.StandardMaterial.prototype.bind = function (world, mesh) {
     BABYLON.StandardMaterial.prototype.bind = function (world, mesh) {
-        var baseColor = this.diffuseColor;
+        this._baseColor.copyFrom(this.diffuseColor);
 
 
         // Values
         // Values
         if (this.diffuseTexture) {
         if (this.diffuseTexture) {
             this._effect.setTexture("diffuseSampler", this.diffuseTexture);
             this._effect.setTexture("diffuseSampler", this.diffuseTexture);
 
 
-            this._effect.setVector2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
+            this._effect.setFloat2("vDiffuseInfos", this.diffuseTexture.coordinatesIndex, this.diffuseTexture.level);
             this._effect.setMatrix("diffuseMatrix", this.diffuseTexture._computeTextureMatrix());
             this._effect.setMatrix("diffuseMatrix", this.diffuseTexture._computeTextureMatrix());
 
 
-            baseColor = new BABYLON.Color3(1, 1, 1);
+            this._baseColor.copyFromFloats(1, 1, 1);
         }
         }
 
 
         if (this.ambientTexture) {
         if (this.ambientTexture) {
             this._effect.setTexture("ambientSampler", this.ambientTexture);
             this._effect.setTexture("ambientSampler", this.ambientTexture);
 
 
-            this._effect.setVector2("vAmbientInfos", this.ambientTexture.coordinatesIndex, this.ambientTexture.level);
+            this._effect.setFloat2("vAmbientInfos", this.ambientTexture.coordinatesIndex, this.ambientTexture.level);
             this._effect.setMatrix("ambientMatrix", this.ambientTexture._computeTextureMatrix());
             this._effect.setMatrix("ambientMatrix", this.ambientTexture._computeTextureMatrix());
         }
         }
 
 
         if (this.opacityTexture) {
         if (this.opacityTexture) {
             this._effect.setTexture("opacitySampler", this.opacityTexture);
             this._effect.setTexture("opacitySampler", this.opacityTexture);
 
 
-            this._effect.setVector2("vOpacityInfos", this.opacityTexture.coordinatesIndex, this.opacityTexture.level);
+            this._effect.setFloat2("vOpacityInfos", this.opacityTexture.coordinatesIndex, this.opacityTexture.level);
             this._effect.setMatrix("opacityMatrix", this.opacityTexture._computeTextureMatrix());
             this._effect.setMatrix("opacityMatrix", this.opacityTexture._computeTextureMatrix());
         }
         }
 
 
@@ -261,29 +271,32 @@
         if (this.emissiveTexture) {
         if (this.emissiveTexture) {
             this._effect.setTexture("emissiveSampler", this.emissiveTexture);
             this._effect.setTexture("emissiveSampler", this.emissiveTexture);
 
 
-            this._effect.setVector2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
+            this._effect.setFloat2("vEmissiveInfos", this.emissiveTexture.coordinatesIndex, this.emissiveTexture.level);
             this._effect.setMatrix("emissiveMatrix", this.emissiveTexture._computeTextureMatrix());
             this._effect.setMatrix("emissiveMatrix", this.emissiveTexture._computeTextureMatrix());
         }
         }
 
 
         if (this.specularTexture) {
         if (this.specularTexture) {
             this._effect.setTexture("specularSampler", this.specularTexture);
             this._effect.setTexture("specularSampler", this.specularTexture);
 
 
-            this._effect.setVector2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
+            this._effect.setFloat2("vSpecularInfos", this.specularTexture.coordinatesIndex, this.specularTexture.level);
             this._effect.setMatrix("specularMatrix", this.specularTexture._computeTextureMatrix());
             this._effect.setMatrix("specularMatrix", this.specularTexture._computeTextureMatrix());
         }
         }
         
         
         if (this.bumpTexture && this._scene.getEngine().getCaps().standardDerivatives) {
         if (this.bumpTexture && this._scene.getEngine().getCaps().standardDerivatives) {
             this._effect.setTexture("bumpSampler", this.bumpTexture);
             this._effect.setTexture("bumpSampler", this.bumpTexture);
 
 
-            this._effect.setVector2("vBumpInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
+            this._effect.setFloat2("vBumpInfos", this.bumpTexture.coordinatesIndex, this.bumpTexture.level);
             this._effect.setMatrix("bumpMatrix", this.bumpTexture._computeTextureMatrix());
             this._effect.setMatrix("bumpMatrix", this.bumpTexture._computeTextureMatrix());
         }
         }
 
 
+        world.multiplyToRef(this._scene.getTransformMatrix(), this._worldViewProjectionMatrix);
+        this._scene.ambientColor.multiplyToRef(this.ambientColor, this._globalAmbientColor);
+
         this._effect.setMatrix("world", world);
         this._effect.setMatrix("world", world);
-        this._effect.setMatrix("worldViewProjection", world.multiply(this._scene.getTransformMatrix()));
+        this._effect.setMatrix("worldViewProjection", this._worldViewProjectionMatrix);
         this._effect.setVector3("vEyePosition", this._scene.activeCamera.position);
         this._effect.setVector3("vEyePosition", this._scene.activeCamera.position);
-        this._effect.setColor3("vAmbientColor", this._scene.ambientColor.multiply(this.ambientColor));
-        this._effect.setColor4("vDiffuseColor", baseColor, this.alpha * mesh.visibility);
+        this._effect.setColor3("vAmbientColor", this._globalAmbientColor);
+        this._effect.setColor4("vDiffuseColor", this._baseColor, this.alpha * mesh.visibility);
         this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
         this._effect.setColor4("vSpecularColor", this.specularColor, this.specularPower);
         this._effect.setColor3("vEmissiveColor", this.emissiveColor);
         this._effect.setColor3("vEmissiveColor", this.emissiveColor);
 
 
@@ -312,13 +325,17 @@
                 this._effect.setFloat4("vLightData" + lightIndex, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0);
                 this._effect.setFloat4("vLightData" + lightIndex, normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0);
                 this._effect.setColor3("vLightGround" + lightIndex, light.groundColor.scale(light.intensity));
                 this._effect.setColor3("vLightGround" + lightIndex, light.groundColor.scale(light.intensity));
             }
             }
-            this._effect.setColor3("vLightDiffuse" + lightIndex, light.diffuse.scale(light.intensity));
-            this._effect.setColor3("vLightSpecular" + lightIndex, light.specular.scale(light.intensity));
+
+            light.diffuse.scaleToRef(light.intensity, this._scaledDiffuse);
+            light.specular.scaleToRef(light.intensity, this._scaledSpecular);
+            this._effect.setColor3("vLightDiffuse" + lightIndex, this._scaledDiffuse);
+            this._effect.setColor3("vLightSpecular" + lightIndex, this._scaledSpecular);
             
             
             // Shadows
             // Shadows
             var shadowGenerator = light.getShadowGenerator();
             var shadowGenerator = light.getShadowGenerator();
             if (mesh.receiveShadows && shadowGenerator && shadowGenerator.isReady()) {
             if (mesh.receiveShadows && shadowGenerator && shadowGenerator.isReady()) {
-                this._effect.setMatrix("lightMatrix" + lightIndex, world.multiply(shadowGenerator.getTransformMatrix()));
+                world.multiplyToRef(shadowGenerator.getTransformMatrix(), this._lightMatrix);
+                this._effect.setMatrix("lightMatrix" + lightIndex, this._lightMatrix);
                 this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMap());
                 this._effect.setTexture("shadowSampler" + lightIndex, shadowGenerator.getShadowMap());
             }
             }
 
 

+ 24 - 5
Babylon/Materials/textures/babylon.dynamicTexture.js

@@ -20,13 +20,32 @@
     };
     };
 
 
     BABYLON.DynamicTexture.prototype = Object.create(BABYLON.Texture.prototype);
     BABYLON.DynamicTexture.prototype = Object.create(BABYLON.Texture.prototype);
-    
+
     // Methods
     // Methods
-    BABYLON.DynamicTexture.prototype.getContext = function() {
+    BABYLON.DynamicTexture.prototype.getContext = function () {
         return this._context;
         return this._context;
     };
     };
-    
-    BABYLON.DynamicTexture.prototype.update = function () {
-        this._scene.getEngine().updateDynamicTexture(this._texture, this._canvas);
+
+    BABYLON.DynamicTexture.prototype.update = function (invertY) {
+        this._scene.getEngine().updateDynamicTexture(this._texture, this._canvas, invertY === undefined ? true : invertY);
+    };
+
+    BABYLON.DynamicTexture.prototype.drawText = function (text, x, y, font, color, clearColor, invertY) {
+        var size = this.getSize();
+        if (clearColor) {
+            this._context.fillStyle = clearColor;
+            this._context.fillRect(0, 0, size.width, size.height);
+        }
+        
+        this._context.font = font;
+        if (x === null) {
+            var textSize = this._context.measureText(text);
+            x = (size.width - textSize.width) / 2;
+        }
+
+        this._context.fillStyle = color;
+        this._context.fillText(text, x, y);
+
+        this.update(invertY);
     };
     };
 })();
 })();

+ 8 - 2
Babylon/Materials/textures/babylon.mirrorTexture.js

@@ -11,6 +11,10 @@
         
         
         // Render list
         // Render list
         this.renderList = [];
         this.renderList = [];
+        
+        // Internals
+        this._transformMatrix = BABYLON.Matrix.Zero();
+        this._mirrorMatrix = BABYLON.Matrix.Zero();
     };
     };
 
 
     BABYLON.MirrorTexture.prototype = Object.create(BABYLON.RenderTargetTexture.prototype);
     BABYLON.MirrorTexture.prototype = Object.create(BABYLON.RenderTargetTexture.prototype);
@@ -22,10 +26,12 @@
     BABYLON.MirrorTexture.prototype.onBeforeRender = function () {
     BABYLON.MirrorTexture.prototype.onBeforeRender = function () {
         var scene = this._scene;
         var scene = this._scene;
 
 
-        var mirrorMatrix = BABYLON.Matrix.Reflection(this.mirrorPlane);
+        BABYLON.Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);
         this._savedViewMatrix = scene.getViewMatrix();
         this._savedViewMatrix = scene.getViewMatrix();
 
 
-        scene.setTransformMatrix(mirrorMatrix.multiply(this._savedViewMatrix), scene.getProjectionMatrix());
+        this._mirrorMatrix.multiplyToRef(this._savedViewMatrix, this._transformMatrix);
+
+        scene.setTransformMatrix(this._transformMatrix, scene.getProjectionMatrix());
 
 
         BABYLON.clipPlane = this.mirrorPlane;
         BABYLON.clipPlane = this.mirrorPlane;
 
 

+ 11 - 4
Babylon/Materials/textures/babylon.renderTargetTexture.js

@@ -10,7 +10,7 @@
         this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
         this._texture = scene.getEngine().createRenderTargetTexture(size, generateMipMaps);
         
         
         // Render list
         // Render list
-        this.renderList = [];
+        this.renderList = [];       
     };
     };
 
 
     BABYLON.RenderTargetTexture.prototype = Object.create(BABYLON.Texture.prototype);
     BABYLON.RenderTargetTexture.prototype = Object.create(BABYLON.Texture.prototype);
@@ -50,6 +50,13 @@
             return;
             return;
         }
         }
         
         
+        if (!this._opaqueSubMeshes) {
+            // Smart arrays
+            this._opaqueSubMeshes = new BABYLON.Tools.SmartArray(256);
+            this._transparentSubMeshes = new BABYLON.Tools.SmartArray(256);
+            this._alphaTestSubMeshes = new BABYLON.Tools.SmartArray(256);
+        }
+        
         // Bind
         // Bind
         engine.bindFramebuffer(this._texture);
         engine.bindFramebuffer(this._texture);
 
 
@@ -57,9 +64,9 @@
         engine.clear(scene.clearColor, true, true);
         engine.clear(scene.clearColor, true, true);
         
         
         // Dispatch subMeshes
         // Dispatch subMeshes
-        this._opaqueSubMeshes = [];
-        this._transparentSubMeshes = [];
-        this._alphaTestSubMeshes = [];
+        this._opaqueSubMeshes.reset();
+        this._transparentSubMeshes.reset();
+        this._alphaTestSubMeshes.reset();
         
         
         for (var meshIndex = 0; meshIndex < this.renderList.length; meshIndex++) {
         for (var meshIndex = 0; meshIndex < this.renderList.length; meshIndex++) {
             var mesh = this.renderList[meshIndex];
             var mesh = this.renderList[meshIndex];

+ 57 - 48
Babylon/Materials/textures/babylon.texture.js

@@ -14,7 +14,7 @@
         }
         }
 
 
         // Animations
         // Animations
-        this.animations = [];
+        this.animations = [];        
     };
     };
 
 
     BABYLON.Texture.prototype = Object.create(BABYLON.BaseTexture.prototype);
     BABYLON.Texture.prototype = Object.create(BABYLON.BaseTexture.prototype);
@@ -26,7 +26,7 @@
     BABYLON.Texture.CUBIC_MODE = 3;
     BABYLON.Texture.CUBIC_MODE = 3;
     BABYLON.Texture.PROJECTION_MODE = 4;
     BABYLON.Texture.PROJECTION_MODE = 4;
     BABYLON.Texture.SKYBOX_MODE = 5;
     BABYLON.Texture.SKYBOX_MODE = 5;
-    
+
     BABYLON.Texture.CLAMP_ADDRESSMODE = 0;
     BABYLON.Texture.CLAMP_ADDRESSMODE = 0;
     BABYLON.Texture.WRAP_ADDRESSMODE = 1;
     BABYLON.Texture.WRAP_ADDRESSMODE = 1;
     BABYLON.Texture.MIRROR_ADDRESSMODE = 2;
     BABYLON.Texture.MIRROR_ADDRESSMODE = 2;
@@ -45,14 +45,12 @@
     BABYLON.Texture.prototype.coordinatesMode = BABYLON.Texture.EXPLICIT_MODE;
     BABYLON.Texture.prototype.coordinatesMode = BABYLON.Texture.EXPLICIT_MODE;
 
 
     // Methods    
     // Methods    
-    BABYLON.Texture.prototype._prepareRowForTextureGeneration = function (t) {
-        var matRot = BABYLON.Matrix.RotationYawPitchRoll(this.vAng, this.uAng, this.wAng);
-
-        t.x -= this.uOffset + 0.5;
-        t.y -= this.vOffset + 0.5;
-        t.z -= 0.5;
+    BABYLON.Texture.prototype._prepareRowForTextureGeneration = function (x, y, z, t) {
+        x -= this.uOffset + 0.5;
+        y -= this.vOffset + 0.5;
+        z -= 0.5;
 
 
-        t = BABYLON.Vector3.TransformCoordinates(t, matRot);
+        BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix, t);
 
 
         t.x *= this.uScale;
         t.x *= this.uScale;
         t.y *= this.vScale;
         t.y *= this.vScale;
@@ -60,8 +58,6 @@
         t.x += 0.5;
         t.x += 0.5;
         t.y += 0.5;
         t.y += 0.5;
         t.z += 0.5;
         t.z += 0.5;
-
-        return t;
     };
     };
 
 
     BABYLON.Texture.prototype._computeTextureMatrix = function () {
     BABYLON.Texture.prototype._computeTextureMatrix = function () {
@@ -73,7 +69,7 @@
             this.uAng === this._cachedUAng &&
             this.uAng === this._cachedUAng &&
             this.vAng === this._cachedVAng &&
             this.vAng === this._cachedVAng &&
             this.wAng === this._cachedWAng) {
             this.wAng === this._cachedWAng) {
-                return this._cachedTextureMatrix;
+            return this._cachedTextureMatrix;
         }
         }
 
 
         this._cachedUOffset = this.uOffset;
         this._cachedUOffset = this.uOffset;
@@ -84,25 +80,29 @@
         this._cachedVAng = this.vAng;
         this._cachedVAng = this.vAng;
         this._cachedWAng = this.wAng;
         this._cachedWAng = this.wAng;
 
 
-        var t0 = new BABYLON.Vector3(0, 0, 0);
-        var t1 = new BABYLON.Vector3(1.0, 0, 0);
-        var t2 = new BABYLON.Vector3(0, 1.0, 0);
-
-        var matTemp = BABYLON.Matrix.Identity();
+        if (!this._cachedTextureMatrix) {
+            this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+            this._rowGenerationMatrix = new BABYLON.Matrix();
+            this._t0 = BABYLON.Vector3.Zero();
+            this._t1 = BABYLON.Vector3.Zero();
+            this._t2 = BABYLON.Vector3.Zero();
+        }
+        
+        BABYLON.Matrix.RotationYawPitchRollToRef(this.vAng, this.uAng, this.wAng, this._rowGenerationMatrix);
 
 
-        t0 = this._prepareRowForTextureGeneration(t0);
-        t1 = this._prepareRowForTextureGeneration(t1);
-        t2 = this._prepareRowForTextureGeneration(t2);
+        this._prepareRowForTextureGeneration(0, 0, 0, this._t0);
+        this._prepareRowForTextureGeneration(1.0, 0, 0, this._t1);
+        this._prepareRowForTextureGeneration(0, 1.0, 0, this._t2);
 
 
-        t1 = t1.subtract(t0);
-        t2 = t2.subtract(t0);
+        this._t1.subtractInPlace(this._t0);
+        this._t2.subtractInPlace(this._t0);
 
 
-        matTemp.m[0] = t1.x; matTemp.m[1] = t1.y; matTemp.m[2] = t1.z;
-        matTemp.m[4] = t2.x; matTemp.m[5] = t2.y; matTemp.m[6] = t2.z;
-        matTemp.m[8] = t0.x; matTemp.m[9] = t0.y; matTemp.m[10] = t0.z;
+        BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+        this._cachedTextureMatrix.m[0] = this._t1.x; this._cachedTextureMatrix.m[1] = this._t1.y; this._cachedTextureMatrix.m[2] = this._t1.z;
+        this._cachedTextureMatrix.m[4] = this._t2.x; this._cachedTextureMatrix.m[5] = this._t2.y; this._cachedTextureMatrix.m[6] = this._t2.z;
+        this._cachedTextureMatrix.m[8] = this._t0.x; this._cachedTextureMatrix.m[9] = this._t0.y; this._cachedTextureMatrix.m[10] = this._t0.z;
 
 
-        this._cachedTextureMatrix = matTemp;
-        return matTemp;
+        return this._cachedTextureMatrix;
     };
     };
 
 
     BABYLON.Texture.prototype._computeReflectionTextureMatrix = function () {
     BABYLON.Texture.prototype._computeReflectionTextureMatrix = function () {
@@ -112,37 +112,46 @@
             this.uScale === this._cachedUScale &&
             this.uScale === this._cachedUScale &&
             this.vScale === this._cachedVScale &&
             this.vScale === this._cachedVScale &&
             this.coordinatesMode === this._cachedCoordinatesMode) {
             this.coordinatesMode === this._cachedCoordinatesMode) {
-                return this._cachedTextureMatrix;
+            return this._cachedTextureMatrix;
         }
         }
 
 
-        var matrix = BABYLON.Matrix.Identity();
+        if (!this._cachedTextureMatrix) {
+            this._cachedTextureMatrix = BABYLON.Matrix.Zero();
+            this._projectionModeMatrix = BABYLON.Matrix.Zero();
+        }
 
 
         switch (this.coordinatesMode) {
         switch (this.coordinatesMode) {
             case BABYLON.Texture.SPHERICAL_MODE:
             case BABYLON.Texture.SPHERICAL_MODE:
-                matrix.m[0] = -0.5 * this.uScale;
-                matrix.m[5] = -0.5 * this.vScale;
-                matrix.m[12] = 0.5 + this.uOffset;
-                matrix.m[13] = 0.5 + this.vOffset;
+                BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                this._cachedTextureMatrix[0] = -0.5 * this.uScale;
+                this._cachedTextureMatrix[5] = -0.5 * this.vScale;
+                this._cachedTextureMatrix[12] = 0.5 + this.uOffset;
+                this._cachedTextureMatrix[13] = 0.5 + this.vOffset;
                 break;
                 break;
             case BABYLON.Texture.PLANAR_MODE:
             case BABYLON.Texture.PLANAR_MODE:
-                matrix.m[0] = this.uScale;
-                matrix.m[5] = this.vScale;
-                matrix.m[12] = this.uOffset;
-                matrix.m[13] = this.vOffset;
+                BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
+                this._cachedTextureMatrix[0] = this.uScale;
+                this._cachedTextureMatrix[5] = this.vScale;
+                this._cachedTextureMatrix[12] = this.uOffset;
+                this._cachedTextureMatrix[13] = this.vOffset;
                 break;
                 break;
             case BABYLON.Texture.PROJECTION_MODE:
             case BABYLON.Texture.PROJECTION_MODE:
-                matrix.m[0] = 0.5;
-                matrix.m[5] = -0.5;
-                matrix.m[10] = 0.0;
-                matrix.m[12] = 0.5;
-                matrix.m[13] = 0.5;
-                matrix.m[14] = 1.0;
-                matrix.m[15] = 1.0;
-
-                matrix = this._scene.getProjectionMatrix().multiply(matrix);
+                BABYLON.Matrix.IdentityToRef(this._projectionModeMatrix);
+
+                this._projectionModeMatrix.m[0] = 0.5;
+                this._projectionModeMatrix.m[5] = -0.5;
+                this._projectionModeMatrix.m[10] = 0.0;
+                this._projectionModeMatrix.m[12] = 0.5;
+                this._projectionModeMatrix.m[13] = 0.5;
+                this._projectionModeMatrix.m[14] = 1.0;
+                this._projectionModeMatrix.m[15] = 1.0;
+
+                this._scene.getProjectionMatrix().multiplyToRef(this._projectionModeMatrix, this._cachedTextureMatrix);
+                break;
+            default:
+                BABYLON.Matrix.IdentityToRef(this._cachedTextureMatrix);
                 break;
                 break;
         }
         }
-        this._cachedTextureMatrix = matrix;
-        return matrix;
+        return this._cachedTextureMatrix;
     };
     };
 })();
 })();

+ 42 - 29
Babylon/Mesh/babylon.mesh.js

@@ -33,12 +33,22 @@
         // Cache
         // Cache
         this._positions = null;
         this._positions = null;
         this._cache = {
         this._cache = {
-            position: null,
-            scaling: null,
-            rotation: null
+            position: BABYLON.Vector3.Zero(),
+            scaling: BABYLON.Vector3.Zero(),
+            rotation: BABYLON.Vector3.Zero()
         };
         };
 
 
         this._childrenFlag = false;
         this._childrenFlag = false;
+        this._localScaling = BABYLON.Matrix.Zero();
+        this._localRotation = BABYLON.Matrix.Zero();
+        this._localTranslation = BABYLON.Matrix.Zero();
+        this._localBillboard = BABYLON.Matrix.Zero();
+        this._localScalingRotation = BABYLON.Matrix.Zero();
+        this._localWorld = BABYLON.Matrix.Zero();
+        this._worldMatrix = BABYLON.Matrix.Zero();
+        
+        this._collisionsTransformMatrix = BABYLON.Matrix.Zero();
+        this._collisionsScalingMatrix = BABYLON.Matrix.Zero();
     };
     };
 
 
     // Constants
     // Constants
@@ -159,22 +169,24 @@
         }
         }
 
 
         this._childrenFlag = true;
         this._childrenFlag = true;
-        this._cache.position = this.position.clone();
-        this._cache.rotation = this.rotation.clone();
-        this._cache.scaling = this.scaling.clone();
+        this._cache.position.copyFrom(this.position);
+        this._cache.rotation.copyFrom(this.rotation);
+        this._cache.scaling.copyFrom(this.scaling);
+
+        BABYLON.Matrix.ScalingToRef(this.scaling.x, this.scaling.y, this.scaling.z, this._localScaling);
+        BABYLON.Matrix.RotationYawPitchRollToRef(this.rotation.y, this.rotation.x, this.rotation.z, this._localRotation);
 
 
-        var localWorld = BABYLON.Matrix.Scaling(this.scaling.x, this.scaling.y, this.scaling.z).multiply(
-            BABYLON.Matrix.RotationYawPitchRoll(this.rotation.y, this.rotation.x, this.rotation.z));
+        this._localScaling.multiplyToRef(this._localRotation, this._localScalingRotation);
 
 
         // Billboarding
         // Billboarding
-        var matTranslation = BABYLON.Matrix.Translation(this.position.x, this.position.y, this.position.z);
+        BABYLON.Matrix.TranslationToRef(this.position.x, this.position.y, this.position.z, this._localTranslation);
         if (this.billboardMode !== BABYLON.Mesh.BILLBOARDMODE_NONE) {
         if (this.billboardMode !== BABYLON.Mesh.BILLBOARDMODE_NONE) {
             var localPosition = this.position.clone();
             var localPosition = this.position.clone();
             var zero = this._scene.activeCamera.position.clone();
             var zero = this._scene.activeCamera.position.clone();
 
 
             if (this.parent) {
             if (this.parent) {
-                localPosition = localPosition.add(this.parent.position);
-                matTranslation = BABYLON.Matrix.Translation(localPosition.x, localPosition.y, localPosition.z);
+                localPosition.addInPlace(this.parent.position);
+                BABYLON.Matrix.TranslationToRef(localPosition.x, localPosition.y, localPosition.z, this._localTranslation);
             }
             }
 
 
             if (this.billboardMode & BABYLON.Mesh.BILLBOARDMODE_ALL === BABYLON.Mesh.BILLBOARDMODE_ALL) {
             if (this.billboardMode & BABYLON.Mesh.BILLBOARDMODE_ALL === BABYLON.Mesh.BILLBOARDMODE_ALL) {
@@ -188,25 +200,25 @@
                     zero.z = localPosition.z + BABYLON.Engine.epsilon;
                     zero.z = localPosition.z + BABYLON.Engine.epsilon;
             }
             }
 
 
-            var matBillboard = BABYLON.Matrix.LookAtLH(localPosition, zero, BABYLON.Vector3.Up());
-            matBillboard.m[12] = matBillboard.m[13] = matBillboard.m[14] = 0;
+            BABYLON.Matrix.LookAtLHToRef(localPosition, zero, BABYLON.Vector3.Up(), this._localBillboard);
+            this._localBillboard.m[12] = this._localBillboard.m[13] = this._localBillboard.m[14] = 0;
 
 
-            matBillboard.invert();
+            this._localBillboard.invert();
 
 
-            localWorld = BABYLON.Matrix.RotationY(Math.PI).multiply(localWorld.multiply(matBillboard));
+            this._localScalingRotation.multiplyToRef(this._localBillboard, this._localWorld);
+            BABYLON.Matrix.RotationY(Math.PI).multiplyToRef(this._localWorld, this._localScalingRotation);
         }
         }
 
 
-        localWorld = localWorld.multiply(matTranslation);
-
         // Parent
         // Parent
         if (this.parent && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {
         if (this.parent && this.billboardMode === BABYLON.Mesh.BILLBOARDMODE_NONE) {
+            this._localScalingRotation.multiplyToRef(this._localTranslation, this._localWorld);
             var parentWorld = this.parent.getWorldMatrix();
             var parentWorld = this.parent.getWorldMatrix();
 
 
-            localWorld = localWorld.multiply(parentWorld);
+            this._localWorld.multiplyToRef(parentWorld, this._worldMatrix);
+        } else {
+            this._localScalingRotation.multiplyToRef(this._localTranslation, this._worldMatrix);
         }
         }
 
 
-        this._worldMatrix = localWorld;
-
         // Bounding info
         // Bounding info
         if (this._boundingInfo) {
         if (this._boundingInfo) {
             this._scaleFactor = Math.max(this.scaling.x, this.scaling.y);
             this._scaleFactor = Math.max(this.scaling.x, this.scaling.y);
@@ -215,16 +227,16 @@
             if (this.parent)
             if (this.parent)
                 this._scaleFactor = this._scaleFactor * this.parent._scaleFactor;
                 this._scaleFactor = this._scaleFactor * this.parent._scaleFactor;
 
 
-            this._boundingInfo._update(localWorld, this._scaleFactor);
+            this._boundingInfo._update(this._worldMatrix, this._scaleFactor);
 
 
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
             for (var subIndex = 0; subIndex < this.subMeshes.length; subIndex++) {
                 var subMesh = this.subMeshes[subIndex];
                 var subMesh = this.subMeshes[subIndex];
 
 
-                subMesh.updateBoundingInfo(localWorld, this._scaleFactor);
+                subMesh.updateBoundingInfo(this._worldMatrix, this._scaleFactor);
             }
             }
         }
         }
 
 
-        return localWorld;
+        return this._worldMatrix;
     };
     };
 
 
     BABYLON.Mesh.prototype._createGlobalSubMesh = function () {
     BABYLON.Mesh.prototype._createGlobalSubMesh = function () {
@@ -484,9 +496,10 @@
             return;
             return;
 
 
         // Transformation matrix
         // Transformation matrix
-        var transformMatrix = this._worldMatrix.multiply(BABYLON.Matrix.Scaling(1.0 / collider.radius.x, 1.0 / collider.radius.y, 1.0 / collider.radius.z));
+        BABYLON.Matrix.ScalingToRef(1.0 / collider.radius.x, 1.0 / collider.radius.y, 1.0 / collider.radius.z, this._collisionsScalingMatrix);
+        this._worldMatrix.multiplyToRef(this._collisionsScalingMatrix, this._collisionsTransformMatrix);
 
 
-        this._processCollisionsForSubModels(collider, transformMatrix);
+        this._processCollisionsForSubModels(collider, this._collisionsTransformMatrix);
     };
     };
 
 
     BABYLON.Mesh.prototype.intersectsMesh = function (mesh, precise) {
     BABYLON.Mesh.prototype.intersectsMesh = function (mesh, precise) {
@@ -936,7 +949,7 @@
 
 
                 vertices.push(position.x, position.y, position.z,
                 vertices.push(position.x, position.y, position.z,
                     normal.x, normal.y, normal.z,
                     normal.x, normal.y, normal.z,
-                    col / subdivisions, row / subdivisions);
+                    col / subdivisions, 1.0 - row / subdivisions);
             }
             }
         }
         }
 
 
@@ -986,7 +999,7 @@
 
 
                     // Compute height
                     // Compute height
                     var heightMapX = (((position.x + width / 2) / width) * (heightMapWidth - 1)) | 0;
                     var heightMapX = (((position.x + width / 2) / width) * (heightMapWidth - 1)) | 0;
-                    var heightMapY = (((position.z + height / 2) / height) * (heightMapHeight - 1)) | 0;
+                    var heightMapY = ((1.0 - (position.z + height / 2) / height) * (heightMapHeight - 1)) | 0;
 
 
                     var pos = (heightMapX + heightMapY * heightMapWidth) * 4;
                     var pos = (heightMapX + heightMapY * heightMapWidth) * 4;
                     var r = buffer[pos] / 255.0;
                     var r = buffer[pos] / 255.0;
@@ -1000,7 +1013,7 @@
                     // Add  vertex
                     // Add  vertex
                     vertices.push(position.x, position.y, position.z,
                     vertices.push(position.x, position.y, position.z,
                         0, 0, 0,
                         0, 0, 0,
-                        col / subdivisions, row / subdivisions);
+                        col / subdivisions, 1.0 - row / subdivisions);
                 }
                 }
             }
             }
 
 
@@ -1074,7 +1087,7 @@
 
 
             var normal = BABYLON.Vector3.Zero();
             var normal = BABYLON.Vector3.Zero();
             for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
             for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
-                normal = normal.add(facesNormals[faces[faceIndex]]);
+                normal.addInPlace(facesNormals[faces[faceIndex]]);
             }
             }
 
 
             normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));
             normal = BABYLON.Vector3.Normalize(normal.scale(1.0 / faces.length));

+ 6 - 6
Babylon/Particles/babylon.particle.js

@@ -2,15 +2,15 @@
 
 
 (function () {
 (function () {
     BABYLON.Particle = function () {
     BABYLON.Particle = function () {
-    };
-    
-    BABYLON.Particle.prototype.position = null;
-    BABYLON.Particle.prototype.direction = null;
+        this.position = BABYLON.Vector3.Zero();
+        this.direction = BABYLON.Vector3.Zero();
+        this.color = new BABYLON.Color4(0, 0, 0, 0);
+        this.colorStep = new BABYLON.Color4(0, 0, 0, 0);
+    };    
+
     BABYLON.Particle.prototype.lifeTime = 1.0;
     BABYLON.Particle.prototype.lifeTime = 1.0;
     BABYLON.Particle.prototype.age = 0;
     BABYLON.Particle.prototype.age = 0;
     BABYLON.Particle.prototype.size = 0;
     BABYLON.Particle.prototype.size = 0;
     BABYLON.Particle.prototype.angle = 0;
     BABYLON.Particle.prototype.angle = 0;
     BABYLON.Particle.prototype.angularSpeed = 0;
     BABYLON.Particle.prototype.angularSpeed = 0;
-    BABYLON.Particle.prototype.color = null;
-    BABYLON.Particle.prototype.colorStep = null;
 })();
 })();

+ 50 - 33
Babylon/Particles/babylon.particleSystem.js

@@ -1,20 +1,6 @@
 var BABYLON = BABYLON || {};
 var BABYLON = BABYLON || {};
 
 
 (function () {
 (function () {
-    var appendParticleVertex = function (particle, vertices, offsetX, offsetY) {
-        vertices.push(particle.position.x);
-        vertices.push(particle.position.y);
-        vertices.push(particle.position.z);
-        vertices.push(particle.color.r);
-        vertices.push(particle.color.g);
-        vertices.push(particle.color.b);
-        vertices.push(particle.color.a);
-        vertices.push(particle.angle);
-        vertices.push(particle.size);
-        vertices.push(offsetX);
-        vertices.push(offsetY);
-    };
-
     var randomNumber = function (min, max) {
     var randomNumber = function (min, max) {
         if (min == max) {
         if (min == max) {
             return (min);
             return (min);
@@ -47,6 +33,7 @@
 
 
         // Particles
         // Particles
         this.particles = [];
         this.particles = [];
+        this._stockParticles = [];
         this._newPartsExcess = 0;
         this._newPartsExcess = 0;
 
 
         // VBO
         // VBO
@@ -67,6 +54,14 @@
         }
         }
 
 
         this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
         this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+
+        this._vertices = new Float32Array(capacity * this._vertexStrideSize);
+        
+        // Internals
+        this._scaledColorStep = new BABYLON.Color4(0, 0, 0, 0);
+        this._colorDiff = new BABYLON.Color4(0, 0, 0, 0);
+        this._scaledDirection = BABYLON.Vector3.Zero();
+        this._scaledGravity = BABYLON.Vector3.Zero();
     };
     };
 
 
     // Members
     // Members
@@ -108,7 +103,22 @@
     BABYLON.ParticleSystem.prototype.stop = function () {
     BABYLON.ParticleSystem.prototype.stop = function () {
         this._stopped = true;
         this._stopped = true;
     };
     };
-
+    
+    BABYLON.ParticleSystem.prototype._appendParticleVertex = function (index, particle, offsetX, offsetY) {
+        var offset = index * 11;
+        this._vertices[offset] = particle.position.x;
+        this._vertices[offset + 1] = particle.position.y;
+        this._vertices[offset + 2] = particle.position.z;
+        this._vertices[offset + 3] = particle.color.r;
+        this._vertices[offset + 4] = particle.color.g;
+        this._vertices[offset + 5] = particle.color.b;
+        this._vertices[offset + 6] = particle.color.a;
+        this._vertices[offset + 7] = particle.angle;
+        this._vertices[offset + 8] = particle.size;
+        this._vertices[offset + 9] = offsetX;
+        this._vertices[offset + 10] = offsetY;
+    };
+    
     BABYLON.ParticleSystem.prototype._update = function (newParticles) {
     BABYLON.ParticleSystem.prototype._update = function (newParticles) {
         // Update current
         // Update current
         this._alive = this.particles.length > 0;
         this._alive = this.particles.length > 0;
@@ -117,21 +127,24 @@
             particle.age += this._scaledUpdateSpeed;
             particle.age += this._scaledUpdateSpeed;
 
 
             if (particle.age >= particle.lifeTime) {
             if (particle.age >= particle.lifeTime) {
-                this.particles.splice(index, 1);
+                this._stockParticles.push(this.particles.splice(index, 1)[0]);
                 index--;
                 index--;
                 continue;
                 continue;
             }
             }
             else {
             else {
-                particle.color = particle.color.add(particle.colorStep.scale(this._scaledUpdateSpeed));
+                particle.colorStep.scaleToRef(this._scaledUpdateSpeed, this._scaledColorStep);
+                particle.color.addInPlace(this._scaledColorStep);
 
 
                 if (particle.color.a < 0)
                 if (particle.color.a < 0)
                     particle.color.a = 0;
                     particle.color.a = 0;
 
 
-                particle.position = particle.position.add(particle.direction.scale(this._scaledUpdateSpeed));
+                particle.direction.scaleToRef(this._scaledUpdateSpeed, this._scaledDirection);
+                particle.position.addInPlace(this._scaledDirection);
 
 
                 particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
                 particle.angle += particle.angularSpeed * this._scaledUpdateSpeed;
 
 
-                particle.direction = particle.direction.add(this.gravity.scale(this._scaledUpdateSpeed));
+                this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
+                particle.direction.addInPlace(this._scaledGravity);
             }
             }
         }
         }
         
         
@@ -149,7 +162,12 @@
                 break;
                 break;
             }
             }
 
 
-            var particle = new BABYLON.Particle();
+            if (this._stockParticles.length !== 0) {
+                particle = this._stockParticles.pop();
+                particle.age = 0;
+            } else {
+                particle = new BABYLON.Particle();
+            }
             this.particles.push(particle);
             this.particles.push(particle);
 
 
             var emitPower = randomNumber(this.minEmitPower, this.maxEmitPower);
             var emitPower = randomNumber(this.minEmitPower, this.maxEmitPower);
@@ -158,7 +176,7 @@
             var randY = randomNumber(this.direction1.y, this.direction2.y);
             var randY = randomNumber(this.direction1.y, this.direction2.y);
             var randZ = randomNumber(this.direction1.z, this.direction2.z);
             var randZ = randomNumber(this.direction1.z, this.direction2.z);
 
 
-            particle.direction = BABYLON.Vector3.TransformNormal(new BABYLON.Vector3(randX, randY, randZ).scale(emitPower), worldMatrix);
+            BABYLON.Vector3.TransformNormalFromFloatsToRef(randX * emitPower, randY * emitPower, randZ * emitPower, worldMatrix, particle.direction);
 
 
             particle.lifeTime = randomNumber(this.minLifeTime, this.maxLifeTime);
             particle.lifeTime = randomNumber(this.minLifeTime, this.maxLifeTime);
 
 
@@ -168,17 +186,15 @@
             randX = randomNumber(this.minEmitBox.x, this.maxEmitBox.x);
             randX = randomNumber(this.minEmitBox.x, this.maxEmitBox.x);
             randY = randomNumber(this.minEmitBox.y, this.maxEmitBox.y);
             randY = randomNumber(this.minEmitBox.y, this.maxEmitBox.y);
             randZ = randomNumber(this.minEmitBox.z, this.maxEmitBox.z);
             randZ = randomNumber(this.minEmitBox.z, this.maxEmitBox.z);
-            var dispatch = new BABYLON.Vector3(randX, randY, randZ);
 
 
-            particle.position = BABYLON.Vector3.TransformCoordinates(dispatch, worldMatrix);
+            BABYLON.Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, particle.position);
 
 
             var step = randomNumber(0, 1.0);
             var step = randomNumber(0, 1.0);
 
 
-            var startColor = BABYLON.Color4.Lerp(this.color1, this.color2, step);
+            BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
 
 
-            particle.color = startColor;
-            var diff = this.colorDead.subtract(startColor);
-            particle.colorStep = diff.scale(1.0 / particle.lifeTime);
+            this.colorDead.subtractToRef(particle.color, this._colorDiff);
+            this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
         }
         }
     };
     };
 
 
@@ -256,17 +272,18 @@
         }
         }
 
 
         // Update VBO
         // Update VBO
-        var vertices = [];
+        var offset = 0;
+        this._vertices.length = this.particles.length * this._vertexStrideSize;
         for (var index = 0; index < this.particles.length; index++) {
         for (var index = 0; index < this.particles.length; index++) {
             var particle = this.particles[index];
             var particle = this.particles[index];
 
 
-            appendParticleVertex(particle, vertices, 0, 0);
-            appendParticleVertex(particle, vertices, 1, 0);
-            appendParticleVertex(particle, vertices, 1, 1);
-            appendParticleVertex(particle, vertices, 0, 1);
+            this._appendParticleVertex(offset++, particle, 0, 0);
+            this._appendParticleVertex(offset++, particle, 1, 0);
+            this._appendParticleVertex(offset++, particle, 1, 1);
+            this._appendParticleVertex(offset++, particle, 0, 1);
         }
         }
         var engine = this._scene.getEngine();
         var engine = this._scene.getEngine();
-        engine.updateDynamicVertexBuffer(this._vertexBuffer, vertices);
+        engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices);
     };
     };
 
 
     BABYLON.ParticleSystem.prototype.render = function () {
     BABYLON.ParticleSystem.prototype.render = function () {

+ 43 - 38
Babylon/Sprites/babylon.spriteManager.js

@@ -1,36 +1,6 @@
 var BABYLON = BABYLON || {};
 var BABYLON = BABYLON || {};
 
 
-(function () {
-    var appendSpriteVertex = function (sprite, vertices, offsetX, offsetY, rowSize, epsilon) {
-        if (offsetX == 0)
-            offsetX = epsilon;
-        else if (offsetX == 1)
-            offsetX = 1 - epsilon;
-        
-        if (offsetY == 0)
-            offsetY = epsilon;
-        else if (offsetY == 1)
-            offsetY = 1 - epsilon;
-
-        vertices.push(sprite.position.x);
-        vertices.push(sprite.position.y);
-        vertices.push(sprite.position.z);
-        vertices.push(sprite.angle);
-        vertices.push(sprite.size);
-        vertices.push(offsetX);
-        vertices.push(offsetY);
-        vertices.push(sprite.invertU ? 1 : 0);
-        vertices.push(sprite.invertV ? 1 : 0);
-        var offset = (sprite.cellIndex / rowSize) >> 0;
-        vertices.push(sprite.cellIndex - offset * rowSize);
-        vertices.push(offset);
-        // Color
-        vertices.push(sprite.color.r);
-        vertices.push(sprite.color.g);
-        vertices.push(sprite.color.b);
-        vertices.push(sprite.color.a);
-    };
-
+(function () {   
     BABYLON.SpriteManager = function (name, imgUrl, capacity, cellSize, scene, epsilon) {
     BABYLON.SpriteManager = function (name, imgUrl, capacity, cellSize, scene, epsilon) {
         this.name = name;
         this.name = name;
         this._capacity = capacity;
         this._capacity = capacity;
@@ -61,6 +31,7 @@
         }
         }
 
 
         this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
         this._indexBuffer = scene.getEngine().createIndexBuffer(indices);
+        this._vertices = new Float32Array(capacity * this._vertexStrideSize);
         
         
         // Sprites
         // Sprites
         this.sprites = [];
         this.sprites = [];
@@ -81,6 +52,38 @@
     BABYLON.SpriteManager.prototype.onDispose = null;
     BABYLON.SpriteManager.prototype.onDispose = null;
 
 
     // Methods
     // Methods
+    BABYLON.SpriteManager.prototype._appendSpriteVertex = function (index, sprite, offsetX, offsetY, rowSize) {
+        var arrayOffset = index * 15;
+
+        if (offsetX == 0)
+            offsetX = this._epsilon;
+        else if (offsetX == 1)
+            offsetX = 1 - this._epsilon;
+
+        if (offsetY == 0)
+            offsetY = this._epsilon;
+        else if (offsetY == 1)
+            offsetY = 1 - this._epsilon;
+
+        this._vertices[arrayOffset] = sprite.position.x;
+        this._vertices[arrayOffset + 1] = sprite.position.y;
+        this._vertices[arrayOffset + 2] = sprite.position.z;
+        this._vertices[arrayOffset + 3] = sprite.angle;
+        this._vertices[arrayOffset + 4] = sprite.size;
+        this._vertices[arrayOffset + 5] = offsetX;
+        this._vertices[arrayOffset + 6] = offsetY;
+        this._vertices[arrayOffset + 7] = sprite.invertU ? 1 : 0;
+        this._vertices[arrayOffset + 8] = sprite.invertV ? 1 : 0;
+        var offset = (sprite.cellIndex / rowSize) >> 0;
+        this._vertices[arrayOffset + 9] = sprite.cellIndex - offset * rowSize;
+        this._vertices[arrayOffset + 10] = offset;
+        // Color
+        this._vertices[arrayOffset + 11] = sprite.color.r;
+        this._vertices[arrayOffset + 12] = sprite.color.g;
+        this._vertices[arrayOffset + 13] = sprite.color.b;
+        this._vertices[arrayOffset + 14] = sprite.color.a;
+    };
+
     BABYLON.SpriteManager.prototype.render = function() {
     BABYLON.SpriteManager.prototype.render = function() {
         // Check
         // Check
         if (!this._effectBase.isReady() || !this._effectFog.isReady() || !this._spriteTexture || !this._spriteTexture.isReady())
         if (!this._effectBase.isReady() || !this._effectFog.isReady() || !this._spriteTexture || !this._spriteTexture.isReady())
@@ -91,20 +94,22 @@
 
 
         // Sprites
         // Sprites
         var deltaTime = BABYLON.Tools.GetDeltaTime();
         var deltaTime = BABYLON.Tools.GetDeltaTime();
-        var vertices = [];
         var max = Math.min(this._capacity, this.sprites.length);
         var max = Math.min(this._capacity, this.sprites.length);
         var rowSize = baseSize.width / this.cellSize;
         var rowSize = baseSize.width / this.cellSize;
+
+        var offset = 0;
+        this._vertices.length = max * this._vertexStrideSize;
         for (var index = 0; index < max; index++) {
         for (var index = 0; index < max; index++) {
             var sprite = this.sprites[index];
             var sprite = this.sprites[index];
 
 
             sprite._animate(deltaTime);
             sprite._animate(deltaTime);
 
 
-            appendSpriteVertex(sprite, vertices, 0, 0, rowSize, this._epsilon);
-            appendSpriteVertex(sprite, vertices, 1, 0, rowSize, this._epsilon);
-            appendSpriteVertex(sprite, vertices, 1, 1, rowSize, this._epsilon);
-            appendSpriteVertex(sprite, vertices, 0, 1, rowSize, this._epsilon);
+            this._appendSpriteVertex(offset++, sprite, 0, 0, rowSize);
+            this._appendSpriteVertex(offset++, sprite, 1, 0, rowSize);
+            this._appendSpriteVertex(offset++, sprite, 1, 1, rowSize);
+            this._appendSpriteVertex(offset++, sprite, 0, 1, rowSize);
         }
         }
-        engine.updateDynamicVertexBuffer(this._vertexBuffer, vertices);
+        engine.updateDynamicVertexBuffer(this._vertexBuffer, this._vertices);
        
        
         // Render
         // Render
         var effect = this._effectBase;
         var effect = this._effectBase;
@@ -120,7 +125,7 @@
         effect.setMatrix("view", viewMatrix);
         effect.setMatrix("view", viewMatrix);
         effect.setMatrix("projection", this._scene.getProjectionMatrix());
         effect.setMatrix("projection", this._scene.getProjectionMatrix());
 
 
-        effect.setVector2("textureInfos", this.cellSize / baseSize.width, this.cellSize / baseSize.height);
+        effect.setFloat2("textureInfos", this.cellSize / baseSize.width, this.cellSize / baseSize.height);
         
         
         // Fog
         // Fog
         if (this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {
         if (this._scene.fogMode !== BABYLON.Scene.FOGMODE_NONE) {

+ 557 - 123
Babylon/Tools/babylon.math.js

@@ -203,6 +203,12 @@
     BABYLON.Color3.prototype.multiply = function (otherColor) {
     BABYLON.Color3.prototype.multiply = function (otherColor) {
         return new BABYLON.Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b);
         return new BABYLON.Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b);
     };
     };
+    
+    BABYLON.Color3.prototype.multiplyToRef = function (otherColor, result) {
+        result.r = this.r * otherColor.r;
+        result.g = this.g * otherColor.g;
+        result.b = this.b * otherColor.b;
+    };
 
 
     BABYLON.Color3.prototype.equals = function (otherColor) {
     BABYLON.Color3.prototype.equals = function (otherColor) {
         return this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;
         return this.r === otherColor.r && this.g === otherColor.g && this.b === otherColor.b;
@@ -212,9 +218,27 @@
         return new BABYLON.Color3(this.r * scale, this.g * scale, this.b * scale);
         return new BABYLON.Color3(this.r * scale, this.g * scale, this.b * scale);
     };
     };
     
     
+    BABYLON.Color3.prototype.scaleToRef = function (scale, result) {
+        result.r = this.r * scale;
+        result.g = this.g * scale;
+        result.b = this.b * scale;
+    };
+    
     BABYLON.Color3.prototype.clone = function () {
     BABYLON.Color3.prototype.clone = function () {
         return new BABYLON.Color3(this.r, this.g, this.b);
         return new BABYLON.Color3(this.r, this.g, this.b);
     };
     };
+    
+    BABYLON.Color3.prototype.copyFrom = function (source) {
+        this.r = source.r;
+        this.g = source.g;
+        this.b = source.b;
+    };
+    
+    BABYLON.Color3.prototype.copyFromFloats = function (r, g, b) {
+        this.r = r;
+        this.g = g;
+        this.b = b;
+    };
 
 
     // Statics
     // Statics
     BABYLON.Color3.FromArray = function (array) {
     BABYLON.Color3.FromArray = function (array) {
@@ -231,6 +255,13 @@
     };
     };
     
     
     // Operators
     // Operators
+    BABYLON.Color4.prototype.addInPlace = function (right) {
+        this.r += right.r;
+        this.g += right.g;
+        this.b += right.b;
+        this.a += right.a;
+    };
+    
     BABYLON.Color4.prototype.add = function (right) {
     BABYLON.Color4.prototype.add = function (right) {
         return new BABYLON.Color4(this.r + right.r, this.g + right.g, this.b + right.b, this.a + right.a);
         return new BABYLON.Color4(this.r + right.r, this.g + right.g, this.b + right.b, this.a + right.a);
     };
     };
@@ -239,9 +270,23 @@
         return new BABYLON.Color4(this.r - right.r, this.g - right.g, this.b - right.b, this.a - right.a);
         return new BABYLON.Color4(this.r - right.r, this.g - right.g, this.b - right.b, this.a - right.a);
     };
     };
     
     
+    BABYLON.Color4.prototype.subtractToRef = function (right, result) {
+        result.r = this.r - right.r;
+        result.g = this.g - right.g;
+        result.b = this.b - right.b;
+        result.a = this.a - right.a;
+    };
+    
     BABYLON.Color4.prototype.scale = function (scale) {
     BABYLON.Color4.prototype.scale = function (scale) {
         return new BABYLON.Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);
         return new BABYLON.Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale);
     };
     };
+    
+    BABYLON.Color4.prototype.scaleToRef = function (scale, result) {
+        result.r = this.r * scale;
+        result.g = this.g * scale;
+        result.b = this.b * scale;
+        result.a = this.a * scale;
+    };
 
 
     BABYLON.Color4.prototype.toString = function () {
     BABYLON.Color4.prototype.toString = function () {
         return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}";
         return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}";
@@ -253,12 +298,18 @@
     
     
     // Statics
     // Statics
     BABYLON.Color4.Lerp = function(left, right, amount) {
     BABYLON.Color4.Lerp = function(left, right, amount) {
-        var r = left.r + (right.r - left.r) * amount;
-        var g = left.g + (right.g - left.g) * amount;
-        var b = left.b + (right.b - left.b) * amount;
-        var a = left.a + (right.a - left.a) * amount;
+        var result = new BABYLON.Color4(0, 0, 0, 0);
 
 
-        return new BABYLON.Color4(r, g, b, a);
+        BABYLON.Color4.LerpToRef(left, right, amount, result);
+
+        return result;
+    };
+    
+    BABYLON.Color4.LerpToRef = function (left, right, amount, result) {
+        result.r = left.r + (right.r - left.r) * amount;
+        result.g = left.g + (right.g - left.g) * amount;
+        result.b = left.b + (right.b - left.b) * amount;
+        result.a = left.a + (right.a - left.a) * amount;
     };
     };
     
     
     BABYLON.Color4.FromArray = function (array, offset) {
     BABYLON.Color4.FromArray = function (array, offset) {
@@ -292,6 +343,11 @@
     BABYLON.Vector2.prototype.negate = function () {
     BABYLON.Vector2.prototype.negate = function () {
         return new BABYLON.Vector2(-this.x, -this.y);
         return new BABYLON.Vector2(-this.x, -this.y);
     };
     };
+    
+    BABYLON.Vector2.prototype.scaleInPlace = function (scale) {
+        this.x *= scale;
+        this.y *= scale;
+    };
 
 
     BABYLON.Vector2.prototype.scale = function (scale) {
     BABYLON.Vector2.prototype.scale = function (scale) {
         return new BABYLON.Vector2(this.x * scale, this.y * scale);
         return new BABYLON.Vector2(this.x * scale, this.y * scale);
@@ -435,33 +491,101 @@
     };
     };
 
 
     // Operators
     // Operators
+    BABYLON.Vector3.prototype.addInPlace = function (otherVector) {
+        this.x += otherVector.x;
+        this.y += otherVector.y;
+        this.z += otherVector.z;
+    };
+    
     BABYLON.Vector3.prototype.add = function (otherVector) {
     BABYLON.Vector3.prototype.add = function (otherVector) {
         return new BABYLON.Vector3(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
         return new BABYLON.Vector3(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.addToRef = function (otherVector, result) {
+        result.x = this.x + otherVector.x;
+        result.y = this.y + otherVector.y;
+        result.z = this.z + otherVector.z;
+    };
+    
+    BABYLON.Vector3.prototype.subtractInPlace = function (otherVector) {
+        this.x -= otherVector.x;
+        this.y -= otherVector.y;
+        this.z -= otherVector.z;
+    };
 
 
     BABYLON.Vector3.prototype.subtract = function (otherVector) {
     BABYLON.Vector3.prototype.subtract = function (otherVector) {
         return new BABYLON.Vector3(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z);
         return new BABYLON.Vector3(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.subtractToRef = function (otherVector, result) {
+        result.x = this.x - otherVector.x;
+        result.y = this.y - otherVector.y;
+        result.z = this.z - otherVector.z;
+    };
+    
+    BABYLON.Vector3.prototype.subtractFromFloats = function (x, y, z) {
+        return new BABYLON.Vector3(this.x - x, this.y - y, this.z - z);
+    };
+
+    BABYLON.Vector3.prototype.subtractFromFloatsToRef = function (x, y, z, result) {
+        result.x = this.x - x;
+        result.y = this.y - y;
+        result.z = this.z - z;
+    };
 
 
     BABYLON.Vector3.prototype.negate = function () {
     BABYLON.Vector3.prototype.negate = function () {
         return new BABYLON.Vector3(-this.x, -this.y, -this.z);
         return new BABYLON.Vector3(-this.x, -this.y, -this.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.scaleInPlace = function (scale) {
+        this.x *= scale;
+        this.y *= scale;
+        this.z *= scale;
+    };
 
 
     BABYLON.Vector3.prototype.scale = function (scale) {
     BABYLON.Vector3.prototype.scale = function (scale) {
         return new BABYLON.Vector3(this.x * scale, this.y * scale, this.z * scale);
         return new BABYLON.Vector3(this.x * scale, this.y * scale, this.z * scale);
     };
     };
+    
+    BABYLON.Vector3.prototype.scaleToRef = function (scale, result) {
+        result.x = this.x * scale;
+        result.y = this.y * scale;
+        result.z = this.z * scale;
+    };
 
 
     BABYLON.Vector3.prototype.equals = function (otherVector) {
     BABYLON.Vector3.prototype.equals = function (otherVector) {
         return this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z;
         return this.x === otherVector.x && this.y === otherVector.y && this.z === otherVector.z;
     };
     };
+    
+    BABYLON.Vector3.prototype.equalsToFloats = function (x, y, z) {
+        return this.x === x && this.y === y && this.z === z;
+    };
+
+    BABYLON.Vector3.prototype.multiplyInPlace = function (otherVector) {
+        this.x *= otherVector.x;
+        this.y *= otherVector.y;
+        this.z *= otherVector.z;
+    };
 
 
     BABYLON.Vector3.prototype.multiply = function (otherVector) {
     BABYLON.Vector3.prototype.multiply = function (otherVector) {
         return new BABYLON.Vector3(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
         return new BABYLON.Vector3(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.multiplyToRef = function (otherVector, result) {
+        result.x = this.x * otherVector.x;
+        result.y = this.y * otherVector.y;
+        result.z = this.z * otherVector.z;
+    };
 
 
     BABYLON.Vector3.prototype.divide = function (otherVector) {
     BABYLON.Vector3.prototype.divide = function (otherVector) {
         return new BABYLON.Vector3(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z);
         return new BABYLON.Vector3(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.divideToRef = function (otherVector, result) {
+        result.x = this.x / otherVector.x;
+        result.y = this.y / otherVector.y;
+        result.z = this.z / otherVector.z;
+    };
 
 
     // Properties
     // Properties
     BABYLON.Vector3.prototype.length = function () {
     BABYLON.Vector3.prototype.length = function () {
@@ -489,6 +613,18 @@
     BABYLON.Vector3.prototype.clone = function () {
     BABYLON.Vector3.prototype.clone = function () {
         return new BABYLON.Vector3(this.x, this.y, this.z);
         return new BABYLON.Vector3(this.x, this.y, this.z);
     };
     };
+    
+    BABYLON.Vector3.prototype.copyFrom = function (source) {
+        this.x = source.x;
+        this.y = source.y;
+        this.z = source.z;
+    };
+    
+    BABYLON.Vector3.prototype.copyFromFloats = function (x, y, z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    };
 
 
     // Statics
     // Statics
     BABYLON.Vector3.FromArray = function (array, offset) {
     BABYLON.Vector3.FromArray = function (array, offset) {
@@ -498,6 +634,22 @@
 
 
         return new BABYLON.Vector3(array[offset], array[offset + 1], array[offset + 2]);
         return new BABYLON.Vector3(array[offset], array[offset + 1], array[offset + 2]);
     };
     };
+    
+    BABYLON.Vector3.FromArrayToRef = function (array, offset, result) {
+        if (!offset) {
+            offset = 0;
+        }
+
+        result.x = array[offset];
+        result.y = array[offset + 1];
+        result.z = array[offset + 2];
+    };
+    
+    BABYLON.Vector3.FromFloatsToRef = function (x, y, z, result) {
+        result.x = x;
+        result.y = y;
+        result.z = z;
+    };
 
 
     BABYLON.Vector3.Zero = function () {
     BABYLON.Vector3.Zero = function () {
         return new BABYLON.Vector3(0, 0, 0);
         return new BABYLON.Vector3(0, 0, 0);
@@ -508,22 +660,54 @@
     };
     };
 
 
     BABYLON.Vector3.TransformCoordinates = function (vector, transformation) {
     BABYLON.Vector3.TransformCoordinates = function (vector, transformation) {
+        var result = BABYLON.Vector3.Zero();
+
+        BABYLON.Vector3.TransformCoordinatesToRef(vector, transformation, result);
+
+        return result;
+    };
+    
+    BABYLON.Vector3.TransformCoordinatesToRef = function (vector, transformation, result) {
         var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]) + transformation.m[12];
         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 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 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];
         var w = (vector.x * transformation.m[3]) + (vector.y * transformation.m[7]) + (vector.z * transformation.m[11]) + transformation.m[15];
 
 
-        return new BABYLON.Vector3(x / w, y / w, z / w);
+        result.x = x / w;
+        result.y = y / w;
+        result.z = z / w;
+    };
+    
+    BABYLON.Vector3.TransformCoordinatesFromFloatsToRef = function (x, y ,z, transformation, result) {
+        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];
+
+        result.x = rx / rw;
+        result.y = ry / rw;
+        result.z = rz / rw;
     };
     };
 
 
     BABYLON.Vector3.TransformNormal = function (vector, transformation) {
     BABYLON.Vector3.TransformNormal = function (vector, transformation) {
-        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]);
+        var result = BABYLON.Vector3.Zero();
 
 
-        return new BABYLON.Vector3(x, y, z);
+        BABYLON.Vector3.TransformNormalToRef(vector, transformation, result);
+
+        return result;
+    };
+    
+    BABYLON.Vector3.TransformNormalToRef = function (vector, transformation, result) {
+        result.x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]);
+        result.y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]);
+        result.z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]);
     };
     };
 
 
+    BABYLON.Vector3.TransformNormalFromFloatsToRef = function (x, y, z, transformation, result) {
+        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]);
+    };
 
 
     BABYLON.Vector3.CatmullRom = function (value1, value2, value3, value4, amount) {
     BABYLON.Vector3.CatmullRom = function (value1, value2, value3, value4, amount) {
         var squared = amount * amount;
         var squared = amount * amount;
@@ -588,17 +772,28 @@
     };
     };
 
 
     BABYLON.Vector3.Cross = function (left, right) {
     BABYLON.Vector3.Cross = function (left, right) {
-        var x = left.y * right.z - left.z * right.y;
-        var y = left.z * right.x - left.x * right.z;
-        var z = left.x * right.y - left.y * right.x;
+        var result = BABYLON.Vector3.Zero();
 
 
-        return new BABYLON.Vector3(x, y, z);
+        BABYLON.Vector3.CrossToRef(left, right, result);
+
+        return result;
+    };
+    
+    BABYLON.Vector3.CrossToRef = function (left, right, result) {
+        result.x = left.y * right.z - left.z * right.y;
+        result.y = left.z * right.x - left.x * right.z;
+        result.z = left.x * right.y - left.y * right.x;
     };
     };
 
 
     BABYLON.Vector3.Normalize = function (vector) {
     BABYLON.Vector3.Normalize = function (vector) {
-        var newVector = vector.clone();
-        newVector.normalize();
-        return newVector;
+        var result = BABYLON.Vector3.Zero();
+        BABYLON.Vector3.NormalizeToRef(vector, result);
+        return result;
+    };
+    
+    BABYLON.Vector3.NormalizeToRef = function (vector, result) {
+        result.copyFrom(vector);
+        result.normalize();
     };
     };
 
 
     BABYLON.Vector3.Unproject = function (source, viewportWidth, viewportHeight, world, view, projection) {
     BABYLON.Vector3.Unproject = function (source, viewportWidth, viewportHeight, world, view, projection) {
@@ -680,6 +875,36 @@
         return new BABYLON.Vector3(x, y, z);
         return new BABYLON.Vector3(x, y, z);
     };
     };
     
     
+    BABYLON.Quaternion.prototype.toRotationMatrix = function(result)
+    {
+        var xx = this.x * this.x;
+        var yy = this.y * this.y;
+        var zz = this.z * this.z;
+        var xy = this.x * this.y;
+        var zw = this.z * this.w;
+        var zx = this.z * this.x;
+        var yw = this.y * this.w;
+        var yz = this.y * this.z;
+        var xw = this.x * this.w;
+
+        result.m[0] = 1.0 - (2.0 * (yy + zz));
+        result.m[1] = 2.0 * (xy + zw);
+        result.m[2] = 2.0 * (zx - yw);
+        result.m[3] = 0;
+        result.m[4] = 2.0 * (xy - zw);
+        result.m[5] = 1.0 - (2.0 * (zz + xx));
+        result.m[6] = 2.0 * (yz + xw);
+        result.m[7] = 0;
+        result.m[8] = 2.0 * (zx + yw);
+        result.m[9] = 2.0 * (yz - xw);
+        result.m[10] = 1.0 - (2.0 * (yy + xx));
+        result.m[11] = 0;
+        result.m[12] = 0;
+        result.m[13] = 0;
+        result.m[14] = 0;
+        result.m[15] = 1.0;
+    };
+    
     // Statics
     // Statics
     BABYLON.Quaternion.FromArray = function (array, offset) {
     BABYLON.Quaternion.FromArray = function (array, offset) {
         if (!offset) {
         if (!offset) {
@@ -689,6 +914,33 @@
         return new BABYLON.Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);
         return new BABYLON.Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]);
     };
     };
 
 
+    BABYLON.Quaternion.RotationYawPitchRoll = function(yaw, pitch, roll) {
+        var result = new BABYLON.Quaternion();
+
+        BABYLON.Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, result);
+
+        return result;
+    };
+
+    BABYLON.Quaternion.RotationYawPitchRollToRef = function (yaw, pitch, roll, result) {
+        var halfRoll = roll * 0.5;
+        var halfPitch = pitch * 0.5;
+        var halfYaw = yaw * 0.5;
+
+        var sinRoll = Math.sin(halfRoll);
+        var cosRoll = Math.cos(halfRoll);
+        var sinPitch = Math.sin(halfPitch);
+        var cosPitch = Math.cos(halfPitch);
+        var sinYaw = Math.sin(halfYaw);
+        var cosYaw = Math.cos(halfYaw);
+
+        result.x = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll);
+        result.y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll);
+        result.z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll);
+        result.w = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll);
+    };
+
+
     BABYLON.Quaternion.Slerp = function(left, right, amount) {
     BABYLON.Quaternion.Slerp = function(left, right, amount) {
         var num2;
         var num2;
         var num3;
         var num3;
@@ -720,12 +972,12 @@
 
 
     ////////////////////////////////// Matrix //////////////////////////////////
     ////////////////////////////////// Matrix //////////////////////////////////
     
     
-    if(!MatrixType) {
-        var MatrixType = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
+    if (!BABYLON.MatrixType) {
+        BABYLON.MatrixType = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
     }
     }
 
 
     BABYLON.Matrix = function () {
     BABYLON.Matrix = function () {
-        this.m = new MatrixType(16);
+        this.m = new BABYLON.MatrixType(16);
     };
     };
 
 
     // Properties
     // Properties
@@ -822,6 +1074,12 @@
     BABYLON.Matrix.prototype.multiply = function (other) {
     BABYLON.Matrix.prototype.multiply = function (other) {
         var result = new BABYLON.Matrix();
         var result = new BABYLON.Matrix();
 
 
+        this.multiplyToRef(other, result);
+
+        return result;
+    };
+    
+    BABYLON.Matrix.prototype.multiplyToRef = function (other, result) {
         result.m[0] = this.m[0] * other.m[0] + this.m[1] * other.m[4] + this.m[2] * other.m[8] + this.m[3] * other.m[12];
         result.m[0] = this.m[0] * other.m[0] + this.m[1] * other.m[4] + this.m[2] * other.m[8] + this.m[3] * other.m[12];
         result.m[1] = this.m[0] * other.m[1] + this.m[1] * other.m[5] + this.m[2] * other.m[9] + this.m[3] * other.m[13];
         result.m[1] = this.m[0] * other.m[1] + this.m[1] * other.m[5] + this.m[2] * other.m[9] + this.m[3] * other.m[13];
         result.m[2] = this.m[0] * other.m[2] + this.m[1] * other.m[6] + this.m[2] * other.m[10] + this.m[3] * other.m[14];
         result.m[2] = this.m[0] * other.m[2] + this.m[1] * other.m[6] + this.m[2] * other.m[10] + this.m[3] * other.m[14];
@@ -841,8 +1099,6 @@
         result.m[13] = this.m[12] * other.m[1] + this.m[13] * other.m[5] + this.m[14] * other.m[9] + this.m[15] * other.m[13];
         result.m[13] = this.m[12] * other.m[1] + this.m[13] * other.m[5] + this.m[14] * other.m[9] + this.m[15] * other.m[13];
         result.m[14] = this.m[12] * other.m[2] + this.m[13] * other.m[6] + this.m[14] * other.m[10] + this.m[15] * other.m[14];
         result.m[14] = this.m[12] * other.m[2] + this.m[13] * other.m[6] + this.m[14] * other.m[10] + this.m[15] * other.m[14];
         result.m[15] = this.m[12] * other.m[3] + this.m[13] * other.m[7] + this.m[14] * other.m[11] + this.m[15] * other.m[15];
         result.m[15] = this.m[12] * other.m[3] + this.m[13] * other.m[7] + this.m[14] * other.m[11] + this.m[15] * other.m[15];
-
-        return result;
     };
     };
 
 
     BABYLON.Matrix.prototype.equals = function (value) {
     BABYLON.Matrix.prototype.equals = function (value) {
@@ -860,6 +1116,29 @@
     };
     };
 
 
     // Statics
     // Statics
+    BABYLON.Matrix.FromValuesToRef = function (initialM11, initialM12, initialM13, initialM14,
+        initialM21, initialM22, initialM23, initialM24,
+        initialM31, initialM32, initialM33, initialM34,
+        initialM41, initialM42, initialM43, initialM44, result) {
+
+        result.m[0] = initialM11;
+        result.m[1] = initialM12;
+        result.m[2] = initialM13;
+        result.m[3] = initialM14;
+        result.m[4] = initialM21;
+        result.m[5] = initialM22;
+        result.m[6] = initialM23;
+        result.m[7] = initialM24;
+        result.m[8] = initialM31;
+        result.m[9] = initialM32;
+        result.m[10] = initialM33;
+        result.m[11] = initialM34;
+        result.m[12] = initialM41;
+        result.m[13] = initialM42;
+        result.m[14] = initialM43;
+        result.m[15] = initialM44;
+    };
+    
     BABYLON.Matrix.FromValues = function (initialM11, initialM12, initialM13, initialM14,
     BABYLON.Matrix.FromValues = function (initialM11, initialM12, initialM13, initialM14,
         initialM21, initialM22, initialM23, initialM24,
         initialM21, initialM22, initialM23, initialM24,
         initialM31, initialM32, initialM33, initialM34,
         initialM31, initialM32, initialM33, initialM34,
@@ -893,6 +1172,13 @@
             0, 0, 1.0, 0,
             0, 0, 1.0, 0,
             0, 0, 0, 1.0);
             0, 0, 0, 1.0);
     };
     };
+    
+    BABYLON.Matrix.IdentityToRef = function (result) {
+        BABYLON.Matrix.FromValuesToRef(1.0, 0, 0, 0,
+            0, 1.0, 0, 0,
+            0, 0, 1.0, 0,
+            0, 0, 0, 1.0, result);
+    };
 
 
     BABYLON.Matrix.Zero = function () {
     BABYLON.Matrix.Zero = function () {
         return BABYLON.Matrix.FromValues(0, 0, 0, 0,
         return BABYLON.Matrix.FromValues(0, 0, 0, 0,
@@ -902,7 +1188,14 @@
     };
     };
 
 
     BABYLON.Matrix.RotationX = function (angle) {
     BABYLON.Matrix.RotationX = function (angle) {
-        var result = BABYLON.Matrix.Zero();
+        var result = new BABYLON.Matrix();
+
+        BABYLON.Matrix.RotationXToRef(angle, result);
+
+        return result;
+    };
+    
+    BABYLON.Matrix.RotationXToRef = function (angle, result) {        
         var s = Math.sin(angle);
         var s = Math.sin(angle);
         var c = Math.cos(angle);
         var c = Math.cos(angle);
 
 
@@ -914,11 +1207,27 @@
         result.m[9] = -s;
         result.m[9] = -s;
         result.m[6] = s;
         result.m[6] = s;
 
 
-        return result;
+        result.m[1] = 0;
+        result.m[2] = 0;
+        result.m[3] = 0;
+        result.m[4] = 0;
+        result.m[7] = 0;
+        result.m[8] = 0;
+        result.m[11] = 0;
+        result.m[12] = 0;
+        result.m[13] = 0;
+        result.m[14] = 0;
     };
     };
 
 
     BABYLON.Matrix.RotationY = function (angle) {
     BABYLON.Matrix.RotationY = function (angle) {
-        var result = BABYLON.Matrix.Zero();
+        var result = new BABYLON.Matrix();
+
+        BABYLON.Matrix.RotationYToRef(angle, result);
+
+        return result;
+    };
+
+    BABYLON.Matrix.RotationYToRef = function (angle, result) {
         var s = Math.sin(angle);
         var s = Math.sin(angle);
         var c = Math.cos(angle);
         var c = Math.cos(angle);
 
 
@@ -930,11 +1239,27 @@
         result.m[8] = s;
         result.m[8] = s;
         result.m[10] = c;
         result.m[10] = c;
 
 
+        result.m[1] = 0;
+        result.m[3] = 0;
+        result.m[4] = 0;
+        result.m[6] = 0;
+        result.m[7] = 0;
+        result.m[9] = 0;
+        result.m[11] = 0;
+        result.m[12] = 0;
+        result.m[13] = 0;
+        result.m[14] = 0;
+    };
+    
+    BABYLON.Matrix.RotationZ = function (angle) {
+        var result = new BABYLON.Matrix();
+
+        BABYLON.Matrix.RotationZToRef(angle, result);
+
         return result;
         return result;
     };
     };
 
 
-    BABYLON.Matrix.RotationZ = function (angle) {
-        var result = BABYLON.Matrix.Zero();
+    BABYLON.Matrix.RotationZToRef = function (angle, result) {
         var s = Math.sin(angle);
         var s = Math.sin(angle);
         var c = Math.cos(angle);
         var c = Math.cos(angle);
 
 
@@ -945,8 +1270,17 @@
         result.m[1] = s;
         result.m[1] = s;
         result.m[4] = -s;
         result.m[4] = -s;
         result.m[5] = c;
         result.m[5] = c;
-
-        return result;
+        
+        result.m[2] = 0;
+        result.m[3] = 0;
+        result.m[6] = 0;
+        result.m[7] = 0;
+        result.m[8] = 0;
+        result.m[9] = 0;
+        result.m[11] = 0;
+        result.m[12] = 0;
+        result.m[13] = 0;
+        result.m[14] = 0;
     };
     };
 
 
     BABYLON.Matrix.RotationAxis = function (axis, angle) {
     BABYLON.Matrix.RotationAxis = function (axis, angle) {
@@ -978,41 +1312,86 @@
     };
     };
 
 
     BABYLON.Matrix.RotationYawPitchRoll = function (yaw, pitch, roll) {
     BABYLON.Matrix.RotationYawPitchRoll = function (yaw, pitch, roll) {
-        return BABYLON.Matrix.RotationZ(roll).multiply(BABYLON.Matrix.RotationX(pitch)).multiply(BABYLON.Matrix.RotationY(yaw));
+        var result = new BABYLON.Matrix();
+
+        BABYLON.Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, result);
+
+        return result;
+    };
+    
+    var tempQuaternion = new BABYLON.Quaternion(); // For RotationYawPitchRoll
+    BABYLON.Matrix.RotationYawPitchRollToRef = function (yaw, pitch, roll, result) {
+        BABYLON.Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, tempQuaternion);
+
+        tempQuaternion.toRotationMatrix(result);
     };
     };
 
 
     BABYLON.Matrix.Scaling = function (x, y, z) {
     BABYLON.Matrix.Scaling = function (x, y, z) {
         var result = BABYLON.Matrix.Zero();
         var result = BABYLON.Matrix.Zero();
 
 
+        BABYLON.Matrix.ScalingToRef(x, y, z, result);
+
+        return result;
+    };
+    
+    BABYLON.Matrix.ScalingToRef = function (x, y, z, result) {
         result.m[0] = x;
         result.m[0] = x;
+        result.m[1] = 0;
+        result.m[2] = 0;
+        result.m[3] = 0;
+        result.m[4] = 0;
         result.m[5] = y;
         result.m[5] = y;
+        result.m[6] = 0;
+        result.m[7] = 0;
+        result.m[8] = 0;
+        result.m[9] = 0;
         result.m[10] = z;
         result.m[10] = z;
+        result.m[11] = 0;
+        result.m[12] = 0;
+        result.m[13] = 0;
+        result.m[14] = 0;
         result.m[15] = 1.0;
         result.m[15] = 1.0;
-
-        return result;
     };
     };
 
 
     BABYLON.Matrix.Translation = function (x, y, z) {
     BABYLON.Matrix.Translation = function (x, y, z) {
         var result = BABYLON.Matrix.Identity();
         var result = BABYLON.Matrix.Identity();
 
 
-        result.m[12] = x;
-        result.m[13] = y;
-        result.m[14] = z;
+        BABYLON.Matrix.TranslationToRef(x, y, z, result);
 
 
         return result;
         return result;
     };
     };
+    
+    BABYLON.Matrix.TranslationToRef = function (x, y, z, result) {
+        BABYLON.Matrix.FromValuesToRef(1.0, 0, 0, 0,
+            0, 1.0, 0, 0,
+            0, 0, 1.0, 0,
+            x, y, z, 1.0, result);
+    };
 
 
     BABYLON.Matrix.LookAtLH = function (eye, target, up) {
     BABYLON.Matrix.LookAtLH = function (eye, target, up) {
+        var result = BABYLON.Matrix.Zero();
+
+        BABYLON.Matrix.LookAtLHToRef(eye, target, up, result);
+
+        return result;
+
+    };
+
+
+    var xAxis = BABYLON.Vector3.Zero();
+    var yAxis = BABYLON.Vector3.Zero();
+    var zAxis = BABYLON.Vector3.Zero();
+    BABYLON.Matrix.LookAtLHToRef = function (eye, target, up, result) {
         // Z axis
         // Z axis
-        var zAxis = target.subtract(eye);
+        target.subtractToRef(eye, zAxis);
         zAxis.normalize();
         zAxis.normalize();
 
 
         // X axis
         // X axis
-        var xAxis = BABYLON.Vector3.Cross(up, zAxis);
+        BABYLON.Vector3.CrossToRef(up, zAxis, xAxis);
         xAxis.normalize();
         xAxis.normalize();
 
 
         // Y axis
         // Y axis
-        var yAxis = BABYLON.Vector3.Cross(zAxis, xAxis);
+        BABYLON.Vector3.CrossToRef(zAxis, xAxis, yAxis);
         yAxis.normalize();
         yAxis.normalize();
 
 
         // Eye angles
         // Eye angles
@@ -1020,10 +1399,10 @@
         var ey = -BABYLON.Vector3.Dot(yAxis, eye);
         var ey = -BABYLON.Vector3.Dot(yAxis, eye);
         var ez = -BABYLON.Vector3.Dot(zAxis, eye);
         var ez = -BABYLON.Vector3.Dot(zAxis, eye);
 
 
-        return BABYLON.Matrix.FromValues(xAxis.x, yAxis.x, zAxis.x, 0,
+        return BABYLON.Matrix.FromValuesToRef(xAxis.x, yAxis.x, zAxis.x, 0,
             xAxis.y, yAxis.y, zAxis.y, 0,
             xAxis.y, yAxis.y, zAxis.y, 0,
             xAxis.z, yAxis.z, zAxis.z, 0,
             xAxis.z, yAxis.z, zAxis.z, 0,
-            ex, ey, ez, 1);
+            ex, ey, ez, 1, result);
     };
     };
 
 
     BABYLON.Matrix.OrthoLH = function (width, height, znear, zfar) {
     BABYLON.Matrix.OrthoLH = function (width, height, znear, zfar) {
@@ -1041,19 +1420,23 @@
     BABYLON.Matrix.OrthoOffCenterLH = function (left, right, bottom, top, znear, zfar) {
     BABYLON.Matrix.OrthoOffCenterLH = function (left, right, bottom, top, znear, zfar) {
         var matrix = BABYLON.Matrix.Zero();
         var matrix = BABYLON.Matrix.Zero();
 
 
-        matrix.m[0] = 2.0 / (right - left);
-        matrix.m[1] = matrix.m[2] = matrix.m[3] = 0;
-        matrix.m[5] = 2.0 / (top - bottom);
-        matrix.m[4] = matrix.m[6] = matrix.m[7] = 0;
-        matrix.m[10] = -1.0 / (znear - zfar);
-        matrix.m[8] = matrix.m[9] = matrix.m[11] = 0;
-        matrix.m[12] = (left + right) / (left - right);
-        matrix.m[13] = (top + bottom) / (bottom - top);
-        matrix.m[14] = znear / (znear - zfar);
-        matrix.m[15] = 1.0;
+        BABYLON.Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, matrix);
 
 
         return matrix;
         return matrix;
     };
     };
+    
+    BABYLON.Matrix.OrthoOffCenterLHToRef = function (left, right, bottom, top, znear, zfar, result) {
+        result.m[0] = 2.0 / (right - left);
+        result.m[1] = result.m[2] = result.m[3] = 0;
+        result.m[5] = 2.0 / (top - bottom);
+        result.m[4] = result.m[6] = result.m[7] = 0;
+        result.m[10] = -1.0 / (znear - zfar);
+        result.m[8] = result.m[9] = result.m[11] = 0;
+        result.m[12] = (left + right) / (left - right);
+        result.m[13] = (top + bottom) / (bottom - top);
+        result.m[14] = znear / (znear - zfar);
+        result.m[15] = 1.0;
+    };
 
 
     BABYLON.Matrix.PerspectiveLH = function (width, height, znear, zfar) {
     BABYLON.Matrix.PerspectiveLH = function (width, height, znear, zfar) {
         var matrix = BABYLON.Matrix.Zero();
         var matrix = BABYLON.Matrix.Zero();
@@ -1074,19 +1457,23 @@
     BABYLON.Matrix.PerspectiveFovLH = function (fov, aspect, znear, zfar) {
     BABYLON.Matrix.PerspectiveFovLH = function (fov, aspect, znear, zfar) {
         var matrix = BABYLON.Matrix.Zero();
         var matrix = BABYLON.Matrix.Zero();
 
 
+        BABYLON.Matrix.PerspectiveFovLHToRef(fov, aspect, znear, zfar, matrix);
+        
+        return matrix;
+    };
+    
+    BABYLON.Matrix.PerspectiveFovLHToRef = function (fov, aspect, znear, zfar, result) {
         var tan = 1.0 / (Math.tan(fov * 0.5));
         var tan = 1.0 / (Math.tan(fov * 0.5));
 
 
-        matrix.m[0] = tan / aspect;
-        matrix.m[1] = matrix.m[2] = matrix.m[3] = 0.0;
-        matrix.m[5] = tan;
-        matrix.m[4] = matrix.m[6] = matrix.m[7] = 0.0;
-        matrix.m[8] = matrix.m[9] = 0.0;
-        matrix.m[10] = -zfar / (znear - zfar);
-        matrix.m[11] = 1.0;
-        matrix.m[12] = matrix.m[13] = matrix.m[15] = 0.0;
-        matrix.m[14] = (znear * zfar) / (znear - zfar);
-
-        return matrix;
+        result.m[0] = tan / aspect;
+        result.m[1] = result.m[2] = result.m[3] = 0.0;
+        result.m[5] = tan;
+        result.m[4] = result.m[6] = result.m[7] = 0.0;
+        result.m[8] = result.m[9] = 0.0;
+        result.m[10] = -zfar / (znear - zfar);
+        result.m[11] = 1.0;
+        result.m[12] = result.m[13] = result.m[15] = 0.0;
+        result.m[14] = (znear * zfar) / (znear - zfar);
     };
     };
 
 
     BABYLON.Matrix.AffineTransformation = function (scaling, rotationCenter, rotation, translation) {
     BABYLON.Matrix.AffineTransformation = function (scaling, rotationCenter, rotation, translation) {
@@ -1139,6 +1526,12 @@
     BABYLON.Matrix.Reflection = function (plane) {
     BABYLON.Matrix.Reflection = function (plane) {
         var matrix = new BABYLON.Matrix();
         var matrix = new BABYLON.Matrix();
 
 
+        BABYLON.Matrix.ReflectionToRef(plane, matrix);
+
+        return matrix;
+    };
+    
+    BABYLON.Matrix.ReflectionToRef = function (plane, result) {
         plane.normalize();
         plane.normalize();
         var x = plane.normal.x;
         var x = plane.normal.x;
         var y = plane.normal.y;
         var y = plane.normal.y;
@@ -1146,24 +1539,22 @@
         var temp = -2 * x;
         var temp = -2 * x;
         var temp2 = -2 * y;
         var temp2 = -2 * y;
         var temp3 = -2 * z;
         var temp3 = -2 * z;
-        matrix.m[0] = (temp * x) + 1;
-        matrix.m[1] = temp2 * x;
-        matrix.m[2] = temp3 * x;
-        matrix.m[3] = 0.0;
-        matrix.m[4] = temp * y;
-        matrix.m[5] = (temp2 * y) + 1;
-        matrix.m[6] = temp3 * y;
-        matrix.m[7] = 0.0;
-        matrix.m[8] = temp * z;
-        matrix.m[9] = temp2 * z;
-        matrix.m[10] = (temp3 * z) + 1;
-        matrix.m[11] = 0.0;
-        matrix.m[12] = temp * plane.d;
-        matrix.m[13] = temp2 * plane.d;
-        matrix.m[14] = temp3 * plane.d;
-        matrix.m[15] = 1.0;
-
-        return matrix;
+        result.m[0] = (temp * x) + 1;
+        result.m[1] = temp2 * x;
+        result.m[2] = temp3 * x;
+        result.m[3] = 0.0;
+        result.m[4] = temp * y;
+        result.m[5] = (temp2 * y) + 1;
+        result.m[6] = temp3 * y;
+        result.m[7] = 0.0;
+        result.m[8] = temp * z;
+        result.m[9] = temp2 * z;
+        result.m[10] = (temp3 * z) + 1;
+        result.m[11] = 0.0;
+        result.m[12] = temp * plane.d;
+        result.m[13] = temp2 * plane.d;
+        result.m[14] = temp3 * plane.d;
+        result.m[15] = 1.0;
     };
     };
 
 
     ////////////////////////////////// Plane //////////////////////////////////
     ////////////////////////////////// Plane //////////////////////////////////
@@ -1207,13 +1598,8 @@
     BABYLON.Plane.prototype.dotCoordinate = function (point) {
     BABYLON.Plane.prototype.dotCoordinate = function (point) {
         return ((((this.normal.x * point.x) + (this.normal.y * point.y)) + (this.normal.z * point.z)) + this.d);
         return ((((this.normal.x * point.x) + (this.normal.y * point.y)) + (this.normal.z * point.z)) + this.d);
     };
     };
-
-    // Statics
-    BABYLON.Plane.FromArray = function (array) {
-        return new BABYLON.Plane(array[0], array[1], array[2], array[3]);
-    };
-
-    BABYLON.Plane.FromPoints = function(point1, point2, point3) {
+    
+    BABYLON.Plane.prototype.copyFromPoints = function (point1, point2, point3) {
         var x1 = point2.x - point1.x;
         var x1 = point2.x - point1.x;
         var y1 = point2.y - point1.y;
         var y1 = point2.y - point1.y;
         var z1 = point2.z - point1.z;
         var z1 = point2.z - point1.z;
@@ -1231,59 +1617,107 @@
         else
         else
             invPyth = 0;
             invPyth = 0;
 
 
-        var normal = new BABYLON.Vector3(yz * invPyth, xz * invPyth, xy * invPyth);
-        var d = -((normal.x * point1.x) + (normal.y * point1.y) + (normal.z * point1.z));
-        return new BABYLON.Plane(normal.x, normal.y, normal.z, d);
+        this.normal.x = yz * invPyth;
+        this.normal.y = xz * invPyth;
+        this.normal.z = xy * invPyth;
+        this.d = -((this.normal.x * point1.x) + (this.normal.y * point1.y) + (this.normal.z * point1.z));
+    };
+    
+    BABYLON.Plane.prototype.isFrontFacingTo = function (direction, epsilon) {
+        var dot = BABYLON.Vector3.Dot(this.normal, direction);
+
+        return (dot <= epsilon);
     };
     };
 
 
+    BABYLON.Plane.prototype.signedDistanceTo = function (point) {
+        return BABYLON.Vector3.Dot(point, this.normal) + this.d;
+    };
+
+    // Statics
+    BABYLON.Plane.FromArray = function (array) {
+        return new BABYLON.Plane(array[0], array[1], array[2], array[3]);
+    };
+
+    BABYLON.Plane.FromPoints = function(point1, point2, point3) {
+        var result = new BABYLON.Plane(0, 0, 0, 0);
+
+        result.copyFromPoints(point1, point2, point3);
+
+        return result;
+    };
+    
+    BABYLON.Plane.FromPositionAndNormal = function (origin, normal) {
+        var result = new BABYLON.Plane(0, 0, 0, 0);
+        normal.normalize();
+
+        result.normal = normal;
+        result.d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);
+
+        return result;
+    };
+
+    BABYLON.Plane.SignedDistanceToPlaneFromPositionAndNormal = function (origin, normal, point) {
+        var d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z);
+
+        return BABYLON.Vector3.Dot(point, normal) + d;
+    };
     ////////////////////////////////// Frustum //////////////////////////////////
     ////////////////////////////////// Frustum //////////////////////////////////
     BABYLON.Frustum = {};
     BABYLON.Frustum = {};
 
 
     // Statics
     // Statics
     BABYLON.Frustum.GetPlanes = function (transform) {
     BABYLON.Frustum.GetPlanes = function (transform) {
         var frustumPlanes = [];
         var frustumPlanes = [];
-        frustumPlanes.push(new BABYLON.Plane( // near
-            transform.m[3] + transform.m[2],
-            transform.m[7] + transform.m[6],
-            transform.m[10] + transform.m[10],
-            transform.m[15] + transform.m[14]));
-        frustumPlanes[0].normalize();
+        
+        for (var index = 0; index < 6; index++) {
+            frustumPlanes.push(new BABYLON.Plane(0, 0, 0, 0));
+        }
 
 
-        frustumPlanes.push(new BABYLON.Plane( // far 
-            transform.m[3] - transform.m[2],
-            transform.m[7] - transform.m[6],
-            transform.m[11] - transform.m[10],
-            transform.m[15] - transform.m[14]));
-        frustumPlanes[1].normalize();
+        BABYLON.Frustum.GetPlanesToRef(transform, frustumPlanes);
 
 
-        frustumPlanes.push(new BABYLON.Plane( // left
-            transform.m[3] + transform.m[0],
-            transform.m[7] + transform.m[4],
-            transform.m[11] + transform.m[8],
-            transform.m[15] + transform.m[12]));
+        return frustumPlanes;
+    };
+    
+    BABYLON.Frustum.GetPlanesToRef = function (transform, frustumPlanes) {
+        // Near
+        frustumPlanes[0].normal.x = transform.m[3] + transform.m[2];
+        frustumPlanes[0].normal.y = transform.m[7] + transform.m[6];
+        frustumPlanes[0].normal.z = transform.m[10] + transform.m[10];
+        frustumPlanes[0].d = transform.m[15] + transform.m[14];
+        frustumPlanes[0].normalize();
+        
+        // Far
+        frustumPlanes[1].normal.x = transform.m[3] - transform.m[2];
+        frustumPlanes[1].normal.y = transform.m[7] - transform.m[6];
+        frustumPlanes[1].normal.z = transform.m[11] - transform.m[10];
+        frustumPlanes[1].d = transform.m[15] - transform.m[14];
+        frustumPlanes[1].normalize();
+        
+        // Left
+        frustumPlanes[2].normal.x = transform.m[3] + transform.m[0];
+        frustumPlanes[2].normal.y = transform.m[7] + transform.m[4];
+        frustumPlanes[2].normal.z = transform.m[11] + transform.m[8];
+        frustumPlanes[2].d = transform.m[15] + transform.m[12];
         frustumPlanes[2].normalize();
         frustumPlanes[2].normalize();
 
 
-        frustumPlanes.push(new BABYLON.Plane( // right
-            transform.m[3] - transform.m[0],
-            transform.m[7] - transform.m[4],
-            transform.m[11] - transform.m[8],
-            transform.m[15] - transform.m[12]));
+        // Right
+        frustumPlanes[3].normal.x = transform.m[3] - transform.m[0];
+        frustumPlanes[3].normal.y = transform.m[7] - transform.m[4];
+        frustumPlanes[3].normal.z = transform.m[11] - transform.m[8];
+        frustumPlanes[3].d = transform.m[15] - transform.m[12];
         frustumPlanes[3].normalize();
         frustumPlanes[3].normalize();
 
 
-        frustumPlanes.push(new BABYLON.Plane( // top
-            transform.m[3] - transform.m[1],
-            transform.m[7] - transform.m[5],
-            transform.m[11] - transform.m[9],
-            transform.m[15] - transform.m[13]));
+        // Top
+        frustumPlanes[4].normal.x = transform.m[3] - transform.m[1];
+        frustumPlanes[4].normal.y = transform.m[7] - transform.m[5];
+        frustumPlanes[4].normal.z = transform.m[11] - transform.m[9];
+        frustumPlanes[4].d = transform.m[15] - transform.m[13];
         frustumPlanes[4].normalize();
         frustumPlanes[4].normalize();
 
 
-        frustumPlanes.push(new BABYLON.Plane( // bottom
-            transform.m[3] + transform.m[1],
-            transform.m[7] + transform.m[5],
-            transform.m[11] + transform.m[9],
-            transform.m[15] + transform.m[13]));
+        // Bottom
+        frustumPlanes[5].normal.x = transform.m[3] + transform.m[1];
+        frustumPlanes[5].normal.y = transform.m[7] + transform.m[5];
+        frustumPlanes[5].normal.z = transform.m[11] + transform.m[9];
+        frustumPlanes[5].d = transform.m[15] + transform.m[13];
         frustumPlanes[5].normalize();
         frustumPlanes[5].normalize();
-
-        return frustumPlanes;
     };
     };
 })();
 })();

+ 42 - 0
Babylon/Tools/babylon.tools.js

@@ -3,6 +3,48 @@
 (function () {
 (function () {
     BABYLON.Tools = {};
     BABYLON.Tools = {};
 
 
+    // Smart array
+    BABYLON.Tools.SmartArray = function(capacity) {
+        this.data = new Array(capacity);
+        this.length = 0;
+    };
+
+    BABYLON.Tools.SmartArray.prototype.push = function(value) {
+        this.data[this.length++] = value;
+        
+        if (this.length > this.data.length) {
+            this.data.length *= 2;
+        }
+    };
+
+    BABYLON.Tools.SmartArray.prototype.reset = function() {
+        this.length = 0;
+    };
+    
+    BABYLON.Tools.SmartArray.prototype.concat = function (array) {
+        if (array.length === 0) {
+            return;
+        }
+        if (this.length + array.length > this.data.length) {
+            this.data.length = (this.length + array.length) * 2;
+        }
+
+        for (var index = 0; index < array.length; index++) {
+            this.data[this.length++] = (array.data || array)[index];
+        }
+    };
+    
+    BABYLON.Tools.SmartArray.prototype.indexOf = function (value) {
+        var position = this.data.indexOf(value);
+        
+        if (position >= this.length) {
+            return -1;
+        }
+
+        return position;
+    };
+
+    // Misc.
     BABYLON.Tools.GetPointerPrefix = function() {
     BABYLON.Tools.GetPointerPrefix = function() {
         var eventPrefix = "pointer";
         var eventPrefix = "pointer";
 
 

+ 28 - 18
Babylon/babylon.engine.js

@@ -114,29 +114,39 @@
 
 
     // Methods
     // Methods
     BABYLON.Engine.prototype.stopRenderLoop = function () {
     BABYLON.Engine.prototype.stopRenderLoop = function () {
+        this._renderFunction = null;
         this._runningLoop = false;
         this._runningLoop = false;
     };
     };
+    
+    BABYLON.Engine.prototype._renderLoop = function () {
+        // Start new frame
+        this.beginFrame();
 
 
-    BABYLON.Engine.prototype.runRenderLoop = function (renderFunction) {
-        this._runningLoop = true;
-        var that = this;
+        if (this._renderFunction) {
+            this._renderFunction();
+        }
 
 
-        var loop = function () {
-            // Start new frame
-            that.beginFrame();
+        // Present
+        this.endFrame();
 
 
-            renderFunction();
+        if (this._runningLoop) {
+            // Register new frame
+            var that = this;
+            BABYLON.Tools.QueueNewFrame(function () {
+                that._renderLoop();
+            });
+        }
+    };
 
 
-            // Present
-            that.endFrame();
+    BABYLON.Engine.prototype.runRenderLoop = function (renderFunction) {
+        this._runningLoop = true;
 
 
-            if (that._runningLoop) {
-                // Register new frame
-                BABYLON.Tools.QueueNewFrame(loop);
-            }
-        };
+        this._renderFunction = renderFunction;
 
 
-        BABYLON.Tools.QueueNewFrame(loop);
+        var that = this;
+        BABYLON.Tools.QueueNewFrame(function() {
+            that._renderLoop();
+        });
     };
     };
 
 
     BABYLON.Engine.prototype.switchFullscreen = function (element) {
     BABYLON.Engine.prototype.switchFullscreen = function (element) {
@@ -311,7 +321,7 @@
         this._gl.attachShader(shaderProgram, fragmentShader);
         this._gl.attachShader(shaderProgram, fragmentShader);
 
 
         this._gl.linkProgram(shaderProgram);
         this._gl.linkProgram(shaderProgram);
-
+        
         this._gl.deleteShader(vertexShader);
         this._gl.deleteShader(vertexShader);
         this._gl.deleteShader(fragmentShader);
         this._gl.deleteShader(fragmentShader);
 
 
@@ -589,9 +599,9 @@
         return texture;
         return texture;
     };
     };
 
 
-    BABYLON.Engine.prototype.updateDynamicTexture = function (texture, canvas) {
+    BABYLON.Engine.prototype.updateDynamicTexture = function (texture, canvas, invertY) {
         this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
         this._gl.bindTexture(this._gl.TEXTURE_2D, texture);
-        this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, true);
+        this._gl.pixelStorei(this._gl.UNPACK_FLIP_Y_WEBGL, invertY);
         this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, canvas);
         this._gl.texImage2D(this._gl.TEXTURE_2D, 0, this._gl.RGBA, this._gl.RGBA, this._gl.UNSIGNED_BYTE, canvas);
         if (texture.generateMipMaps) {
         if (texture.generateMipMaps) {
             this._gl.generateMipmap(this._gl.TEXTURE_2D);
             this._gl.generateMipmap(this._gl.TEXTURE_2D);

+ 60 - 37
Babylon/babylon.scene.js

@@ -17,7 +17,7 @@
         this._renderTargetsDuration = 0;
         this._renderTargetsDuration = 0;
         this._renderDuration = 0;
         this._renderDuration = 0;
 
 
-        this._toBeDisposed = [];
+        this._toBeDisposed = new BABYLON.Tools.SmartArray(256);
 
 
         this._onReadyCallbacks = [];
         this._onReadyCallbacks = [];
         this._pendingData = [];
         this._pendingData = [];
@@ -40,7 +40,15 @@
 
 
         // Meshes
         // Meshes
         this.meshes = [];
         this.meshes = [];
-        this._activeMeshes = [];
+        
+        // Internal smart arrays
+        this._activeMeshes = new BABYLON.Tools.SmartArray(256);
+        this._opaqueSubMeshes = new BABYLON.Tools.SmartArray(256);
+        this._transparentSubMeshes = new BABYLON.Tools.SmartArray(256);
+        this._alphaTestSubMeshes = new BABYLON.Tools.SmartArray(256);
+        this._processedMaterials = new BABYLON.Tools.SmartArray(256);
+        this._renderTargets = new BABYLON.Tools.SmartArray(256);
+        this._activeParticleSystems = new BABYLON.Tools.SmartArray(256);
 
 
         // Materials
         // Materials
         this.materials = [];
         this.materials = [];
@@ -66,6 +74,13 @@
 
 
         // Animations
         // Animations
         this._activeAnimatables = [];
         this._activeAnimatables = [];
+        
+        // Matrices
+        this._transformMatrix = BABYLON.Matrix.Zero();
+        
+        // Internals
+        this._scaledPosition = BABYLON.Vector3.Zero();
+        this._scaledVelocity = BABYLON.Vector3.Zero();
     };
     };
 
 
     // Properties   
     // Properties   
@@ -129,6 +144,10 @@
         return true;
         return true;
     };
     };
 
 
+    BABYLON.Scene.prototype.getWaitingItemsCount = function() {
+        return this._pendingData.length;
+    };
+
     BABYLON.Scene.prototype.executeWhenReady = function (func) {
     BABYLON.Scene.prototype.executeWhenReady = function (func) {
         if (this.isReady()) {
         if (this.isReady()) {
             func();
             func();
@@ -233,7 +252,7 @@
         this._viewMatrix = view;
         this._viewMatrix = view;
         this._projectionMatrix = projection;
         this._projectionMatrix = projection;
 
 
-        this._transformMatrix = this._viewMatrix.multiply(this._projectionMatrix);
+        this._viewMatrix.multiplyToRef(this._projectionMatrix, this._transformMatrix);
     };
     };
 
 
     // Methods
     // Methods
@@ -302,15 +321,19 @@
     };
     };
 
 
     BABYLON.Scene.prototype._evaluateActiveMeshes = function () {
     BABYLON.Scene.prototype._evaluateActiveMeshes = function () {
-        this._activeMeshes = [];
-        this._opaqueSubMeshes = [];
-        this._transparentSubMeshes = [];
-        this._alphaTestSubMeshes = [];
-        this._processedMaterials = [];
-        this._renderTargets = [];
-        this._activeParticleSystems = [];
+        this._activeMeshes.reset();
+        this._opaqueSubMeshes.reset();
+        this._transparentSubMeshes.reset();
+        this._alphaTestSubMeshes.reset();
+        this._processedMaterials.reset();
+        this._renderTargets.reset();
+        this._activeParticleSystems.reset();
 
 
-        var frustumPlanes = BABYLON.Frustum.GetPlanes(this._transformMatrix);
+        if (!this._frustumPlanes) {
+            this._frustumPlanes = BABYLON.Frustum.GetPlanes(this._transformMatrix);
+        } else {
+            BABYLON.Frustum.GetPlanesToRef(this._transformMatrix, this._frustumPlanes);
+        }
 
 
         this._totalVertices = 0;
         this._totalVertices = 0;
         this._activeVertices = 0;
         this._activeVertices = 0;
@@ -327,11 +350,11 @@
 
 
             mesh.computeWorldMatrix();
             mesh.computeWorldMatrix();
 
 
-            if (mesh.isEnabled() && mesh.isVisible && mesh.visibility > 0 && mesh.isInFrustrum(frustumPlanes)) {
+            if (mesh.isEnabled() && mesh.isVisible && mesh.visibility > 0 && mesh.isInFrustrum(this._frustumPlanes)) {
                 for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                 for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
                     var subMesh = mesh.subMeshes[subIndex];
                     var subMesh = mesh.subMeshes[subIndex];
 
 
-                    if (mesh.subMeshes.length == 1 || subMesh.isInFrustrum(frustumPlanes)) {
+                    if (mesh.subMeshes.length == 1 || subMesh.isInFrustrum(this._frustumPlanes)) {
                         var material = subMesh.getMaterial();
                         var material = subMesh.getMaterial();
 
 
                         if (this._activeMeshes.indexOf(mesh) === -1) {
                         if (this._activeMeshes.indexOf(mesh) === -1) {
@@ -344,7 +367,7 @@
                                 if (this._processedMaterials.indexOf(material) === -1) {
                                 if (this._processedMaterials.indexOf(material) === -1) {
                                     this._processedMaterials.push(material);
                                     this._processedMaterials.push(material);
 
 
-                                    this._renderTargets = this._renderTargets.concat(material.getRenderTargetTextures());
+                                    this._renderTargets.concat(material.getRenderTargetTextures());
                                 }
                                 }
                             }
                             }
 
 
@@ -385,7 +408,7 @@
         var subIndex;
         var subIndex;
         var submesh;
         var submesh;
         for (subIndex = 0; subIndex < opaqueSubMeshes.length; subIndex++) {
         for (subIndex = 0; subIndex < opaqueSubMeshes.length; subIndex++) {
-            submesh = opaqueSubMeshes[subIndex];
+            submesh = opaqueSubMeshes.data[subIndex];
             this._activeVertices += submesh.verticesCount;
             this._activeVertices += submesh.verticesCount;
 
 
             submesh.render();
             submesh.render();
@@ -394,7 +417,7 @@
         // Alpha test
         // Alpha test
         engine.setAlphaTesting(true);
         engine.setAlphaTesting(true);
         for (subIndex = 0; subIndex < alphaTestSubMeshes.length; subIndex++) {
         for (subIndex = 0; subIndex < alphaTestSubMeshes.length; subIndex++) {
-            submesh = alphaTestSubMeshes[subIndex];
+            submesh = alphaTestSubMeshes.data[subIndex];
             this._activeVertices += submesh.verticesCount;
             this._activeVertices += submesh.verticesCount;
 
 
             submesh.render();
             submesh.render();
@@ -415,7 +438,7 @@
         // Transparent
         // Transparent
         engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
         engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
         for (subIndex = 0; subIndex < transparentSubMeshes.length; subIndex++) {
         for (subIndex = 0; subIndex < transparentSubMeshes.length; subIndex++) {
-            submesh = transparentSubMeshes[subIndex];
+            submesh = transparentSubMeshes.data[subIndex];
             this._activeVertices += submesh.verticesCount;
             this._activeVertices += submesh.verticesCount;
 
 
             submesh.render();
             submesh.render();
@@ -425,7 +448,7 @@
         // Particles
         // Particles
         var beforeParticlesDate = new Date();
         var beforeParticlesDate = new Date();
         for (var particleIndex = 0; particleIndex < this._activeParticleSystems.length; particleIndex++) {
         for (var particleIndex = 0; particleIndex < this._activeParticleSystems.length; particleIndex++) {
-            var particleSystem = this._activeParticleSystems[particleIndex];
+            var particleSystem = this._activeParticleSystems.data[particleIndex];
 
 
             if (!particleSystem.emitter.position || !activeMeshes || activeMeshes.indexOf(particleSystem.emitter) !== -1) {
             if (!particleSystem.emitter.position || !activeMeshes || activeMeshes.indexOf(particleSystem.emitter) !== -1) {
                 this._activeParticles += particleSystem.render();
                 this._activeParticles += particleSystem.render();
@@ -477,7 +500,7 @@
         // Render targets
         // Render targets
         var beforeRenderTargetDate = new Date();
         var beforeRenderTargetDate = new Date();
         for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
         for (var renderIndex = 0; renderIndex < this._renderTargets.length; renderIndex++) {
-            var renderTarget = this._renderTargets[renderIndex];
+            var renderTarget = this._renderTargets.data[renderIndex];
 
 
             renderTarget.render();
             renderTarget.render();
         }
         }
@@ -533,9 +556,10 @@
         // Cleaning
         // Cleaning
         for (var index = 0; index < this._toBeDisposed.length; index++) {
         for (var index = 0; index < this._toBeDisposed.length; index++) {
             this._toBeDisposed[index].dispose();
             this._toBeDisposed[index].dispose();
+            this._toBeDisposed[index] = null;
         }
         }
 
 
-        this._toBeDisposed = [];
+        this._toBeDisposed.reset();
 
 
         this._lastFrameDuration = new Date() - startDate;
         this._lastFrameDuration = new Date() - startDate;
     };
     };
@@ -594,25 +618,24 @@
     };
     };
 
 
     // Collisions
     // Collisions
-    BABYLON.Scene.prototype._getNewPosition = function (position, velocity, collider, maximumRetry) {
-        var scaledPosition = position.divide(collider.radius);
-        var scaledVelocity = velocity.divide(collider.radius);
+    BABYLON.Scene.prototype._getNewPosition = function (position, velocity, collider, maximumRetry, finalPosition) {
+        position.divideToRef(collider.radius, this._scaledPosition);
+        velocity.divideToRef(collider.radius, this._scaledVelocity);
 
 
         collider.retry = 0;
         collider.retry = 0;
-        collider.initialVelocity = scaledVelocity;
-        collider.initialPosition = scaledPosition;
-        var finalPosition = this._collideWithWorld(scaledPosition, scaledVelocity, collider, maximumRetry);
-
-        finalPosition = finalPosition.multiply(collider.radius);
+        collider.initialVelocity = this._scaledVelocity;
+        collider.initialPosition = this._scaledPosition;
+        this._collideWithWorld(this._scaledPosition, this._scaledVelocity, collider, maximumRetry, finalPosition);
 
 
-        return finalPosition;
+        finalPosition.multiplyInPlace(collider.radius);
     };
     };
 
 
-    BABYLON.Scene.prototype._collideWithWorld = function (position, velocity, collider, maximumRetry) {
+    BABYLON.Scene.prototype._collideWithWorld = function (position, velocity, collider, maximumRetry, finalPosition) {
         var closeDistance = BABYLON.Engine.collisionsEpsilon * 10.0;
         var closeDistance = BABYLON.Engine.collisionsEpsilon * 10.0;
 
 
         if (collider.retry >= maximumRetry) {
         if (collider.retry >= maximumRetry) {
-            return position;
+            finalPosition.copyFrom(position);
+            return;
         }
         }
 
 
         collider._initialize(position, velocity, closeDistance);
         collider._initialize(position, velocity, closeDistance);
@@ -626,21 +649,21 @@
         }
         }
 
 
         if (!collider.collisionFound) {
         if (!collider.collisionFound) {
-            return position.add(velocity);
+            position.addToRef(velocity, finalPosition);
+            return;
         }
         }
 
 
         if (velocity.x != 0 || velocity.y != 0 || velocity.z != 0) {
         if (velocity.x != 0 || velocity.y != 0 || velocity.z != 0) {
-            var response = collider._getResponse(position, velocity);
-            position = response.position;
-            velocity = response.velocity;
+            collider._getResponse(position, velocity);
         }
         }
 
 
         if (velocity.length() <= closeDistance) {
         if (velocity.length() <= closeDistance) {
-            return position;
+            finalPosition.copyFrom(position);
+            return;
         }
         }
 
 
         collider.retry++;
         collider.retry++;
-        return this._collideWithWorld(position, velocity, collider, maximumRetry);
+        this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition);
     };
     };
 
 
     // Picking
     // Picking

+ 129 - 0
Samples/Scenes/Customs/charting.js

@@ -0,0 +1,129 @@
+var CreateChartingTestScene = function (engine) {
+    var scene = new BABYLON.Scene(engine);
+    var light = new BABYLON.DirectionalLight("dir01", new BABYLON.Vector3(0, -0.5, 1.0), scene);
+    var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0, 10, BABYLON.Vector3.Zero(), scene);
+    camera.setPosition(new BABYLON.Vector3(20, 70, -100));
+    light.position = new BABYLON.Vector3(0, 25, -50);
+    
+    // Data
+    var scale = 0.6;
+    var operatingSystem_Series = [
+        { label: "Macintosh", value: 12, color: new BABYLON.Color3(0, 1, 0) },
+        { label: "Windows", value: 77, color: new BABYLON.Color3(1, 0, 0) },
+        { label: "Linux", value: 4, color: new BABYLON.Color3(1, 0, 1) },
+        { label: "iOS", value: 3, color: new BABYLON.Color3(1, 1, 0) },
+        { label: "Android", value: 2, color: new BABYLON.Color3(0, 0, 1) },
+        { label: "Win Phone", value: 1, color: new BABYLON.Color3(1, 1, 1) }
+    ];
+    
+    var browsers_Series = [
+        { label: "IE", value: 32, color: new BABYLON.Color3(0, 0, 1) },
+        { label: "Chrome", value: 28, color: new BABYLON.Color3(1, 0, 0) },
+        { label: "Firefox", value: 16, color: new BABYLON.Color3(1, 0, 1) },
+        { label: "Opera", value: 14, color: new BABYLON.Color3(1, 1, 0) },
+        { label: "Safari", value: 10, color: new BABYLON.Color3(0, 1, 1) }        
+    ];
+    
+    var playgroundSize = 100;
+    // Background
+    var background = BABYLON.Mesh.CreatePlane("background", playgroundSize, scene, false);
+    background.material = new BABYLON.StandardMaterial("background", scene);
+    background.scaling.y = 0.5;
+    background.position.z = playgroundSize / 2 - 0.5;
+    background.position.y = playgroundSize / 4;
+    background.receiveShadows = true;
+    var backgroundTexture = new BABYLON.DynamicTexture("dynamic texture", 512, scene, true);
+    background.material.diffuseTexture = backgroundTexture;
+    background.material.specularColor = new BABYLON.Color3(0, 0, 0);
+    background.material.backFaceCulling = false;
+
+    backgroundTexture.drawText("Eternalcoding", null, 80, "bold 70px Segoe UI", "white", "#555555");
+    backgroundTexture.drawText("- browsers statistics -", null, 250, "35px Segoe UI", "white", null);
+    //background.material.reflectionTexture = new BABYLON.MirrorTexture("mirror", 1024, scene, true);
+    //background.material.reflectionTexture.mirrorPlane = new BABYLON.Plane(0, 0, 1.0, -playgroundSize / 2 + 0.5);
+    //background.material.reflectionTexture.level = 0.5;
+
+    // Ground    
+    var ground = BABYLON.Mesh.CreateGround("ground", playgroundSize, playgroundSize, 1, scene, false);
+    var groundMaterial = new BABYLON.StandardMaterial("ground", scene);
+    groundMaterial.diffuseColor = new BABYLON.Color3(0.5, 0.5, 0.5);
+    groundMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
+    ground.material = groundMaterial;
+    ground.receiveShadows = true;
+    ground.position.y = -0.1;
+    //background.material.reflectionTexture.renderList.push(ground);
+    
+    var shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
+
+    var createSeries = function (series) {
+        var margin = 2;
+        var offset = playgroundSize / (series.length) - margin;
+        var x = -playgroundSize / 2 + offset / 2;
+
+        for (var index = 0; index < series.length; index++) {
+            var data = series[index];
+
+            var bar = BABYLON.Mesh.CreateBox(data.label, 1.0, scene, false);
+            bar.scaling = new BABYLON.Vector3(offset / 2.0, 0, offset / 2.0);
+            bar.position.x = x;
+            bar.position.y = 0;
+            
+            // Animate a bit
+            var animation = new BABYLON.Animation("anim", "scaling", 30, BABYLON.Animation.ANIMATIONTYPE_VECTOR3);
+            animation.setKeys([
+                { frame: 0, value: new BABYLON.Vector3(offset / 2.0, 0, offset / 2.0) },
+                { frame: 100, value: new BABYLON.Vector3(offset / 2.0, data.value * scale, offset / 2.0) }]);
+            bar.animations.push(animation);
+            
+            animation = new BABYLON.Animation("anim2", "position.y", 30, BABYLON.Animation.ANIMATIONTYPE_FLOAT);
+            animation.setKeys([
+                { frame: 0, value: 0 },
+                { frame: 100, value: (data.value * scale) / 2 }]);
+            bar.animations.push(animation);            
+            scene.beginAnimation(bar, 0, 100, false, 2.0);
+
+            // Material
+            bar.material = new BABYLON.StandardMaterial(data.label + "mat", scene);
+            bar.material.diffuseColor = data.color;
+            bar.material.emissiveColor = data.color.scale(0.3);
+            bar.material.specularColor = new BABYLON.Color3(0, 0, 0);
+
+            // Shadows
+            shadowGenerator.getShadowMap().renderList.push(bar);
+            
+            // Mirror
+          //  background.material.reflectionTexture.renderList.push(bar);
+            
+            // Legend
+            var barLegend = BABYLON.Mesh.CreateGround(data.label + "Legend", playgroundSize / 2, offset * 2, 1, scene, false);
+            barLegend.position.x = x;
+            barLegend.position.z = -playgroundSize / 4;
+            barLegend.rotation.y = Math.PI / 2;
+            
+            barLegend.material = new BABYLON.StandardMaterial(data.label + "LegendMat", scene);
+            var barLegendTexture = new BABYLON.DynamicTexture("dynamic texture", 512, scene, true);
+            barLegendTexture.hasAlpha = true;
+            barLegend.material.diffuseTexture = barLegendTexture;
+            barLegend.material.emissiveColor = new BABYLON.Color3(0.4, 0.4, 0.4);
+            
+            var size = barLegendTexture.getSize();
+            barLegendTexture.drawText(data.label + " (" + data.value + "%)", 80, size.height / 2 + 30, "bold 50px Segoe UI", "white", "transparent");
+         //   background.material.reflectionTexture.renderList.push(barLegend);
+            
+            // Going next
+            x += offset + margin;
+        }
+    };
+
+    createSeries(browsers_Series);
+
+    // Limit camera
+    camera.lowerAlphaLimit = Math.PI;
+    camera.upperAlphaLimit = 2 * Math.PI;
+    camera.lowerBetaLimit = 0.1;
+    camera.upperBetaLimit = (Math.PI / 2) * 0.99;
+    camera.lowerRadiusLimit = 5;
+    camera.upperRadiusLimit = 150;
+
+    return scene;
+};

+ 1 - 1
Samples/Scenes/Customs/test.js

@@ -149,7 +149,7 @@
             spaceDek3.rotation.y -= 0.01;
             spaceDek3.rotation.y -= 0.01;
         }
         }
         
         
-        if (torus.intersectsMesh(box)) {
+        if (torus.intersectsMesh(box, true)) {
             material2.alpha = 1;
             material2.alpha = 1;
             torus.scaling = new BABYLON.Vector3(2, 2, 2);
             torus.scaling = new BABYLON.Vector3(2, 2, 2);
         } else {
         } else {

BIN
Samples/Screenshots/charting.jpg


File diff suppressed because it is too large
+ 2 - 2
Samples/babylon.js


+ 1 - 1
Samples/index.html

@@ -28,7 +28,6 @@
     <script src="Babylon/Lights/babylon.hemisphericLight.js"></script>
     <script src="Babylon/Lights/babylon.hemisphericLight.js"></script>
     <script src="Babylon/Lights/babylon.directionalLight.js"></script>
     <script src="Babylon/Lights/babylon.directionalLight.js"></script>
     <script src="Babylon/Lights/Shadows/babylon.shadowGenerator.js"></script>
     <script src="Babylon/Lights/Shadows/babylon.shadowGenerator.js"></script>
-    <script src="Babylon/Collisions/babylon.collisionPlane.js"></script>
     <script src="Babylon/Collisions/babylon.collider.js"></script>
     <script src="Babylon/Collisions/babylon.collider.js"></script>
     <script src="Babylon/Cameras/babylon.camera.js"></script>
     <script src="Babylon/Cameras/babylon.camera.js"></script>
     <script src="Babylon/Cameras/babylon.freeCamera.js"></script>
     <script src="Babylon/Cameras/babylon.freeCamera.js"></script>
@@ -64,6 +63,7 @@
     <script src="Scenes/Customs/multimat.js"></script>
     <script src="Scenes/Customs/multimat.js"></script>
     <script src="Scenes/Customs/heightMap_test.js"></script>
     <script src="Scenes/Customs/heightMap_test.js"></script>
     <script src="Scenes/Customs/shadows.js"></script>
     <script src="Scenes/Customs/shadows.js"></script>
+    <script src="Scenes/Customs/charting.js"></script>
     <script src="index.js"></script>
     <script src="index.js"></script>
 </head>
 </head>
 <body onload="onload();">
 <body onload="onload();">

+ 44 - 37
Samples/index.js

@@ -27,6 +27,7 @@
         }];
         }];
 
 
     var tests = [
     var tests = [
+        { title: "CHARTING", id: 7, screenshot: "charting.jpg", size: "1.0 MB" },
         { title: "SHADOWS", id: 6, screenshot: "shadows.jpg", size: "1.0 MB" },
         { title: "SHADOWS", id: 6, screenshot: "shadows.jpg", size: "1.0 MB" },
         { title: "HEIGHTMAP", id: 5, screenshot: "heightmap.jpg", size: "1.0 MB" },
         { title: "HEIGHTMAP", id: 5, screenshot: "heightmap.jpg", size: "1.0 MB" },
         { title: "LIGHTS", id: 1, screenshot: "testlight.jpg", size: "0.1 MB" },
         { title: "LIGHTS", id: 1, screenshot: "testlight.jpg", size: "0.1 MB" },
@@ -202,6 +203,9 @@
                     case 6:
                     case 6:
                         newScene = CreateShadowsTestScene(engine);
                         newScene = CreateShadowsTestScene(engine);
                         break;
                         break;
+                    case 7:
+                        newScene = CreateChartingTestScene(engine);
+                        break;
                 }
                 }
 
 
                 newScene.activeCamera.attachControl(canvas);
                 newScene.activeCamera.attachControl(canvas);
@@ -222,7 +226,7 @@
             BABYLON.SceneLoader.Load("Scenes/" + name + "/", name + ".babylon", engine, function (newScene) {
             BABYLON.SceneLoader.Load("Scenes/" + name + "/", name + ".babylon", engine, function (newScene) {
                 scene = newScene;
                 scene = newScene;
                 scene.fogMode = BABYLON.Scene.FOGMODE_NONE;
                 scene.fogMode = BABYLON.Scene.FOGMODE_NONE;
-                loadingText.innerHTML = "Streaming textures...";
+                loadingText.innerHTML = "Streaming textures..." + scene.getWaitingItemsCount() + " remaining";
                 scene.executeWhenReady(function () {
                 scene.executeWhenReady(function () {
                     if (scene.activeCamera) {
                     if (scene.activeCamera) {
                         scene.activeCamera.attachControl(canvas);
                         scene.activeCamera.attachControl(canvas);
@@ -256,48 +260,51 @@
         loadingText.className = "";
         loadingText.className = "";
         opacityMask.className = "";
         opacityMask.className = "";
         loadingText.innerHTML = "Loading, please wait...";
         loadingText.innerHTML = "Loading, please wait...";
+    };
 
 
-        // Render loop
-        var renderFunction = function () {
-            // Fps
-            divFps.innerHTML = BABYLON.Tools.GetFps().toFixed() + " fps";
-
-            // Render scene
-            if (scene) {
-                scene.render();
-
-                // Stats
-                if (enableStats.checked) {
-                    stats.innerHTML = "Total vertices: " + scene.getTotalVertices() + "<br>"
-                        + "Active vertices: " + scene.getActiveVertices() + "<br>"
-                        + "Active particles: " + scene.getActiveParticles() + "<br><br><br>"
-                        + "Frame duration: " + scene.getLastFrameDuration() + " ms<br><br>"
-                        + "<i>Evaluate Active Meshes duration:</i> " + scene.getEvaluateActiveMeshesDuration() + " ms<br>"
-                        + "<i>Render Targets duration:</i> " + scene.getRenderTargetsDuration() + " ms<br>"
-                        + "<i>Particles duration:</i> " + scene.getParticlesDuration() + " ms<br>"
-                        + "<i>Sprites duration:</i> " + scene.getSpritesDuration() + " ms<br>"
-                        + "<i>Render duration:</i> " + scene.getRenderDuration() + " ms";
-                }
+    // Render loop
+    var renderFunction = function () {
+        // Fps
+        divFps.innerHTML = BABYLON.Tools.GetFps().toFixed() + " fps";
+
+        // Render scene
+        if (scene) {
+            if (!scene.isReady()) {
+                loadingText.innerHTML = "Streaming textures...(" + scene.getWaitingItemsCount() + " remaining)";
             }
             }
-        };
 
 
-        // Launch render loop
-        engine.runRenderLoop(renderFunction);
+            scene.render();
+
+            // Stats
+            if (enableStats.checked) {
+                stats.innerHTML = "Total vertices: " + scene.getTotalVertices() + "<br>"
+                    + "Active vertices: " + scene.getActiveVertices() + "<br>"
+                    + "Active particles: " + scene.getActiveParticles() + "<br><br><br>"
+                    + "Frame duration: " + scene.getLastFrameDuration() + " ms<br><br>"
+                    + "<i>Evaluate Active Meshes duration:</i> " + scene.getEvaluateActiveMeshesDuration() + " ms<br>"
+                    + "<i>Render Targets duration:</i> " + scene.getRenderTargetsDuration() + " ms<br>"
+                    + "<i>Particles duration:</i> " + scene.getParticlesDuration() + " ms<br>"
+                    + "<i>Sprites duration:</i> " + scene.getSpritesDuration() + " ms<br>"
+                    + "<i>Render duration:</i> " + scene.getRenderDuration() + " ms";
+            }
+        }
+    };
 
 
-        // Resize
-        window.addEventListener("resize", function () {
-            engine.resize();
-        });
+    // Launch render loop
+    engine.runRenderLoop(renderFunction);
 
 
+    // Resize
+    window.addEventListener("resize", function () {
+        engine.resize();
+    });
 
 
-        // Caps
-        var caps = engine.getCaps();
-        document.getElementById("extensions").innerHTML =
-                "Max textures image units: <b>" + caps.maxTexturesImageUnits + "</b><br>" +
-                "Max texture size: <b>" + caps.maxTextureSize + "</b><br>" +
-                "Max cubemap texture size: <b>" + caps.maxCubemapTextureSize + "</b><br>" +
-                "Max render texture size: <b>" + caps.maxRenderTextureSize + "</b><br>";
-    }
+    // Caps
+    var caps = engine.getCaps();
+    document.getElementById("extensions").innerHTML =
+            "Max textures image units: <b>" + caps.maxTexturesImageUnits + "</b><br>" +
+            "Max texture size: <b>" + caps.maxTextureSize + "</b><br>" +
+            "Max cubemap texture size: <b>" + caps.maxCubemapTextureSize + "</b><br>" +
+            "Max render texture size: <b>" + caps.maxRenderTextureSize + "</b><br>";
 
 
     // UI
     // UI
 
 

File diff suppressed because it is too large
+ 0 - 13
babylon.1.1.0.js


File diff suppressed because it is too large
+ 13 - 0
babylon.1.2.0.js


+ 4 - 0
what's new.txt

@@ -1,3 +1,7 @@
+1.2.0:
+ - Major rework of the API to remove GC pressure.
+ - FreeCamera: Support for QWERTY keyboards
+ - New 3D charting demo
 1.1.0:
 1.1.0:
  - Shadow Maps and Variance Shadow Maps
  - Shadow Maps and Variance Shadow Maps
  - Shadows Maps and animations are now exported from Blender
  - Shadows Maps and animations are now exported from Blender