فهرست منبع

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

nockawa 8 سال پیش
والد
کامیت
384d477ba7
56فایلهای تغییر یافته به همراه9914 افزوده شده و 7287 حذف شده
  1. 1 1
      .travis.yml
  2. 1734 579
      Exporters/3ds Max/ActionsBuilder/Sources/babylon.max.js
  3. 3 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonAbstractMesh.cs
  4. 0 3
      Exporters/3ds Max/BabylonExport.Entities/BabylonMesh.cs
  5. 5 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonPBRMaterial.cs
  6. BIN
      Exporters/3ds Max/Max2Babylon-0.6.0.zip
  7. BIN
      Exporters/3ds Max/Max2Babylon-0.7.0.zip
  8. 1 0
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs
  9. 3 0
      Playground/index-local.html
  10. 7 0
      Tools/Gulp/config.json
  11. 33 0
      contributing.md
  12. 25 25
      dist/preview release/babylon.core.js
  13. 3093 2955
      dist/preview release/babylon.d.ts
  14. 38 38
      dist/preview release/babylon.js
  15. 646 134
      dist/preview release/babylon.max.js
  16. 3093 2955
      dist/preview release/babylon.module.d.ts
  17. 38 38
      dist/preview release/babylon.noworker.js
  18. 25 25
      dist/preview release/canvas2D/babylon.canvas2d.js
  19. 9 9
      dist/preview release/canvas2D/babylon.canvas2d.min.js
  20. 248 248
      dist/preview release/inspector/babylon.inspector.bundle.js
  21. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  22. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  23. 11 0
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.d.ts
  24. 46 0
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js
  25. 1 0
      dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.min.js
  26. 8 0
      dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.d.ts
  27. 28 0
      dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.js
  28. 1 0
      dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.min.js
  29. 2 0
      dist/preview release/what's new.md
  30. 9 1
      proceduralTexturesLibrary/index.html
  31. 37 0
      proceduralTexturesLibrary/src/normalMap/babylon.normalMapProceduralTexture.ts
  32. 30 0
      proceduralTexturesLibrary/src/normalMap/normalMapProceduralTexture.fragment.fx
  33. 6 0
      proceduralTexturesLibrary/test/addNormalMapPT.js
  34. 3 9
      readme.md
  35. 432 180
      src/Bones/babylon.boneLookController.ts
  36. 1 1
      src/Bones/babylon.skeleton.ts
  37. 31 18
      src/Cameras/Inputs/babylon.freecamera.input.gamepad.ts
  38. 1 1
      src/Cameras/babylon.arcRotateCamera.ts
  39. 8 0
      src/Cameras/babylon.camera.ts
  40. 1 1
      src/Cameras/babylon.freeCamera.ts
  41. 10 0
      src/Cameras/babylon.targetCamera.ts
  42. 4 1
      src/Debug/babylon.debugLayer.ts
  43. 40 35
      src/Lights/babylon.directionalLight.ts
  44. 2 0
      src/Lights/babylon.light.ts
  45. 8 2
      src/Lights/babylon.pointLight.ts
  46. 8 2
      src/Lights/babylon.spotLight.ts
  47. 8 3
      src/Materials/babylon.effect.ts
  48. 67 1
      src/Math/babylon.math.ts
  49. 3 1
      src/Mesh/babylon.geometry.ts
  50. 8 0
      src/PostProcess/babylon.postProcess.ts
  51. 76 14
      src/PostProcess/babylon.standardRenderingPipeline.ts
  52. 2 2
      src/Tools/babylon.database.ts
  53. 6 0
      src/Tools/babylon.smartArray.ts
  54. 2 2
      src/Tools/babylon.tools.ts
  55. 9 1
      src/babylon.engine.ts
  56. 1 0
      src/babylon.mixins.ts

+ 1 - 1
.travis.yml

@@ -1,6 +1,6 @@
 language: node_js
 language: node_js
 node_js:
 node_js:
-  - "4.1"
+  - "6"
 before_script:
 before_script:
   - npm install -g gulp
   - npm install -g gulp
   - cd ./Tools/Gulp
   - cd ./Tools/Gulp

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1734 - 579
Exporters/3ds Max/ActionsBuilder/Sources/babylon.max.js


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

@@ -6,6 +6,9 @@ namespace BabylonExport.Entities
     public class BabylonAbstractMesh: BabylonIAnimatable
     public class BabylonAbstractMesh: BabylonIAnimatable
     {
     {
         [DataMember]
         [DataMember]
+        public string id { get; set; }
+
+        [DataMember]
         public string name { get; set; }
         public string name { get; set; }
         
         
         [DataMember]
         [DataMember]

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

@@ -6,9 +6,6 @@ namespace BabylonExport.Entities
     public class BabylonMesh : BabylonAbstractMesh
     public class BabylonMesh : BabylonAbstractMesh
     {
     {
         [DataMember]
         [DataMember]
-        public string id { get; set; }
-
-        [DataMember]
         public string materialId { get; set; }
         public string materialId { get; set; }
 
 
         [DataMember]
         [DataMember]

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

@@ -209,5 +209,10 @@ namespace BabylonExport.Entities
             overloadedEmissive = new[] {1f, 1f, 1f };
             overloadedEmissive = new[] {1f, 1f, 1f };
             overloadedReflection = new[] { 1f, 1f, 1f };
             overloadedReflection = new[] { 1f, 1f, 1f };
         }
         }
+
+        public void SetCustomType(string type)
+        {
+            this.customType = type;
+        }
     }
     }
 }
 }

BIN
Exporters/3ds Max/Max2Babylon-0.6.0.zip


BIN
Exporters/3ds Max/Max2Babylon-0.7.0.zip


+ 1 - 0
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Mesh.cs

@@ -478,6 +478,7 @@ namespace Max2Babylon
                     var instanceRotation = instanceLocalTM.Rotation;
                     var instanceRotation = instanceLocalTM.Rotation;
                     var instanceScale = instanceLocalTM.Scaling;
                     var instanceScale = instanceLocalTM.Scaling;
 
 
+                    instance.id = instanceGameNode.MaxNode.GetGuid().ToString();
                     instance.position = new[] { instanceTrans.X, instanceTrans.Y, instanceTrans.Z };
                     instance.position = new[] { instanceTrans.X, instanceTrans.Y, instanceTrans.Z };
 
 
                     if (exportQuaternions)
                     if (exportQuaternions)

+ 3 - 0
Playground/index-local.html

@@ -16,6 +16,9 @@
     <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
     <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
     <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
     <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
     <!-- Babylon.js -->    
     <!-- Babylon.js -->    
+    
+    <script src="https://babylonjs.azurewebsites.net/cannon.js"></script>
+    <script src="https://babylonjs.azurewebsites.net/Oimo.js"></script>
 	<script src="../tools/DevLoader/BabylonLoader.js"></script>
 	<script src="../tools/DevLoader/BabylonLoader.js"></script>
     <link href="index.css" rel="stylesheet" />
     <link href="index.css" rel="stylesheet" />
 </head>
 </head>

+ 7 - 0
Tools/Gulp/config.json

@@ -411,6 +411,13 @@
           "../../proceduralTexturesLibrary/src/starfield/starfieldProceduralTexture.fragment.fx"
           "../../proceduralTexturesLibrary/src/starfield/starfieldProceduralTexture.fragment.fx"
         ],
         ],
         "output": "babylon.starfieldProceduralTexture.js"
         "output": "babylon.starfieldProceduralTexture.js"
+      },
+      {
+        "files": ["../../proceduralTexturesLibrary/src/normalMap/babylon.normalMapProceduralTexture.ts"],
+        "shaderFiles": [
+          "../../proceduralTexturesLibrary/src/normalMap/normalMapProceduralTexture.fragment.fx"
+        ],
+        "output": "babylon.normalMapProceduralTexture.js"
       }
       }
     ],
     ],
     "build": {
     "build": {

+ 33 - 0
contributing.md

@@ -0,0 +1,33 @@
+# Contributing to Babylon.js
+
+The foundation of **Babylon.js** is simplicity. 
+
+A developer should be able to quickly and easily learn to use the API. 
+
+Simplicity and a low barrier to entry are must-have features of every API. If you have any second thoughts about the complexity of a design, it is almost always much better to cut the feature from the current release and spend more time to get the design right for the next release. 
+
+You can always add to an API, you cannot ever remove anything from one. If the design does not feel right, and you ship it anyway, you are likely to regret having done so.
+
+That's why many of the guidelines of this document are obvious and serve only one purpose: Simplicity.
+
+## Forum and Github issues
+
+Since the very beginning, Babylon.js relies on a great forum and a tremendous community: http://www.html5gamedevs.com/forum/16-babylonjs/.
+Please use the forum for **ANY questions you may have**.
+
+Please use the Github issues **only** for:
+- Bugs
+- Feature requests
+
+We will try to enforce these rules as we consider the forum is a better place for discussions and learnings.
+
+## Pull requests
+
+We are not complicated people, but we still have some [coding guidelines](http://doc.babylonjs.com/generals/Approved_Naming_Conventions)
+Before submitting your PR, just check that everything goes well by [creating the minified version](http://doc.babylonjs.com/generals/Creating_the_Mini-fied_Version)
+
+Need help contributing, here are some links:
+  - [Gulp](https://github.com/BabylonJS/Babylon.js/tree/master/Tools/Gulp) to build from command line.
+  - [VSCode Editor](https://code.visualstudio.com/), Microsoft Code editor, see [Julian Chenard's post](http://pixelcodr.com/tutos/contribute/contribute.html) a Microsoft code editor.
+  - [Visual Studio](http://doc.babylonjs.com/generals/setup_visualStudio), Microsoft's IDE.
+  - [Forum thread](http://www.html5gamedevs.com/topic/20456-contributing-on-babylonjs/) for assistance from our very helpful family.

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 25 - 25
dist/preview release/babylon.core.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3093 - 2955
dist/preview release/babylon.d.ts


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 38 - 38
dist/preview release/babylon.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 646 - 134
dist/preview release/babylon.max.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3093 - 2955
dist/preview release/babylon.module.d.ts


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 38 - 38
dist/preview release/babylon.noworker.js


+ 25 - 25
dist/preview release/canvas2D/babylon.canvas2d.js

@@ -3844,14 +3844,14 @@ var BABYLON;
     var RowDefinition = (function (_super) {
     var RowDefinition = (function (_super) {
         __extends(RowDefinition, _super);
         __extends(RowDefinition, _super);
         function RowDefinition() {
         function RowDefinition() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         return RowDefinition;
         return RowDefinition;
     }(GridDimensionDefinition));
     }(GridDimensionDefinition));
     var ColumnDefinition = (function (_super) {
     var ColumnDefinition = (function (_super) {
         __extends(ColumnDefinition, _super);
         __extends(ColumnDefinition, _super);
         function ColumnDefinition() {
         function ColumnDefinition() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         return ColumnDefinition;
         return ColumnDefinition;
     }(GridDimensionDefinition));
     }(GridDimensionDefinition));
@@ -6897,7 +6897,7 @@ var BABYLON;
     var Prim2DBase = Prim2DBase_1 = (function (_super) {
     var Prim2DBase = Prim2DBase_1 = (function (_super) {
         __extends(Prim2DBase, _super);
         __extends(Prim2DBase, _super);
         function Prim2DBase(settings) {
         function Prim2DBase(settings) {
-            var _this = this;
+            var _this;
             // Avoid checking every time if the object exists
             // Avoid checking every time if the object exists
             if (settings == null) {
             if (settings == null) {
                 settings = {};
                 settings = {};
@@ -11025,7 +11025,7 @@ var BABYLON;
     var Shape2DInstanceData = (function (_super) {
     var Shape2DInstanceData = (function (_super) {
         __extends(Shape2DInstanceData, _super);
         __extends(Shape2DInstanceData, _super);
         function Shape2DInstanceData() {
         function Shape2DInstanceData() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         Object.defineProperty(Shape2DInstanceData.prototype, "fillSolidColor", {
         Object.defineProperty(Shape2DInstanceData.prototype, "fillSolidColor", {
             // FILL ATTRIBUTES
             // FILL ATTRIBUTES
@@ -11200,7 +11200,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function Group2D(settings) {
         function Group2D(settings) {
-            var _this = this;
+            var _this;
             if (settings == null) {
             if (settings == null) {
                 settings = {};
                 settings = {};
             }
             }
@@ -12139,7 +12139,7 @@ var BABYLON;
     var WireFrame2DRenderCache = (function (_super) {
     var WireFrame2DRenderCache = (function (_super) {
         __extends(WireFrame2DRenderCache, _super);
         __extends(WireFrame2DRenderCache, _super);
         function WireFrame2DRenderCache() {
         function WireFrame2DRenderCache() {
-            var _this = _super !== null && _super.apply(this, arguments) || this;
+            var _this = _super.apply(this, arguments) || this;
             _this.effectsReady = false;
             _this.effectsReady = false;
             _this.vb = null;
             _this.vb = null;
             _this.vtxCount = 0;
             _this.vtxCount = 0;
@@ -12365,7 +12365,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function WireFrame2D(wireFrameGroups, settings) {
         function WireFrame2D(wireFrameGroups, settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -12745,7 +12745,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function Rectangle2D(settings) {
         function Rectangle2D(settings) {
-            var _this = this;
+            var _this;
             // Avoid checking every time if the object exists
             // Avoid checking every time if the object exists
             if (settings == null) {
             if (settings == null) {
                 settings = {};
                 settings = {};
@@ -13260,7 +13260,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function Ellipse2D(settings) {
         function Ellipse2D(settings) {
-            var _this = this;
+            var _this;
             // Avoid checking every time if the object exists
             // Avoid checking every time if the object exists
             if (settings == null) {
             if (settings == null) {
                 settings = {};
                 settings = {};
@@ -13444,7 +13444,7 @@ var BABYLON;
     var Sprite2DRenderCache = (function (_super) {
     var Sprite2DRenderCache = (function (_super) {
         __extends(Sprite2DRenderCache, _super);
         __extends(Sprite2DRenderCache, _super);
         function Sprite2DRenderCache() {
         function Sprite2DRenderCache() {
-            var _this = _super !== null && _super.apply(this, arguments) || this;
+            var _this = _super.apply(this, arguments) || this;
             _this.effectsReady = false;
             _this.effectsReady = false;
             _this.vb = null;
             _this.vb = null;
             _this.ib = null;
             _this.ib = null;
@@ -13564,7 +13564,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function Sprite2D(texture, settings) {
         function Sprite2D(texture, settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -14202,7 +14202,7 @@ var BABYLON;
     var Text2DRenderCache = (function (_super) {
     var Text2DRenderCache = (function (_super) {
         __extends(Text2DRenderCache, _super);
         __extends(Text2DRenderCache, _super);
         function Text2DRenderCache() {
         function Text2DRenderCache() {
-            var _this = _super !== null && _super.apply(this, arguments) || this;
+            var _this = _super.apply(this, arguments) || this;
             _this.effectsReady = false;
             _this.effectsReady = false;
             _this.vb = null;
             _this.vb = null;
             _this.ib = null;
             _this.ib = null;
@@ -14400,7 +14400,7 @@ var BABYLON;
          * - wordWrap: if true the text will wrap inside content area
          * - wordWrap: if true the text will wrap inside content area
          */
          */
         function Text2D(text, settings) {
         function Text2D(text, settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -15237,7 +15237,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function Lines2D(points, settings) {
         function Lines2D(points, settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -17891,7 +17891,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see PrimitiveThickness.fromString)
          */
          */
         function WorldSpaceCanvas2D(scene, size, settings) {
         function WorldSpaceCanvas2D(scene, size, settings) {
-            var _this = this;
+            var _this;
             BABYLON.Prim2DBase._isCanvasInit = true;
             BABYLON.Prim2DBase._isCanvasInit = true;
             var s = settings;
             var s = settings;
             s.isScreenSpace = false;
             s.isScreenSpace = false;
@@ -18053,7 +18053,7 @@ var BABYLON;
          * - padding: top, left, right and bottom padding formatted as a single string (see BABYLON.PrimitiveThickness.fromString)
          * - padding: top, left, right and bottom padding formatted as a single string (see BABYLON.PrimitiveThickness.fromString)
          */
          */
         function ScreenSpaceCanvas2D(scene, settings) {
         function ScreenSpaceCanvas2D(scene, settings) {
-            var _this = this;
+            var _this;
             BABYLON.Prim2DBase._isCanvasInit = true;
             BABYLON.Prim2DBase._isCanvasInit = true;
             _this = _super.call(this, scene, settings) || this;
             _this = _super.call(this, scene, settings) || this;
             return _this;
             return _this;
@@ -19037,7 +19037,7 @@ var BABYLON;
     var StackPanel = StackPanel_1 = (function (_super) {
     var StackPanel = StackPanel_1 = (function (_super) {
         __extends(StackPanel, _super);
         __extends(StackPanel, _super);
         function StackPanel(settings) {
         function StackPanel(settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -19100,7 +19100,7 @@ var BABYLON;
     var DefaultStackPanelRenderingTemplate = DefaultStackPanelRenderingTemplate_1 = (function (_super) {
     var DefaultStackPanelRenderingTemplate = DefaultStackPanelRenderingTemplate_1 = (function (_super) {
         __extends(DefaultStackPanelRenderingTemplate, _super);
         __extends(DefaultStackPanelRenderingTemplate, _super);
         function DefaultStackPanelRenderingTemplate() {
         function DefaultStackPanelRenderingTemplate() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         DefaultStackPanelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
         DefaultStackPanelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
             return { root: visualPlaceholder, contentPlaceholder: visualPlaceholder };
             return { root: visualPlaceholder, contentPlaceholder: visualPlaceholder };
@@ -19229,7 +19229,7 @@ var BABYLON;
     var ContentControl = ContentControl_1 = (function (_super) {
     var ContentControl = ContentControl_1 = (function (_super) {
         __extends(ContentControl, _super);
         __extends(ContentControl, _super);
         function ContentControl(settings) {
         function ContentControl(settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -19384,7 +19384,7 @@ var BABYLON;
     var Window = Window_1 = (function (_super) {
     var Window = Window_1 = (function (_super) {
         __extends(Window, _super);
         __extends(Window, _super);
         function Window(scene, settings) {
         function Window(scene, settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -19569,7 +19569,7 @@ var BABYLON;
     var DefaultWindowRenderingTemplate = DefaultWindowRenderingTemplate_1 = (function (_super) {
     var DefaultWindowRenderingTemplate = DefaultWindowRenderingTemplate_1 = (function (_super) {
         __extends(DefaultWindowRenderingTemplate, _super);
         __extends(DefaultWindowRenderingTemplate, _super);
         function DefaultWindowRenderingTemplate() {
         function DefaultWindowRenderingTemplate() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         DefaultWindowRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
         DefaultWindowRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
             var r = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#808080FF" });
             var r = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#808080FF" });
@@ -19600,7 +19600,7 @@ var BABYLON;
     var Label = Label_1 = (function (_super) {
     var Label = Label_1 = (function (_super) {
         __extends(Label, _super);
         __extends(Label, _super);
         function Label(settings) {
         function Label(settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -19647,7 +19647,7 @@ var BABYLON;
     var DefaultLabelRenderingTemplate = DefaultLabelRenderingTemplate_1 = (function (_super) {
     var DefaultLabelRenderingTemplate = DefaultLabelRenderingTemplate_1 = (function (_super) {
         __extends(DefaultLabelRenderingTemplate, _super);
         __extends(DefaultLabelRenderingTemplate, _super);
         function DefaultLabelRenderingTemplate() {
         function DefaultLabelRenderingTemplate() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         DefaultLabelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
         DefaultLabelRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
             var r = new BABYLON.Text2D("", { parent: visualPlaceholder });
             var r = new BABYLON.Text2D("", { parent: visualPlaceholder });
@@ -19680,7 +19680,7 @@ var BABYLON;
     var Button = Button_1 = (function (_super) {
     var Button = Button_1 = (function (_super) {
         __extends(Button, _super);
         __extends(Button, _super);
         function Button(settings) {
         function Button(settings) {
-            var _this = this;
+            var _this;
             if (!settings) {
             if (!settings) {
                 settings = {};
                 settings = {};
             }
             }
@@ -19834,7 +19834,7 @@ var BABYLON;
     var DefaultButtonRenderingTemplate = DefaultButtonRenderingTemplate_1 = (function (_super) {
     var DefaultButtonRenderingTemplate = DefaultButtonRenderingTemplate_1 = (function (_super) {
         __extends(DefaultButtonRenderingTemplate, _super);
         __extends(DefaultButtonRenderingTemplate, _super);
         function DefaultButtonRenderingTemplate() {
         function DefaultButtonRenderingTemplate() {
-            return _super !== null && _super.apply(this, arguments) || this;
+            return _super.apply(this, arguments) || this;
         }
         }
         DefaultButtonRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
         DefaultButtonRenderingTemplate.prototype.createVisualTree = function (owner, visualPlaceholder) {
             this._rect = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#FF8080FF", border: "#FF8080FF", roundRadius: 10, borderThickness: 2 });
             this._rect = new BABYLON.Rectangle2D({ parent: visualPlaceholder, fill: "#FF8080FF", border: "#FF8080FF", roundRadius: 10, borderThickness: 2 });

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 9 - 9
dist/preview release/canvas2D/babylon.canvas2d.min.js


+ 248 - 248
dist/preview release/inspector/babylon.inspector.bundle.js

@@ -65,8 +65,8 @@ var INSPECTOR =
 	if(false) {
 	if(false) {
 		// When the styles change, update the <style> tags
 		// When the styles change, update the <style> tags
 		if(!content.locals) {
 		if(!content.locals) {
-			module.hot.accept("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
-				var newContent = require("!!../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
+			module.hot.accept("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css", function() {
+				var newContent = require("!!./../../../Tools/Gulp/node_modules/css-loader/index.js!./babylon.inspector.css");
 				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
 				if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
 				update(newContent);
 				update(newContent);
 			});
 			});
@@ -150,252 +150,252 @@ var INSPECTOR =
 /* 4 */
 /* 4 */
 /***/ function(module, exports, __webpack_require__) {
 /***/ function(module, exports, __webpack_require__) {
 
 
-	/*
-		MIT License http://www.opensource.org/licenses/mit-license.php
-		Author Tobias Koppers @sokra
-	*/
-	var stylesInDom = {},
-		memoize = function(fn) {
-			var memo;
-			return function () {
-				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
-				return memo;
-			};
-		},
-		isOldIE = memoize(function() {
-			return /msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase());
-		}),
-		getHeadElement = memoize(function () {
-			return document.head || document.getElementsByTagName("head")[0];
-		}),
-		singletonElement = null,
-		singletonCounter = 0,
-		styleElementsInsertedAtTop = [];
-
-	module.exports = function(list, options) {
-		if(false) {
-			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
-		}
-
-		options = options || {};
-		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
-		// tags it will allow on a page
-		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
-
-		// By default, add <style> tags to the bottom of <head>.
-		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
-
-		var styles = listToStyles(list);
-		addStylesToDom(styles, options);
-
-		return function update(newList) {
-			var mayRemove = [];
-			for(var i = 0; i < styles.length; i++) {
-				var item = styles[i];
-				var domStyle = stylesInDom[item.id];
-				domStyle.refs--;
-				mayRemove.push(domStyle);
-			}
-			if(newList) {
-				var newStyles = listToStyles(newList);
-				addStylesToDom(newStyles, options);
-			}
-			for(var i = 0; i < mayRemove.length; i++) {
-				var domStyle = mayRemove[i];
-				if(domStyle.refs === 0) {
-					for(var j = 0; j < domStyle.parts.length; j++)
-						domStyle.parts[j]();
-					delete stylesInDom[domStyle.id];
-				}
-			}
-		};
-	}
-
-	function addStylesToDom(styles, options) {
-		for(var i = 0; i < styles.length; i++) {
-			var item = styles[i];
-			var domStyle = stylesInDom[item.id];
-			if(domStyle) {
-				domStyle.refs++;
-				for(var j = 0; j < domStyle.parts.length; j++) {
-					domStyle.parts[j](item.parts[j]);
-				}
-				for(; j < item.parts.length; j++) {
-					domStyle.parts.push(addStyle(item.parts[j], options));
-				}
-			} else {
-				var parts = [];
-				for(var j = 0; j < item.parts.length; j++) {
-					parts.push(addStyle(item.parts[j], options));
-				}
-				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
-			}
-		}
-	}
-
-	function listToStyles(list) {
-		var styles = [];
-		var newStyles = {};
-		for(var i = 0; i < list.length; i++) {
-			var item = list[i];
-			var id = item[0];
-			var css = item[1];
-			var media = item[2];
-			var sourceMap = item[3];
-			var part = {css: css, media: media, sourceMap: sourceMap};
-			if(!newStyles[id])
-				styles.push(newStyles[id] = {id: id, parts: [part]});
-			else
-				newStyles[id].parts.push(part);
-		}
-		return styles;
-	}
-
-	function insertStyleElement(options, styleElement) {
-		var head = getHeadElement();
-		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
-		if (options.insertAt === "top") {
-			if(!lastStyleElementInsertedAtTop) {
-				head.insertBefore(styleElement, head.firstChild);
-			} else if(lastStyleElementInsertedAtTop.nextSibling) {
-				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
-			} else {
-				head.appendChild(styleElement);
-			}
-			styleElementsInsertedAtTop.push(styleElement);
-		} else if (options.insertAt === "bottom") {
-			head.appendChild(styleElement);
-		} else {
-			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
-		}
-	}
-
-	function removeStyleElement(styleElement) {
-		styleElement.parentNode.removeChild(styleElement);
-		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
-		if(idx >= 0) {
-			styleElementsInsertedAtTop.splice(idx, 1);
-		}
-	}
-
-	function createStyleElement(options) {
-		var styleElement = document.createElement("style");
-		styleElement.type = "text/css";
-		insertStyleElement(options, styleElement);
-		return styleElement;
-	}
-
-	function createLinkElement(options) {
-		var linkElement = document.createElement("link");
-		linkElement.rel = "stylesheet";
-		insertStyleElement(options, linkElement);
-		return linkElement;
-	}
-
-	function addStyle(obj, options) {
-		var styleElement, update, remove;
-
-		if (options.singleton) {
-			var styleIndex = singletonCounter++;
-			styleElement = singletonElement || (singletonElement = createStyleElement(options));
-			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
-			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
-		} else if(obj.sourceMap &&
-			typeof URL === "function" &&
-			typeof URL.createObjectURL === "function" &&
-			typeof URL.revokeObjectURL === "function" &&
-			typeof Blob === "function" &&
-			typeof btoa === "function") {
-			styleElement = createLinkElement(options);
-			update = updateLink.bind(null, styleElement);
-			remove = function() {
-				removeStyleElement(styleElement);
-				if(styleElement.href)
-					URL.revokeObjectURL(styleElement.href);
-			};
-		} else {
-			styleElement = createStyleElement(options);
-			update = applyToTag.bind(null, styleElement);
-			remove = function() {
-				removeStyleElement(styleElement);
-			};
-		}
-
-		update(obj);
-
-		return function updateStyle(newObj) {
-			if(newObj) {
-				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
-					return;
-				update(obj = newObj);
-			} else {
-				remove();
-			}
-		};
-	}
-
-	var replaceText = (function () {
-		var textStore = [];
-
-		return function (index, replacement) {
-			textStore[index] = replacement;
-			return textStore.filter(Boolean).join('\n');
-		};
-	})();
-
-	function applyToSingletonTag(styleElement, index, remove, obj) {
-		var css = remove ? "" : obj.css;
-
-		if (styleElement.styleSheet) {
-			styleElement.styleSheet.cssText = replaceText(index, css);
-		} else {
-			var cssNode = document.createTextNode(css);
-			var childNodes = styleElement.childNodes;
-			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
-			if (childNodes.length) {
-				styleElement.insertBefore(cssNode, childNodes[index]);
-			} else {
-				styleElement.appendChild(cssNode);
-			}
-		}
-	}
-
-	function applyToTag(styleElement, obj) {
-		var css = obj.css;
-		var media = obj.media;
-
-		if(media) {
-			styleElement.setAttribute("media", media)
-		}
-
-		if(styleElement.styleSheet) {
-			styleElement.styleSheet.cssText = css;
-		} else {
-			while(styleElement.firstChild) {
-				styleElement.removeChild(styleElement.firstChild);
-			}
-			styleElement.appendChild(document.createTextNode(css));
-		}
-	}
-
-	function updateLink(linkElement, obj) {
-		var css = obj.css;
-		var sourceMap = obj.sourceMap;
-
-		if(sourceMap) {
-			// http://stackoverflow.com/a/26603875
-			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
-		}
-
-		var blob = new Blob([css], { type: "text/css" });
-
-		var oldSrc = linkElement.href;
-
-		linkElement.href = URL.createObjectURL(blob);
-
-		if(oldSrc)
-			URL.revokeObjectURL(oldSrc);
-	}
+	/*
+		MIT License http://www.opensource.org/licenses/mit-license.php
+		Author Tobias Koppers @sokra
+	*/
+	var stylesInDom = {},
+		memoize = function(fn) {
+			var memo;
+			return function () {
+				if (typeof memo === "undefined") memo = fn.apply(this, arguments);
+				return memo;
+			};
+		},
+		isOldIE = memoize(function() {
+			return /msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase());
+		}),
+		getHeadElement = memoize(function () {
+			return document.head || document.getElementsByTagName("head")[0];
+		}),
+		singletonElement = null,
+		singletonCounter = 0,
+		styleElementsInsertedAtTop = [];
+
+	module.exports = function(list, options) {
+		if(false) {
+			if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
+		}
+
+		options = options || {};
+		// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
+		// tags it will allow on a page
+		if (typeof options.singleton === "undefined") options.singleton = isOldIE();
+
+		// By default, add <style> tags to the bottom of <head>.
+		if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
+
+		var styles = listToStyles(list);
+		addStylesToDom(styles, options);
+
+		return function update(newList) {
+			var mayRemove = [];
+			for(var i = 0; i < styles.length; i++) {
+				var item = styles[i];
+				var domStyle = stylesInDom[item.id];
+				domStyle.refs--;
+				mayRemove.push(domStyle);
+			}
+			if(newList) {
+				var newStyles = listToStyles(newList);
+				addStylesToDom(newStyles, options);
+			}
+			for(var i = 0; i < mayRemove.length; i++) {
+				var domStyle = mayRemove[i];
+				if(domStyle.refs === 0) {
+					for(var j = 0; j < domStyle.parts.length; j++)
+						domStyle.parts[j]();
+					delete stylesInDom[domStyle.id];
+				}
+			}
+		};
+	}
+
+	function addStylesToDom(styles, options) {
+		for(var i = 0; i < styles.length; i++) {
+			var item = styles[i];
+			var domStyle = stylesInDom[item.id];
+			if(domStyle) {
+				domStyle.refs++;
+				for(var j = 0; j < domStyle.parts.length; j++) {
+					domStyle.parts[j](item.parts[j]);
+				}
+				for(; j < item.parts.length; j++) {
+					domStyle.parts.push(addStyle(item.parts[j], options));
+				}
+			} else {
+				var parts = [];
+				for(var j = 0; j < item.parts.length; j++) {
+					parts.push(addStyle(item.parts[j], options));
+				}
+				stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
+			}
+		}
+	}
+
+	function listToStyles(list) {
+		var styles = [];
+		var newStyles = {};
+		for(var i = 0; i < list.length; i++) {
+			var item = list[i];
+			var id = item[0];
+			var css = item[1];
+			var media = item[2];
+			var sourceMap = item[3];
+			var part = {css: css, media: media, sourceMap: sourceMap};
+			if(!newStyles[id])
+				styles.push(newStyles[id] = {id: id, parts: [part]});
+			else
+				newStyles[id].parts.push(part);
+		}
+		return styles;
+	}
+
+	function insertStyleElement(options, styleElement) {
+		var head = getHeadElement();
+		var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
+		if (options.insertAt === "top") {
+			if(!lastStyleElementInsertedAtTop) {
+				head.insertBefore(styleElement, head.firstChild);
+			} else if(lastStyleElementInsertedAtTop.nextSibling) {
+				head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
+			} else {
+				head.appendChild(styleElement);
+			}
+			styleElementsInsertedAtTop.push(styleElement);
+		} else if (options.insertAt === "bottom") {
+			head.appendChild(styleElement);
+		} else {
+			throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
+		}
+	}
+
+	function removeStyleElement(styleElement) {
+		styleElement.parentNode.removeChild(styleElement);
+		var idx = styleElementsInsertedAtTop.indexOf(styleElement);
+		if(idx >= 0) {
+			styleElementsInsertedAtTop.splice(idx, 1);
+		}
+	}
+
+	function createStyleElement(options) {
+		var styleElement = document.createElement("style");
+		styleElement.type = "text/css";
+		insertStyleElement(options, styleElement);
+		return styleElement;
+	}
+
+	function createLinkElement(options) {
+		var linkElement = document.createElement("link");
+		linkElement.rel = "stylesheet";
+		insertStyleElement(options, linkElement);
+		return linkElement;
+	}
+
+	function addStyle(obj, options) {
+		var styleElement, update, remove;
+
+		if (options.singleton) {
+			var styleIndex = singletonCounter++;
+			styleElement = singletonElement || (singletonElement = createStyleElement(options));
+			update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
+			remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
+		} else if(obj.sourceMap &&
+			typeof URL === "function" &&
+			typeof URL.createObjectURL === "function" &&
+			typeof URL.revokeObjectURL === "function" &&
+			typeof Blob === "function" &&
+			typeof btoa === "function") {
+			styleElement = createLinkElement(options);
+			update = updateLink.bind(null, styleElement);
+			remove = function() {
+				removeStyleElement(styleElement);
+				if(styleElement.href)
+					URL.revokeObjectURL(styleElement.href);
+			};
+		} else {
+			styleElement = createStyleElement(options);
+			update = applyToTag.bind(null, styleElement);
+			remove = function() {
+				removeStyleElement(styleElement);
+			};
+		}
+
+		update(obj);
+
+		return function updateStyle(newObj) {
+			if(newObj) {
+				if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
+					return;
+				update(obj = newObj);
+			} else {
+				remove();
+			}
+		};
+	}
+
+	var replaceText = (function () {
+		var textStore = [];
+
+		return function (index, replacement) {
+			textStore[index] = replacement;
+			return textStore.filter(Boolean).join('\n');
+		};
+	})();
+
+	function applyToSingletonTag(styleElement, index, remove, obj) {
+		var css = remove ? "" : obj.css;
+
+		if (styleElement.styleSheet) {
+			styleElement.styleSheet.cssText = replaceText(index, css);
+		} else {
+			var cssNode = document.createTextNode(css);
+			var childNodes = styleElement.childNodes;
+			if (childNodes[index]) styleElement.removeChild(childNodes[index]);
+			if (childNodes.length) {
+				styleElement.insertBefore(cssNode, childNodes[index]);
+			} else {
+				styleElement.appendChild(cssNode);
+			}
+		}
+	}
+
+	function applyToTag(styleElement, obj) {
+		var css = obj.css;
+		var media = obj.media;
+
+		if(media) {
+			styleElement.setAttribute("media", media)
+		}
+
+		if(styleElement.styleSheet) {
+			styleElement.styleSheet.cssText = css;
+		} else {
+			while(styleElement.firstChild) {
+				styleElement.removeChild(styleElement.firstChild);
+			}
+			styleElement.appendChild(document.createTextNode(css));
+		}
+	}
+
+	function updateLink(linkElement, obj) {
+		var css = obj.css;
+		var sourceMap = obj.sourceMap;
+
+		if(sourceMap) {
+			// http://stackoverflow.com/a/26603875
+			css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
+		}
+
+		var blob = new Blob([css], { type: "text/css" });
+
+		var oldSrc = linkElement.href;
+
+		linkElement.href = URL.createObjectURL(blob);
+
+		if(oldSrc)
+			URL.revokeObjectURL(oldSrc);
+	}
 
 
 
 
 /***/ },
 /***/ },

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 11 - 0
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.d.ts

@@ -0,0 +1,11 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts" />
+declare module BABYLON {
+    class NormalMapProceduralTexture extends ProceduralTexture {
+        private _baseTexture;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        resize(size: any, generateMipMaps: any): void;
+        baseTexture: Texture;
+    }
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 46 - 0
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
dist/preview release/proceduralTexturesLibrary/babylon.normalMapProceduralTexture.min.js


+ 8 - 0
dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.d.ts

@@ -0,0 +1,8 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts" />
+declare module BABYLON {
+    class WaterProceduralTexture extends ProceduralTexture {
+        private _time;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        render(useCameraPostProcess?: boolean): void;
+    }
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 28 - 0
dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
dist/preview release/proceduralTexturesLibrary/babylon.waterProceduralTexture.min.js


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

@@ -15,6 +15,8 @@
  - Multi-platform Compressed Textures for Desktops & Mobile Devices with fall back.  Batch (dos) scripts to convert entire directories of .jpg's & .png's ([jcpalmer](https://github.com/Palmer-JC))
  - Multi-platform Compressed Textures for Desktops & Mobile Devices with fall back.  Batch (dos) scripts to convert entire directories of .jpg's & .png's ([jcpalmer](https://github.com/Palmer-JC))
 
 
 ### Updates
 ### Updates
+- Added `Light.customProjectionMatrixBuilder` to allow developers to define their own projection matrix for shadows ([deltakosh](https://github.com/deltakosh))
+- Added `set()` function to all basic types ([deltakosh](https://github.com/deltakosh))
 - Added `HDRCubeTextureAssetTask` to AssetManager ([deltakosh](https://github.com/deltakosh))
 - Added `HDRCubeTextureAssetTask` to AssetManager ([deltakosh](https://github.com/deltakosh))
 - Engine now uses range based fog ([deltakosh](https://github.com/deltakosh))
 - Engine now uses range based fog ([deltakosh](https://github.com/deltakosh))
 - `VertexBuffer.updatable` is now serialized ([deltakosh](https://github.com/deltakosh))
 - `VertexBuffer.updatable` is now serialized ([deltakosh](https://github.com/deltakosh))

+ 9 - 1
proceduralTexturesLibrary/index.html

@@ -49,6 +49,7 @@
 	<script src="test/addBrickPT.js"></script>
 	<script src="test/addBrickPT.js"></script>
 	<script src="test/addMarblePT.js"></script>
 	<script src="test/addMarblePT.js"></script>
 	<script src="test/addStarfieldPT.js"></script>
 	<script src="test/addStarfieldPT.js"></script>
+	<script src="test/addNormalMapPT.js"></script>
 	<script>
 	<script>
 		BABYLONDEVTOOLS.Loader.load(function() {
 		BABYLONDEVTOOLS.Loader.load(function() {
 		if (BABYLON.Engine.isSupported()) {
 		if (BABYLON.Engine.isSupported()) {
@@ -186,6 +187,10 @@
 				
 				
 				// Starfield Procedural Texture
 				// Starfield Procedural Texture
                 var starfieldPT = addStarfieldPT();
                 var starfieldPT = addStarfieldPT();
+
+				// Normal Map Procedural Texture
+				var normalMapPT = addNormalMapPT();
+				normalMapPT.baseTexture = diffuseTexture;
 								
 								
 				// Default to std
 				// Default to std
 				var currentTexture = diffuseTexture;
 				var currentTexture = diffuseTexture;
@@ -302,7 +307,7 @@
 					}
 					}
 				}
 				}
 				
 				
-				gui.add(options, 'texture', ['default', 'fire', 'wood', 'cloud', 'grass', 'road', 'brick', 'marble', 'starfield']).onFinishChange(function () {
+				gui.add(options, 'texture', ['default', 'fire', 'wood', 'cloud', 'grass', 'road', 'brick', 'marble', 'starfield', 'normalMap']).onFinishChange(function () {
 					resetPTOptions();
 					resetPTOptions();
 					switch (options.texture) {
 					switch (options.texture) {
 						case "fire":
 						case "fire":
@@ -337,6 +342,9 @@
 							currentTexture = starfieldPT;
 							currentTexture = starfieldPT;
 							addPToptions(starfieldPT, ['saturation', 'distfading', 'darkmatter', 'alpha', 'time', 'beta', 'zoom', 'formuparam', 'stepsize', 'tile', 'brightness']);
 							addPToptions(starfieldPT, ['saturation', 'distfading', 'darkmatter', 'alpha', 'time', 'beta', 'zoom', 'formuparam', 'stepsize', 'tile', 'brightness']);
 							break;
 							break;
+						case "normalMap":
+							currentTexture = normalMapPT;
+							break;
 						case "none":
 						case "none":
 						default:
 						default:
 							currentTexture = diffuseTexture;
 							currentTexture = diffuseTexture;

+ 37 - 0
proceduralTexturesLibrary/src/normalMap/babylon.normalMapProceduralTexture.ts

@@ -0,0 +1,37 @@
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON {
+    export class NormalMapProceduralTexture extends ProceduralTexture {
+        private _baseTexture: Texture;
+
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean) {
+            super(name, size, "normalMapProceduralTexture", scene, fallbackTexture, generateMipMaps);
+            this.updateShaderUniforms();
+        }
+
+        public updateShaderUniforms() {
+            this.setTexture("baseSampler", this._baseTexture);
+            this.setFloat("size", this.getRenderSize());
+        }
+
+        public render(useCameraPostProcess?: boolean) {
+            super.render(useCameraPostProcess);
+        }
+
+        public resize(size: any, generateMipMaps: any): void {
+            super.resize(size, generateMipMaps);
+
+            // We need to update the "size" uniform
+            this.updateShaderUniforms();
+        }
+
+        public get baseTexture(): Texture {
+            return this._baseTexture;
+        }
+
+        public set baseTexture(texture: Texture) {
+            this._baseTexture = texture;
+            this.updateShaderUniforms();
+        }
+    }
+}

+ 30 - 0
proceduralTexturesLibrary/src/normalMap/normalMapProceduralTexture.fragment.fx

@@ -0,0 +1,30 @@
+precision highp float;
+
+// Uniforms
+uniform sampler2D baseSampler;
+uniform float size;
+
+// Varyings
+varying vec2 vUV;
+
+// Constants
+const vec3 LUMA_COEFFICIENT = vec3(0.2126, 0.7152, 0.0722);
+
+float lumaAtCoord(vec2 coord)
+{
+	vec3 pixel = texture2D(baseSampler, coord).rgb;
+	float luma = dot(pixel, LUMA_COEFFICIENT);
+	return luma;
+}
+
+void main()
+{
+	float lumaU0 = lumaAtCoord(vUV + vec2(-1.0,  0.0) / size);
+	float lumaU1 = lumaAtCoord(vUV + vec2( 1.0,  0.0) / size);
+	float lumaV0 = lumaAtCoord(vUV + vec2( 0.0, -1.0) / size);
+	float lumaV1 = lumaAtCoord(vUV + vec2( 0.0,  1.0) / size);
+
+	vec2 slope = (vec2(lumaU0 - lumaU1, lumaV0 - lumaV1) + 1.0) * 0.5;
+
+	gl_FragColor = vec4(slope, 1.0, 1.0);
+}

+ 6 - 0
proceduralTexturesLibrary/test/addNormalMapPT.js

@@ -0,0 +1,6 @@
+window.addNormalMapPT = function() {
+    // 128 = the size of the base texture which is "amiga" here
+    var nm = new BABYLON.NormalMapProceduralTexture("normalMapPT", 128, scene);
+
+    return nm;
+};

+ 3 - 9
readme.md

@@ -14,15 +14,9 @@ Getting started? Play directly with the Babylon.js API via our [playground](http
 - http://cdn.babylonjs.com/2-5/babylon.core.js 
 - http://cdn.babylonjs.com/2-5/babylon.core.js 
 
 
 ## Preview release
 ## Preview release
-You can help by testing or contributing to the next version.
-- **3.0-alpha** can be found [here](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release)
-- We are not complicated people, but we still have some [coding guidelines](http://doc.babylonjs.com/generals/Approved_Naming_Conventions)
-- Before submitting your PR, just check that everything goes well by [creating the minified version](http://doc.babylonjs.com/generals/Creating_the_Mini-fied_Version)
-- Need help contributing, here are some links:
-  - [Gulp](https://github.com/BabylonJS/Babylon.js/tree/master/Tools/Gulp) to build from command line.
-  - [VSCode Editor](https://code.visualstudio.com/), Microsoft Code editor, see [Julian Chenard's post](http://pixelcodr.com/tutos/contribute/contribute.html) a Microsoft code editor.
-  - [Visual Studio](http://doc.babylonjs.com/generals/setup_visualStudio), Microsoft's IDE.
-  - [Forum thread](http://www.html5gamedevs.com/topic/20456-contributing-on-babylonjs/) for assistance from our very helpful family.
+
+**3.0-alpha** can be found [here](https://github.com/BabylonJS/Babylon.js/tree/master/dist/preview%20release)
+If you want to contribute, please read our [contribution guidelines](https://github.com/BabylonJS/Babylon.js/blob/master/contributing.md) first.
 
 
 ## Documentation
 ## Documentation
 - [Documentation](http://doc.babylonjs.com)
 - [Documentation](http://doc.babylonjs.com)

+ 432 - 180
src/Bones/babylon.boneLookController.ts

@@ -3,114 +3,167 @@ module BABYLON {
 
 
         private static _tmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         private static _tmpVecs: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(),Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
         private static _tmpQuat = Quaternion.Identity();
         private static _tmpQuat = Quaternion.Identity();
-        private static _tmpMat1 = Matrix.Identity();
-        private static _tmpMat2 = Matrix.Identity();
-
+        private static _tmpMats: Matrix[] = [Matrix.Identity(), Matrix.Identity(), Matrix.Identity(), Matrix.Identity(), Matrix.Identity()];
+        
+        /**
+         * The target Vector3 that the bone will look at.
+         */
         public target: Vector3;
         public target: Vector3;
+
+        /**
+         * The mesh that the bone is attached to.
+         */
         public mesh: AbstractMesh;
         public mesh: AbstractMesh;
+
+        /**
+         * The bone that will be looking to the target.
+         */
         public bone: Bone;
         public bone: Bone;
+
+        /**
+         * The up axis of the coordinate system that is used when the bone is rotated.
+         */
         public upAxis: Vector3 = Vector3.Up();
         public upAxis: Vector3 = Vector3.Up();
+
+        /**
+         * The space that the up axis is in - BABYLON.Space.BONE, BABYLON.Space.LOCAL (default), or BABYLON.Space.WORLD.
+         */
+        public upAxisSpace: Space = Space.LOCAL;
+
+        /**
+         * Used to make an adjustment to the yaw of the bone.
+         */
+        public adjustYaw = 0;
+
+        /**
+         * Used to make an adjustment to the pitch of the bone.
+         */
+        public adjustPitch = 0;
+
+        /**
+         * Used to make an adjustment to the roll of the bone.
+         */
+        public adjustRoll = 0;
+
+        /**
+         * The amount to slerp (spherical linear interpolation) to the target.  Set this to a value between 0 and 1 (a value of 1 disables slerp).
+         */
         public slerpAmount = 1;
         public slerpAmount = 1;
 
 
-        private _adjustRotY = 0;
-        private _adjustRotX = 0;
-        private _adjustRotZ = 0;
-        private _minRotY:number;
-        private _maxRotY:number;
-        private _minRotX:number;
-        private _maxRotX:number;
-        private _minRotYSin:number;
-        private _minRotYCos:number;
-        private _maxRotYSin:number;
-        private _maxRotYCos:number;
-        private _minRotXTan:number;
-        private _maxRotXTan:number;
-        private _minRotZ:number;
-        private _maxRotZ:number;
-        private _minRotZSin:number;
-        private _minRotZCos:number;
-        private _maxRotZSin:number;
-        private _maxRotZCos:number;
+        private _minYaw:number;
+        private _maxYaw:number;
+        private _minPitch:number;
+        private _maxPitch:number;
+        private _minYawSin:number;
+        private _minYawCos:number;
+        private _maxYawSin:number;
+        private _maxYawCos:number;
+        private _midYawConstraint:number;
+        private _minPitchTan:number;
+        private _maxPitchTan:number;
+        
         private _boneQuat:Quaternion = Quaternion.Identity();
         private _boneQuat:Quaternion = Quaternion.Identity();
         private _slerping = false;
         private _slerping = false;
-
-        get minRotationY():number{
-            return this._minRotY - this._adjustRotY;
-        }
-
-        set minRotationY(value:number){
-            this._minRotY = value + this._adjustRotY;
-            this._minRotYSin = Math.sin(this._minRotY);
-            this._minRotYCos = Math.cos(this._minRotY);
-        }
-
-        get maxRoationY():number{
-            return this._maxRotY - this._adjustRotY;
-        }
-
-        set maxRotationY(value:number){
-            this._maxRotY = value + this._adjustRotY;
-            this._maxRotYSin = Math.sin(this._maxRotY);
-            this._maxRotYCos = Math.cos(this._maxRotY);
-        }
-
-        get minRotationX():number{
-            return this._minRotX - this._adjustRotX;
+        private _transformYawPitch:Matrix;
+        private _transformYawPitchInv:Matrix;
+        private _firstFrameSkipped = false;
+        private _yawRange:number;
+        private _fowardAxis: Vector3 = Vector3.Forward();
+
+        /**
+         * Get/set the minimum yaw angle that the bone can look to.
+         */
+        get minYaw():number{
+            return this._minYaw;
         }
         }
 
 
-        set minRotationX(value:number){
-            this._minRotX = value + this._adjustRotX;
-            this._minRotXTan = Math.tan(this._minRotX);
+        set minYaw(value:number){
+            this._minYaw = value;
+            this._minYawSin = Math.sin(value);
+            this._minYawCos = Math.cos(value);
+            if(this._maxYaw != null){
+                this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw)*.5 + this._minYaw;
+                this._yawRange = this._maxYaw - this._minYaw;
+            }
         }
         }
 
 
-        get maxRotationX():number{
-            return this._maxRotX - this._adjustRotX;
+        /**
+         * Get/set the maximum yaw angle that the bone can look to.
+         */
+        get maxYaw():number{
+            return this._maxYaw;
         }
         }
 
 
-        set maxRotationX(value:number){
-            this._maxRotX = value + this._adjustRotX;
-            this._maxRotXTan = Math.tan(this._maxRotX);
+        set maxYaw(value:number){
+            this._maxYaw = value;
+            this._maxYawSin = Math.sin(value);
+            this._maxYawCos = Math.cos(value);
+            if(this._minYaw != null){
+                this._midYawConstraint = this._getAngleDiff(this._minYaw, this._maxYaw)*.5 + this._minYaw;
+                this._yawRange = this._maxYaw - this._minYaw;
+            }
         }
         }
 
 
-        get minRotationZ():number{
-            return this._minRotZ - this._adjustRotZ;
+        /**
+         * Get/set the minimum pitch angle that the bone can look to.
+         */
+        get minPitch():number{
+            return this._minPitch;
         }
         }
 
 
-        set minRotationZ(value:number){
-            this._minRotZ = value + this._adjustRotZ;
-            this._minRotZSin = Math.sin(this._minRotZ);
-            this._minRotZCos = Math.cos(this._minRotZ);
+        set minPitch(value:number){
+            this._minPitch = value;
+            this._minPitchTan = Math.tan(value);
         }
         }
 
 
-        get maxRotationZ():number{
-            return this._maxRotZ - this._adjustRotZ;
+        /**
+         * Get/set the maximum pitch angle that the bone can look to.
+         */
+        get maxPitch():number{
+            return this._maxPitch;
         }
         }
 
 
-        set maxRotationZ(value:number){
-            this._maxRotZ = value + this._adjustRotZ;
-            this._maxRotZSin = Math.sin(this._maxRotZ);
-            this._maxRotZCos = Math.cos(this._maxRotZ);
+        set maxPitch(value:number){
+            this._maxPitch = value;
+            this._maxPitchTan = Math.tan(value);
         }
         }
 
 
+        /**
+         * Create a BoneLookController
+         * @param mesh the mesh that the bone belongs to
+         * @param bone the bone that will be looking to the target
+         * @param target the target Vector3 to look at
+         * @param settings optional settings:
+         * - maxYaw: the maximum angle the bone will yaw to
+         * - minYaw: the minimum angle the bone will yaw to
+         * - maxPitch: the maximum angle the bone will pitch to
+         * - minPitch: the minimum angle the bone will yaw to
+         * - slerpAmount: set the between 0 and 1 to make the bone slerp to the target.
+         * - upAxis: the up axis of the coordinate system
+         * - upAxisSpace: the space that the up axis is in - BABYLON.Space.BONE, BABYLON.Space.LOCAL (default), or BABYLON.Space.WORLD.
+         * - yawAxis: set yawAxis if the bone does not yaw on the y axis
+         * - pitchAxis: set pitchAxis if the bone does not pitch on the x axis
+         * - adjustYaw: used to make an adjustment to the yaw of the bone
+         * - adjustPitch: used to make an adjustment to the pitch of the bone
+         * - adjustRoll: used to make an adjustment to the roll of the bone
+         **/
         constructor(mesh: AbstractMesh, 
         constructor(mesh: AbstractMesh, 
                     bone: Bone, 
                     bone: Bone, 
                     target: Vector3, 
                     target: Vector3, 
-                    options?: { 
-                        adjustRotationX?: number, 
-                        adjustRotationY?: number, 
-                        adjustRotationZ?: number, 
-                        slerpAmount?: number, 
-                        maxRotationY?:number, 
-                        minRotationY?:number,
-                        maxRotationX?:number, 
-                        minRotationX?:number,
-                        maxRotationZ?:number, 
-                        minRotationZ?:number,
+                    options?: {
                         adjustYaw?: number, 
                         adjustYaw?: number, 
                         adjustPitch?: number, 
                         adjustPitch?: number, 
-                        adjustRoll?: number 
-                    } 
-                    ){
+                        adjustRoll?: number, 
+                        slerpAmount?: number, 
+                        maxYaw?:number, 
+                        minYaw?:number, 
+                        maxPitch?:number, 
+                        minPitch?:number,
+                        upAxis?:Vector3,
+                        upAxisSpace?:Space,
+                        yawAxis?:Vector3,
+                        pitchAxis?:Vector3
+                    }){
 
 
             this.mesh = mesh;
             this.mesh = mesh;
             this.bone = bone;
             this.bone = bone;
@@ -119,158 +172,292 @@ module BABYLON {
             if(options){
             if(options){
 
 
                 if(options.adjustYaw){
                 if(options.adjustYaw){
-                    this._adjustRotY = options.adjustYaw;
+                    this.adjustYaw = options.adjustYaw;
                 }
                 }
 
 
                 if(options.adjustPitch){
                 if(options.adjustPitch){
-                    this._adjustRotX = options.adjustPitch;
+                    this.adjustPitch = options.adjustPitch;
                 }
                 }
 
 
                 if(options.adjustRoll){
                 if(options.adjustRoll){
-                    this._adjustRotZ = options.adjustRoll;
+                    this.adjustRoll = options.adjustRoll;
                 }
                 }
 
 
-                if(options.adjustRotationY){
-                    this._adjustRotY = options.adjustRotationY;
+                if(options.maxYaw != null){
+                    this.maxYaw = options.maxYaw;
+                }else{
+                    this.maxYaw = Math.PI;
                 }
                 }
 
 
-                if(options.adjustRotationX){
-                    this._adjustRotX = options.adjustRotationX;
+                if(options.minYaw != null){
+                    this.minYaw = options.minYaw;
+                }else{
+                    this.minYaw = -Math.PI;
                 }
                 }
 
 
-                if(options.adjustRotationZ){
-                    this._adjustRotZ = options.adjustRotationZ;
+                if(options.maxPitch != null){
+                    this.maxPitch = options.maxPitch;
+                }else{
+                    this.maxPitch = Math.PI;
                 }
                 }
 
 
-                if(options.maxRotationY != undefined){
-                    this.maxRotationY = options.maxRotationY;
+                if(options.minPitch != null){
+                    this.minPitch = options.minPitch;
+                }else{
+                    this.minPitch = -Math.PI;
                 }
                 }
 
 
-                if(options.minRotationY != undefined){
-                    this.minRotationY = options.minRotationY;
+                if(options.slerpAmount != null){
+                    this.slerpAmount = options.slerpAmount;
                 }
                 }
 
 
-                if(options.maxRotationX != undefined){
-                    this.maxRotationX = options.maxRotationX;
+                if(options.upAxis != null){
+                    this.upAxis = options.upAxis;
                 }
                 }
 
 
-                if(options.minRotationX != undefined){
-                    this.minRotationX = options.minRotationX;
+                if(options.upAxisSpace != null){
+                    this.upAxisSpace = options.upAxisSpace;
                 }
                 }
 
 
-                if(options.maxRotationZ != undefined){
-                    this.maxRotationZ = options.maxRotationZ;
-                }
+                if(options.yawAxis != null || options.pitchAxis != null){
 
 
-                if(options.minRotationZ != undefined){
-                    this.minRotationZ = options.minRotationZ;
-                }
+                    var newYawAxis = Axis.Y;
+                    var newPitchAxis = Axis.X;
 
 
-                if(options.slerpAmount != undefined){
-                    this.slerpAmount = options.slerpAmount;
+                    if(options.yawAxis != null){
+                        newYawAxis = options.yawAxis.clone();
+                        newYawAxis.normalize();
+                    }
+
+                    if(options.pitchAxis != null){
+                        newPitchAxis = options.pitchAxis.clone();
+                        newPitchAxis.normalize();
+                    }
+
+                    var newRollAxis = Vector3.Cross(newPitchAxis, newYawAxis);
+
+                    this._transformYawPitch = Matrix.Identity();
+                    Matrix.FromXYZAxesToRef(newPitchAxis, newYawAxis, newRollAxis, this._transformYawPitch);
+
+                    this._transformYawPitchInv = this._transformYawPitch.clone();
+                    this._transformYawPitch.invert();
+                    
                 }
                 }
 
 
             }
             }
 
 
+            if(!bone.getParent() && this.upAxisSpace == Space.BONE){
+                this.upAxisSpace = Space.LOCAL;
+            }
+
         }
         }
 
 
+        /**
+         * Update the bone to look at the target.  This should be called before the scene is rendered (use scene.registerBeforeRender()).
+         */
         public update (): void {
         public update (): void {
-                
+
+            //skip the first frame when slerping so that the mesh rotation is correct
+            if(this.slerpAmount < 1 && !this._firstFrameSkipped){
+                this._firstFrameSkipped = true;
+                return;
+            }
+
             var bone = this.bone;
             var bone = this.bone;
-            var target = this.target;
-            var mat1 = BoneLookController._tmpMat1;
-            var mat2 = BoneLookController._tmpMat2;
+            var bonePos = BoneLookController._tmpVecs[0];
+            bone.getAbsolutePositionToRef(this.mesh, bonePos);
 
 
+            var target = this.target;
+            var _tmpMat1 = BoneLookController._tmpMats[0];
+            var _tmpMat2 = BoneLookController._tmpMats[1];
+            
+            var mesh = this.mesh;
             var parentBone = bone.getParent();
             var parentBone = bone.getParent();
 
 
-            if(parentBone){
-                if(this._maxRotX != undefined || this._minRotX != undefined){
-                    var localTarget = BoneLookController._tmpVecs[4];
-                    var _tmpVec5 = BoneLookController._tmpVecs[5];
-                    parentBone.getLocalPositionFromAbsoluteToRef(target, this.mesh, localTarget);
-                    bone.getPositionToRef(Space.LOCAL, null, _tmpVec5);
-                    localTarget.x -= _tmpVec5.x;
-                    localTarget.y -= _tmpVec5.y;
-                    localTarget.z -= _tmpVec5.z;
-                    var xzlen = Math.sqrt(localTarget.x*localTarget.x + localTarget.z*localTarget.z);
-                    var rotX = Math.atan2(localTarget.y, xzlen);
-
-                    if(rotX > this._maxRotX){
-                        localTarget.y = this._maxRotXTan*xzlen + _tmpVec5.y;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
-                        target = localTarget;
-                    }else if(rotX < this._minRotX){
-                        localTarget.y = this._minRotXTan*xzlen + _tmpVec5.y;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
-                        target = localTarget;
-                    }
+            var upAxis = BoneLookController._tmpVecs[1];
+            upAxis.copyFrom(this.upAxis);
+
+            if(this.upAxisSpace == Space.BONE){
+                if (this._transformYawPitch){
+                    Vector3.TransformCoordinatesToRef(upAxis, this._transformYawPitchInv, upAxis);
                 }
                 }
+                parentBone.getDirectionToRef(upAxis, this.mesh, upAxis);
+            }else if(this.upAxisSpace == Space.LOCAL){
+                mesh.getDirectionToRef(upAxis, upAxis);
+                if(mesh.scaling.x != 1 || mesh.scaling.y != 1 || mesh.scaling.z != 1){
+                    upAxis.normalize();
+                }
+            }
+
+            var checkYaw = false;
+            var checkPitch = false;
+
+            if(this._maxYaw != Math.PI || this._minYaw != -Math.PI){
+                checkYaw = true;
+            }
+            if(this._maxPitch != Math.PI || this._minPitch != -Math.PI){
+                checkPitch = true;
+            }
 
 
-                if(this._maxRotY != undefined || this._minRotY != undefined){
-                    var localTarget = BoneLookController._tmpVecs[6];
-                    var _tmpVec7 = BoneLookController._tmpVecs[7];
-                    parentBone.getLocalPositionFromAbsoluteToRef(target, this.mesh, localTarget);
-                    bone.getPositionToRef(Space.LOCAL, null, _tmpVec7);
-                    localTarget.x -= _tmpVec7.x;
-                    localTarget.z -= _tmpVec7.z;
-                    var rotY = Math.atan2(localTarget.x, localTarget.z);
+            if(checkYaw || checkPitch){
+
+                var _tmpMat3 = BoneLookController._tmpMats[2];
+                var _tmpMat3Inv = BoneLookController._tmpMats[3];
+
+                if(this.upAxisSpace == Space.BONE && upAxis.y == 1){
+
+                    parentBone.getRotationMatrixToRef(Space.WORLD, this.mesh, _tmpMat3);
                     
                     
-                    if(rotY > this._maxRotY){
-                        var xzlen = Math.sqrt(localTarget.x*localTarget.x + localTarget.z*localTarget.z);
-                        localTarget.z = this._maxRotYCos*xzlen;
-                        localTarget.x = this._maxRotYSin*xzlen;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
-                        target = localTarget;
-                    }else if(rotY < this._minRotY){
-                        var xzlen = Math.sqrt(localTarget.x*localTarget.x + localTarget.z*localTarget.z);
-                        localTarget.z = this._minRotYCos*xzlen;
-                        localTarget.x = this._minRotYSin*xzlen;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
-                        target = localTarget;
+                }else if(this.upAxisSpace == Space.LOCAL && upAxis.y == 1 && !parentBone){
+
+                    _tmpMat3.copyFrom(mesh.getWorldMatrix());
+
+                }else{
+
+                    var forwardAxis = BoneLookController._tmpVecs[2];
+                    forwardAxis.copyFrom(this._fowardAxis);
+                    
+                    if (this._transformYawPitch) {
+                        Vector3.TransformCoordinatesToRef(forwardAxis, this._transformYawPitchInv, forwardAxis);
+                    }
+
+                    if(parentBone){
+                        parentBone.getDirectionToRef(forwardAxis, this.mesh, forwardAxis);
+                    }else{
+                        mesh.getDirectionToRef(forwardAxis, forwardAxis);
                     }
                     }
+
+                    var rightAxis = Vector3.Cross(upAxis, forwardAxis);
+                    rightAxis.normalize();
+                    var forwardAxis = Vector3.Cross(rightAxis, upAxis);
+
+                    Matrix.FromXYZAxesToRef(rightAxis, upAxis, forwardAxis, _tmpMat3);
+                    
                 }
                 }
 
 
-                if(this._maxRotZ != undefined || this._minRotZ != undefined){
-                    var localTarget = BoneLookController._tmpVecs[8];
-                    var _tmpVec9 = BoneLookController._tmpVecs[9];
-                    parentBone.getLocalPositionFromAbsoluteToRef(target, this.mesh, localTarget);
-                    bone.getPositionToRef(Space.LOCAL, null, _tmpVec9);
-                    localTarget.x -= _tmpVec9.x;
-                    localTarget.y -= _tmpVec9.y;
-                    var rotZ = Math.atan2(localTarget.y, localTarget.x);
+                _tmpMat3.invertToRef(_tmpMat3Inv);
+                
+                var xzlen:number;
+
+                if(checkPitch){
+                    var localTarget = BoneLookController._tmpVecs[3];
+                    Vector3.TransformCoordinatesToRef(target.subtract(bonePos), _tmpMat3Inv, localTarget);
+
+                    var xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
+                    var pitch = Math.atan2(localTarget.y, xzlen);
+                    var newPitch = pitch;
+
+                    if(pitch > this._maxPitch){
+                        localTarget.y = this._maxPitchTan*xzlen;
+                        newPitch = this._maxPitch;
+                    }else if(pitch < this._minPitch){
+                        localTarget.y = this._minPitchTan*xzlen;
+                        newPitch = this._minPitch;
+                    }
                     
                     
-                    if(rotZ > this._maxRotZ){
-                        var xylen = Math.sqrt(localTarget.x*localTarget.x + localTarget.y*localTarget.y);
-                        localTarget.x = this._maxRotZCos*xylen;
-                        localTarget.y = this._maxRotZSin*xylen;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
-                        target = localTarget;
-                    }else if(rotZ < this._minRotZ){
-                        var xylen = Math.sqrt(localTarget.x*localTarget.x + localTarget.y*localTarget.y);
-                        localTarget.x = this._minRotZCos*xylen;
-                        localTarget.y = this._minRotZSin*xylen;
-                        parentBone.getAbsolutePositionFromLocalToRef(localTarget, this.mesh, localTarget);
+                    if(pitch != newPitch){
+                        Vector3.TransformCoordinatesToRef(localTarget, _tmpMat3, localTarget);
+                        localTarget.addInPlace(bonePos);
                         target = localTarget;
                         target = localTarget;
                     }
                     }
                 }
                 }
 
 
+                if(checkYaw){
+                    var localTarget = BoneLookController._tmpVecs[4];
+                    Vector3.TransformCoordinatesToRef(target.subtract(bonePos), _tmpMat3Inv, localTarget);
+
+                    var yaw = Math.atan2(localTarget.x, localTarget.z);
+                    var newYaw = yaw;
+
+                    if(yaw > this._maxYaw || yaw < this._minYaw){
+                        
+                        if(xzlen == null){
+                            xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
+                        }
+
+                        if(this._yawRange > Math.PI){
+                            if (this._isAngleBetween(yaw, this._maxYaw, this._midYawConstraint)) {
+                                localTarget.z = this._maxYawCos * xzlen;
+                                localTarget.x = this._maxYawSin * xzlen;
+                                newYaw = this._maxYaw;
+                            }else if (this._isAngleBetween(yaw, this._midYawConstraint, this._minYaw)) {
+                                localTarget.z = this._minYawCos * xzlen;
+                                localTarget.x = this._minYawSin * xzlen;
+                                newYaw = this._minYaw;
+                            }
+                        }else{
+                            if (yaw > this._maxYaw) {
+                                localTarget.z = this._maxYawCos * xzlen;
+                                localTarget.x = this._maxYawSin * xzlen;
+                                newYaw = this._maxYaw;
+                            }else if (yaw < this._minYaw) {
+                                localTarget.z = this._minYawCos * xzlen;
+                                localTarget.x = this._minYawSin * xzlen;
+                                newYaw = this._minYaw;
+                            }
+                        }
+                    }
+
+                    if(this._slerping && this._yawRange > Math.PI){
+                        //are we going to be crossing into the min/max region
+                        var _tmpVec8 = BoneLookController._tmpVecs[8];
+                        _tmpVec8.copyFrom(Axis.Z);
+                        if (this._transformYawPitch) {
+                            Vector3.TransformCoordinatesToRef(_tmpVec8, this._transformYawPitchInv, _tmpVec8);
+                        }
+
+                        var boneRotMat = BABYLON.BoneLookController._tmpMats[4];
+                        this._boneQuat.toRotationMatrix(boneRotMat);
+                        this.mesh.getWorldMatrix().multiplyToRef(boneRotMat, boneRotMat);
+                        BABYLON.Vector3.TransformCoordinatesToRef(_tmpVec8, boneRotMat, _tmpVec8);
+                        BABYLON.Vector3.TransformCoordinatesToRef(_tmpVec8, _tmpMat3Inv, _tmpVec8);
+
+                        var boneYaw = Math.atan2(_tmpVec8.x, _tmpVec8.z);
+                        var ang1 = this._getAngleBetween(boneYaw, yaw);
+                        var ang2 = this._getAngleBetween(boneYaw, this._midYawConstraint);
+
+                        if(ang1 > ang2){
+
+                            if (xzlen == null) {
+                                xzlen = Math.sqrt(localTarget.x * localTarget.x + localTarget.z * localTarget.z);
+                            }
+
+                            var ang3 = this._getAngleBetween(boneYaw, this._maxYaw);
+                            var ang4 = this._getAngleBetween(boneYaw, this._minYaw);
+
+                            if(ang4 < ang3){
+                                newYaw = boneYaw+Math.PI*.75;
+                                localTarget.z = Math.cos(newYaw) * xzlen;
+                                localTarget.x = Math.sin(newYaw) * xzlen;
+                            }else{
+                                newYaw = boneYaw-Math.PI*.75;
+                                localTarget.z = Math.cos(newYaw) * xzlen;
+                                localTarget.x = Math.sin(newYaw) * xzlen;
+                            }
+                        }
+                    }
+
+                    if(yaw != newYaw){
+                        Vector3.TransformCoordinatesToRef(localTarget, _tmpMat3, localTarget);
+                        localTarget.addInPlace(bonePos);
+                        target = localTarget;
+                    }
+                }
 
 
             }
             }
 
 
-            var bonePos = BoneLookController._tmpVecs[0];
-            var zaxis = BoneLookController._tmpVecs[1];
-            var xaxis = BoneLookController._tmpVecs[2];
-            var yaxis = BoneLookController._tmpVecs[3];
+            var zaxis = BoneLookController._tmpVecs[5];
+            var xaxis = BoneLookController._tmpVecs[6];
+            var yaxis = BoneLookController._tmpVecs[7];
             var _tmpQuat = BoneLookController._tmpQuat;
             var _tmpQuat = BoneLookController._tmpQuat;
 
 
-            bone.getAbsolutePositionToRef(this.mesh, bonePos);
             target.subtractToRef(bonePos, zaxis);
             target.subtractToRef(bonePos, zaxis);
             zaxis.normalize();
             zaxis.normalize();
-            Vector3.CrossToRef(this.upAxis, zaxis, xaxis);
+            Vector3.CrossToRef(upAxis, zaxis, xaxis);
             xaxis.normalize();
             xaxis.normalize();
             Vector3.CrossToRef(zaxis, xaxis, yaxis);
             Vector3.CrossToRef(zaxis, xaxis, yaxis);
             yaxis.normalize();
             yaxis.normalize();
-            Matrix.FromXYZAxesToRef(xaxis, yaxis, zaxis, mat1);
+            Matrix.FromXYZAxesToRef(xaxis, yaxis, zaxis, _tmpMat1);
 
 
             if(xaxis.x === 0 && xaxis.y === 0 && xaxis.z === 0){
             if(xaxis.x === 0 && xaxis.y === 0 && xaxis.z === 0){
                 return;
                 return;
@@ -284,25 +471,90 @@ module BABYLON {
                 return;
                 return;
             }
             }
 
 
-            if (this._adjustRotY || this._adjustRotX || this._adjustRotZ) {
-                Matrix.RotationYawPitchRollToRef(this._adjustRotY, this._adjustRotX, this._adjustRotZ, mat2);
-                mat2.multiplyToRef(mat1, mat1);
+            if (this.adjustYaw || this.adjustPitch || this.adjustRoll) {
+                Matrix.RotationYawPitchRollToRef(this.adjustYaw, this.adjustPitch, this.adjustRoll, _tmpMat2);
+                _tmpMat2.multiplyToRef(_tmpMat1, _tmpMat1);
             }
             }
 
 
             if (this.slerpAmount < 1) {
             if (this.slerpAmount < 1) {
                 if (!this._slerping) {
                 if (!this._slerping) {
                     this.bone.getRotationQuaternionToRef(Space.WORLD, this.mesh, this._boneQuat);
                     this.bone.getRotationQuaternionToRef(Space.WORLD, this.mesh, this._boneQuat);
                 }
                 }
-                Quaternion.FromRotationMatrixToRef(mat1, _tmpQuat);
+                if(this._transformYawPitch){
+                    this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);
+                }
+                Quaternion.FromRotationMatrixToRef(_tmpMat1, _tmpQuat);
                 Quaternion.SlerpToRef(this._boneQuat, _tmpQuat, this.slerpAmount, this._boneQuat);
                 Quaternion.SlerpToRef(this._boneQuat, _tmpQuat, this.slerpAmount, this._boneQuat);
+                
                 this.bone.setRotationQuaternion(this._boneQuat, Space.WORLD, this.mesh);
                 this.bone.setRotationQuaternion(this._boneQuat, Space.WORLD, this.mesh);
                 this._slerping = true;
                 this._slerping = true;
             } else {
             } else {
-                this.bone.setRotationMatrix(mat1, Space.WORLD, this.mesh);
+                if(this._transformYawPitch){
+                    this._transformYawPitch.multiplyToRef(_tmpMat1, _tmpMat1);
+                }
+                this.bone.setRotationMatrix(_tmpMat1, Space.WORLD, this.mesh);
                 this._slerping = false;
                 this._slerping = false;
             }
             }
 
 
         }
         }
 
 
+        private _getAngleDiff(ang1, ang2):number {
+
+            var angDiff = ang2 - ang1;
+            angDiff %= Math.PI*2;
+            
+            if(angDiff > Math.PI){
+                angDiff -= Math.PI*2;
+            }else if (angDiff < -Math.PI){
+                angDiff += Math.PI*2;
+            }
+            
+            return angDiff;
+        }
+
+        private _getAngleBetween(ang1, ang2):number {
+
+            ang1 %= (2 * Math.PI);
+            ang1 = (ang1 < 0) ? ang1 + (2 * Math.PI) : ang1;
+
+            ang2 %= (2 * Math.PI);
+            ang2 = (ang2 < 0) ? ang2 + (2 * Math.PI) : ang2;
+
+            var ab = 0;
+
+            if(ang1 < ang2){
+                ab = ang2 - ang1;
+            }else{
+                ab = ang1 - ang2;
+            }
+
+            if(ab > Math.PI){
+                ab = Math.PI*2 - ab;
+            }
+
+            return ab;
+        }
+
+        private _isAngleBetween(ang, ang1, ang2):boolean {
+
+            ang %= (2 * Math.PI);
+            ang = (ang < 0) ? ang + (2 * Math.PI) : ang;
+            ang1 %= (2 * Math.PI);
+            ang1 = (ang1 < 0) ? ang1 + (2 * Math.PI) : ang1;
+            ang2 %= (2 * Math.PI);
+            ang2 = (ang2 < 0) ? ang2 + (2 * Math.PI) : ang2;
+
+            if(ang1 < ang2){
+                if(ang > ang1 && ang < ang2){
+                    return true;
+                }
+            }else{
+                if(ang > ang2 && ang < ang1){
+                    return true;
+                }
+            }
+            return false;
+        }
+
     }
     }
 }
 }

+ 1 - 1
src/Bones/babylon.skeleton.ts

@@ -361,7 +361,7 @@
                 var serializedBone: any = {
                 var serializedBone: any = {
                     parentBoneIndex: bone.getParent() ? this.bones.indexOf(bone.getParent()) : -1,
                     parentBoneIndex: bone.getParent() ? this.bones.indexOf(bone.getParent()) : -1,
                     name: bone.name,
                     name: bone.name,
-                    matrix: bone.getLocalMatrix().toArray(),
+                    matrix: bone.getBaseMatrix().toArray(),
                     rest: bone.getRestPose().toArray()
                     rest: bone.getRestPose().toArray()
                 };
                 };
 
 

+ 31 - 18
src/Cameras/Inputs/babylon.freecamera.input.gamepad.ts

@@ -1,7 +1,7 @@
-module BABYLON {       
+module BABYLON {
     export class FreeCameraGamepadInput implements ICameraInput<FreeCamera> {
     export class FreeCameraGamepadInput implements ICameraInput<FreeCamera> {
-        camera : FreeCamera;
-        
+        camera: FreeCamera;
+
         public gamepad: Gamepad;
         public gamepad: Gamepad;
         private _gamepads: Gamepads;
         private _gamepads: Gamepads;
 
 
@@ -10,19 +10,25 @@ module BABYLON {
 
 
         @serialize()
         @serialize()
         public gamepadMoveSensibility = 40;
         public gamepadMoveSensibility = 40;
-        
-        attachControl(element : HTMLElement, noPreventDefault?: boolean){
+
+        // private members
+        private _cameraTransform: Matrix = Matrix.Identity();
+        private _deltaTransform: Vector3 = Vector3.Zero();
+        private _vector3: Vector3 = Vector3.Zero();
+        private _vector2: Vector2 = Vector2.Zero();
+
+        attachControl(element: HTMLElement, noPreventDefault?: boolean) {
             this._gamepads = new Gamepads((gamepad: Gamepad) => { this._onNewGameConnected(gamepad); });
             this._gamepads = new Gamepads((gamepad: Gamepad) => { this._onNewGameConnected(gamepad); });
         }
         }
-        
+
         detachControl(element: HTMLElement) {
         detachControl(element: HTMLElement) {
             if (this._gamepads) {
             if (this._gamepads) {
                 this._gamepads.dispose();
                 this._gamepads.dispose();
             }
             }
             this.gamepad = null;
             this.gamepad = null;
         }
         }
-        
-        checkInputs(){
+
+        checkInputs() {
             if (this.gamepad) {
             if (this.gamepad) {
                 var camera = this.camera;
                 var camera = this.camera;
                 var LSValues = this.gamepad.leftStick;
                 var LSValues = this.gamepad.leftStick;
@@ -37,30 +43,37 @@ module BABYLON {
                 RSValues.x = Math.abs(normalizedRX) > 0.001 ? 0 + normalizedRX : 0;
                 RSValues.x = Math.abs(normalizedRX) > 0.001 ? 0 + normalizedRX : 0;
                 RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
                 RSValues.y = Math.abs(normalizedRY) > 0.001 ? 0 + normalizedRY : 0;
 
 
-                var cameraTransform = Matrix.RotationYawPitchRoll(camera.rotation.y, camera.rotation.x, 0);
+                if (!camera.rotationQuaternion) {
+                    Matrix.RotationYawPitchRollToRef(camera.rotation.y, camera.rotation.x, 0, this._cameraTransform);
+                } else {
+                    camera.rotationQuaternion.toRotationMatrix(this._cameraTransform);
+                }
 
 
                 var speed = camera._computeLocalCameraSpeed() * 50.0;
                 var speed = camera._computeLocalCameraSpeed() * 50.0;
-                var deltaTransform = Vector3.TransformCoordinates(new Vector3(LSValues.x * speed, 0, -LSValues.y * speed), cameraTransform);
-                camera.cameraDirection = camera.cameraDirection.add(deltaTransform);
-                camera.cameraRotation = camera.cameraRotation.add(new Vector2(RSValues.y, RSValues.x));
+                this._vector3.copyFromFloats(LSValues.x * speed, 0, -LSValues.y * speed);
+
+                Vector3.TransformCoordinatesToRef(this._vector3, this._cameraTransform, this._deltaTransform);
+                camera.cameraDirection.addInPlace(this._deltaTransform);
+                this._vector2.copyFromFloats(RSValues.y, RSValues.x)
+                camera.cameraRotation.addInPlace(this._vector2);
             }
             }
         }
         }
-        
+
         private _onNewGameConnected(gamepad: Gamepad) {
         private _onNewGameConnected(gamepad: Gamepad) {
             // Only the first gamepad can control the camera
             // Only the first gamepad can control the camera
             if (gamepad.index === 0) {
             if (gamepad.index === 0) {
                 this.gamepad = gamepad;
                 this.gamepad = gamepad;
             }
             }
         }
         }
-        
-        getTypeName(): string{
+
+        getTypeName(): string {
             return "FreeCameraGamepadInput";
             return "FreeCameraGamepadInput";
         }
         }
-        
-        getSimpleName(){
+
+        getSimpleName() {
             return "gamepad";
             return "gamepad";
         }
         }
     }
     }
-    
+
     CameraInputTypes["FreeCameraGamepadInput"] = FreeCameraGamepadInput;
     CameraInputTypes["FreeCameraGamepadInput"] = FreeCameraGamepadInput;
 }
 }

+ 1 - 1
src/Cameras/babylon.arcRotateCamera.ts

@@ -445,7 +445,7 @@ module BABYLON {
                 this.position.copyFrom(this._newPosition);
                 this.position.copyFrom(this._newPosition);
 
 
                 var up = this.upVector;
                 var up = this.upVector;
-                if (this.allowUpsideDown && this.beta < 0) {
+                if (this.allowUpsideDown && sinb < 0) {
                     up = up.clone();
                     up = up.clone();
                     up = up.negate();
                     up = up.negate();
                 }
                 }

+ 8 - 0
src/Cameras/babylon.camera.ts

@@ -292,6 +292,14 @@
         public _checkInputs(): void {
         public _checkInputs(): void {
         }
         }
 
 
+        public get rigCameras(): Camera[] {
+            return this._rigCameras;
+        }
+
+        public get rigPostProcess(): PostProcess {
+            return this._rigPostProcess;
+        }
+
         private _cascadePostProcessesToRigCams(): void {
         private _cascadePostProcessesToRigCams(): void {
             // invalidate framebuffer
             // invalidate framebuffer
             if (this._postProcesses.length > 0) {
             if (this._postProcesses.length > 0) {

+ 1 - 1
src/Cameras/babylon.freeCamera.ts

@@ -181,7 +181,7 @@
             if (this.checkCollisions && this.getScene().collisionsEnabled) {
             if (this.checkCollisions && this.getScene().collisionsEnabled) {
                 this._collideWithWorld(this.cameraDirection);
                 this._collideWithWorld(this.cameraDirection);
             } else {
             } else {
-                this.position.addInPlace(this.cameraDirection);
+                super._updatePosition();
             }
             }
         }
         }
 
 

+ 10 - 0
src/Cameras/babylon.targetCamera.ts

@@ -142,6 +142,10 @@ module BABYLON {
             }
             }
         }
         }
 
 
+
+        /**
+         * Return the current target position of the camera. This value is expressed in local space.
+         */
         public getTarget(): Vector3 {
         public getTarget(): Vector3 {
             return this._currentTarget;
             return this._currentTarget;
         }
         }
@@ -151,6 +155,12 @@ module BABYLON {
         }
         }
 
 
         public _updatePosition(): void {
         public _updatePosition(): void {
+            if (this.parent) {
+                this.parent.getWorldMatrix().invertToRef(Tmp.Matrix[0]);
+                Vector3.TransformNormalToRef(this.cameraDirection, Tmp.Matrix[0], Tmp.Vector3[0]);
+                this.position.addInPlace(Tmp.Vector3[0]);
+                return;
+            }
             this.position.addInPlace(this.cameraDirection);
             this.position.addInPlace(this.cameraDirection);
         }
         }
         public _checkInputs(): void {
         public _checkInputs(): void {

+ 4 - 1
src/Debug/babylon.debugLayer.ts

@@ -21,7 +21,10 @@ module BABYLON {
         }
         }
         
         
         public isVisible(): boolean {
         public isVisible(): boolean {
-            return false;
+            if (!this._inspector) {
+                return false;
+            }
+            return true;
         }
         }
 
 
         public hide() {
         public hide() {

+ 40 - 35
src/Lights/babylon.directionalLight.ts

@@ -17,6 +17,8 @@ module BABYLON {
 
 
         @serialize()
         @serialize()
         public autoUpdateExtends = true;
         public autoUpdateExtends = true;
+        
+        public customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
 
 
         // Cache
         // Cache
         private _orthoLeft = Number.MAX_VALUE;
         private _orthoLeft = Number.MAX_VALUE;
@@ -60,55 +62,58 @@ module BABYLON {
          * Returns the DirectionalLight.  
          * Returns the DirectionalLight.  
          */
          */
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): DirectionalLight {
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): DirectionalLight {
-            var activeCamera = this.getScene().activeCamera;
+            if (this.customProjectionMatrixBuilder) {
+                this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
+            } else {
+                var activeCamera = this.getScene().activeCamera;
 
 
-            // Check extends
-            if (this.autoUpdateExtends || this._orthoLeft === Number.MAX_VALUE) {
-                var tempVector3 = Vector3.Zero();
+                // Check extends
+                if (this.autoUpdateExtends || this._orthoLeft === Number.MAX_VALUE) {
+                    var tempVector3 = Vector3.Zero();
 
 
-                this._orthoLeft = Number.MAX_VALUE;
-                this._orthoRight = Number.MIN_VALUE;
-                this._orthoTop = Number.MIN_VALUE;
-                this._orthoBottom = Number.MAX_VALUE;
+                    this._orthoLeft = Number.MAX_VALUE;
+                    this._orthoRight = Number.MIN_VALUE;
+                    this._orthoTop = Number.MIN_VALUE;
+                    this._orthoBottom = Number.MAX_VALUE;
 
 
-                for (var meshIndex = 0; meshIndex < renderList.length; meshIndex++) {
-                    var mesh = renderList[meshIndex];
+                    for (var meshIndex = 0; meshIndex < renderList.length; meshIndex++) {
+                        var mesh = renderList[meshIndex];
 
 
-                    if (!mesh) {
-                        continue;
-                    }
+                        if (!mesh) {
+                            continue;
+                        }
 
 
-                    var boundingInfo = mesh.getBoundingInfo();
+                        var boundingInfo = mesh.getBoundingInfo();
 
 
-                    if (!boundingInfo) {
-                        continue;
-                    }
+                        if (!boundingInfo) {
+                            continue;
+                        }
 
 
-                    var boundingBox = boundingInfo.boundingBox;
+                        var boundingBox = boundingInfo.boundingBox;
 
 
-                    for (var index = 0; index < boundingBox.vectorsWorld.length; index++) {
-                        Vector3.TransformCoordinatesToRef(boundingBox.vectorsWorld[index], viewMatrix, tempVector3);
+                        for (var index = 0; index < boundingBox.vectorsWorld.length; index++) {
+                            Vector3.TransformCoordinatesToRef(boundingBox.vectorsWorld[index], viewMatrix, tempVector3);
 
 
-                        if (tempVector3.x < this._orthoLeft)
-                            this._orthoLeft = tempVector3.x;
-                        if (tempVector3.y < this._orthoBottom)
-                            this._orthoBottom = tempVector3.y;
+                            if (tempVector3.x < this._orthoLeft)
+                                this._orthoLeft = tempVector3.x;
+                            if (tempVector3.y < this._orthoBottom)
+                                this._orthoBottom = tempVector3.y;
 
 
-                        if (tempVector3.x > this._orthoRight)
-                            this._orthoRight = tempVector3.x;
-                        if (tempVector3.y > this._orthoTop)
-                            this._orthoTop = tempVector3.y;
+                            if (tempVector3.x > this._orthoRight)
+                                this._orthoRight = tempVector3.x;
+                            if (tempVector3.y > this._orthoTop)
+                                this._orthoTop = tempVector3.y;
+                        }
                     }
                     }
                 }
                 }
-            }
 
 
-            var xOffset = this._orthoRight - this._orthoLeft;
-            var yOffset = this._orthoTop - this._orthoBottom;
-
-            Matrix.OrthoOffCenterLHToRef(this._orthoLeft - xOffset * this.shadowOrthoScale, this._orthoRight + xOffset * this.shadowOrthoScale,
-                this._orthoBottom - yOffset * this.shadowOrthoScale, this._orthoTop + yOffset * this.shadowOrthoScale,
-                -activeCamera.maxZ, activeCamera.maxZ, matrix);
+                var xOffset = this._orthoRight - this._orthoLeft;
+                var yOffset = this._orthoTop - this._orthoBottom;
 
 
+                Matrix.OrthoOffCenterLHToRef(this._orthoLeft - xOffset * this.shadowOrthoScale, this._orthoRight + xOffset * this.shadowOrthoScale,
+                    this._orthoBottom - yOffset * this.shadowOrthoScale, this._orthoTop + yOffset * this.shadowOrthoScale,
+                    -activeCamera.maxZ, activeCamera.maxZ, matrix);
+            }
             return this;
             return this;
         }
         }
 
 

+ 2 - 0
src/Lights/babylon.light.ts

@@ -9,6 +9,8 @@
         computeTransformedPosition(): boolean;
         computeTransformedPosition(): boolean;
         getScene(): Scene;
         getScene(): Scene;
 
 
+
+        customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
         setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
         setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): void;
 
 
         supportsVSM(): boolean;
         supportsVSM(): boolean;

+ 8 - 2
src/Lights/babylon.pointLight.ts

@@ -5,6 +5,8 @@
 
 
         @serializeAsVector3()
         @serializeAsVector3()
         public position: Vector3;
         public position: Vector3;
+        
+        public customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
 
 
         /**
         /**
          * Creates a PointLight object from the passed name and position (Vector3) and adds it in the scene.  
          * Creates a PointLight object from the passed name and position (Vector3) and adds it in the scene.  
@@ -117,8 +119,12 @@
          * Returns the PointLight.  
          * Returns the PointLight.  
          */
          */
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): PointLight {
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): PointLight {
-            var activeCamera = this.getScene().activeCamera;
-            Matrix.PerspectiveFovLHToRef(Math.PI / 2, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
+            if (this.customProjectionMatrixBuilder) {
+                this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
+            } else {
+                var activeCamera = this.getScene().activeCamera;
+                Matrix.PerspectiveFovLHToRef(Math.PI / 2, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
+            }
             return this;
             return this;
         }
         }
 
 

+ 8 - 2
src/Lights/babylon.spotLight.ts

@@ -14,6 +14,8 @@
 
 
         public transformedPosition: Vector3;
         public transformedPosition: Vector3;
 
 
+        public customProjectionMatrixBuilder: (viewMatrix: Matrix, renderList: Array<AbstractMesh>, result: Matrix) => void;
+
         private _transformedDirection: Vector3;
         private _transformedDirection: Vector3;
         private _worldMatrix: Matrix;
         private _worldMatrix: Matrix;
 
 
@@ -52,8 +54,12 @@
          * Returns the SpotLight.  
          * Returns the SpotLight.  
          */
          */
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): SpotLight {
         public setShadowProjectionMatrix(matrix: Matrix, viewMatrix: Matrix, renderList: Array<AbstractMesh>): SpotLight {
-            var activeCamera = this.getScene().activeCamera;
-            Matrix.PerspectiveFovLHToRef(this.angle, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
+            if (this.customProjectionMatrixBuilder) {
+                this.customProjectionMatrixBuilder(viewMatrix, renderList, matrix);
+            } else {
+                var activeCamera = this.getScene().activeCamera;
+                Matrix.PerspectiveFovLHToRef(this.angle, 1.0, activeCamera.minZ, activeCamera.maxZ, matrix);
+            }
             return this;
             return this;
         }
         }
         /**
         /**

+ 8 - 3
src/Materials/babylon.effect.ts

@@ -28,6 +28,9 @@
             this._meshRank = rank;
             this._meshRank = rank;
             this._mesh = mesh;
             this._mesh = mesh;
 
 
+            if (rank < this._currentRank) {
+                this._currentRank = rank;
+            }
             if (rank > this._maxRank) {
             if (rank > this._maxRank) {
                 this._maxRank = rank;
                 this._maxRank = rank;
             }
             }
@@ -40,9 +43,10 @@
         public reduce(currentDefines: string): string {
         public reduce(currentDefines: string): string {
 
 
             var currentFallbacks = this._defines[this._currentRank];
             var currentFallbacks = this._defines[this._currentRank];
-
-            for (var index = 0; index < currentFallbacks.length; index++) {
-                currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
+            if (currentFallbacks) {
+                for (var index = 0; index < currentFallbacks.length; index++) {
+                    currentDefines = currentDefines.replace("#define " + currentFallbacks[index], "");
+                }
             }
             }
 
 
             if (this._mesh && this._currentRank === this._meshRank) {
             if (this._mesh && this._currentRank === this._meshRank) {
@@ -300,6 +304,7 @@
             result = result.replace(/[ \t]attribute/g, " in");
             result = result.replace(/[ \t]attribute/g, " in");
             
             
             if (isFragment) {
             if (isFragment) {
+                result = result.replace(/texture2DLodEXT\(/g, "textureLod(");
                 result = result.replace(/textureCubeLodEXT\(/g, "textureLod(");
                 result = result.replace(/textureCubeLodEXT\(/g, "textureLod(");
                 result = result.replace(/texture2D\(/g, "texture(");
                 result = result.replace(/texture2D\(/g, "texture(");
                 result = result.replace(/textureCube\(/g, "texture(");
                 result = result.replace(/textureCube\(/g, "texture(");

+ 67 - 1
src/Math/babylon.math.ts

@@ -238,6 +238,15 @@
             this.b = b;
             this.b = b;
             return this;
             return this;
         }
         }
+
+        /**
+         * Updates the Color3 rgb values from the passed floats.  
+         * Returns the Color3.  
+         */
+        public set(r: number, g: number, b: number): Color3 {
+            return this.copyFromFloats(r, g, b);
+        }
+
         /**
         /**
          * Returns the Color3 hexadecimal code as a string.  
          * Returns the Color3 hexadecimal code as a string.  
          */
          */
@@ -489,6 +498,26 @@
             this.a = source.a;
             this.a = source.a;
             return this;
             return this;
         }
         }
+
+        /**
+         * Copies the passed float values into the current one.  
+         * Returns the updated Color4.  
+         */
+        public copyFromFloats(r: number, g: number, b: number, a: number): Color4 {
+            this.r = r;
+            this.g = g;
+            this.b = b;
+            this.a = a;
+            return this;
+        }
+
+        /**
+         * Copies the passed float values into the current one.  
+         * Returns the updated Color4.  
+         */
+        public set(r: number, g: number, b: number, a: number): Color4 {
+            return this.copyFromFloats(r, g, b,a);
+        }
         /**
         /**
          * Returns a string containing the hexadecimal Color4 code.  
          * Returns a string containing the hexadecimal Color4 code.  
          */
          */
@@ -634,6 +663,13 @@
             return this;
             return this;
         }
         }
         /**
         /**
+         * Sets the Vector2 coordinates with the passed floats.  
+         * Returns the updated Vector2.  
+         */
+        public set(x: number, y: number): Vector2 {
+            return this.copyFromFloats(x, y);
+        }
+        /**
          * Returns a new Vector2 set with the addition of the current Vector2 and the passed one coordinates.  
          * Returns a new Vector2 set with the addition of the current Vector2 and the passed one coordinates.  
          */
          */
         public add(otherVector: Vector2): Vector2 {
         public add(otherVector: Vector2): Vector2 {
@@ -1338,6 +1374,14 @@
             return this;
             return this;
         }
         }
 
 
+        /**
+         * Copies the passed floats to the current Vector3 coordinates.  
+         * Returns the updated Vector3.  
+         */
+        public set(x: number, y: number, z: number): Vector3 {
+            return this.copyFromFloats(x, y, z);
+        }
+
         // Statics
         // Statics
         /**
         /**
          * 
          * 
@@ -2088,6 +2132,13 @@
             this.w = w;
             this.w = w;
             return this;
             return this;
         }
         }
+        /**
+         * Updates the current Vector4 coordinates with the passed floats.  
+         * Returns the updated Vector4.  
+         */
+        public set(x: number, y: number, z: number, w: number): Vector4 {
+            return this.copyFromFloats(x, y, z, w);
+        }
 
 
         // Statics
         // Statics
         /**
         /**
@@ -2238,6 +2289,13 @@
             return this;
             return this;
         }
         }
         /**
         /**
+         * Updates in place the current Size from the passed floats.  
+         * Returns the updated Size.   
+         */
+        public set(width: number, height: number): Size {
+            return this.copyFromFloats(width, height);
+        }        
+        /**
          * Returns a new Size set with the multiplication result of the current Size and the passed floats.  
          * Returns a new Size set with the multiplication result of the current Size and the passed floats.  
          */
          */
         public multiplyByFloats(w: number, h: number): Size {
         public multiplyByFloats(w: number, h: number): Size {
@@ -2368,6 +2426,13 @@
             return this;
             return this;
         }
         }
         /**
         /**
+         * Updates the current Quaternion from the passed float coordinates.  
+         * Returns the updated Quaterion.  
+         */
+        public set(x: number, y: number, z: number, w: number): Quaternion {
+            return this.copyFromFloats(x, y, z, w);
+        }        
+        /**
          * Returns a new Quaternion as the addition result of the passed one and the current Quaternion.  
          * Returns a new Quaternion as the addition result of the passed one and the current Quaternion.  
          */
          */
         public add(other: Quaternion): Quaternion {
         public add(other: Quaternion): Quaternion {
@@ -4271,7 +4336,8 @@
 
 
     export enum Space {
     export enum Space {
         LOCAL = 0,
         LOCAL = 0,
-        WORLD = 1
+        WORLD = 1,
+        BONE = 2
     }
     }
 
 
     export class Axis {
     export class Axis {

+ 3 - 1
src/Mesh/babylon.geometry.ts

@@ -401,7 +401,9 @@
                 if (numOfMeshes === 1) {
                 if (numOfMeshes === 1) {
                     this._vertexBuffers[kind].create();
                     this._vertexBuffers[kind].create();
                 }
                 }
-                this._vertexBuffers[kind].getBuffer().references = numOfMeshes;
+                var buffer = this._vertexBuffers[kind].getBuffer();
+                if (buffer)
+                    buffer.references = numOfMeshes;
 
 
                 if (kind === VertexBuffer.PositionKind) {
                 if (kind === VertexBuffer.PositionKind) {
                     mesh._resetPointsArrayCache();
                     mesh._resetPointsArrayCache();

+ 8 - 0
src/PostProcess/babylon.postProcess.ts

@@ -14,6 +14,8 @@
         */ 
         */ 
         public enablePixelPerfectMode = false;
         public enablePixelPerfectMode = false;
 
 
+        public samples = 1;
+
         private _camera: Camera;
         private _camera: Camera;
         private _scene: Scene;
         private _scene: Scene;
         private _engine: Engine;
         private _engine: Engine;
@@ -193,6 +195,12 @@
                 this.onSizeChangedObservable.notifyObservers(this);
                 this.onSizeChangedObservable.notifyObservers(this);
             }
             }
 
 
+            this._textures.forEach(texture => {
+                if (texture.samples !== this.samples) {
+                    this._engine.updateRenderTargetTextureSampleCount(texture, this.samples);
+                }
+            });
+
             if (this.enablePixelPerfectMode) {
             if (this.enablePixelPerfectMode) {
                 this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);
                 this._scaleRatio.copyFromFloats(requiredWidth / desiredWidth, requiredHeight / desiredHeight);
                 this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd], 0, requiredWidth, requiredHeight);
                 this._engine.bindFramebuffer(this._textures.data[this._currentRenderTextureInd], 0, requiredWidth, requiredHeight);

+ 76 - 14
src/PostProcess/babylon.standardRenderingPipeline.ts

@@ -14,6 +14,7 @@ module BABYLON {
         public textureAdderPostProcess: PostProcess = null;
         public textureAdderPostProcess: PostProcess = null;
 
 
         public textureAdderFinalPostProcess: PostProcess = null;
         public textureAdderFinalPostProcess: PostProcess = null;
+        public lensFlareFinalPostProcess: PostProcess = null;
 
 
         public lensFlarePostProcess: PostProcess = null;
         public lensFlarePostProcess: PostProcess = null;
         public lensFlareComposePostProcess: PostProcess = null;
         public lensFlareComposePostProcess: PostProcess = null;
@@ -21,26 +22,46 @@ module BABYLON {
         public depthOfFieldPostProcess: PostProcess = null;
         public depthOfFieldPostProcess: PostProcess = null;
 
 
         // Values
         // Values
+        @serialize()
         public brightThreshold: number = 1.0;
         public brightThreshold: number = 1.0;
 
 
+        @serialize()
         public blurWidth: number = 2.0;
         public blurWidth: number = 2.0;
+        @serialize()
+        public horizontalBlur: boolean = false;
+        @serialize()
         public gaussianCoefficient: number = 0.25;
         public gaussianCoefficient: number = 0.25;
+        @serialize()
         public gaussianMean: number = 1.0;
         public gaussianMean: number = 1.0;
+        @serialize()
         public gaussianStandardDeviation: number = 1.0;
         public gaussianStandardDeviation: number = 1.0;
 
 
+        @serialize()
         public exposure: number = 1.0;
         public exposure: number = 1.0;
+        @serializeAsTexture("lensTexture")
         public lensTexture: Texture = null;
         public lensTexture: Texture = null;
 
 
+        @serializeAsTexture("lensColorTexture")
         public lensColorTexture: Texture = null;
         public lensColorTexture: Texture = null;
+        @serialize()
         public lensFlareStrength: number = 20.0;
         public lensFlareStrength: number = 20.0;
+        @serialize()
         public lensFlareGhostDispersal: number = 1.4;
         public lensFlareGhostDispersal: number = 1.4;
+        @serialize()
         public lensFlareHaloWidth: number = 0.7;
         public lensFlareHaloWidth: number = 0.7;
+        @serialize()
         public lensFlareDistortionStrength: number = 16.0;
         public lensFlareDistortionStrength: number = 16.0;
+        @serializeAsTexture("lensStarTexture")
         public lensStarTexture: Texture = null;
         public lensStarTexture: Texture = null;
+        @serializeAsTexture("lensFlareDirtTexture")
         public lensFlareDirtTexture: Texture = null;
         public lensFlareDirtTexture: Texture = null;
 
 
+        @serialize()
         public depthOfFieldDistance: number = 10.0;
         public depthOfFieldDistance: number = 10.0;
 
 
+        @serialize()
+        public depthOfFieldBlurWidth: number = 2.0;
+
         // IAnimatable
         // IAnimatable
         public animations: Animation[] = [];
         public animations: Animation[] = [];
 
 
@@ -50,6 +71,7 @@ module BABYLON {
         private _scene: Scene;
         private _scene: Scene;
 
 
         private _depthRenderer: DepthRenderer = null;
         private _depthRenderer: DepthRenderer = null;
+        private _currentDepthOfFieldSource: PostProcess = null;
 
 
         // Getters and setters
         // Getters and setters
         private _depthOfFieldEnabled: boolean = true;
         private _depthOfFieldEnabled: boolean = true;
@@ -73,6 +95,7 @@ module BABYLON {
             this._depthOfFieldEnabled = enabled;
             this._depthOfFieldEnabled = enabled;
         }
         }
 
 
+        @serialize()
         public get DepthOfFieldEnabled(): boolean {
         public get DepthOfFieldEnabled(): boolean {
             return this._depthOfFieldEnabled;
             return this._depthOfFieldEnabled;
         }
         }
@@ -86,6 +109,8 @@ module BABYLON {
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRGaussianBlurH" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRGaussianBlurH" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRGaussianBlurV" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRGaussianBlurV" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRLensFlareCompose", this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, "HDRLensFlareCompose", this._scene.cameras);
+
+                this._setDepthOfFieldSavePostProcess("HDRPostLensFlareDepthOfFieldSource");
             }
             }
             else if (!enabled && this._lensFlareEnabled) {
             else if (!enabled && this._lensFlareEnabled) {
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRLensFlare", this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRLensFlare", this._scene.cameras);
@@ -93,11 +118,14 @@ module BABYLON {
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRGaussianBlurH" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRGaussianBlurH" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRGaussianBlurV" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRGaussianBlurV" + blurIndex, this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRLensFlareCompose", this._scene.cameras);
                 this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRLensFlareCompose", this._scene.cameras);
+
+                this._setDepthOfFieldSavePostProcess("HDRBaseDepthOfFieldSource");
             }
             }
 
 
             this._lensFlareEnabled = enabled;
             this._lensFlareEnabled = enabled;
         }
         }
 
 
+        @serialize()
         public get LensFlareEnabled(): boolean {
         public get LensFlareEnabled(): boolean {
             return this._lensFlareEnabled;
             return this._lensFlareEnabled;
         }
         }
@@ -118,7 +146,7 @@ module BABYLON {
 
 
             // Create pass post-processe
             // Create pass post-processe
             if (!originalPostProcess) {
             if (!originalPostProcess) {
-                this.originalPostProcess = new PostProcess("HDRPass", "standard", [], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), true, "#define PASS_POST_PROCESS", Engine.TEXTURETYPE_FLOAT);
+                this.originalPostProcess = new PostProcess("HDRPass", "standard", [], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", Engine.TEXTURETYPE_FLOAT);
             }
             }
             else {
             else {
                 this.originalPostProcess = originalPostProcess;
                 this.originalPostProcess = originalPostProcess;
@@ -142,14 +170,18 @@ module BABYLON {
             this._createTextureAdderPostProcess(scene, ratio);
             this._createTextureAdderPostProcess(scene, ratio);
 
 
             // Create depth-of-field source post-process
             // Create depth-of-field source post-process
-            this.textureAdderFinalPostProcess = new PostProcess("HDRDepthOfFieldSource", "standard", [], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), true, "#define PASS_POST_PROCESS", Engine.TEXTURETYPE_UNSIGNED_INT);
-            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRDepthOfFieldSource", () => { return this.textureAdderFinalPostProcess; }, true));
+            this.textureAdderFinalPostProcess = new PostProcess("HDRDepthOfFieldSource", "standard", [], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", Engine.TEXTURETYPE_UNSIGNED_INT);
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRBaseDepthOfFieldSource", () => { return this.textureAdderFinalPostProcess; }, true));
 
 
             // Create lens flare post-process
             // Create lens flare post-process
             this._createLensFlarePostProcess(scene, ratio);
             this._createLensFlarePostProcess(scene, ratio);
 
 
+            // Create depth-of-field source post-process post lens-flare and disable it now
+            this.lensFlareFinalPostProcess = new PostProcess("HDRPostLensFlareDepthOfFieldSource", "standard", [], [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define PASS_POST_PROCESS", Engine.TEXTURETYPE_UNSIGNED_INT);
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRPostLensFlareDepthOfFieldSource", () => { return this.lensFlareFinalPostProcess; }, true));
+
             // Create gaussian blur used by depth-of-field
             // Create gaussian blur used by depth-of-field
-            this._createGaussianBlurPostProcesses(scene, ratio / 2, 5);
+            this._createGaussianBlurPostProcesses(scene, ratio / 2, 5, "depthOfFieldBlurWidth");
 
 
             // Create depth-of-field post-process
             // Create depth-of-field post-process
             this._createDepthOfFieldPostProcess(scene, ratio);
             this._createDepthOfFieldPostProcess(scene, ratio);
@@ -166,6 +198,19 @@ module BABYLON {
             this.DepthOfFieldEnabled = false;
             this.DepthOfFieldEnabled = false;
         }
         }
 
 
+        // Sets depth-of-field save post-process
+        private _setDepthOfFieldSavePostProcess(name: string): void {
+            this._scene.postProcessRenderPipelineManager.disableEffectInPipeline(this._name, "HDRPostLensFlareDepthOfFieldSource", this._scene.cameras);
+
+            this._scene.postProcessRenderPipelineManager.enableEffectInPipeline(this._name, name, this._scene.cameras);
+
+            switch (name) {
+                case "HDRBaseDepthOfFieldSource": this._currentDepthOfFieldSource = this.textureAdderFinalPostProcess; break;
+                case "HDRPostLensFlareDepthOfFieldSource": this._currentDepthOfFieldSource = this.lensFlareFinalPostProcess; break;
+                default: break;
+            }
+        }
+
         // Down Sample X4 Post-Processs
         // Down Sample X4 Post-Processs
         private _createDownSampleX4PostProcess(scene: Scene, ratio: number): void {
         private _createDownSampleX4PostProcess(scene: Scene, ratio: number): void {
             var downSampleX4Offsets = new Array<number>(32);
             var downSampleX4Offsets = new Array<number>(32);
@@ -215,7 +260,7 @@ module BABYLON {
         }
         }
 
 
         // Create gaussian blur H&V post-processes
         // Create gaussian blur H&V post-processes
-        private _createGaussianBlurPostProcesses(scene: Scene, ratio: number, indice: number): void {
+        private _createGaussianBlurPostProcesses(scene: Scene, ratio: number, indice: number, blurWidthKey: string = "blurWidth"): void {
             var blurOffsets = new Array<number>(9);
             var blurOffsets = new Array<number>(9);
             var blurWeights = new Array<number>(9);
             var blurWeights = new Array<number>(9);
             var uniforms: string[] = ["blurOffsets", "blurWeights", "blurWidth"];
             var uniforms: string[] = ["blurOffsets", "blurWeights", "blurWidth"];
@@ -245,16 +290,22 @@ module BABYLON {
 
 
                     effect.setArray("blurOffsets", blurOffsets);
                     effect.setArray("blurOffsets", blurOffsets);
                     effect.setArray("blurWeights", blurWeights);
                     effect.setArray("blurWeights", blurWeights);
-                    effect.setFloat("blurWidth", this.blurWidth);
+
+                    if (height) {
+                        effect.setFloat("blurWidth", this.horizontalBlur ? 1.0 : this[blurWidthKey]);
+                    }
+                    else {
+                        effect.setFloat("blurWidth", this[blurWidthKey]);
+                    }
                 };
                 };
             };
             };
 
 
             // Create horizontal gaussian blur post-processes
             // Create horizontal gaussian blur post-processes
-            var gaussianBlurHPostProcess = new PostProcess("HDRGaussianBlurH" + ratio, "standard", uniforms, [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define GAUSSIAN_BLUR_H", Engine.TEXTURETYPE_UNSIGNED_INT);
+            var gaussianBlurHPostProcess = new PostProcess("HDRGaussianBlurH_" + ratio + "_" + indice, "standard", uniforms, [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define GAUSSIAN_BLUR_H", Engine.TEXTURETYPE_UNSIGNED_INT);
             gaussianBlurHPostProcess.onApply = callback(false);
             gaussianBlurHPostProcess.onApply = callback(false);
 
 
             // Create vertical gaussian blur post-process
             // Create vertical gaussian blur post-process
-            var gaussianBlurVPostProcess = new PostProcess("HDRGaussianBlurV" + ratio, "standard", uniforms, [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define GAUSSIAN_BLUR_V", Engine.TEXTURETYPE_UNSIGNED_INT);
+            var gaussianBlurVPostProcess = new PostProcess("HDRGaussianBlurV_" + ratio + "_" + indice, "standard", uniforms, [], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define GAUSSIAN_BLUR_V", Engine.TEXTURETYPE_UNSIGNED_INT);
             gaussianBlurVPostProcess.onApply = callback(true);
             gaussianBlurVPostProcess.onApply = callback(true);
 
 
             // Add to pipeline
             // Add to pipeline
@@ -268,8 +319,6 @@ module BABYLON {
 
 
         // Create texture adder post-process
         // Create texture adder post-process
         private _createTextureAdderPostProcess(scene: Scene, ratio: number): void {
         private _createTextureAdderPostProcess(scene: Scene, ratio: number): void {
-            var lastGaussianBlurPostProcess = this.gaussianBlurVPostProcesses[3];
-
             this.textureAdderPostProcess = new PostProcess("HDRTextureAdder", "standard", ["exposure"], ["otherSampler", "lensSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define TEXTURE_ADDER", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.textureAdderPostProcess = new PostProcess("HDRTextureAdder", "standard", ["exposure"], ["otherSampler", "lensSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define TEXTURE_ADDER", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.textureAdderPostProcess.onApply = (effect: Effect) => {
             this.textureAdderPostProcess.onApply = (effect: Effect) => {
                 effect.setTextureFromPostProcess("otherSampler", this.originalPostProcess);
                 effect.setTextureFromPostProcess("otherSampler", this.originalPostProcess);
@@ -284,13 +333,13 @@ module BABYLON {
 
 
         // Create lens flare post-process
         // Create lens flare post-process
         private _createLensFlarePostProcess(scene: Scene, ratio: number): void {
         private _createLensFlarePostProcess(scene: Scene, ratio: number): void {
-            this.lensFlarePostProcess = new PostProcess("HDRLensFlare", "standard", ["strength", "ghostDispersal", "haloWidth", "resolution", "distortionStrength"], ["lensColorSampler"], ratio / 2, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), true, "#define LENS_FLARE", Engine.TEXTURETYPE_UNSIGNED_INT);
-            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRLensFlare", () => { return this.lensFlarePostProcess; }, false));
+            this.lensFlarePostProcess = new PostProcess("HDRLensFlare", "standard", ["strength", "ghostDispersal", "haloWidth", "resolution", "distortionStrength"], ["lensColorSampler"], ratio / 2, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE", Engine.TEXTURETYPE_UNSIGNED_INT);
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRLensFlare", () => { return this.lensFlarePostProcess; }, true));
 
 
             this._createGaussianBlurPostProcesses(scene, ratio / 4, 4);
             this._createGaussianBlurPostProcesses(scene, ratio / 4, 4);
 
 
             this.lensFlareComposePostProcess = new PostProcess("HDRLensFlareCompose", "standard", ["lensStarMatrix"], ["otherSampler", "lensDirtSampler", "lensStarSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE_COMPOSE", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.lensFlareComposePostProcess = new PostProcess("HDRLensFlareCompose", "standard", ["lensStarMatrix"], ["otherSampler", "lensDirtSampler", "lensStarSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define LENS_FLARE_COMPOSE", Engine.TEXTURETYPE_UNSIGNED_INT);
-            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRLensFlareCompose", () => { return this.lensFlareComposePostProcess; }, false));
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), "HDRLensFlareCompose", () => { return this.lensFlareComposePostProcess; }, true));
 
 
             var resolution = new Vector2(0, 0);
             var resolution = new Vector2(0, 0);
 
 
@@ -353,7 +402,7 @@ module BABYLON {
         private _createDepthOfFieldPostProcess(scene: Scene, ratio: number): void {
         private _createDepthOfFieldPostProcess(scene: Scene, ratio: number): void {
             this.depthOfFieldPostProcess = new PostProcess("HDRDepthOfField", "standard", ["distance"], ["otherSampler", "depthSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DEPTH_OF_FIELD", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.depthOfFieldPostProcess = new PostProcess("HDRDepthOfField", "standard", ["distance"], ["otherSampler", "depthSampler"], ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, "#define DEPTH_OF_FIELD", Engine.TEXTURETYPE_UNSIGNED_INT);
             this.depthOfFieldPostProcess.onApply = (effect: Effect) => {
             this.depthOfFieldPostProcess.onApply = (effect: Effect) => {
-                effect.setTextureFromPostProcess("otherSampler", this.textureAdderFinalPostProcess);
+                effect.setTextureFromPostProcess("otherSampler", this._currentDepthOfFieldSource);
                 effect.setTexture("depthSampler", this._depthRenderer.getDepthMap());
                 effect.setTexture("depthSampler", this._depthRenderer.getDepthMap());
 
 
                 effect.setFloat("distance", this.depthOfFieldDistance);
                 effect.setFloat("distance", this.depthOfFieldDistance);
@@ -391,5 +440,18 @@ module BABYLON {
 
 
             super.dispose();
             super.dispose();
         }
         }
+
+        // Serialize rendering pipeline
+        public serialize(): any {
+            var serializationObject = SerializationHelper.Serialize(this);
+            serializationObject.customType = "StandardRenderingPipeline";
+
+            return serializationObject;
+        }
+
+        // Parse serialized pipeline
+        public static Parse(source: any, scene: Scene, rootUrl: string): StandardRenderingPipeline {
+            return SerializationHelper.Parse(() => new StandardRenderingPipeline(source._name, scene, source._ratio), source, scene, rootUrl);
+        }
     }
     }
 }
 }

+ 2 - 2
src/Tools/babylon.database.ts

@@ -43,7 +43,7 @@ module BABYLON {
         }
         }
 
 
         static ReturnFullUrlLocation = (url: string): string => {
         static ReturnFullUrlLocation = (url: string): string => {
-            if (url.indexOf("http:/") === -1) {
+            if (url.indexOf("http:/") === -1 && url.indexOf("https:/") === -1) {
                 return (Database.parseURL(window.location.href) + url);
                 return (Database.parseURL(window.location.href) + url);
             }
             }
             else {
             else {
@@ -584,4 +584,4 @@ module BABYLON {
             }
             }
         }
         }
     }
     }
-}
+}

+ 6 - 0
src/Tools/babylon.smartArray.ts

@@ -25,6 +25,12 @@
             value.__smartArrayFlags[this._id] = this._duplicateId;
             value.__smartArrayFlags[this._id] = this._duplicateId;
         }
         }
 
 
+        public forEach(func: (content: T) => void): void {
+            for (var index = 0; index < this.length; index++) {
+                func(this.data[index]);
+            }
+        }
+
         public pushNoDuplicate(value): boolean {
         public pushNoDuplicate(value): boolean {
             if (value.__smartArrayFlags && value.__smartArrayFlags[this._id] === this._duplicateId) {
             if (value.__smartArrayFlags && value.__smartArrayFlags[this._id] === this._duplicateId) {
                 return false;
                 return false;

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

@@ -298,13 +298,13 @@
             }
             }
         }
         }
 
 
-        public static SetCorsBehavior(url: string, img: HTMLImageElement): string {
+        public static SetCorsBehavior(url: string, img: HTMLImageElement): void {
             if (Tools.CorsBehavior) {
             if (Tools.CorsBehavior) {
                 switch (typeof (Tools.CorsBehavior)) {
                 switch (typeof (Tools.CorsBehavior)) {
                     case "function":
                     case "function":
                         var result = Tools.CorsBehavior(url);
                         var result = Tools.CorsBehavior(url);
                         if (result) {
                         if (result) {
-                            return result;
+                            img.crossOrigin = result;
                         }
                         }
                         break;
                         break;
                     case "string":
                     case "string":

+ 9 - 1
src/babylon.engine.ts

@@ -2005,7 +2005,7 @@
                     this._alphaState.alphaBlend = false;
                     this._alphaState.alphaBlend = false;
                     break;
                     break;
                 case Engine.ALPHA_PREMULTIPLIED:
                 case Engine.ALPHA_PREMULTIPLIED:
-                    this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA);
+                    this._alphaState.setAlphaBlendFunctionParameters(this._gl.ONE, this._gl.ONE_MINUS_SRC_ALPHA, this._gl.ONE, this._gl.ONE);
                     this._alphaState.alphaBlend = true;
                     this._alphaState.alphaBlend = true;
                     break;
                     break;
                 case Engine.ALPHA_COMBINE:
                 case Engine.ALPHA_COMBINE:
@@ -2499,6 +2499,7 @@
             texture._width = width;
             texture._width = width;
             texture._height = height;
             texture._height = height;
             texture.isReady = true;
             texture.isReady = true;
+            texture.samples = 1;
             texture.generateMipMaps = generateMipMaps;
             texture.generateMipMaps = generateMipMaps;
             texture.references = 1;
             texture.references = 1;
             texture.samplingMode = samplingMode;
             texture.samplingMode = samplingMode;
@@ -2550,6 +2551,11 @@
             if (this.webGLVersion < 2) {
             if (this.webGLVersion < 2) {
                 return 1;
                 return 1;
             }
             }
+
+            if (texture.samples === samples) {
+                return samples;
+            }
+
             var gl = this._gl;
             var gl = this._gl;
 
 
             samples = Math.min(samples, gl.getParameter(gl.MAX_SAMPLES));
             samples = Math.min(samples, gl.getParameter(gl.MAX_SAMPLES));
@@ -2582,6 +2588,7 @@
                 this.bindUnboundFramebuffer(texture._framebuffer);
                 this.bindUnboundFramebuffer(texture._framebuffer);
             }
             }
 
 
+            texture.samples = samples;
             texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(texture._generateStencilBuffer, texture._generateDepthBuffer, texture._width, texture._height, samples);
             texture._depthStencilBuffer = this._setupFramebufferDepthAttachments(texture._generateStencilBuffer, texture._generateDepthBuffer, texture._width, texture._height, samples);
 
 
             gl.bindRenderbuffer(gl.RENDERBUFFER, null);
             gl.bindRenderbuffer(gl.RENDERBUFFER, null);
@@ -2614,6 +2621,7 @@
             texture.references = 1;
             texture.references = 1;
             texture.generateMipMaps = generateMipMaps;
             texture.generateMipMaps = generateMipMaps;
             texture.references = 1;
             texture.references = 1;
+            texture.samples = 1;
             texture.samplingMode = samplingMode;
             texture.samplingMode = samplingMode;
 
 
             var filters = getSamplingParameters(samplingMode, generateMipMaps, gl);
             var filters = getSamplingParameters(samplingMode, generateMipMaps, gl);

+ 1 - 0
src/babylon.mixins.ts

@@ -89,6 +89,7 @@ interface WebGLTexture {
     samplingMode: number;
     samplingMode: number;
     references: number;
     references: number;
     generateMipMaps: boolean;
     generateMipMaps: boolean;
+    samples: number;
     type: number;
     type: number;
     onLoadedCallbacks: Array<Function>;
     onLoadedCallbacks: Array<Function>;
     _size: number;
     _size: number;