Przeglądaj źródła

Merge remote-tracking branch 'upstream/master' into bmfontbug

nockawa 8 lat temu
rodzic
commit
c57afdd41d

+ 4 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonPBRMaterial.cs

@@ -152,6 +152,9 @@ namespace BabylonExport.Entities
         public bool useRadianceOverAlpha { get; set; }
         public bool useRadianceOverAlpha { get; set; }
 
 
         [DataMember]
         [DataMember]
+        public bool usePhysicalLightFalloff { get; set; }
+
+        [DataMember]
         public float indexOfRefraction { get; set; }
         public float indexOfRefraction { get; set; }
 
 
         [DataMember]
         [DataMember]
@@ -179,6 +182,7 @@ namespace BabylonExport.Entities
             indexOfRefraction = 0.66f;
             indexOfRefraction = 0.66f;
             useRadianceOverAlpha = true;
             useRadianceOverAlpha = true;
             useSpecularOverAlpha = true;
             useSpecularOverAlpha = true;
+            usePhysicalLightFalloff = true;
             useEmissiveAsIllumination = false;
             useEmissiveAsIllumination = false;
 
 
             // Default Null Metallic Workflow
             // Default Null Metallic Workflow

+ 3 - 3
Tools/Gulp/package.json

@@ -8,10 +8,10 @@
   "license": "(Apache-2.0)",
   "license": "(Apache-2.0)",
   "devDependencies": {
   "devDependencies": {
     "gulp": "^3.8.11",
     "gulp": "^3.8.11",
-    "gulp-uglify": "~1.5.3",
+    "gulp-uglify": "^2.0.1",
     "gulp-sourcemaps": "~1.9.1",
     "gulp-sourcemaps": "~1.9.1",
-    "typescript": "^2.1.4",
-    "gulp-typescript": "^3.1.3",
+    "typescript": "~2.1.4",
+    "gulp-typescript": "^3.1.5",
     "through2": "~0.6.5",
     "through2": "~0.6.5",
     "gulp-util": "~3.0.4",
     "gulp-util": "~3.0.4",
     "gulp-concat": "~2.5.2",
     "gulp-concat": "~2.5.2",

+ 3 - 2
canvas2D/src/Engine/babylon.sprite2d.ts

@@ -355,8 +355,9 @@
             super(settings);
             super(settings);
 
 
             this.texture = texture;
             this.texture = texture;
-            this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
-            this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
+            // This is removed to let the user the possibility to setup the addressing mode he wants
+            //this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
+            //this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
             this._useSize = false;
             this._useSize = false;
             this._spriteSize = (settings.spriteSize!=null) ? settings.spriteSize.clone() : null;
             this._spriteSize = (settings.spriteSize!=null) ? settings.spriteSize.clone() : null;
             this._spriteLocation = (settings.spriteLocation!=null) ? settings.spriteLocation.clone() : new Vector2(0, 0);
             this._spriteLocation = (settings.spriteLocation!=null) ? settings.spriteLocation.clone() : new Vector2(0, 0);

+ 12 - 2
canvas2D/src/Engine/babylon.text2d.ts

@@ -226,7 +226,11 @@
             }
             }
             this._text = value;
             this._text = value;
             this._textSize = null;    // A change of text will reset the TextSize which will be recomputed next time it's used
             this._textSize = null;    // A change of text will reset the TextSize which will be recomputed next time it's used
-            this._size = null;
+
+            if(!this._sizeSetByUser){
+                this._size = null;
+            }
+
             this._updateCharCount();
             this._updateCharCount();
 
 
             // Trigger a textSize to for a sizeChange if necessary, which is needed for layout to recompute
             // Trigger a textSize to for a sizeChange if necessary, which is needed for layout to recompute
@@ -480,7 +484,12 @@
             this._tabulationSize     = (settings.tabulationSize == null) ? 4 : settings.tabulationSize;
             this._tabulationSize     = (settings.tabulationSize == null) ? 4 : settings.tabulationSize;
             this._textSize           = null;
             this._textSize           = null;
             this.text                = text;
             this.text                = text;
-            this.size                = (settings.size==null) ? null : settings.size;
+            if(settings.size != null){
+                this.size = settings.size;
+                this._sizeSetByUser = true;
+            }else{
+                this.size = null;
+            }
             this.textAlignmentH      = (settings.textAlignmentH==null) ? Text2D.AlignLeft : settings.textAlignmentH;
             this.textAlignmentH      = (settings.textAlignmentH==null) ? Text2D.AlignLeft : settings.textAlignmentH;
             this.textAlignmentV      = (settings.textAlignmentV==null) ? Text2D.AlignTop : settings.textAlignmentV;
             this.textAlignmentV      = (settings.textAlignmentV==null) ? Text2D.AlignTop : settings.textAlignmentV;
             this.textAlignment       = (settings.textAlignment==null) ? "" : settings.textAlignment;
             this.textAlignment       = (settings.textAlignment==null) ? "" : settings.textAlignment;
@@ -866,6 +875,7 @@
         private _textSize: Size;
         private _textSize: Size;
         private _wordWrap: boolean;
         private _wordWrap: boolean;
         private _textAlignment: string;
         private _textAlignment: string;
+        private _sizeSetByUser: boolean;
 
 
         public textAlignmentH: number;
         public textAlignmentH: number;
         public textAlignmentV: number;
         public textAlignmentV: number;

Plik diff jest za duży
+ 25 - 25
dist/preview release/babylon.core.js


Plik diff jest za duży
+ 1038 - 1009
dist/preview release/babylon.d.ts


Plik diff jest za duży
+ 35 - 35
dist/preview release/babylon.js


Plik diff jest za duży
+ 177 - 75
dist/preview release/babylon.max.js


Plik diff jest za duży
+ 1038 - 1009
dist/preview release/babylon.module.d.ts


Plik diff jest za duży
+ 34 - 34
dist/preview release/babylon.noworker.js


+ 1 - 0
dist/preview release/canvas2D/babylon.canvas2d.d.ts

@@ -4136,6 +4136,7 @@ declare module BABYLON {
         private _textSize;
         private _textSize;
         private _wordWrap;
         private _wordWrap;
         private _textAlignment;
         private _textAlignment;
+        private _sizeSetByUser;
         textAlignmentH: number;
         textAlignmentH: number;
         textAlignmentV: number;
         textAlignmentV: number;
     }
     }

+ 13 - 4
dist/preview release/canvas2D/babylon.canvas2d.js

@@ -13473,8 +13473,9 @@ var BABYLON;
             }
             }
             _this = _super.call(this, settings) || this;
             _this = _super.call(this, settings) || this;
             _this.texture = texture;
             _this.texture = texture;
-            _this.texture.wrapU = BABYLON.Texture.CLAMP_ADDRESSMODE;
-            _this.texture.wrapV = BABYLON.Texture.CLAMP_ADDRESSMODE;
+            // This is removed to let the user the possibility to setup the addressing mode he wants
+            //this.texture.wrapU = Texture.CLAMP_ADDRESSMODE;
+            //this.texture.wrapV = Texture.CLAMP_ADDRESSMODE;
             _this._useSize = false;
             _this._useSize = false;
             _this._spriteSize = (settings.spriteSize != null) ? settings.spriteSize.clone() : null;
             _this._spriteSize = (settings.spriteSize != null) ? settings.spriteSize.clone() : null;
             _this._spriteLocation = (settings.spriteLocation != null) ? settings.spriteLocation.clone() : new BABYLON.Vector2(0, 0);
             _this._spriteLocation = (settings.spriteLocation != null) ? settings.spriteLocation.clone() : new BABYLON.Vector2(0, 0);
@@ -14327,7 +14328,13 @@ var BABYLON;
             _this._tabulationSize = (settings.tabulationSize == null) ? 4 : settings.tabulationSize;
             _this._tabulationSize = (settings.tabulationSize == null) ? 4 : settings.tabulationSize;
             _this._textSize = null;
             _this._textSize = null;
             _this.text = text;
             _this.text = text;
-            _this.size = (settings.size == null) ? null : settings.size;
+            if (settings.size != null) {
+                _this.size = settings.size;
+                _this._sizeSetByUser = true;
+            }
+            else {
+                _this.size = null;
+            }
             _this.textAlignmentH = (settings.textAlignmentH == null) ? Text2D_1.AlignLeft : settings.textAlignmentH;
             _this.textAlignmentH = (settings.textAlignmentH == null) ? Text2D_1.AlignLeft : settings.textAlignmentH;
             _this.textAlignmentV = (settings.textAlignmentV == null) ? Text2D_1.AlignTop : settings.textAlignmentV;
             _this.textAlignmentV = (settings.textAlignmentV == null) ? Text2D_1.AlignTop : settings.textAlignmentV;
             _this.textAlignment = (settings.textAlignment == null) ? "" : settings.textAlignment;
             _this.textAlignment = (settings.textAlignment == null) ? "" : settings.textAlignment;
@@ -14413,7 +14420,9 @@ var BABYLON;
                 }
                 }
                 this._text = value;
                 this._text = value;
                 this._textSize = null; // A change of text will reset the TextSize which will be recomputed next time it's used
                 this._textSize = null; // A change of text will reset the TextSize which will be recomputed next time it's used
-                this._size = null;
+                if (!this._sizeSetByUser) {
+                    this._size = null;
+                }
                 this._updateCharCount();
                 this._updateCharCount();
                 // Trigger a textSize to for a sizeChange if necessary, which is needed for layout to recompute
                 // Trigger a textSize to for a sizeChange if necessary, which is needed for layout to recompute
                 var s = this.textSize;
                 var s = this.textSize;

Plik diff jest za duży
+ 6 - 6
dist/preview release/canvas2D/babylon.canvas2d.min.js


Plik diff jest za duży
+ 3 - 3
dist/preview release/inspector/babylon.inspector.bundle.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/inspector/babylon.inspector.min.js


+ 1 - 4
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -497,9 +497,6 @@ var BABYLON;
         var nodesToRootToAdd = [];
         var nodesToRootToAdd = [];
         getNodesToRoot(gltfRuntime, newSkeleton, skins, nodesToRoot);
         getNodesToRoot(gltfRuntime, newSkeleton, skins, nodesToRoot);
         newSkeleton.bones = [];
         newSkeleton.bones = [];
-        if (nodesToRoot.length === 0) {
-            newSkeleton.needInitialSkinMatrix = true;
-        }
         // Joints
         // Joints
         for (var i = 0; i < skins.jointNames.length; i++) {
         for (var i = 0; i < skins.jointNames.length; i++) {
             var jointNode = getJointNode(gltfRuntime, skins.jointNames[i]);
             var jointNode = getJointNode(gltfRuntime, skins.jointNames[i]);
@@ -728,11 +725,11 @@ var BABYLON;
             var mat = BABYLON.Matrix.FromArray(node.matrix);
             var mat = BABYLON.Matrix.FromArray(node.matrix);
             mat.decompose(scaling, rotation, position);
             mat.decompose(scaling, rotation, position);
             configureNode(newNode, position, rotation, scaling);
             configureNode(newNode, position, rotation, scaling);
-            newNode.computeWorldMatrix(true);
         }
         }
         else {
         else {
             configureNode(newNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.FromArray(node.rotation), BABYLON.Vector3.FromArray(node.scale));
             configureNode(newNode, BABYLON.Vector3.FromArray(node.translation), BABYLON.Quaternion.FromArray(node.rotation), BABYLON.Vector3.FromArray(node.scale));
         }
         }
+        newNode.computeWorldMatrix(true);
     };
     };
     /**
     /**
     * Imports a node
     * Imports a node

Plik diff jest za duży
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


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

@@ -25,7 +25,7 @@
 - GroundMesh : `getHeightAtCoordinates()`, `getNormalAtCoordinates()` and `getNormalAtCoordinatesToRef()` can now work with rotated grounds ([jerome](https://github.com/jbousquie))  
 - GroundMesh : `getHeightAtCoordinates()`, `getNormalAtCoordinates()` and `getNormalAtCoordinatesToRef()` can now work with rotated grounds ([jerome](https://github.com/jbousquie))  
 - `GroundMesh`, `facetData` and `SolidParticleSystem` improvement in normal computations ([jerome](https://github.com/jbousquie))   
 - `GroundMesh`, `facetData` and `SolidParticleSystem` improvement in normal computations ([jerome](https://github.com/jbousquie))   
 - Added `AbstractMesh.addRotation()` ([jerome](https://github.com/jbousquie))  
 - Added `AbstractMesh.addRotation()` ([jerome](https://github.com/jbousquie))  
-- Added `Quaternion.QuaternionRotationFromAxis()` and `Quaternion.QuaternionRotationFromAxisToRef()` ([jerome](https://github.com/jbousquie), thanks to [abow](https://github.com/abow))   
+- Added `Quaternion.RotationQuaternionFromAxis()` and `Quaternion.RotationQuaternionFromAxisToRef()` ([jerome](https://github.com/jbousquie), thanks to [abow](https://github.com/abow))   
 - Added `Curve3.CreateCatmullRomSpline()` ([jerome](https://github.com/jbousquie) and [BitOfGold](https://github.com/BitOfGold))  
 - Added `Curve3.CreateCatmullRomSpline()` ([jerome](https://github.com/jbousquie) and [BitOfGold](https://github.com/BitOfGold))  
 - Added the optional parameter`colorFilter` to `CreateGroundFromHeightMap()` ([jerome](https://github.com/jbousquie))  
 - Added the optional parameter`colorFilter` to `CreateGroundFromHeightMap()` ([jerome](https://github.com/jbousquie))  
 - Improved the internal code of `Vector3.RotationFromAxisToRef()` ([jerome](https://github.com/jbousquie), thanks to [abow](https://github.com/abow))   
 - Improved the internal code of `Vector3.RotationFromAxisToRef()` ([jerome](https://github.com/jbousquie), thanks to [abow](https://github.com/abow))   

+ 8 - 1
src/Bones/babylon.bone.ts

@@ -626,13 +626,20 @@ module BABYLON {
 
 
             }else{
             }else{
                 
                 
+                var wm;
+                
+                //mesh.getWorldMatrix() needs to be called before skeleton.computeAbsoluteTransforms()
+                if(mesh){
+                    wm = mesh.getWorldMatrix();
+                }
+                
                 this._skeleton.computeAbsoluteTransforms();
                 this._skeleton.computeAbsoluteTransforms();
                 
                 
                 var tmat = Tmp.Matrix[0];
                 var tmat = Tmp.Matrix[0];
 
 
                 if (mesh) {
                 if (mesh) {
                     tmat.copyFrom(this.getAbsoluteTransform());
                     tmat.copyFrom(this.getAbsoluteTransform());
-                    tmat.multiplyToRef(mesh.getWorldMatrix(), tmat);
+                    tmat.multiplyToRef(wm, tmat);
                 }else{
                 }else{
                     tmat = this.getAbsoluteTransform();
                     tmat = this.getAbsoluteTransform();
                 }
                 }

+ 10 - 0
src/Bones/babylon.skeleton.ts

@@ -16,6 +16,13 @@
 
 
         private _lastAbsoluteTransformsUpdateId = -1;
         private _lastAbsoluteTransformsUpdateId = -1;
 
 
+        // Events
+        /**
+         * An event triggered before computing the skeleton's matrices
+         * @type {BABYLON.Observable}
+         */
+        public onBeforeComputeObservable = new Observable<Skeleton>();
+
         constructor(public name: string, public id: string, scene: Scene) {
         constructor(public name: string, public id: string, scene: Scene) {
             this.bones = [];
             this.bones = [];
 
 
@@ -208,6 +215,9 @@
         }
         }
 
 
         public _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Matrix): void {
         public _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Matrix): void {
+
+            this.onBeforeComputeObservable.notifyObservers(this);
+
             for (var index = 0; index < this.bones.length; index++) {
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var bone = this.bones[index];
                 var parentBone = bone.getParent();
                 var parentBone = bone.getParent();

+ 1 - 1
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -295,7 +295,7 @@
                         continue;
                         continue;
                     }
                     }
 
 
-                    if (this.renderList.indexOf(particleSystem.emitter) >= 0) {
+                    if (currentRenderList.indexOf(particleSystem.emitter) >= 0) {
                         this._renderingManager.dispatchParticles(particleSystem);
                         this._renderingManager.dispatchParticles(particleSystem);
                     }
                     }
                 }
                 }

+ 85 - 22
src/Math/babylon.math.ts

@@ -1603,10 +1603,10 @@
          * The cross product is then orthogonal to both "left" and "right". 
          * The cross product is then orthogonal to both "left" and "right". 
          */
          */
         public static CrossToRef(left: Vector3, right: Vector3, result: Vector3): void {
         public static CrossToRef(left: Vector3, right: Vector3, result: Vector3): void {
-            Tmp.Vector3[0].x = left.y * right.z - left.z * right.y;
-            Tmp.Vector3[0].y = left.z * right.x - left.x * right.z;
-            Tmp.Vector3[0].z = left.x * right.y - left.y * right.x;
-            result.copyFrom(Tmp.Vector3[0]);
+            MathTmp.Vector3[0].x = left.y * right.z - left.z * right.y;
+            MathTmp.Vector3[0].y = left.z * right.x - left.x * right.z;
+            MathTmp.Vector3[0].z = left.x * right.y - left.y * right.x;
+            result.copyFrom(MathTmp.Vector3[0]);
         }
         }
 
 
         /**
         /**
@@ -1735,8 +1735,8 @@
          * The same than RotationFromAxis but updates the passed ref Vector3 parameter instead of returning a new Vector3.  
          * The same than RotationFromAxis but updates the passed ref Vector3 parameter instead of returning a new Vector3.  
          */
          */
         public static RotationFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Vector3): void {
         public static RotationFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Vector3): void {
-            var quat = BABYLON.Tmp.Quaternion[1];
-            Quaternion.QuaternionRotationFromAxisToRef(axis1, axis2, axis3, quat);
+            var quat = MathTmp.Quaternion[0];
+            Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);
             quat.toEulerAnglesToRef(ref);
             quat.toEulerAnglesToRef(ref);
         }
         }
     }
     }
@@ -2598,6 +2598,12 @@
             }
             }
         }
         }
         /**
         /**
+         * Returns a new Quaternion set to (0.0, 0.0, 0.0).  
+         */
+        public static Zero(): Quaternion {
+            return new Quaternion(0.0, 0.0, 0.0, 0.0);
+        }
+        /**
          * Returns a new Quaternion as the inverted current Quaternion.  
          * Returns a new Quaternion as the inverted current Quaternion.  
          */
          */
         public static Inverse(q: Quaternion): Quaternion {
         public static Inverse(q: Quaternion): Quaternion {
@@ -2693,9 +2699,9 @@
          * cf to Vector3.RotationFromAxis() documentation.  
          * cf to Vector3.RotationFromAxis() documentation.  
          * Note : axis1, axis2 and axis3 are normalized during this operation.   
          * Note : axis1, axis2 and axis3 are normalized during this operation.   
          */
          */
-         public static QuaternionRotationFromAxis(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): Quaternion {
+         public static RotationQuaternionFromAxis(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): Quaternion {
             var quat = new Quaternion(0.0, 0.0, 0.0, 0.0);
             var quat = new Quaternion(0.0, 0.0, 0.0, 0.0);
-            Quaternion.QuaternionRotationFromAxisToRef(axis1, axis2, axis3, quat);
+            Quaternion.RotationQuaternionFromAxisToRef(axis1, axis2, axis3, quat);
             return quat;
             return quat;
         }
         }
         /**
         /**
@@ -2703,8 +2709,8 @@
          * cf to Vector3.RotationFromAxis() documentation.  
          * cf to Vector3.RotationFromAxis() documentation.  
          * Note : axis1, axis2 and axis3 are normalized during this operation.   
          * Note : axis1, axis2 and axis3 are normalized during this operation.   
          */
          */
-        public static QuaternionRotationFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): void {
-            var rotMat = Tmp.Matrix[0];
+        public static RotationQuaternionFromAxisToRef(axis1: Vector3, axis2: Vector3, axis3: Vector3, ref: Quaternion): void {
+            var rotMat = MathTmp.Matrix[0];
             BABYLON.Matrix.FromXYZAxesToRef(axis1.normalize(), axis2.normalize(), axis3.normalize(), rotMat);
             BABYLON.Matrix.FromXYZAxesToRef(axis1.normalize(), axis2.normalize(), axis3.normalize(), rotMat);
             BABYLON.Quaternion.FromRotationMatrixToRef(rotMat, ref);
             BABYLON.Quaternion.FromRotationMatrixToRef(rotMat, ref);
         }
         }
@@ -2915,6 +2921,16 @@
             return this;
             return this;
         }
         }
         /**
         /**
+         * Inserts the translation vector (using 3 x floats) in the current Matrix.  
+         * Returns the updated Matrix.  
+         */
+        public setTranslationFromFloats(x: number, y: number, z: number): Matrix {
+            this.m[12] = x;
+            this.m[13] = y;
+            this.m[14] = z;
+            return this;
+        }
+                /**
          * Inserts the translation vector in the current Matrix.  
          * Inserts the translation vector in the current Matrix.  
          * Returns the updated Matrix.  
          * Returns the updated Matrix.  
          */
          */
@@ -2931,6 +2947,26 @@
             return new Vector3(this.m[12], this.m[13], this.m[14]);
             return new Vector3(this.m[12], this.m[13], this.m[14]);
         }
         }
         /**
         /**
+         * Fill a Vector3 with the extracted translation from the Matrix.  
+         */
+        public getTranslationToRef(result:Vector3): Matrix {
+            result.x = this.m[12];
+            result.y = this.m[13];
+            result.z = this.m[14];
+
+            return this;
+        }
+        /**
+         * Remove rotation and scaling part from the Matrix. 
+         * Returns the updated Matrix. 
+         */
+        public removeRotationAndScaling(): Matrix {
+            this.setRowFromFloats(0, 1, 0, 0, 0);
+            this.setRowFromFloats(1, 0, 1, 0, 0);
+            this.setRowFromFloats(2, 0, 0, 1, 0);
+            return this;
+        }        
+        /**
          * Returns a new Matrix set with the multiplication result of the current Matrix and the passed one.  
          * Returns a new Matrix set with the multiplication result of the current Matrix and the passed one.  
          */
          */
         public multiply(other: Matrix): Matrix {
         public multiply(other: Matrix): Matrix {
@@ -3092,9 +3128,9 @@
                 this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
                 this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
                 this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
                 this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
                 this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
                 this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
-                0, 0, 0, 1, Tmp.Matrix[0]);
+                0, 0, 0, 1, MathTmp.Matrix[0]);
 
 
-            Quaternion.FromRotationMatrixToRef(Tmp.Matrix[0], rotation);
+            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
 
 
             return true;
             return true;
         }
         }
@@ -3208,6 +3244,22 @@
             this.m[i + 3] = row.w;
             this.m[i + 3] = row.w;
             return this;
             return this;
         }
         }
+        
+        /**
+         * Sets the index-th row of the current matrix with the passed 4 x float values.
+         * Returns the updated Matrix.    
+         */
+        public setRowFromFloats(index: number, x: number, y: number, z: number, w: number): Matrix {
+            if (index < 0 || index > 3) {
+                return this;
+            }
+            var i = index * 4;
+            this.m[i + 0] = x;
+            this.m[i + 1] = y;
+            this.m[i + 2] = z;
+            this.m[i + 3] = w;
+            return this;
+        }
         /**
         /**
          * Returns a new Matrix set from the 16 passed floats.  
          * Returns a new Matrix set from the 16 passed floats.  
          */
          */
@@ -3242,19 +3294,25 @@
          * Returns a new Matrix composed by the passed scale (vector3), rotation (quaternion) and translation (vector3).  
          * Returns a new Matrix composed by the passed scale (vector3), rotation (quaternion) and translation (vector3).  
          */
          */
         public static Compose(scale: Vector3, rotation: Quaternion, translation: Vector3): Matrix {
         public static Compose(scale: Vector3, rotation: Quaternion, translation: Vector3): Matrix {
-            var result = Matrix.FromValues(scale.x, 0, 0, 0,
+            var result = Matrix.Identity();
+            Matrix.ComposeToRef(scale, rotation, translation, result);
+            return result;
+        }
+
+          /**
+         * Update a Matrix with values composed by the passed scale (vector3), rotation (quaternion) and translation (vector3).  
+         */
+        public static ComposeToRef(scale: Vector3, rotation: Quaternion, translation: Vector3, result: Matrix): void {
+            Matrix.FromValuesToRef(scale.x, 0, 0, 0,
                 0, scale.y, 0, 0,
                 0, scale.y, 0, 0,
                 0, 0, scale.z, 0,
                 0, 0, scale.z, 0,
-                0, 0, 0, 1);
+                0, 0, 0, 1, MathTmp.Matrix[1]);
 
 
-            var rotationMatrix = Matrix.Identity();
-            rotation.toRotationMatrix(rotationMatrix);
-            result = result.multiply(rotationMatrix);
+            rotation.toRotationMatrix(MathTmp.Matrix[0]);
+            MathTmp.Matrix[1].multiplyToRef(MathTmp.Matrix[0], result);
 
 
             result.setTranslation(translation);
             result.setTranslation(translation);
-
-            return result;
-        }
+        }      
         /**
         /**
          * Returns a new indentity Matrix.  
          * Returns a new indentity Matrix.  
          */
          */
@@ -4909,11 +4967,16 @@
         public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),
         public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),
             Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];    // 9 temp Vector3 at once should be enough
             Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];    // 9 temp Vector3 at once should be enough
         public static Vector4: Vector4[] = [Vector4.Zero(), Vector4.Zero(), Vector4.Zero()];  // 3 temp Vector4 at once should be enough
         public static Vector4: Vector4[] = [Vector4.Zero(), Vector4.Zero(), Vector4.Zero()];  // 3 temp Vector4 at once should be enough
-        public static Quaternion: Quaternion[] = [new Quaternion(0.0, 0.0, 0.0, 0.0), 
-            new Quaternion(0.0, 0.0, 0.0, 0.0)];                // 2 temp Quaternion at once should be enough
+        public static Quaternion: Quaternion[] = [Quaternion.Zero(), Quaternion.Zero()];                // 2 temp Quaternion at once should be enough
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero(),
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero(),
             Matrix.Zero(), Matrix.Zero(),
             Matrix.Zero(), Matrix.Zero(),
             Matrix.Zero(), Matrix.Zero(),
             Matrix.Zero(), Matrix.Zero(),
             Matrix.Zero(), Matrix.Zero()];                      // 6 temp Matrices at once should be enough
             Matrix.Zero(), Matrix.Zero()];                      // 6 temp Matrices at once should be enough
     }
     }
+    // Same as Tmp but not exported to keep it onyl for math functions to avoid conflicts
+    class MathTmp {
+        public static Vector3: Vector3[] = [Vector3.Zero()];
+        public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero()];
+        public static Quaternion: Quaternion[] = [Quaternion.Zero()];
+    }
 }
 }

+ 60 - 41
src/Mesh/babylon.abstractMesh.ts

@@ -203,7 +203,6 @@
         // Cache
         // Cache
         private _localWorld = Matrix.Zero();
         private _localWorld = Matrix.Zero();
         public _worldMatrix = Matrix.Zero();
         public _worldMatrix = Matrix.Zero();
-        private _rotateYByPI = Matrix.RotationY(Math.PI);
         private _absolutePosition = Vector3.Zero();
         private _absolutePosition = Vector3.Zero();
         private _collisionsTransformMatrix = Matrix.Zero();
         private _collisionsTransformMatrix = Matrix.Zero();
         private _collisionsScalingMatrix = Matrix.Zero();
         private _collisionsScalingMatrix = Matrix.Zero();
@@ -869,63 +868,83 @@
             this._pivotMatrix.multiplyToRef(Tmp.Matrix[1], Tmp.Matrix[4]);
             this._pivotMatrix.multiplyToRef(Tmp.Matrix[1], Tmp.Matrix[4]);
             Tmp.Matrix[4].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[5]);
             Tmp.Matrix[4].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[5]);
 
 
-            // Billboarding
-            if (this.billboardMode !== AbstractMesh.BILLBOARDMODE_NONE && this.getScene().activeCamera) {
-                Tmp.Vector3[0].copyFrom(this.position);
-                var localPosition = Tmp.Vector3[0];
-
-                if (this.parent && this.parent.getWorldMatrix) {
-                    this._markSyncedWithParent();
+            // Mesh referal
+            var completeMeshReferalMatrix = Tmp.Matrix[6];
+            if (this._meshToBoneReferal && this.parent && this.parent.getWorldMatrix) {
+                this.parent.getWorldMatrix().multiplyToRef(this._meshToBoneReferal.getWorldMatrix(), completeMeshReferalMatrix);
+            }
 
 
-                    var parentMatrix: Matrix;
-                    if (this._meshToBoneReferal) {
-                        this.parent.getWorldMatrix().multiplyToRef(this._meshToBoneReferal.getWorldMatrix(), Tmp.Matrix[6]);
-                        parentMatrix = Tmp.Matrix[6];
+            // Billboarding (testing PG:http://www.babylonjs-playground.com/#UJEIL#13)
+            if (this.billboardMode !== AbstractMesh.BILLBOARDMODE_NONE && this.getScene().activeCamera) {
+                if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_ALL) !== AbstractMesh.BILLBOARDMODE_ALL) {
+                    // Need to decompose each rotation here
+                    var currentPosition = Tmp.Vector3[3];
+
+                    if (this.parent && this.parent.getWorldMatrix) {
+                        if (this._meshToBoneReferal) {
+                            Vector3.TransformCoordinatesToRef(this.position, completeMeshReferalMatrix, currentPosition);
+                        } else {
+                            Vector3.TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), currentPosition);
+                        }
                     } else {
                     } else {
-                        parentMatrix = this.parent.getWorldMatrix();
+                        currentPosition.copyFrom(this.position);
                     }
                     }
 
 
-                    Vector3.TransformNormalToRef(localPosition, parentMatrix, Tmp.Vector3[1]);
-                    localPosition = Tmp.Vector3[1];
-                }
-
-                var zero = this.getScene().activeCamera.globalPosition.clone();
+                    currentPosition.subtractInPlace(this.getScene().activeCamera.globalPosition);
 
 
-                if (this.parent && (<any>this.parent).position) {
-                    localPosition.addInPlace((<any>this.parent).position);
-                    Matrix.TranslationToRef(localPosition.x, localPosition.y, localPosition.z, Tmp.Matrix[2]);
-                }
+                    var finalEuler = Tmp.Vector3[4].copyFromFloats(0, 0, 0);
+                    if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_X) === AbstractMesh.BILLBOARDMODE_X)
+                    {
+                        finalEuler.x = Math.atan2(-currentPosition.y, currentPosition.z);
+                    }
+                    
+                    if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_Y) === AbstractMesh.BILLBOARDMODE_Y)
+                    {
+                        finalEuler.y = Math.atan2(currentPosition.x, currentPosition.z);
+                    }
+                    
+                    if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_Z) === AbstractMesh.BILLBOARDMODE_Z)
+                    {
+                        finalEuler.z = Math.atan2(currentPosition.y, currentPosition.x);
+                    }
+ 
+                    Matrix.RotationYawPitchRollToRef(finalEuler.y, finalEuler.x, finalEuler.z, Tmp.Matrix[0]);
+                } else {
+                    Tmp.Matrix[1].copyFrom(this.getScene().activeCamera.getViewMatrix());
 
 
-                if ((this.billboardMode & AbstractMesh.BILLBOARDMODE_ALL) !== AbstractMesh.BILLBOARDMODE_ALL) {
-                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_X)
-                        zero.x = localPosition.x + Epsilon;
-                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Y)
-                        zero.y = localPosition.y + Epsilon;
-                    if (this.billboardMode & AbstractMesh.BILLBOARDMODE_Z)
-                        zero.z = localPosition.z + Epsilon;
+                    Tmp.Matrix[1].setTranslationFromFloats(0, 0, 0);
+                    Tmp.Matrix[1].invertToRef(Tmp.Matrix[0]);
                 }
                 }
 
 
-                Matrix.LookAtLHToRef(localPosition, zero, Vector3.Up(), Tmp.Matrix[3]);
-                Tmp.Matrix[3].m[12] = Tmp.Matrix[3].m[13] = Tmp.Matrix[3].m[14] = 0;
-
-                Tmp.Matrix[3].invert();
-
-                Tmp.Matrix[5].multiplyToRef(Tmp.Matrix[3], this._localWorld);
-                this._rotateYByPI.multiplyToRef(this._localWorld, Tmp.Matrix[5]);
+                Tmp.Matrix[1].copyFrom(Tmp.Matrix[5]);
+                Tmp.Matrix[1].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[5]);
             }
             }
 
 
             // Local world
             // Local world
             Tmp.Matrix[5].multiplyToRef(Tmp.Matrix[2], this._localWorld);
             Tmp.Matrix[5].multiplyToRef(Tmp.Matrix[2], this._localWorld);
 
 
             // Parent
             // Parent
-            if (this.parent && this.parent.getWorldMatrix && this.billboardMode === AbstractMesh.BILLBOARDMODE_NONE) {
+            if (this.parent && this.parent.getWorldMatrix) {
                 this._markSyncedWithParent();
                 this._markSyncedWithParent();
 
 
-                if (this._meshToBoneReferal) {
-                    this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), Tmp.Matrix[6]);
-                    Tmp.Matrix[6].multiplyToRef(this._meshToBoneReferal.getWorldMatrix(), this._worldMatrix);
+                if (this.billboardMode !== AbstractMesh.BILLBOARDMODE_NONE) {
+                    if (this._meshToBoneReferal) {
+                        Tmp.Matrix[5].copyFrom(completeMeshReferalMatrix);
+                    } else {
+                        Tmp.Matrix[5].copyFrom(this.parent.getWorldMatrix());
+                    }
+                    
+                    this._localWorld.getTranslationToRef(Tmp.Vector3[5]);
+                    Vector3.TransformCoordinatesToRef(Tmp.Vector3[5], Tmp.Matrix[5], Tmp.Vector3[5]);
+                    this._worldMatrix.copyFrom(this._localWorld);
+                    this._worldMatrix.setTranslation(Tmp.Vector3[5]);
+                    
                 } else {
                 } else {
-                    this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
+                    if (this._meshToBoneReferal) {
+                        this._localWorld.multiplyToRef(completeMeshReferalMatrix, this._worldMatrix);
+                    } else {
+                        this._localWorld.multiplyToRef(this.parent.getWorldMatrix(), this._worldMatrix);
+                    }
                 }
                 }
             } else {
             } else {
                 this._worldMatrix.copyFrom(this._localWorld);
                 this._worldMatrix.copyFrom(this._localWorld);

+ 6 - 6
src/Tools/babylon.tools.ts

@@ -908,8 +908,6 @@
             return "[" + padStr(date.getHours()) + ":" + padStr(date.getMinutes()) + ":" + padStr(date.getSeconds()) + "]: " + message;
             return "[" + padStr(date.getHours()) + ":" + padStr(date.getMinutes()) + ":" + padStr(date.getSeconds()) + "]: " + message;
         }
         }
 
 
-        public static Log: (message: string) => void = Tools._LogEnabled;
-
         private static _LogDisabled(message: string): void {
         private static _LogDisabled(message: string): void {
             // nothing to do
             // nothing to do
         }
         }
@@ -921,8 +919,6 @@
             Tools._AddLogEntry(entry);
             Tools._AddLogEntry(entry);
         }
         }
 
 
-        public static Warn: (message: string) => void = Tools._WarnEnabled;
-
         private static _WarnDisabled(message: string): void {
         private static _WarnDisabled(message: string): void {
             // nothing to do
             // nothing to do
         }
         }
@@ -934,8 +930,6 @@
             Tools._AddLogEntry(entry);
             Tools._AddLogEntry(entry);
         }
         }
 
 
-        public static Error: (message: string) => void = Tools._ErrorEnabled;
-
         private static _ErrorDisabled(message: string): void {
         private static _ErrorDisabled(message: string): void {
             // nothing to do
             // nothing to do
         }
         }
@@ -948,6 +942,12 @@
             Tools._AddLogEntry(entry);
             Tools._AddLogEntry(entry);
         }
         }
 
 
+        public static Log: (message: string) => void = Tools._LogEnabled;
+
+        public static Warn: (message: string) => void = Tools._WarnEnabled;
+
+        public static Error: (message: string) => void = Tools._ErrorEnabled;
+
         public static get LogCache(): string {
         public static get LogCache(): string {
             return Tools._LogCache;
             return Tools._LogCache;
         }
         }

+ 1 - 4
src/babylon.mixins.ts

@@ -41,10 +41,6 @@ interface WebGLRenderingContext {
     deleteVertexArray(vao: WebGLVertexArrayObject): void;
     deleteVertexArray(vao: WebGLVertexArrayObject): void;
 }
 }
 
 
-interface AudioContext extends EventTarget {
-    decodeAudioData(audioData: ArrayBuffer, successCallback: DecodeSuccessCallback, errorCallback?: any): void;
-}
-
 interface HTMLURL {
 interface HTMLURL {
     createObjectURL(param1: any, param2?: any);
     createObjectURL(param1: any, param2?: any);
 }
 }
@@ -74,6 +70,7 @@ interface CanvasRenderingContext2D {
     mozImageSmoothingEnabled: boolean;
     mozImageSmoothingEnabled: boolean;
     oImageSmoothingEnabled: boolean;
     oImageSmoothingEnabled: boolean;
     webkitImageSmoothingEnabled: boolean;
     webkitImageSmoothingEnabled: boolean;
+    msImageSmoothingEnabled: boolean;
 }
 }
 
 
 interface WebGLTexture {
 interface WebGLTexture {