Trevor Baron преди 7 години
родител
ревизия
915f2ee870
променени са 100 файла, в които са добавени 46804 реда и са изтрити 36950 реда
  1. 10303 8110
      Playground/babylon.d.txt
  2. 183 0
      Playground/scenes/BoomBox/UnlitBoomBox.gltf
  3. 6 1
      Tools/Gulp/config.json
  4. 3 3
      Tools/Gulp/gulp-addDtsExport.js
  5. 1 1
      Tools/Gulp/gulp-addES6Exports.js
  6. 1 1
      Tools/Gulp/gulp-addModuleExports.js
  7. 26 8
      Tools/Gulp/gulp-validateTypedoc.js
  8. 7 3
      Tools/Gulp/gulpfile.js
  9. 1 1
      Viewer/tsconfig-gulp.json
  10. 1 1
      Viewer/tsconfig.json
  11. 4 0
      dist/babylon.glTF2Interface.d.ts
  12. 14166 11974
      dist/preview release/babylon.d.ts
  13. 56 56
      dist/preview release/babylon.js
  14. 2876 600
      dist/preview release/babylon.max.js
  15. 57 57
      dist/preview release/babylon.worker.js
  16. 2875 599
      dist/preview release/es6.js
  17. 1 1
      dist/preview release/gui/babylon.gui.js
  18. 4 4
      dist/preview release/gui/babylon.gui.min.js
  19. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  20. 3 0
      dist/preview release/inspector/babylon.inspector.d.ts
  21. 31 29
      dist/preview release/inspector/babylon.inspector.js
  22. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  23. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  24. 20 13
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  25. 193 146
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  26. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  27. 20 13
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  28. 193 146
      dist/preview release/loaders/babylon.glTFFileLoader.js
  29. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  30. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  31. 1128 0
      dist/preview release/loaders/babylonjs.loaders.d.ts
  32. 185 147
      dist/preview release/loaders/babylonjs.loaders.js
  33. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  34. 22 13
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  35. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  37. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  38. 580 0
      dist/preview release/materialsLibrary/babylonjs.materials.d.ts
  39. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js
  40. 3 3
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  41. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  42. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  43. 201 0
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.d.ts
  44. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  45. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  46. 155 0
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts
  47. 1 1
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  48. 1 1
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js
  49. 1 2
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  50. 59 75
      dist/preview release/serializers/babylon.glTF2Serializer.js
  51. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  52. 512 0
      dist/preview release/serializers/babylonjs.serializers.d.ts
  53. 60 76
      dist/preview release/serializers/babylonjs.serializers.js
  54. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  55. 3 2
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  56. 7008 12850
      dist/preview release/typedocValidationBaseline.json
  57. 64 64
      dist/preview release/viewer/babylon.viewer.js
  58. 2969 733
      dist/preview release/viewer/babylon.viewer.max.js
  59. 5 2
      dist/preview release/what's new.md
  60. 15 2
      inspector/src/adapters/CameraAdapter.ts
  61. 0 18
      inspector/src/tabs/SceneTab.ts
  62. 26 10
      inspector/src/treetools/CameraPOV.ts
  63. 6 6
      inspector/test/index.js
  64. 7 3
      loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts
  65. 9 9
      loaders/src/glTF/2.0/Extensions/KHR_lights.ts
  66. 2 2
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  67. 76 0
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  68. 4 4
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  69. 97 157
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  70. 3 3
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  71. 3 1
      loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts
  72. 0 4
      loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts
  73. 64 84
      serializers/src/glTF/2.0/babylon.glTFExporter.ts
  74. 4 1
      src/Bones/babylon.skeleton.ts
  75. 1 1
      src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts
  76. 101 0
      src/Debug/babylon.axesViewer.ts
  77. 53 0
      src/Debug/babylon.boneAxesViewer.ts
  78. 0 461
      src/Debug/babylon.debugModules.ts
  79. 192 0
      src/Debug/babylon.physicsViewer.ts
  80. 134 0
      src/Debug/babylon.skeletonViewer.ts
  81. 1332 112
      src/Engine/babylon.engine.ts
  82. 11 1
      src/Engine/babylon.nullEngine.ts
  83. 6 6
      src/Instrumentation/babylon.sceneInstrumentation.ts
  84. 20 1
      src/Layer/babylon.effectLayer.ts
  85. 78 1
      src/Layer/babylon.glowLayer.ts
  86. 3 3
      src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts
  87. 43 29
      src/Mesh/babylon.buffer.ts
  88. 56 32
      src/Mesh/babylon.geometry.ts
  89. 1 1
      src/Mesh/babylon.linesMesh.ts
  90. 2 2
      src/Mesh/babylon.mesh.ts
  91. 224 29
      src/Mesh/babylon.vertexBuffer.ts
  92. 189 178
      src/PostProcess/babylon.blurPostProcess.ts
  93. 5 3
      src/PostProcess/babylon.depthOfFieldEffect.ts
  94. 2 2
      src/PostProcess/babylon.depthOfFieldMergePostProcess.ts
  95. 2 0
      src/PostProcess/babylon.postProcessManager.ts
  96. 1 2
      src/Shaders/ShadersInclude/kernelBlurFragment.fx
  97. 1 2
      src/Shaders/ShadersInclude/kernelBlurFragment2.fx
  98. 3 7
      src/Shaders/circleOfConfusion.fragment.fx
  99. 11 8
      src/Shaders/depthOfFieldMerge.fragment.fx
  100. 0 0
      src/Shaders/kernelBlur.fragment.fx

Файловите разлики са ограничени, защото са твърде много
+ 10303 - 8110
Playground/babylon.d.txt


+ 183 - 0
Playground/scenes/BoomBox/UnlitBoomBox.gltf

@@ -0,0 +1,183 @@
+{
+  "accessors": [
+    {
+      "bufferView": 0,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 3,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC3",
+      "max": [
+        0.009921154,
+        0.00977163,
+        0.0100762453
+      ],
+      "min": [
+        -0.009921154,
+        -0.00977163,
+        -0.0100762453
+      ]
+    },
+    {
+      "bufferView": 4,
+      "componentType": 5123,
+      "count": 18108,
+      "type": "SCALAR"
+    }
+  ],
+  "asset": {
+    "generator": "glTF Tools for Unity",
+    "version": "2.0"
+  },
+  "bufferViews": [
+    {
+      "buffer": 0,
+      "byteLength": 28600
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 28600,
+      "byteLength": 42900
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 71500,
+      "byteLength": 57200
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 128700,
+      "byteLength": 42900
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 171600,
+      "byteLength": 36216
+    }
+  ],
+  "buffers": [
+    {
+      "uri": "BoomBox.bin",
+      "byteLength": 207816
+    }
+  ],
+  "extensionsUsed": [
+    "KHR_materials_unlit"
+  ],
+  "images": [
+    {
+      "uri": "BoomBox_baseColor.png"
+    },
+    {
+      "uri": "BoomBox_occlusionRoughnessMetallic.png"
+    },
+    {
+      "uri": "BoomBox_normal.png"
+    },
+    {
+      "uri": "BoomBox_emissive.png"
+    }
+  ],
+  "meshes": [
+    {
+      "primitives": [
+        {
+          "attributes": {
+            "TEXCOORD_0": 0,
+            "NORMAL": 1,
+            "TANGENT": 2,
+            "POSITION": 3
+          },
+          "indices": 4,
+          "material": 0
+        }
+      ],
+      "name": "BoomBox"
+    }
+  ],
+  "materials": [
+    {
+      "pbrMetallicRoughness": {
+        "baseColorTexture": {
+          "index": 0
+        },
+        "metallicRoughnessTexture": {
+          "index": 1
+        }
+      },
+      "normalTexture": {
+        "index": 2
+      },
+      "occlusionTexture": {
+        "index": 1
+      },
+      "emissiveFactor": [
+        1.0,
+        1.0,
+        1.0
+      ],
+      "emissiveTexture": {
+        "index": 3
+      },
+      "name": "BoomBox_Mat",
+      "extensions": {
+        "KHR_materials_unlit": {}
+      }
+    }
+  ],
+  "nodes": [
+    {
+      "mesh": 0,
+      "rotation": [
+        0.0,
+        1.0,
+        0.0,
+        0.0
+      ],
+      "scale": [ 1, 1, 1 ],
+      "name": "BoomBox"
+    }
+  ],
+  "scene": 0,
+  "scenes": [
+    {
+      "nodes": [
+        0
+      ]
+    }
+  ],
+  "textures": [
+    {
+      "name": "baseColor",
+      "source": 0
+    },
+    {
+      "name": "occlusionRoughnessMetallic",
+      "source": 1
+    },
+    {
+      "name": "normal",
+      "source": 2
+    },
+    {
+      "name": "emissive",
+      "source": 3
+    }
+  ]
+}

+ 6 - 1
Tools/Gulp/config.json

@@ -999,9 +999,12 @@
         },
         "debug": {
             "files": [
-                "../../src/Debug/babylon.debugModules.js",
+                "../../src/Debug/babylon.skeletonViewer.js",
+                "../../src/Debug/babylon.axesViewer.js",
+                "../../src/Debug/babylon.boneAxesViewer.js",
                 "../../src/Debug/babylon.rayHelper.js",
                 "../../src/Debug/babylon.debugLayer.js",
+                "../../src/Debug/babylon.physicsViewer.js",
                 "../../src/Rendering/babylon.boundingBoxRenderer.js"
             ],
             "dependUpon": [
@@ -1527,6 +1530,7 @@
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "doNotIncludeInBundle": true,
@@ -1548,6 +1552,7 @@
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "output": "babylon.glTFFileLoader.js"

+ 3 - 3
Tools/Gulp/gulp-addDtsExport.js

@@ -11,15 +11,15 @@ module.exports = function (varName, moduleName, subModule, extendsRoot, dependen
 
         let referenceText = '';
         if (subModule) {
-            // referenceText = '/// <reference types="babylonjs"/>\n';
+            //referenceText = '/// <reference types="babylonjs"/>\n';
         }
 
         if (dependencies) {
             referenceText = '';
             dependencies.forEach(element => {
                 // was "babylonjs/${element}""
-                /*referenceText += `/// <reference types="${element}"/>
-`;*/
+                referenceText += `/// <reference types="${element}"/>
+`;
             });
         }
 

+ 1 - 1
Tools/Gulp/gulp-addES6Exports.js

@@ -37,7 +37,7 @@ globalObject["${base}"] = ${base}${(subModule && !extendsRoot) ? '.' + varName :
             let enumMatcher = new RegExp(`\\(${base}\\.([A-Za-z0-9].*)= {}\\)`, "g");
             let enumMatch = enumMatcher.exec(fileContent);
             while (enumMatch != null) {
-                if (enumMatch[1]) {
+                if (enumMatch[1] && listOfExports.indexOf(enumMatch[1]) === -1) {
                     listOfExports.push(enumMatch[1]);
                 }
                 enumMatch = enumMatcher.exec(fileContent);

+ 1 - 1
Tools/Gulp/gulp-addModuleExports.js

@@ -46,7 +46,7 @@ module.exports = function (varName, config) {
                     amdText += `        ${dep.optional ? ' if(require.specified && require.specified("' + dep.module + '"))' : ''} amdDependencies.push("${dep.module}");
 `;
                     dependenciesDefinition += `
-    var ${dep.name} = root.${dep.name};`;
+    var ${dep.name} = root.${dep.name} || this.${dep.name};`;
                     afterInitText += `  ${dep.name} = ${dep.name} || this.${dep.name};
 `
                 });

+ 26 - 8
Tools/Gulp/gulp-validateTypedoc.js

@@ -289,7 +289,7 @@ Validate.prototype.validateTypedocNamespaces = function (namespaces) {
         this.validateNaming(null, containerNode);
 
         // Validate Comments.
-        if (isPublic && !this.validateComment(containerNode)) {            
+        if (isPublic && !this.validateComment(containerNode)) {      
             this.errorCallback(null,
                 containerNode.name,
                 containerNode.kindString,
@@ -319,7 +319,7 @@ Validate.prototype.validateTypedocNamespaces = function (namespaces) {
                 this.validateNaming(containerNode, childNode);
 
                 //if comment contains @ignore then skip validation completely
-                if (Validate.hasTag(childNode, 'ignore')) continue;                
+                if (Validate.hasTag(childNode, 'ignore')) continue;
 
                 if (isPublic) {
                     tags = this.validateTags(childNode);
@@ -413,7 +413,7 @@ Validate.prototype.validateTags = function(node) {
         if (tags) {
             for (var i = 0; i < tags.length; i++) {
                 var tag = tags[i];
-                var validTags = ["constructor", "throw", "type", "deprecated", "example", "examples", "remark", "see", "remarks"]
+                var validTags = ["constructor", "throw", "type", "deprecated", "example", "examples", "remark", "see", "remarks", "ignorenaming"]
                 if (validTags.indexOf(tag.tag) === -1) {
                     errorTags.push(tag.tag);
                 }
@@ -448,11 +448,10 @@ Validate.prototype.validateComment = function(node) {
     // Return true for overwrited properties
     if (node.overwrites) {
         return true;
-    }
-    
+    } 
 
+    // Check comments.
     if (node.comment) {
-
         if (node.comment.text || node.comment.shortText) {
             return true;
         }
@@ -460,6 +459,11 @@ Validate.prototype.validateComment = function(node) {
         return false;
     }
 
+    // Return true for inherited properties (need to check signatures)
+    if (node.kindString === "Function") {
+        return true;
+    }
+
     return false;
 }
 
@@ -500,6 +504,20 @@ Validate.prototype.validateNaming = function(parent, node) {
         return;
     }
 
+    // Ignore Naming Tag Check
+    if (Validate.hasTag(node, 'ignoreNaming')) {
+        return;
+    } else {
+        if (node.signatures) {
+            for (var index = 0; index < node.signatures.length; index++) {
+                var signature = node.signatures[index];
+                if (Validate.hasTag(signature, 'ignoreNaming')) {
+                    return;
+                }
+            }
+        }
+    }
+
     if (node.inheritedFrom) {
         return;
     }
@@ -540,13 +558,13 @@ Validate.prototype.validateNaming = function(parent, node) {
         }
     }
     else if (node.kindString == "Module") {
-        if (!Validate.upperCase.test(node.name)) {
+        if (!(Validate.upperCase.test(node.name) || Validate.pascalCase.test(node.name))) {
             this.errorCallback(parent ? parent.name : null,
                 node.name,
                 node.kindString,
                 "Naming",
                 "NotUpperCase",
-                "Module is not Upper Case " + node.name + " (id: " + node.id + ")", Validate.position(node));
+                "Module is not Upper Case or Pascal Case " + node.name + " (id: " + node.id + ")", Validate.position(node));
         }
     }
     else if (node.kindString == "Interface" ||

+ 7 - 3
Tools/Gulp/gulpfile.js

@@ -331,13 +331,17 @@ var buildExternalLibraries = function (settings) {
             let dtsFiles = files.map(function (filename) {
                 return filename.replace(".js", ".d.ts");
             });
-            let dtsTask = gulp.src(dtsFiles)
+            let dtsModuleTask = gulp.src(dtsFiles)
                 .pipe(concat(settings.build.outputFilename + ".module.d.ts"))
                 .pipe(replace(referenceSearchRegex, ""))
                 .pipe(addDtsExport(settings.build.moduleDeclaration, settings.build.moduleName, true, settings.build.extendsRoot, settings.build.extraTypesDependencies))
                 .pipe(gulp.dest(outputDirectory));
+            let dtsTask = gulp.src(dtsFiles)
+                .pipe(concat(settings.build.outputFilename + ".d.ts"))
+                .pipe(replace(referenceSearchRegex, ""))
+                .pipe(gulp.dest(outputDirectory));
 
-            return merge2([srcTask, dtsTask]);
+            return merge2([srcTask, dtsTask, dtsModuleTask]);
         });
     }
 
@@ -589,7 +593,7 @@ gulp.task("watch", ["srcTscWatch"], function () {
 
 gulp.task("intellisense", function () {
     gulp.src(config.build.intellisenseSources)
-        .pipe(concat(config.build.intellisenseFile))    
+        .pipe(concat(config.build.intellisenseFile))
         .pipe(replace(/^\s+_.*?;/gm, ""))
         .pipe(replace(/^\s+_[\S\s]*?}/gm, ""))
         .pipe(replace(/^\s*readonly _/gm, "protected readonly _"))

+ 1 - 1
Viewer/tsconfig-gulp.json

@@ -25,7 +25,7 @@
                 "../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
+                "../dist/preview release/loaders/babylonjs.loaders.d.ts"
             ],
             "babylonjs-gltf2interface": [
                 "../dist/babylon.glTF2Interface.d.ts"

+ 1 - 1
Viewer/tsconfig.json

@@ -25,7 +25,7 @@
                 "../../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "../../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
+                "../../dist/preview release/loaders/babylonjs.loaders.d.ts"
             ],
             "babylonjs-gltf2interface": [
                 "../../dist/babylon.glTF2Interface.d.ts"

+ 4 - 0
dist/babylon.glTF2Interface.d.ts

@@ -1,3 +1,7 @@
+declare module "babylonjs-gltf2interface" {
+    export = BABYLON.GLTF2;
+}
+
 declare module BABYLON.GLTF2 {
     const enum AccessorComponentType {
         BYTE = 5120,

Файловите разлики са ограничени, защото са твърде много
+ 14166 - 11974
dist/preview release/babylon.d.ts


Файловите разлики са ограничени, защото са твърде много
+ 56 - 56
dist/preview release/babylon.js


Файловите разлики са ограничени, защото са твърде много
+ 2876 - 600
dist/preview release/babylon.max.js


Файловите разлики са ограничени, защото са твърде много
+ 57 - 57
dist/preview release/babylon.worker.js


Файловите разлики са ограничени, защото са твърде много
+ 2875 - 599
dist/preview release/es6.js


+ 1 - 1
dist/preview release/gui/babylon.gui.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 

Файловите разлики са ограничени, защото са твърде много
+ 4 - 4
dist/preview release/gui/babylon.gui.min.js


Файловите разлики са ограничени, защото са твърде много
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


+ 3 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -294,6 +294,7 @@ declare module INSPECTOR {
         getProperties(): Array<PropertyLine>;
         getTools(): Array<AbstractTreeTool>;
         setPOV(): void;
+        getCurrentActiveCamera(): string;
     }
 }
 
@@ -1256,6 +1257,8 @@ declare module INSPECTOR {
 declare module INSPECTOR {
     interface ICameraPOV {
         setPOV: () => void;
+        getCurrentActiveCamera: () => string;
+        id: () => string;
     }
     /**
      *

+ 31 - 29
dist/preview release/inspector/babylon.inspector.js

@@ -710,12 +710,22 @@ var INSPECTOR;
         };
         CameraAdapter.prototype.getTools = function () {
             var tools = [];
-            // tools.push(new Checkbox(this));
             tools.push(new INSPECTOR.CameraPOV(this));
             return tools;
         };
+        // Set the point of view of the chosen camera
         CameraAdapter.prototype.setPOV = function () {
-            this._obj.getScene().activeCamera = this._obj;
+            this._obj.getScene().switchActiveCamera(this._obj);
+        };
+        // Return the name of the current active camera
+        CameraAdapter.prototype.getCurrentActiveCamera = function () {
+            var activeCamera = this._obj.getScene().activeCamera;
+            if (activeCamera != null) {
+                return activeCamera.name;
+            }
+            else {
+                return "0";
+            }
         };
         return CameraAdapter;
     }(INSPECTOR.Adapter));
@@ -3441,25 +3451,6 @@ var INSPECTOR;
                 point.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = true; _this._inspector.scene.forceWireframe = false; });
                 wireframe.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = true; });
                 solid.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = false; });
-                // Cameras
-                title = INSPECTOR.Helpers.CreateDiv('actions-title', _this._actions);
-                title.textContent = 'Cameras';
-                var cameraRadioButtons = [];
-                var _loop_1 = function (camera) {
-                    var cameraRadio = INSPECTOR.Helpers.CreateDiv('action-radio', this_1._actions);
-                    cameraRadio.textContent = camera.name;
-                    if (this_1._inspector.scene.activeCamera == camera) {
-                        cameraRadio.classList.add('active');
-                    }
-                    cameraRadioButtons.push(cameraRadio);
-                    cameraRadio.addEventListener('click', function () { _this._inspector.scene.switchActiveCamera(camera); });
-                };
-                var this_1 = this;
-                for (var _a = 0, _b = _this._inspector.scene.cameras; _a < _b.length; _a++) {
-                    var camera = _b[_a];
-                    _loop_1(camera);
-                }
-                _this._generateRadioAction(cameraRadioButtons);
                 // Textures
                 title = INSPECTOR.Helpers.CreateDiv('actions-title', _this._actions);
                 title.textContent = 'Textures channels';
@@ -5023,7 +5014,15 @@ var INSPECTOR;
         function CameraPOV(camera) {
             var _this = _super.call(this) || this;
             _this.cameraPOV = camera;
-            _this._elem.classList.add('fa-video-camera');
+            // Setting the id of the line with the name of the camera
+            _this._elem.id = _this.cameraPOV.id();
+            // Put the right icon 
+            if (_this._elem.id == _this.cameraPOV.getCurrentActiveCamera()) {
+                _this._elem.classList.add('fa-check-circle');
+            }
+            else {
+                _this._elem.classList.add('fa-circle');
+            }
             return _this;
         }
         CameraPOV.prototype.action = function () {
@@ -5031,16 +5030,19 @@ var INSPECTOR;
             this._gotoPOV();
         };
         CameraPOV.prototype._gotoPOV = function () {
-            var actives = INSPECTOR.Inspector.DOCUMENT.querySelectorAll(".fa-video-camera.active");
-            console.log(actives);
+            // Uncheck all the radio buttons
+            var actives = INSPECTOR.Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
             for (var i = 0; i < actives.length; i++) {
-                actives[i].classList.remove('active');
+                actives[i].classList.remove('fa-check-circle');
+                actives[i].classList.add('fa-circle');
             }
-            //if (this._on) {
-            // set icon camera
-            this._elem.classList.add('active');
-            //}
+            // setting the point off view to the right camera
             this.cameraPOV.setPOV();
+            // Check the right radio button
+            if (this._elem.id == this.cameraPOV.getCurrentActiveCamera()) {
+                this._elem.classList.remove('fa-circle');
+                this._elem.classList.add('fa-check-circle');
+            }
         };
         return CameraPOV;
     }(INSPECTOR.AbstractTreeTool));

Файловите разлики са ограничени, защото са твърде много
+ 4 - 4
dist/preview release/inspector/babylon.inspector.min.js


Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 20 - 13
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -176,9 +176,6 @@ declare module BABYLON {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -198,7 +195,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -220,6 +218,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -341,10 +340,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -359,7 +356,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -397,19 +395,19 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (context: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
         /** Helper method called by the loader to allow extensions to override loading scenes. */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -446,7 +444,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 
@@ -461,6 +459,15 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
+    class KHR_materials_unlit extends GLTFLoaderExtension {
+        readonly name: string;
+        protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;

+ 193 - 146
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -946,9 +946,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -973,24 +974,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -998,18 +992,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -1018,9 +1007,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -1040,7 +1033,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -1048,93 +1041,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -1451,9 +1406,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -1462,7 +1417,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -1470,63 +1424,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
                 }
-                return targetBuffer;
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
+                }
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -2063,9 +2019,9 @@ var BABYLON;
                 }
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                         var firstPromise;
-                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(extensionContext, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -2110,9 +2066,9 @@ var BABYLON;
                     if (this._loadingNodeLOD) {
                         return null;
                     }
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         var firstPromise;
-                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(extensionContext, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -2274,7 +2230,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);
@@ -2321,7 +2281,7 @@ var BABYLON;
                 }
                 KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
                         var babylonData = material._babylonData[babylonDrawMode];
                         if (!babylonData) {
@@ -2329,7 +2289,7 @@ var BABYLON;
                             var name_1 = material.name || "materialSG_" + material._index;
                             var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
                             promises.push(_this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(context, material, extension, babylonMaterial));
+                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
                             _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                             babylonData = {
                                 material: babylonMaterial,
@@ -2397,6 +2357,93 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
+            // https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit
+            var NAME = "KHR_materials_unlit";
+            var KHR_materials_unlit = /** @class */ (function (_super) {
+                __extends(KHR_materials_unlit, _super);
+                function KHR_materials_unlit() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, material, function () {
+                        material._babylonData = material._babylonData || {};
+                        var babylonData = material._babylonData[babylonDrawMode];
+                        if (!babylonData) {
+                            var name_1 = material.name || "materialUnlit_" + material._index;
+                            var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
+                            babylonMaterial.unlit = true;
+                            var promise = _this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+                            _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                            babylonData = {
+                                material: babylonMaterial,
+                                meshes: [],
+                                loaded: promise
+                            };
+                            material._babylonData[babylonDrawMode] = babylonData;
+                        }
+                        babylonData.meshes.push(babylonMesh);
+                        assign(babylonData.material);
+                        return babylonData.loaded;
+                    });
+                };
+                KHR_materials_unlit.prototype._loadUnlitPropertiesAsync = function (context, material, babylonMaterial) {
+                    var promises = new Array();
+                    // Ensure metallic workflow
+                    babylonMaterial.metallic = 1;
+                    babylonMaterial.roughness = 1;
+                    var properties = material.pbrMetallicRoughness;
+                    if (properties) {
+                        if (properties.baseColorFactor) {
+                            babylonMaterial.albedoColor = BABYLON.Color3.FromArray(properties.baseColorFactor);
+                            babylonMaterial.alpha = properties.baseColorFactor[3];
+                        }
+                        else {
+                            babylonMaterial.albedoColor = BABYLON.Color3.White();
+                        }
+                        if (properties.baseColorTexture) {
+                            promises.push(this._loader._loadTextureAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                babylonMaterial.albedoTexture = texture;
+                            }));
+                        }
+                    }
+                    if (material.doubleSided) {
+                        babylonMaterial.backFaceCulling = false;
+                        babylonMaterial.twoSidedLighting = true;
+                    }
+                    this._loader._loadMaterialAlphaProperties(context, material, babylonMaterial);
+                    return Promise.all(promises).then(function () { });
+                };
+                return KHR_materials_unlit;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHR_materials_unlit = KHR_materials_unlit;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_unlit(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_materials_unlit.js.map
+
+"use strict";
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             // https://github.com/MiiBond/glTF/tree/khr_lights_v1/extensions/Khronos/KHR_lights
             var NAME = "KHR_lights";
             var LightType;
@@ -2415,11 +2462,11 @@ var BABYLON;
                 }
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, scene, function (context, extension) {
-                        var promise = _this._loader._loadSceneAsync(context, scene);
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        var promise = _this._loader._loadSceneAsync(extensionContext, scene);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         if (light.type !== LightType.AMBIENT) {
-                            throw new Error(context + ": Only ambient lights are allowed on a scene");
+                            throw new Error(extensionContext + ": Only ambient lights are allowed on a scene");
                         }
                         _this._loader._babylonScene.ambientColor = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.Black();
                         return promise;
@@ -2427,14 +2474,14 @@ var BABYLON;
                 };
                 KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
-                        var promise = _this._loader._loadNodeAsync(context, node);
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        var promise = _this._loader._loadNodeAsync(extensionContext, node);
                         var babylonLight;
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         var name = node._babylonMesh.name;
                         switch (light.type) {
                             case LightType.AMBIENT: {
-                                throw new Error(context + ": Ambient lights are not allowed on a node");
+                                throw new Error(extensionContext + ": Ambient lights are not allowed on a node");
                             }
                             case LightType.DIRECTIONAL: {
                                 babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Forward(), _this._loader._babylonScene);
@@ -2453,7 +2500,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type (" + light.type + ")");
+                                throw new Error(extensionContext + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();

Файловите разлики са ограничени, защото са твърде много
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 20 - 13
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -732,9 +732,6 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -754,7 +751,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -776,6 +774,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -897,10 +896,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -915,7 +912,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -953,19 +951,19 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (context: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
         /** Helper method called by the loader to allow extensions to override loading scenes. */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -1002,7 +1000,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 
@@ -1017,6 +1015,15 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
+    class KHR_materials_unlit extends GLTFLoaderExtension {
+        readonly name: string;
+        protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;

+ 193 - 146
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3144,9 +3144,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -3171,24 +3172,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -3196,18 +3190,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -3216,9 +3205,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -3238,7 +3231,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -3246,93 +3239,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -3649,9 +3604,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -3660,7 +3615,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -3668,63 +3622,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
                 }
-                return targetBuffer;
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
+                }
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -4261,9 +4217,9 @@ var BABYLON;
                 }
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                         var firstPromise;
-                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(extensionContext, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -4308,9 +4264,9 @@ var BABYLON;
                     if (this._loadingNodeLOD) {
                         return null;
                     }
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         var firstPromise;
-                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(extensionContext, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -4472,7 +4428,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);
@@ -4519,7 +4479,7 @@ var BABYLON;
                 }
                 KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
                         var babylonData = material._babylonData[babylonDrawMode];
                         if (!babylonData) {
@@ -4527,7 +4487,7 @@ var BABYLON;
                             var name_1 = material.name || "materialSG_" + material._index;
                             var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
                             promises.push(_this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(context, material, extension, babylonMaterial));
+                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
                             _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                             babylonData = {
                                 material: babylonMaterial,
@@ -4595,6 +4555,93 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
+            // https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit
+            var NAME = "KHR_materials_unlit";
+            var KHR_materials_unlit = /** @class */ (function (_super) {
+                __extends(KHR_materials_unlit, _super);
+                function KHR_materials_unlit() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, material, function () {
+                        material._babylonData = material._babylonData || {};
+                        var babylonData = material._babylonData[babylonDrawMode];
+                        if (!babylonData) {
+                            var name_1 = material.name || "materialUnlit_" + material._index;
+                            var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
+                            babylonMaterial.unlit = true;
+                            var promise = _this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+                            _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                            babylonData = {
+                                material: babylonMaterial,
+                                meshes: [],
+                                loaded: promise
+                            };
+                            material._babylonData[babylonDrawMode] = babylonData;
+                        }
+                        babylonData.meshes.push(babylonMesh);
+                        assign(babylonData.material);
+                        return babylonData.loaded;
+                    });
+                };
+                KHR_materials_unlit.prototype._loadUnlitPropertiesAsync = function (context, material, babylonMaterial) {
+                    var promises = new Array();
+                    // Ensure metallic workflow
+                    babylonMaterial.metallic = 1;
+                    babylonMaterial.roughness = 1;
+                    var properties = material.pbrMetallicRoughness;
+                    if (properties) {
+                        if (properties.baseColorFactor) {
+                            babylonMaterial.albedoColor = BABYLON.Color3.FromArray(properties.baseColorFactor);
+                            babylonMaterial.alpha = properties.baseColorFactor[3];
+                        }
+                        else {
+                            babylonMaterial.albedoColor = BABYLON.Color3.White();
+                        }
+                        if (properties.baseColorTexture) {
+                            promises.push(this._loader._loadTextureAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                babylonMaterial.albedoTexture = texture;
+                            }));
+                        }
+                    }
+                    if (material.doubleSided) {
+                        babylonMaterial.backFaceCulling = false;
+                        babylonMaterial.twoSidedLighting = true;
+                    }
+                    this._loader._loadMaterialAlphaProperties(context, material, babylonMaterial);
+                    return Promise.all(promises).then(function () { });
+                };
+                return KHR_materials_unlit;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHR_materials_unlit = KHR_materials_unlit;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_unlit(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_materials_unlit.js.map
+
+"use strict";
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             // https://github.com/MiiBond/glTF/tree/khr_lights_v1/extensions/Khronos/KHR_lights
             var NAME = "KHR_lights";
             var LightType;
@@ -4613,11 +4660,11 @@ var BABYLON;
                 }
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, scene, function (context, extension) {
-                        var promise = _this._loader._loadSceneAsync(context, scene);
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        var promise = _this._loader._loadSceneAsync(extensionContext, scene);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         if (light.type !== LightType.AMBIENT) {
-                            throw new Error(context + ": Only ambient lights are allowed on a scene");
+                            throw new Error(extensionContext + ": Only ambient lights are allowed on a scene");
                         }
                         _this._loader._babylonScene.ambientColor = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.Black();
                         return promise;
@@ -4625,14 +4672,14 @@ var BABYLON;
                 };
                 KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
-                        var promise = _this._loader._loadNodeAsync(context, node);
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        var promise = _this._loader._loadNodeAsync(extensionContext, node);
                         var babylonLight;
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         var name = node._babylonMesh.name;
                         switch (light.type) {
                             case LightType.AMBIENT: {
-                                throw new Error(context + ": Ambient lights are not allowed on a node");
+                                throw new Error(extensionContext + ": Ambient lights are not allowed on a node");
                             }
                             case LightType.DIRECTIONAL: {
                                 babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Forward(), _this._loader._babylonScene);
@@ -4651,7 +4698,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type (" + light.type + ")");
+                                throw new Error(extensionContext + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();

Файловите разлики са ограничени, защото са твърде много
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1128 - 0
dist/preview release/loaders/babylonjs.loaders.d.ts


+ 185 - 147
dist/preview release/loaders/babylonjs.loaders.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 
@@ -4123,9 +4123,10 @@ var BABYLON;
                 var _this = this;
                 var promises = new Array();
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonVertexData) {
-                    new BABYLON.Geometry(babylonMesh.name, _this._babylonScene, babylonVertexData, false, babylonMesh);
-                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+                promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
+                    return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
+                        babylonGeometry.applyToMesh(babylonMesh);
+                    });
                 }));
                 var babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
                 if (primitive.material == undefined) {
@@ -4150,24 +4151,17 @@ var BABYLON;
                     throw new Error(context + ": Attributes are missing");
                 }
                 var promises = new Array();
-                var babylonVertexData = new BABYLON.VertexData();
+                var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene);
                 if (primitive.indices == undefined) {
-                    var positionAccessorIndex = attributes["POSITION"];
-                    if (positionAccessorIndex != undefined) {
-                        var accessor = GLTFLoader._GetProperty(context + "/attributes/POSITION", this._gltf.accessors, positionAccessorIndex);
-                        babylonVertexData.indices = new Uint32Array(accessor.count);
-                        for (var i = 0; i < babylonVertexData.indices.length; i++) {
-                            babylonVertexData.indices[i] = i;
-                        }
-                    }
+                    babylonMesh.isUnIndexed = true;
                 }
                 else {
-                    var indicesAccessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
-                    promises.push(this._loadAccessorAsync("#/accessors/" + indicesAccessor._index, indicesAccessor).then(function (data) {
-                        babylonVertexData.indices = data;
+                    var accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                    promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
+                        babylonGeometry.setIndices(data);
                     }));
                 }
-                var loadAttribute = function (attribute, kind) {
+                var loadAttribute = function (attribute, kind, callback) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
@@ -4175,18 +4169,13 @@ var BABYLON;
                     if (babylonMesh._delayInfo.indexOf(kind) === -1) {
                         babylonMesh._delayInfo.push(kind);
                     }
-                    if (attribute === "COLOR_0") {
-                        // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                        babylonMesh.hasVertexAlpha = true;
-                    }
                     var accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, _this._gltf.accessors, attributes[attribute]);
-                    promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        var attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-                        if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                            attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                        }
-                        babylonVertexData.set(attributeData, kind);
+                    promises.push(_this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(function (babylonVertexBuffer) {
+                        babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                     }));
+                    if (callback) {
+                        callback(accessor);
+                    }
                 };
                 loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind);
                 loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind);
@@ -4195,9 +4184,13 @@ var BABYLON;
                 loadAttribute("TEXCOORD_1", BABYLON.VertexBuffer.UV2Kind);
                 loadAttribute("JOINTS_0", BABYLON.VertexBuffer.MatricesIndicesKind);
                 loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
-                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
+                loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind, function (accessor) {
+                    if (accessor.type === "VEC4" /* VEC4 */) {
+                        babylonMesh.hasVertexAlpha = true;
+                    }
+                });
                 return Promise.all(promises).then(function () {
-                    return babylonVertexData;
+                    return babylonGeometry;
                 });
             };
             GLTFLoader.prototype._createMorphTargets = function (context, node, mesh, primitive, babylonMesh) {
@@ -4217,7 +4210,7 @@ var BABYLON;
                     // TODO: tell the target whether it has positions, normals, tangents
                 }
             };
-            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonVertexData) {
+            GLTFLoader.prototype._loadMorphTargetsAsync = function (context, primitive, babylonMesh, babylonGeometry) {
                 if (!primitive.targets) {
                     return Promise.resolve();
                 }
@@ -4225,93 +4218,55 @@ var BABYLON;
                 var morphTargetManager = babylonMesh.morphTargetManager;
                 for (var index = 0; index < morphTargetManager.numTargets; index++) {
                     var babylonMorphTarget = morphTargetManager.getTarget(index);
-                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                    promises.push(this._loadMorphTargetVertexDataAsync(context + "/targets/" + index, babylonGeometry, primitive.targets[index], babylonMorphTarget));
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonVertexData, attributes, babylonMorphTarget) {
+            GLTFLoader.prototype._loadMorphTargetVertexDataAsync = function (context, babylonGeometry, attributes, babylonMorphTarget) {
                 var _this = this;
                 var promises = new Array();
-                var loadAttribute = function (attribute, setData) {
+                var loadAttribute = function (attribute, kind, setData) {
                     if (attributes[attribute] == undefined) {
                         return;
                     }
+                    var babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                    if (!babylonVertexBuffer) {
+                        return;
+                    }
                     var accessor = GLTFLoader._GetProperty(context + "/" + attribute, _this._gltf.accessors, attributes[attribute]);
                     promises.push(_this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(function (data) {
-                        setData(data);
+                        if (!(data instanceof Float32Array)) {
+                            throw new Error(context + ": Morph target accessor must have float data");
+                        }
+                        setData(babylonVertexBuffer, data);
                     }));
                 };
-                loadAttribute("POSITION", function (data) {
-                    if (babylonVertexData.positions) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.positions[i];
-                        }
-                        babylonMorphTarget.setPositions(data);
-                    }
+                loadAttribute("POSITION", BABYLON.VertexBuffer.PositionKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setPositions(data);
                 });
-                loadAttribute("NORMAL", function (data) {
-                    if (babylonVertexData.normals) {
-                        for (var i = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.normals[i];
-                        }
-                        babylonMorphTarget.setNormals(data);
-                    }
+                loadAttribute("NORMAL", BABYLON.VertexBuffer.NormalKind, function (babylonVertexBuffer, data) {
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
+                        data[index] += value;
+                    });
+                    babylonMorphTarget.setNormals(data);
                 });
-                loadAttribute("TANGENT", function (data) {
-                    if (babylonVertexData.tangents) {
+                loadAttribute("TANGENT", BABYLON.VertexBuffer.TangentKind, function (babylonVertexBuffer, data) {
+                    var dataIndex = 0;
+                    babylonVertexBuffer.forEach(data.length, function (value, index) {
                         // Tangent data for morph targets is stored as xyz delta.
                         // The vertexData.tangent is stored as xyzw.
                         // So we need to skip every fourth vertexData.tangent.
-                        for (var i = 0, j = 0; i < data.length; i++) {
-                            data[i] += babylonVertexData.tangents[j++];
-                            if ((i + 1) % 3 == 0) {
-                                j++;
-                            }
+                        if (((index + 1) % 4) !== 0) {
+                            data[dataIndex++] += value;
                         }
-                        babylonMorphTarget.setTangents(data);
-                    }
+                    });
+                    babylonMorphTarget.setTangents(data);
                 });
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader._ConvertToFloat32Array = function (context, accessor, data) {
-                if (accessor.componentType == 5126 /* FLOAT */) {
-                    return data;
-                }
-                var factor = 1;
-                if (accessor.normalized) {
-                    switch (accessor.componentType) {
-                        case 5121 /* UNSIGNED_BYTE */: {
-                            factor = 1 / 255;
-                            break;
-                        }
-                        case 5123 /* UNSIGNED_SHORT */: {
-                            factor = 1 / 65535;
-                            break;
-                        }
-                        default: {
-                            throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
-                        }
-                    }
-                }
-                var result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-                for (var i = 0; i < result.length; i++) {
-                    result[i] = data[i] * factor;
-                }
-                return result;
-            };
-            GLTFLoader._ConvertVec3ToVec4 = function (context, data) {
-                var result = new Float32Array(data.length / 3 * 4);
-                var offset = 0;
-                for (var i = 0; i < result.length; i++) {
-                    if ((i + 1) % 4 === 0) {
-                        result[i] = 1;
-                    }
-                    else {
-                        result[i] = data[offset++];
-                    }
-                }
-                return result;
-            };
             GLTFLoader._LoadTransform = function (node, babylonNode) {
                 var position = BABYLON.Vector3.Zero();
                 var rotation = BABYLON.Quaternion.Identity();
@@ -4628,9 +4583,9 @@ var BABYLON;
                     return bufferView._data;
                 }
                 var buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
-                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (bufferData) {
+                bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(function (data) {
                     try {
-                        return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                        return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                     }
                     catch (e) {
                         throw new Error(context + ": " + e.message);
@@ -4639,7 +4594,6 @@ var BABYLON;
                 return bufferView._data;
             };
             GLTFLoader.prototype._loadAccessorAsync = function (context, accessor) {
-                var _this = this;
                 if (accessor.sparse) {
                     throw new Error(context + ": Sparse accessors are not currently supported");
                 }
@@ -4647,63 +4601,65 @@ var BABYLON;
                     return accessor._data;
                 }
                 var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
-                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (bufferViewData) {
-                    var numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                    var byteOffset = accessor.byteOffset || 0;
-                    var byteStride = bufferView.byteStride;
-                    if (byteStride === 0) {
-                        BABYLON.Tools.Warn(context + ": Byte stride of 0 is not valid");
-                    }
+                accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
+                    var buffer = data.buffer;
+                    var byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                    var length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
                     try {
                         switch (accessor.componentType) {
                             case 5120 /* BYTE */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int8Array(buffer, byteOffset, length);
                             }
                             case 5121 /* UNSIGNED_BYTE */: {
-                                return _this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint8Array(buffer, byteOffset, length);
                             }
                             case 5122 /* SHORT */: {
-                                return _this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Int16Array(buffer, byteOffset, length);
                             }
                             case 5123 /* UNSIGNED_SHORT */: {
-                                return _this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint16Array(buffer, byteOffset, length);
                             }
                             case 5125 /* UNSIGNED_INT */: {
-                                return _this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Uint32Array(buffer, byteOffset, length);
                             }
                             case 5126 /* FLOAT */: {
-                                return _this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                                return new Float32Array(buffer, byteOffset, length);
                             }
                             default: {
-                                throw new Error(context + ": Invalid component type (" + accessor.componentType + ")");
+                                throw new Error(context + ": Invalid accessor component type " + accessor.componentType);
                             }
                         }
                     }
                     catch (e) {
-                        throw new Error(context + ": " + e.messsage);
+                        throw new Error(context + ": " + e);
                     }
                 });
                 return accessor._data;
             };
-            GLTFLoader.prototype._buildArrayBuffer = function (typedArray, data, byteOffset, count, numComponents, byteStride) {
-                byteOffset += data.byteOffset;
-                var targetLength = count * numComponents;
-                if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                    return new typedArray(data.buffer, byteOffset, targetLength);
+            GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
+                var _this = this;
+                if (bufferView._babylonBuffer) {
+                    return bufferView._babylonBuffer;
                 }
-                var elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-                var sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-                var targetBuffer = new typedArray(targetLength);
-                var sourceIndex = 0;
-                var targetIndex = 0;
-                while (targetIndex < targetLength) {
-                    for (var componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                        targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                        targetIndex++;
-                    }
-                    sourceIndex += elementStride;
+                bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(function (data) {
+                    return new BABYLON.Buffer(_this._babylonScene.getEngine(), data, false);
+                });
+                return bufferView._babylonBuffer;
+            };
+            GLTFLoader.prototype._loadVertexAccessorAsync = function (context, accessor, kind) {
+                var _this = this;
+                if (accessor.sparse) {
+                    throw new Error(context + ": Sparse accessors are not currently supported");
+                }
+                if (accessor._babylonVertexBuffer) {
+                    return accessor._babylonVertexBuffer;
                 }
-                return targetBuffer;
+                var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+                accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(function (buffer) {
+                    var size = GLTFLoader._GetNumComponents(context, accessor.type);
+                    return new BABYLON.VertexBuffer(_this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride, false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+                });
+                return accessor._babylonVertexBuffer;
             };
             GLTFLoader.prototype._getDefaultMaterial = function (drawMode) {
                 var babylonMaterial = this._defaultBabylonMaterials[drawMode];
@@ -5231,9 +5187,9 @@ var BABYLON;
                 }
                 MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                         var firstPromise;
-                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(extensionContext, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -5278,9 +5234,9 @@ var BABYLON;
                     if (this._loadingNodeLOD) {
                         return null;
                     }
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         var firstPromise;
-                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(extensionContext, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -5433,7 +5389,11 @@ var BABYLON;
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
-                                return _this._dracoCompression.decodeMeshAsync(data, attributes);
+                                return _this._dracoCompression.decodeMeshAsync(data, attributes).then(function (babylonVertexData) {
+                                    var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
+                                    babylonVertexData.applyToGeometry(babylonGeometry);
+                                    return babylonGeometry;
+                                });
                             }
                             catch (e) {
                                 throw new Error(context + ": " + e.message);
@@ -5471,7 +5431,7 @@ var BABYLON;
                 }
                 KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, material, function (context, extension) {
+                    return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         material._babylonData = material._babylonData || {};
                         var babylonData = material._babylonData[babylonDrawMode];
                         if (!babylonData) {
@@ -5479,7 +5439,7 @@ var BABYLON;
                             var name_1 = material.name || "materialSG_" + material._index;
                             var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
                             promises.push(_this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(context, material, extension, babylonMaterial));
+                            promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
                             _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                             babylonData = {
                                 material: babylonMaterial,
@@ -5538,6 +5498,84 @@ var BABYLON;
     (function (GLTF2) {
         var Extensions;
         (function (Extensions) {
+            // https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit
+            var NAME = "KHR_materials_unlit";
+            var KHR_materials_unlit = /** @class */ (function (_super) {
+                __extends(KHR_materials_unlit, _super);
+                function KHR_materials_unlit() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
+                }
+                KHR_materials_unlit.prototype._loadMaterialAsync = function (context, material, babylonMesh, babylonDrawMode, assign) {
+                    var _this = this;
+                    return this._loadExtensionAsync(context, material, function () {
+                        material._babylonData = material._babylonData || {};
+                        var babylonData = material._babylonData[babylonDrawMode];
+                        if (!babylonData) {
+                            var name_1 = material.name || "materialUnlit_" + material._index;
+                            var babylonMaterial = _this._loader._createMaterial(BABYLON.PBRMaterial, name_1, babylonDrawMode);
+                            babylonMaterial.unlit = true;
+                            var promise = _this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+                            _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                            babylonData = {
+                                material: babylonMaterial,
+                                meshes: [],
+                                loaded: promise
+                            };
+                            material._babylonData[babylonDrawMode] = babylonData;
+                        }
+                        babylonData.meshes.push(babylonMesh);
+                        assign(babylonData.material);
+                        return babylonData.loaded;
+                    });
+                };
+                KHR_materials_unlit.prototype._loadUnlitPropertiesAsync = function (context, material, babylonMaterial) {
+                    var promises = new Array();
+                    // Ensure metallic workflow
+                    babylonMaterial.metallic = 1;
+                    babylonMaterial.roughness = 1;
+                    var properties = material.pbrMetallicRoughness;
+                    if (properties) {
+                        if (properties.baseColorFactor) {
+                            babylonMaterial.albedoColor = BABYLON.Color3.FromArray(properties.baseColorFactor);
+                            babylonMaterial.alpha = properties.baseColorFactor[3];
+                        }
+                        else {
+                            babylonMaterial.albedoColor = BABYLON.Color3.White();
+                        }
+                        if (properties.baseColorTexture) {
+                            promises.push(this._loader._loadTextureAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                                babylonMaterial.albedoTexture = texture;
+                            }));
+                        }
+                    }
+                    if (material.doubleSided) {
+                        babylonMaterial.backFaceCulling = false;
+                        babylonMaterial.twoSidedLighting = true;
+                    }
+                    this._loader._loadMaterialAlphaProperties(context, material, babylonMaterial);
+                    return Promise.all(promises).then(function () { });
+                };
+                return KHR_materials_unlit;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHR_materials_unlit = KHR_materials_unlit;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_unlit(loader); });
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_materials_unlit.js.map
+
+"use strict";
+
+
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
             // https://github.com/MiiBond/glTF/tree/khr_lights_v1/extensions/Khronos/KHR_lights
             var NAME = "KHR_lights";
             var LightType;
@@ -5556,11 +5594,11 @@ var BABYLON;
                 }
                 KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, scene, function (context, extension) {
-                        var promise = _this._loader._loadSceneAsync(context, scene);
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                    return this._loadExtensionAsync(context, scene, function (extensionContext, extension) {
+                        var promise = _this._loader._loadSceneAsync(extensionContext, scene);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         if (light.type !== LightType.AMBIENT) {
-                            throw new Error(context + ": Only ambient lights are allowed on a scene");
+                            throw new Error(extensionContext + ": Only ambient lights are allowed on a scene");
                         }
                         _this._loader._babylonScene.ambientColor = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.Black();
                         return promise;
@@ -5568,14 +5606,14 @@ var BABYLON;
                 };
                 KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
-                    return this._loadExtensionAsync(context, node, function (context, extension) {
-                        var promise = _this._loader._loadNodeAsync(context, node);
+                    return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
+                        var promise = _this._loader._loadNodeAsync(extensionContext, node);
                         var babylonLight;
-                        var light = GLTF2.GLTFLoader._GetProperty(context, _this._lights, extension.light);
+                        var light = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._lights, extension.light);
                         var name = node._babylonMesh.name;
                         switch (light.type) {
                             case LightType.AMBIENT: {
-                                throw new Error(context + ": Ambient lights are not allowed on a node");
+                                throw new Error(extensionContext + ": Ambient lights are not allowed on a node");
                             }
                             case LightType.DIRECTIONAL: {
                                 babylonLight = new BABYLON.DirectionalLight(name, BABYLON.Vector3.Forward(), _this._loader._babylonScene);
@@ -5594,7 +5632,7 @@ var BABYLON;
                                 break;
                             }
                             default: {
-                                throw new Error(context + ": Invalid light type (" + light.type + ")");
+                                throw new Error(extensionContext + ": Invalid light type (" + light.type + ")");
                             }
                         }
                         babylonLight.diffuse = light.color ? BABYLON.Color3.FromArray(light.color) : BABYLON.Color3.White();

Файловите разлики са ограничени, защото са твърде много
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 22 - 13
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1,3 +1,5 @@
+/// <reference types="babylonjs"/>
+/// <reference types="babylonjs-gltf2interface"/>
 
 
 declare module 'babylonjs-loaders' { 
@@ -832,9 +834,6 @@ declare module BABYLON.GLTF1 {
 
 
 declare module BABYLON.GLTF2 {
-    interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
     interface IArrayItem {
         _index: number;
     }
@@ -854,7 +853,8 @@ declare module BABYLON.GLTF2 {
 
 declare module BABYLON.GLTF2 {
     interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
     interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
     }
@@ -876,6 +876,7 @@ declare module BABYLON.GLTF2 {
     }
     interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
     interface ILoaderCamera extends ICamera, IArrayItem {
     }
@@ -997,10 +998,8 @@ declare module BABYLON.GLTF2 {
         private _loadPrimitiveAsync(context, node, mesh, primitive, babylonMesh);
         private _loadVertexDataAsync(context, primitive, babylonMesh);
         private _createMorphTargets(context, node, mesh, primitive, babylonMesh);
-        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
-        private _loadMorphTargetVertexDataAsync(context, babylonVertexData, attributes, babylonMorphTarget);
-        private static _ConvertToFloat32Array(context, accessor, data);
-        private static _ConvertVec3ToVec4(context, data);
+        private _loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry);
+        private _loadMorphTargetVertexDataAsync(context, babylonGeometry, attributes, babylonMorphTarget);
         private static _LoadTransform(node, babylonNode);
         private _loadSkinAsync(context, node, mesh, skin);
         private _loadSkinInverseBindMatricesDataAsync(context, skin);
@@ -1015,7 +1014,8 @@ declare module BABYLON.GLTF2 {
         private _loadBufferAsync(context, buffer);
         _loadBufferViewAsync(context: string, bufferView: ILoaderBufferView): Promise<ArrayBufferView>;
         private _loadAccessorAsync(context, accessor);
-        private _buildArrayBuffer<T>(typedArray, data, byteOffset, count, numComponents, byteStride?);
+        _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer>;
+        private _loadVertexAccessorAsync(context, accessor, kind);
         private _getDefaultMaterial(drawMode);
         private _loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial);
         _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Promise<void>;
@@ -1053,19 +1053,19 @@ declare module BABYLON.GLTF2 {
         /** Override this method to modify the default behavior for loading nodes. */
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading uris. */
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (context: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>>;
         /** Helper method called by the loader to allow extensions to override loading scenes. */
         static _LoadSceneAsync(loader: GLTFLoader, context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading nodes. */
         static _LoadNodeAsync(loader: GLTFLoader, context: string, node: ILoaderNode): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /** Helper method called by the loader to allow extensions to override loading materials. */
         static _LoadMaterialAsync(loader: GLTFLoader, context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
         /** Helper method called by the loader to allow extensions to override loading uris. */
@@ -1102,7 +1102,7 @@ declare module BABYLON.GLTF2.Extensions {
         private _dracoCompression;
         constructor(loader: GLTFLoader);
         dispose(): void;
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>>;
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     }
 }
 
@@ -1117,6 +1117,15 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 declare module BABYLON.GLTF2.Extensions {
+    class KHR_materials_unlit extends GLTFLoaderExtension {
+        readonly name: string;
+        protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>>;
+        private _loadUnlitPropertiesAsync(context, material, babylonMaterial);
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
     class KHR_lights extends GLTFLoaderExtension {
         readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 580 - 0
dist/preview release/materialsLibrary/babylonjs.materials.d.ts

@@ -0,0 +1,580 @@
+
+declare module BABYLON {
+    class ShadowOnlyMaterial extends PushMaterial {
+        private _renderId;
+        private _activeLight;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        activeLight: IShadowLight;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        clone(name: string): ShadowOnlyMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class GradientMaterial extends PushMaterial {
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        topColor: Color3;
+        topColorAlpha: number;
+        bottomColor: Color3;
+        bottomColorAlpha: number;
+        offset: number;
+        smoothness: number;
+        disableLighting: boolean;
+        private _scaledDiffuse;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): GradientMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class NormalMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): NormalMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class LavaMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        noiseTexture: BaseTexture;
+        fogColor: Color3;
+        speed: number;
+        movingSpeed: number;
+        lowFrequencySpeed: number;
+        fogDensity: number;
+        private _lastTime;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _scaledDiffuse;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): LavaMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): LavaMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class SimpleMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): SimpleMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class WaterMaterial extends PushMaterial {
+        renderTargetSize: Vector2;
+        private _bumpTexture;
+        bumpTexture: BaseTexture;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        /**
+        * @param {number}: Represents the wind force
+        */
+        windForce: number;
+        /**
+        * @param {Vector2}: The direction of the wind in the plane (X, Z)
+        */
+        windDirection: Vector2;
+        /**
+        * @param {number}: Wave height, represents the height of the waves
+        */
+        waveHeight: number;
+        /**
+        * @param {number}: Bump height, represents the bump height related to the bump map
+        */
+        bumpHeight: number;
+        /**
+         * @param {boolean}: Add a smaller moving bump to less steady waves.
+         */
+        private _bumpSuperimpose;
+        bumpSuperimpose: boolean;
+        /**
+         * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
+         */
+        private _fresnelSeparate;
+        fresnelSeparate: boolean;
+        /**
+         * @param {boolean}: bump Waves modify the reflection.
+         */
+        private _bumpAffectsReflection;
+        bumpAffectsReflection: boolean;
+        /**
+        * @param {number}: The water color blended with the refraction (near)
+        */
+        waterColor: Color3;
+        /**
+        * @param {number}: The blend factor related to the water color
+        */
+        colorBlendFactor: number;
+        /**
+         * @param {number}: The water color blended with the reflection (far)
+         */
+        waterColor2: Color3;
+        /**
+         * @param {number}: The blend factor related to the water color (reflection, far)
+         */
+        colorBlendFactor2: number;
+        /**
+        * @param {number}: Represents the maximum length of a wave
+        */
+        waveLength: number;
+        /**
+        * @param {number}: Defines the waves speed
+        */
+        waveSpeed: number;
+        protected _renderTargets: SmartArray<RenderTargetTexture>;
+        private _mesh;
+        private _refractionRTT;
+        private _reflectionRTT;
+        private _reflectionTransform;
+        private _lastTime;
+        private _lastDeltaTime;
+        private _renderId;
+        private _useLogarithmicDepth;
+        private _waitingRenderList;
+        /**
+        * Constructor
+        */
+        constructor(name: string, scene: Scene, renderTargetSize?: Vector2);
+        useLogarithmicDepth: boolean;
+        readonly refractionTexture: Nullable<RenderTargetTexture>;
+        readonly reflectionTexture: Nullable<RenderTargetTexture>;
+        addToRenderList(node: any): void;
+        enableRenderTargets(enable: boolean): void;
+        getRenderList(): Nullable<AbstractMesh[]>;
+        readonly renderTargetsEnabled: boolean;
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        private _createRenderTargets(scene, renderTargetSize);
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): WaterMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): WaterMaterial;
+        static CreateDefaultMesh(name: string, scene: Scene): Mesh;
+    }
+}
+
+
+declare module BABYLON {
+    class FireMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: Nullable<BaseTexture>;
+        private _distortionTexture;
+        distortionTexture: Nullable<BaseTexture>;
+        private _opacityTexture;
+        opacityTexture: Nullable<BaseTexture>;
+        diffuseColor: Color3;
+        speed: number;
+        private _scaledDiffuse;
+        private _renderId;
+        private _lastTime;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        getClassName(): string;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): FireMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class FurMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        private _heightTexture;
+        heightTexture: BaseTexture;
+        diffuseColor: Color3;
+        furLength: number;
+        furAngle: number;
+        furColor: Color3;
+        furOffset: number;
+        furSpacing: number;
+        furGravity: Vector3;
+        furSpeed: number;
+        furDensity: number;
+        furTexture: DynamicTexture;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        highLevelFur: boolean;
+        _meshes: AbstractMesh[];
+        private _renderId;
+        private _furTime;
+        constructor(name: string, scene: Scene);
+        furTime: number;
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        updateFur(): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): FurMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial;
+        static GenerateTexture(name: string, scene: Scene): DynamicTexture;
+        static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[];
+    }
+}
+
+
+declare module BABYLON {
+    class TerrainMaterial extends PushMaterial {
+        private _mixTexture;
+        mixTexture: BaseTexture;
+        private _diffuseTexture1;
+        diffuseTexture1: Texture;
+        private _diffuseTexture2;
+        diffuseTexture2: Texture;
+        private _diffuseTexture3;
+        diffuseTexture3: Texture;
+        private _bumpTexture1;
+        bumpTexture1: Texture;
+        private _bumpTexture2;
+        bumpTexture2: Texture;
+        private _bumpTexture3;
+        bumpTexture3: Texture;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): TerrainMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): TerrainMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class TriPlanarMaterial extends PushMaterial {
+        mixTexture: BaseTexture;
+        private _diffuseTextureX;
+        diffuseTextureX: BaseTexture;
+        private _diffuseTextureY;
+        diffuseTextureY: BaseTexture;
+        private _diffuseTextureZ;
+        diffuseTextureZ: BaseTexture;
+        private _normalTextureX;
+        normalTextureX: BaseTexture;
+        private _normalTextureY;
+        normalTextureY: BaseTexture;
+        private _normalTextureZ;
+        normalTextureZ: BaseTexture;
+        tileSize: number;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): TriPlanarMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class SkyMaterial extends PushMaterial {
+        luminance: number;
+        turbidity: number;
+        rayleigh: number;
+        mieCoefficient: number;
+        mieDirectionalG: number;
+        distance: number;
+        inclination: number;
+        azimuth: number;
+        sunPosition: Vector3;
+        useSunPosition: boolean;
+        private _cameraPosition;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): SkyMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): SkyMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * The grid materials allows you to wrap any shape with a grid.
+     * Colors are customizable.
+     */
+    class GridMaterial extends BABYLON.PushMaterial {
+        /**
+         * Main color of the grid (e.g. between lines)
+         */
+        mainColor: Color3;
+        /**
+         * Color of the grid lines.
+         */
+        lineColor: Color3;
+        /**
+         * The scale of the grid compared to unit.
+         */
+        gridRatio: number;
+        /**
+         * Allows setting an offset for the grid lines.
+         */
+        gridOffset: Vector3;
+        /**
+         * The frequency of thicker lines.
+         */
+        majorUnitFrequency: number;
+        /**
+         * The visibility of minor units in the grid.
+         */
+        minorUnitVisibility: number;
+        /**
+         * The grid opacity outside of the lines.
+         */
+        opacity: number;
+        /**
+         * Determine RBG output is premultiplied by alpha value.
+         */
+        preMultiplyAlpha: boolean;
+        private _gridControl;
+        private _renderId;
+        /**
+         * constructor
+         * @param name The name given to the material in order to identify it afterwards.
+         * @param scene The scene the material is used in.
+         */
+        constructor(name: string, scene: Scene);
+        /**
+         * Returns wehter or not the grid requires alpha blending.
+         */
+        needAlphaBlending(): boolean;
+        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): GridMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class CustomShaderStructure {
+        FragmentStore: string;
+        VertexStore: string;
+        constructor();
+    }
+    class ShaderSpecialParts {
+        constructor();
+        Fragment_Begin: string;
+        Fragment_Definitions: string;
+        Fragment_MainBegin: string;
+        Fragment_Custom_Diffuse: string;
+        Fragment_Custom_Alpha: string;
+        Fragment_Before_FragColor: string;
+        Vertex_Begin: string;
+        Vertex_Definitions: string;
+        Vertex_MainBegin: string;
+        Vertex_Before_PositionUpdated: string;
+        Vertex_Before_NormalUpdated: string;
+    }
+    class CustomMaterial extends StandardMaterial {
+        static ShaderIndexer: number;
+        CustomParts: ShaderSpecialParts;
+        _isCreatedShader: boolean;
+        _createdShaderName: string;
+        _customUniform: string[];
+        _newUniforms: string[];
+        _newUniformInstances: any[];
+        _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
+        AttachAfterBind(mesh: Mesh, effect: Effect): void;
+        ReviewUniform(name: string, arr: string[]): string[];
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string;
+        constructor(name: string, scene: Scene);
+        AddUniform(name: string, kind: string, param: any): CustomMaterial;
+        Fragment_Begin(shaderPart: string): CustomMaterial;
+        Fragment_Definitions(shaderPart: string): CustomMaterial;
+        Fragment_MainBegin(shaderPart: string): CustomMaterial;
+        Fragment_Custom_Diffuse(shaderPart: string): CustomMaterial;
+        Fragment_Custom_Alpha(shaderPart: string): CustomMaterial;
+        Fragment_Before_FragColor(shaderPart: string): CustomMaterial;
+        Vertex_Begin(shaderPart: string): CustomMaterial;
+        Vertex_Definitions(shaderPart: string): CustomMaterial;
+        Vertex_MainBegin(shaderPart: string): CustomMaterial;
+        Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
+        Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class CellMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        _computeHighLevel: boolean;
+        computeHighLevel: boolean;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        getClassName(): string;
+        clone(name: string): CellMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): CellMaterial;
+    }
+}

+ 1 - 1
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 

Файловите разлики са ограничени, защото са твърде много
+ 3 - 3
dist/preview release/materialsLibrary/babylonjs.materials.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


+ 201 - 0
dist/preview release/postProcessesLibrary/babylonjs.postProcess.d.ts

@@ -0,0 +1,201 @@
+
+declare module BABYLON {
+    /**
+     * AsciiArtFontTexture is the helper class used to easily create your ascii art font texture.
+     *
+     * It basically takes care rendering the font front the given font size to a texture.
+     * This is used later on in the postprocess.
+     */
+    class AsciiArtFontTexture extends BaseTexture {
+        private _font;
+        private _text;
+        private _charSize;
+        /**
+         * Gets the size of one char in the texture (each char fits in size * size space in the texture).
+         */
+        readonly charSize: number;
+        /**
+         * Create a new instance of the Ascii Art FontTexture class
+         * @param name the name of the texture
+         * @param font the font to use, use the W3C CSS notation
+         * @param text the caracter set to use in the rendering.
+         * @param scene the scene that owns the texture
+         */
+        constructor(name: string, font: string, text: string, scene?: Nullable<Scene>);
+        /**
+         * Gets the max char width of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char width
+         */
+        private getFontWidth(font);
+        /**
+         * Gets the max char height of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char height
+         */
+        private getFontHeight(font);
+        /**
+         * Clones the current AsciiArtTexture.
+         * @return the clone of the texture.
+         */
+        clone(): AsciiArtFontTexture;
+        /**
+         * Parses a json object representing the texture and returns an instance of it.
+         * @param source the source JSON representation
+         * @param scene the scene to create the texture for
+         * @return the parsed texture
+         */
+        static Parse(source: any, scene: Scene): AsciiArtFontTexture;
+    }
+    /**
+     * Option available in the Ascii Art Post Process.
+     */
+    interface IAsciiArtPostProcessOptions {
+        /**
+         * The font to use following the w3c font definition.
+         */
+        font?: string;
+        /**
+         * The character set to use in the postprocess.
+         */
+        characterSet?: string;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile?: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal?: number;
+    }
+    /**
+     * AsciiArtPostProcess helps rendering everithing in Ascii Art.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage: var pp = new AsciiArtPostProcess("myAscii", "20px Monospace", camera);
+     */
+    class AsciiArtPostProcess extends PostProcess {
+        /**
+         * The font texture used to render the char in the post process.
+         */
+        private _asciiArtFontTexture;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal: number;
+        /**
+         * Instantiates a new Ascii Art Post Process.
+         * @param name the name to give to the postprocess
+         * @camera the camera to apply the post process to.
+         * @param options can either be the font name or an option object following the IAsciiArtPostProcessOptions format
+         */
+        constructor(name: string, camera: Camera, options?: string | IAsciiArtPostProcessOptions);
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * DigitalRainFontTexture is the helper class used to easily create your digital rain font texture.
+     *
+     * It basically takes care rendering the font front the given font size to a texture.
+     * This is used later on in the postprocess.
+     */
+    class DigitalRainFontTexture extends BaseTexture {
+        private _font;
+        private _text;
+        private _charSize;
+        /**
+         * Gets the size of one char in the texture (each char fits in size * size space in the texture).
+         */
+        readonly charSize: number;
+        /**
+         * Create a new instance of the Digital Rain FontTexture class
+         * @param name the name of the texture
+         * @param font the font to use, use the W3C CSS notation
+         * @param text the caracter set to use in the rendering.
+         * @param scene the scene that owns the texture
+         */
+        constructor(name: string, font: string, text: string, scene?: Nullable<Scene>);
+        /**
+         * Gets the max char width of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char width
+         */
+        private getFontWidth(font);
+        /**
+         * Gets the max char height of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char height
+         */
+        private getFontHeight(font);
+        /**
+         * Clones the current DigitalRainFontTexture.
+         * @return the clone of the texture.
+         */
+        clone(): DigitalRainFontTexture;
+        /**
+         * Parses a json object representing the texture and returns an instance of it.
+         * @param source the source JSON representation
+         * @param scene the scene to create the texture for
+         * @return the parsed texture
+         */
+        static Parse(source: any, scene: Scene): DigitalRainFontTexture;
+    }
+    /**
+     * Option available in the Digital Rain Post Process.
+     */
+    interface IDigitalRainPostProcessOptions {
+        /**
+         * The font to use following the w3c font definition.
+         */
+        font?: string;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile?: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal?: number;
+    }
+    /**
+     * DigitalRainPostProcess helps rendering everithing in digital rain.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage: var pp = new DigitalRainPostProcess("digitalRain", "20px Monospace", camera);
+     */
+    class DigitalRainPostProcess extends PostProcess {
+        /**
+         * The font texture used to render the char in the post process.
+         */
+        private _digitalRainFontTexture;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal: number;
+        /**
+         * Instantiates a new Digital Rain Post Process.
+         * @param name the name to give to the postprocess
+         * @camera the camera to apply the post process to.
+         * @param options can either be the font name or an option object following the IDigitalRainPostProcessOptions format
+         */
+        constructor(name: string, camera: Camera, options?: string | IDigitalRainPostProcessOptions);
+    }
+}

+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


+ 155 - 0
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts

@@ -0,0 +1,155 @@
+
+declare module BABYLON {
+    class WoodProceduralTexture extends ProceduralTexture {
+        private _ampScale;
+        private _woodColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        ampScale: number;
+        woodColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class FireProceduralTexture extends ProceduralTexture {
+        private _time;
+        private _speed;
+        private _autoGenerateTime;
+        private _fireColors;
+        private _alphaThreshold;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        static readonly PurpleFireColors: Color3[];
+        static readonly GreenFireColors: Color3[];
+        static readonly RedFireColors: Color3[];
+        static readonly BlueFireColors: Color3[];
+        fireColors: Color3[];
+        time: number;
+        speed: Vector2;
+        alphaThreshold: number;
+    }
+}
+
+
+declare module BABYLON {
+    class CloudProceduralTexture extends ProceduralTexture {
+        private _skyColor;
+        private _cloudColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        skyColor: Color4;
+        cloudColor: Color4;
+    }
+}
+
+
+declare module BABYLON {
+    class GrassProceduralTexture extends ProceduralTexture {
+        private _grassColors;
+        private _groundColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        grassColors: Color3[];
+        groundColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class RoadProceduralTexture extends ProceduralTexture {
+        private _roadColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        roadColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class BrickProceduralTexture extends ProceduralTexture {
+        private _numberOfBricksHeight;
+        private _numberOfBricksWidth;
+        private _jointColor;
+        private _brickColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        numberOfBricksHeight: number;
+        numberOfBricksWidth: number;
+        jointColor: Color3;
+        brickColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class MarbleProceduralTexture extends ProceduralTexture {
+        private _numberOfTilesHeight;
+        private _numberOfTilesWidth;
+        private _amplitude;
+        private _jointColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        numberOfTilesHeight: number;
+        amplitude: number;
+        numberOfTilesWidth: number;
+        jointColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class StarfieldProceduralTexture extends ProceduralTexture {
+        private _time;
+        private _alpha;
+        private _beta;
+        private _zoom;
+        private _formuparam;
+        private _stepsize;
+        private _tile;
+        private _brightness;
+        private _darkmatter;
+        private _distfading;
+        private _saturation;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        time: number;
+        alpha: number;
+        beta: number;
+        formuparam: number;
+        stepsize: number;
+        zoom: number;
+        tile: number;
+        brightness: number;
+        darkmatter: number;
+        distfading: number;
+        saturation: number;
+    }
+}
+
+
+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;
+    }
+}
+
+
+declare module BABYLON {
+    class PerlinNoiseProceduralTexture extends ProceduralTexture {
+        time: number;
+        speed: number;
+        translationSpeed: number;
+        private _currentTranslation;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        resize(size: any, generateMipMaps: any): void;
+    }
+}

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js


+ 1 - 2
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -170,12 +170,11 @@ declare module BABYLON.GLTF2 {
          * Returns the bytelength of the data.
          * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
          * @param meshAttributeArray - Array containing the attribute data.
-         * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.

+ 59 - 75
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -193,17 +193,17 @@ var BABYLON;
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
              * @param meshAttributeArray - Array containing the attribute data.
-             * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var end = meshAttributeArray.length / strideSize;
+                var stride = BABYLON.VertexBuffer.DeduceStride(vertexBufferKind);
+                var end = meshAttributeArray.length / stride;
                 var byteLength = 0;
                 for (var k = 0; k < end; ++k) {
-                    var index = k * strideSize;
+                    var index = k * stride;
                     var vector = [];
                     if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
                         var vertexData = BABYLON.Vector3.FromArray(meshAttributeArray, index);
@@ -445,28 +445,17 @@ var BABYLON;
                     bufferMesh = babylonMesh.sourceMesh;
                 }
                 if (bufferMesh) {
-                    var vertexBuffer = null;
-                    var vertexBufferOffset = null;
-                    var vertexData = null;
-                    var vertexStrideSize = null;
-                    if (bufferMesh.isVerticesDataPresent(kind)) {
-                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        if (vertexBuffer) {
-                            vertexBufferOffset = vertexBuffer.getOffset();
-                            vertexData = vertexBuffer.getData();
-                            if (vertexData) {
-                                vertexStrideSize = vertexBuffer.getStrideSize();
-                                if (dataBuffer && vertexData) {
-                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
-                                    byteOffset += byteLength;
-                                }
-                                else {
-                                    byteLength = vertexData.length * 4;
-                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
-                                    byteOffset += byteLength;
-                                    this.bufferViews.push(bufferView);
-                                }
-                            }
+                    var vertexData = bufferMesh.getVerticesData(kind);
+                    if (vertexData) {
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, byteOffset, dataBuffer);
+                            byteOffset += byteLength;
+                        }
+                        else {
+                            byteLength = vertexData.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, kind + " - " + bufferMesh.name);
+                            byteOffset += byteLength;
+                            this.bufferViews.push(bufferView);
                         }
                     }
                 }
@@ -539,55 +528,50 @@ var BABYLON;
                                 for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
                                     var attribute = attributeData_2[_c];
                                     var attributeKind = attribute.kind;
-                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
-                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
-                                        if (vertexBuffer) {
-                                            var bufferData = vertexBuffer.getData();
-                                            if (bufferData) {
-                                                var strideSize = vertexBuffer.getStrideSize();
-                                                var minMax = void 0;
-                                                var min = null;
-                                                var max = null;
-                                                var bufferViewIndex = attribute.bufferViewIndex;
-                                                if (bufferViewIndex != undefined) {
-                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
-                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
-                                                        min = minMax.min;
-                                                        max = minMax.max;
-                                                    }
-                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
-                                                    this.accessors.push(accessor);
-                                                    switch (attributeKind) {
-                                                        case BABYLON.VertexBuffer.PositionKind: {
-                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.NormalKind: {
-                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.ColorKind: {
-                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.TangentKind: {
-                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UVKind: {
-                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UV2Kind: {
-                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        default: {
-                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
-                                                        }
-                                                    }
+                                    var vertexData = bufferMesh.getVerticesData(attributeKind);
+                                    if (vertexData) {
+                                        var stride = BABYLON.VertexBuffer.DeduceStride(attributeKind);
+                                        var minMax = void 0;
+                                        var min = null;
+                                        var max = null;
+                                        var bufferViewIndex = attribute.bufferViewIndex;
+                                        if (bufferViewIndex != undefined) {
+                                            if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                minMax = this.calculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
+                                                min = minMax.min;
+                                                max = minMax.max;
+                                            }
+                                            var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, min, max);
+                                            this.accessors.push(accessor);
+                                            switch (attributeKind) {
+                                                case BABYLON.VertexBuffer.PositionKind: {
+                                                    meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.NormalKind: {
+                                                    meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.ColorKind: {
+                                                    meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.TangentKind: {
+                                                    meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UVKind: {
+                                                    meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UV2Kind: {
+                                                    meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                default: {
+                                                    BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
                                                 }
                                             }
                                         }

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 512 - 0
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -0,0 +1,512 @@
+
+declare module BABYLON {
+    class OBJExport {
+        static OBJ(mesh: Mesh[], materials?: boolean, matlibname?: string, globalposition?: boolean): string;
+        static MTL(mesh: Mesh): string;
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * Holds a collection of exporter options and parameters
+     */
+    interface IExporterOptions {
+        /**
+         * Function which indicates whether a babylon mesh should be exported or not.
+         * @param mesh - source Babylon mesh. It is used to check whether it should be
+         * exported to glTF or not.
+         * @returns boolean, which indicates whether the mesh should be exported (true) or not (false)
+         */
+        shouldExportMesh?(mesh: AbstractMesh): boolean;
+    }
+    /**
+     * Class for generating glTF data from a Babylon scene.
+     */
+    class GLTF2Export {
+        /**
+         * Exports the geometry of the scene to .gltf file format.
+         * @param scene - Babylon scene with scene hierarchy information.
+         * @param filePrefix - File prefix to use when generating the glTF file.
+         * @param options - Exporter options.
+         * @returns - Returns an object with a .gltf file and associates texture names
+         * as keys and their data and paths as values.
+         */
+        static GLTF(scene: Scene, filePrefix: string, options?: IExporterOptions): _GLTFData;
+        /**
+         * Exports the geometry of the scene to .glb file format.
+         * @param scene - Babylon scene with scene hierarchy information.
+         * @param filePrefix - File prefix to use when generating glb file.
+         * @param options - Exporter options.
+         * @returns - Returns an object with a .glb filename as key and data as value
+         */
+        static GLB(scene: Scene, filePrefix: string, options?: IExporterOptions): _GLTFData;
+    }
+}
+
+
+/**
+ * Module for the Babylon glTF 2.0 exporter.  Should ONLY be used internally.
+ * @ignore - capitalization of GLTF2 module.
+ */
+declare module BABYLON.GLTF2 {
+    /**
+     * Converts Babylon Scene into glTF 2.0.
+     */
+    class _Exporter {
+        /**
+         * Stores all generated buffer views, which represents views into the main glTF buffer data.
+         */
+        private bufferViews;
+        /**
+         * Stores all the generated accessors, which is used for accessing the data within the buffer views in glTF.
+         */
+        private accessors;
+        /**
+         * Stores all the generated nodes, which contains transform and/or mesh information per node.
+         */
+        private nodes;
+        /**
+         * Stores the glTF asset information, which represents the glTF version and this file generator.
+         */
+        private asset;
+        /**
+         * Stores all the generated glTF scenes, which stores multiple node hierarchies.
+         */
+        private scenes;
+        /**
+         * Stores all the generated mesh information, each containing a set of primitives to render in glTF.
+         */
+        private meshes;
+        /**
+         * Stores all the generated material information, which represents the appearance of each primitive.
+         */
+        private materials;
+        /**
+         * Stores all the generated texture information, which is referenced by glTF materials.
+         */
+        private textures;
+        /**
+         * Stores all the generated image information, which is referenced by glTF textures.
+         */
+        private images;
+        /**
+         * Stores the total amount of bytes stored in the glTF buffer.
+         */
+        private totalByteLength;
+        /**
+         * Stores a reference to the Babylon scene containing the source geometry and material information.
+         */
+        private babylonScene;
+        /**
+         * Stores the exporter options, which are optionally passed in from the glTF serializer.
+         */
+        private options?;
+        /**
+         * Stores a map of the image data, where the key is the file name and the value
+         * is the image data.
+         */
+        private imageData;
+        /**
+         * Stores a map of the unique id of a node to its index in the node array.
+         */
+        private nodeMap;
+        /**
+         * Stores the binary buffer used to store geometry data.
+         */
+        private binaryBuffer;
+        /**
+         * Specifies if the Babylon scene should be converted to right-handed on export.
+         */
+        private convertToRightHandedSystem;
+        /**
+         * Creates a glTF Exporter instance, which can accept optional exporter options.
+         * @param babylonScene - Babylon scene object
+         * @param options - Options to modify the behavior of the exporter.
+         */
+        constructor(babylonScene: Scene, options?: IExporterOptions);
+        /**
+         * Creates a buffer view based on teh supplied arguments
+         * @param bufferIndex - index value of the specified buffer
+         * @param byteOffset - byte offset value
+         * @param byteLength - byte length of the bufferView
+         * @param byteStride - byte distance between conequential elements.
+         * @param name - name of the buffer view
+         * @returns - bufferView for glTF
+         */
+        private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
+        /**
+         * Creates an accessor based on the supplied arguments
+         * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+         * @param name - The name of the accessor.
+         * @param type - The type of the accessor.
+         * @param componentType - The datatype of components in the attribute.
+         * @param count - The number of attributes referenced by this accessor.
+         * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+         * @param min - Minimum value of each component in this attribute.
+         * @param max - Maximum value of each component in this attribute.
+         * @returns - accessor for glTF
+         */
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset, min, max);
+        /**
+         * Calculates the minimum and maximum values of an array of position floats.
+         * @param positions - Positions array of a mesh.
+         * @param vertexStart - Starting vertex offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @returns - min number array and max number array.
+         */
+        private calculateMinMaxPositions(positions, vertexStart, vertexCount);
+        /**
+         * Converts a vector3 array to right-handed.
+         * @param vector - vector3 Array to convert to right-handed.
+         * @returns - right-handed Vector3 array.
+         */
+        private static GetRightHandedVector3(vector);
+        /**
+         * Converts a vector4 array to right-handed.
+         * @param vector - vector4 Array to convert to right-handed.
+         * @returns - right-handed vector4 array.
+         */
+        private static GetRightHandedVector4(vector);
+        /**
+         * Converts a quaternion to right-handed.
+         * @param quaternion - Source quaternion to convert to right-handed.
+         */
+        private static GetRightHandedQuaternion(quaternion);
+        /**
+         * Writes mesh attribute data to a data buffer.
+         * Returns the bytelength of the data.
+         * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+         * @param meshAttributeArray - Array containing the attribute data.
+         * @param byteOffset - The offset to start counting bytes from.
+         * @param dataBuffer - The buffer to write the binary data to.
+         * @returns - Byte length of the attribute data.
+         */
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
+        /**
+         * Generates glTF json data
+         * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @param prettyPrint - Indicates whether the json file should be pretty printed (true) or not (false).
+         * @returns - json data as string
+         */
+        private generateJSON(shouldUseGlb, glTFPrefix?, prettyPrint?);
+        /**
+         * Generates data for .gltf and .bin files based on the glTF prefix string
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
+         */
+        _generateGLTF(glTFPrefix: string): _GLTFData;
+        /**
+         * Creates a binary buffer for glTF
+         * @returns - array buffer for binary data
+         */
+        private generateBinary();
+        /**
+         * Pads the number to a multiple of 4
+         * @param num - number to pad
+         * @returns - padded number
+         */
+        private _getPadding(num);
+        /**
+         * Generates a glb file from the json and binary data.
+         * Returns an object with the glb file name as the key and data as the value.
+         * @param glTFPrefix
+         * @returns - object with glb filename as key and data as value
+         */
+        _generateGLB(glTFPrefix: string): _GLTFData;
+        /**
+         * Sets the TRS for each node
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         */
+        private setNodeTransformation(node, babylonMesh);
+        /**
+         * Creates a bufferview based on the vertices type for the Babylon mesh
+         * @param kind - Indicates the type of vertices data.
+         * @param babylonMesh - The Babylon mesh to get the vertices data from.
+         * @param byteOffset - The offset from the buffer to start indexing from.
+         * @param dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, dataBuffer);
+        /**
+         * Sets data for the primitive attributes of each submesh
+         * @param mesh - glTF Mesh object to store the primitive attribute information.
+         * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
+         * @param byteOffset - The offset in bytes of the buffer data.
+         * @param dataBuffer - Buffer to write the attribute data to.
+         * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+         */
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
+        /**
+         * Creates a glTF scene based on the array of meshes.
+         * Returns the the total byte offset.
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @returns bytelength + byteoffset
+         */
+        private createScene(babylonScene, byteOffset);
+        /**
+         * Creates a mapping of Node unique id to node index
+         * @param scene - Babylon Scene.
+         * @param byteOffset - The initial byte offset.
+         * @returns - Node mapping of unique id to index.
+         */
+        private createNodeMap(scene, byteOffset);
+        /**
+         * Creates a glTF node from a Babylon mesh.
+         * @param babylonMesh - Source Babylon mesh.
+         * @param byteOffset - The initial byte offset.
+         * @param dataBuffer - Buffer for storing geometry data.
+         * @returns - Object containing an INode and byteoffset.
+         */
+        private createNode(babylonMesh, byteOffset, dataBuffer);
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * Class for holding and downloading glTF file data
+     */
+    class _GLTFData {
+        /**
+         * Object which contains the file name as the key and its data as the value.
+         */
+        glTFFiles: {
+            [fileName: string]: string | Blob;
+        };
+        /**
+         * Initializes the glTF file object.
+         */
+        constructor();
+        /**
+         * Downloads the glTF data as files based on their names and data.
+         */
+        downloadFiles(): void;
+    }
+}
+
+
+declare module BABYLON.GLTF2 {
+    /**
+     * Utility methods for working with glTF material conversion properties.  This class should only be used internally.
+     */
+    class _GLTFMaterial {
+        /**
+         * Represents the dielectric specular values for R, G and B.
+         */
+        private static readonly _dielectricSpecular;
+        /**
+         * Allows the maximum specular power to be defined for material calculations.
+         */
+        private static _maxSpecularPower;
+        /**
+         * Numeric tolerance value
+         */
+        private static _epsilon;
+        /**
+         * Specifies if two colors are approximately equal in value.
+         * @param color1 - first color to compare to.
+         * @param color2 - second color to compare to.
+         * @param epsilon - threshold value
+         */
+        private static FuzzyEquals(color1, color2, epsilon);
+        /**
+         * Gets the materials from a Babylon scene and converts them to glTF materials.
+         * @param scene - babylonjs scene.
+         * @param mimeType - texture mime type.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param materials - array of materials.
+         * @param imageData - mapping of texture names to base64 textures
+         * @param hasTextureCoords - specifies if texture coordinates are present on the material.
+         */
+        static _ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Makes a copy of the glTF material without the texture parameters.
+         * @param originalMaterial - original glTF material.
+         * @returns glTF material without texture parameters
+         */
+        static _StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        /**
+         * Specifies if the material has any texture parameters present.
+         * @param material - glTF Material.
+         * @returns boolean specifying if texture parameters are present
+         */
+        static _HasTexturesPresent(material: IMaterial): boolean;
+        /**
+         * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
+         * @param babylonStandardMaterial
+         * @returns - glTF Metallic Roughness Material representation
+         */
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        /**
+         * Computes the metallic factor
+         * @param diffuse - diffused value
+         * @param specular - specular value
+         * @param oneMinusSpecularStrength - one minus the specular strength
+         * @returns - metallic value
+         */
+        static _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
+        /**
+         * Gets the glTF alpha mode from the Babylon Material
+         * @param babylonMaterial - Babylon Material
+         * @returns - The Babylon alpha mode value
+         */
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
+        /**
+         * Converts a Babylon Standard Material to a glTF Material.
+         * @param babylonStandardMaterial - BJS Standard Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMetalRoughMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Converts an image typed array buffer to a base64 image.
+         * @param buffer - typed array buffer.
+         * @param width - width of the image.
+         * @param height - height of the image.
+         * @param mimeType - mimetype of the image.
+         * @returns - base64 image string.
+         */
+        private static _CreateBase64FromCanvas(buffer, width, height, mimeType);
+        /**
+         * Generates a white texture based on the specified width and height.
+         * @param width - width of the texture in pixels.
+         * @param height - height of the texture in pixels.
+         * @param scene - babylonjs scene.
+         * @returns - white texture.
+         */
+        private static _CreateWhiteTexture(width, height, scene);
+        /**
+         * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+         * @param texture1 - first texture to resize.
+         * @param texture2 - second texture to resize.
+         * @param scene - babylonjs scene.
+         * @returns resized textures or null.
+         */
+        private static _ResizeTexturesToSameDimensions(texture1, texture2, scene);
+        /**
+         * Convert Specular Glossiness Textures to Metallic Roughness.
+         * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+         * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param diffuseTexture - texture used to store diffuse information.
+         * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+         * @param factors - specular glossiness material factors.
+         * @param mimeType - the mime type to use for the texture.
+         * @returns pbr metallic roughness interface or null.
+         */
+        private static _ConvertSpecularGlossinessTexturesToMetallicRoughness(diffuseTexture, specularGlossinessTexture, factors, mimeType);
+        /**
+         * Converts specular glossiness material properties to metallic roughness.
+         * @param specularGlossiness - interface with specular glossiness material properties.
+         * @returns - interface with metallic roughness material properties.
+         */
+        private static _ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+        /**
+         * Calculates the surface reflectance, independent of lighting conditions.
+         * @param color - Color source to calculate brightness from.
+         * @returns number representing the perceived brightness, or zero if color is undefined.
+         */
+        private static _GetPerceivedBrightness(color);
+        /**
+         * Returns the maximum color component value.
+         * @param color
+         * @returns maximum color component value, or zero if color is null or undefined.
+         */
+        private static _GetMaxComponent(color);
+        /**
+         * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param glTFPbrMetallicRoughness - glTF PBR Metallic Roughness interface.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         * @returns - glTF PBR Metallic Roughness factors.
+         */
+        private static _ConvertMetalRoughFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
+        /**
+         * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param glTFPbrMetallicRoughness - glTF PBR Metallic Roughness interface.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         * @returns - glTF PBR Metallic Roughness factors.
+         */
+        private static _ConvertSpecGlossFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Extracts a texture from a Babylon texture into file data and glTF data.
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @param images - Array of glTF images.
+         * @param textures - Array of glTF textures.
+         * @param imageData - map of image file name and data.
+         * @return - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _ExportTexture(babylonTexture, mimeType, images, textures, imageData);
+        /**
+         * Builds a texture from base64 string.
+         * @param base64Texture - base64 texture string.
+         * @param textureName - Name to use for the texture.
+         * @param mimeType - image mime type for the texture.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param imageData - map of image data.
+         * @returns - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _GetTextureInfoFromBase64(base64Texture, textureName, mimeType, images, textures, imageData);
+    }
+}

+ 60 - 76
dist/preview release/serializers/babylonjs.serializers.js

@@ -4,7 +4,7 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 
 (function universalModuleDefinition(root, factory) {
     var amdDependencies = [];
-    var BABYLON = root.BABYLON;
+    var BABYLON = root.BABYLON || this.BABYLON;
     if(typeof exports === 'object' && typeof module === 'object') {
          BABYLON = BABYLON || require("babylonjs"); 
 
@@ -344,17 +344,17 @@ var BABYLON;
              * Returns the bytelength of the data.
              * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
              * @param meshAttributeArray - Array containing the attribute data.
-             * @param strideSize - Represents the offset between consecutive attributes
              * @param byteOffset - The offset to start counting bytes from.
              * @param dataBuffer - The buffer to write the binary data to.
              * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer) {
                 var byteOff = byteOffset;
-                var end = meshAttributeArray.length / strideSize;
+                var stride = BABYLON.VertexBuffer.DeduceStride(vertexBufferKind);
+                var end = meshAttributeArray.length / stride;
                 var byteLength = 0;
                 for (var k = 0; k < end; ++k) {
-                    var index = k * strideSize;
+                    var index = k * stride;
                     var vector = [];
                     if (vertexBufferKind === BABYLON.VertexBuffer.PositionKind || vertexBufferKind === BABYLON.VertexBuffer.NormalKind) {
                         var vertexData = BABYLON.Vector3.FromArray(meshAttributeArray, index);
@@ -596,28 +596,17 @@ var BABYLON;
                     bufferMesh = babylonMesh.sourceMesh;
                 }
                 if (bufferMesh) {
-                    var vertexBuffer = null;
-                    var vertexBufferOffset = null;
-                    var vertexData = null;
-                    var vertexStrideSize = null;
-                    if (bufferMesh.isVerticesDataPresent(kind)) {
-                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                        if (vertexBuffer) {
-                            vertexBufferOffset = vertexBuffer.getOffset();
-                            vertexData = vertexBuffer.getData();
-                            if (vertexData) {
-                                vertexStrideSize = vertexBuffer.getStrideSize();
-                                if (dataBuffer && vertexData) {
-                                    byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer);
-                                    byteOffset += byteLength;
-                                }
-                                else {
-                                    byteLength = vertexData.length * 4;
-                                    var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
-                                    byteOffset += byteLength;
-                                    this.bufferViews.push(bufferView);
-                                }
-                            }
+                    var vertexData = bufferMesh.getVerticesData(kind);
+                    if (vertexData) {
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, byteOffset, dataBuffer);
+                            byteOffset += byteLength;
+                        }
+                        else {
+                            byteLength = vertexData.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, kind + " - " + bufferMesh.name);
+                            byteOffset += byteLength;
+                            this.bufferViews.push(bufferView);
                         }
                     }
                 }
@@ -690,55 +679,50 @@ var BABYLON;
                                 for (var _c = 0, attributeData_2 = attributeData; _c < attributeData_2.length; _c++) {
                                     var attribute = attributeData_2[_c];
                                     var attributeKind = attribute.kind;
-                                    if (bufferMesh.isVerticesDataPresent(attributeKind)) {
-                                        var vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
-                                        if (vertexBuffer) {
-                                            var bufferData = vertexBuffer.getData();
-                                            if (bufferData) {
-                                                var strideSize = vertexBuffer.getStrideSize();
-                                                var minMax = void 0;
-                                                var min = null;
-                                                var max = null;
-                                                var bufferViewIndex = attribute.bufferViewIndex;
-                                                if (bufferViewIndex != undefined) {
-                                                    if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
-                                                        minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
-                                                        min = minMax.min;
-                                                        max = minMax.max;
-                                                    }
-                                                    var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, bufferData.length / strideSize, 0, min, max);
-                                                    this.accessors.push(accessor);
-                                                    switch (attributeKind) {
-                                                        case BABYLON.VertexBuffer.PositionKind: {
-                                                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.NormalKind: {
-                                                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.ColorKind: {
-                                                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.TangentKind: {
-                                                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UVKind: {
-                                                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        case BABYLON.VertexBuffer.UV2Kind: {
-                                                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                                                            uvCoordsPresent = true;
-                                                            break;
-                                                        }
-                                                        default: {
-                                                            BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
-                                                        }
-                                                    }
+                                    var vertexData = bufferMesh.getVerticesData(attributeKind);
+                                    if (vertexData) {
+                                        var stride = BABYLON.VertexBuffer.DeduceStride(attributeKind);
+                                        var minMax = void 0;
+                                        var min = null;
+                                        var max = null;
+                                        var bufferViewIndex = attribute.bufferViewIndex;
+                                        if (bufferViewIndex != undefined) {
+                                            if (attributeKind == BABYLON.VertexBuffer.PositionKind) {
+                                                minMax = this.calculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
+                                                min = minMax.min;
+                                                max = minMax.max;
+                                            }
+                                            var accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, 5126 /* FLOAT */, vertexData.length / stride, 0, min, max);
+                                            this.accessors.push(accessor);
+                                            switch (attributeKind) {
+                                                case BABYLON.VertexBuffer.PositionKind: {
+                                                    meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.NormalKind: {
+                                                    meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.ColorKind: {
+                                                    meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.TangentKind: {
+                                                    meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UVKind: {
+                                                    meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                case BABYLON.VertexBuffer.UV2Kind: {
+                                                    meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                    uvCoordsPresent = true;
+                                                    break;
+                                                }
+                                                default: {
+                                                    BABYLON.Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
                                                 }
                                             }
                                         }

Файловите разлики са ограничени, защото са твърде много
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 3 - 2
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -1,3 +1,5 @@
+/// <reference types="babylonjs"/>
+/// <reference types="babylonjs-gltf2interface"/>
 
 
 declare module 'babylonjs-serializers' { 
@@ -183,12 +185,11 @@ declare module BABYLON.GLTF2 {
          * Returns the bytelength of the data.
          * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
          * @param meshAttributeArray - Array containing the attribute data.
-         * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
         /**
          * Generates glTF json data
          * @param shouldUseGlb - Indicates whether the json should be written for a glb file.

Файловите разлики са ограничени, защото са твърде много
+ 7008 - 12850
dist/preview release/typedocValidationBaseline.json


Файловите разлики са ограничени, защото са твърде много
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


Файловите разлики са ограничени, защото са твърде много
+ 2969 - 733
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -13,7 +13,7 @@
 - Added [VideoDome](http://doc.babylonjs.com/how_to/360videodome) class to easily support 360 videos. Demo [here](https://www.babylonjs-playground.com/frame.html#1E9JQ8#7) ([DavidHGillen](https://github.com/DavidHGillen))
 - Added [GlowLayer](https://doc.babylonjs.com/how_to/glow_layer) to easily support glow from emissive materials. Demo [here](http://www.babylonjs.com/demos/GlowLayer/) ([sebavan](https://github.com/sebavan))
 - New [AssetContainer](http://doc.babylonjs.com/how_to/how_to_use_assetcontainer) class and loading methods ([trevordev](https://github.com/trevordev))
-- Added [depth of field](https://www.babylonjs-playground.com/frame.html#8F5HYV#9), [sharpening, MSAA, chromatic aberration and grain effect](https://www.babylonjs-playground.com/#Y3C0HQ#146) to the default pipeline ([trevordev](https://github.com/trevordev))
+- Added [depth of field](https://www.babylonjs-playground.com/frame.html#8F5HYV#9), [MSAA, sharpening, chromatic aberration and grain effect](https://www.babylonjs-playground.com/#Y3C0HQ#146) to the default pipeline ([trevordev](https://github.com/trevordev))
 - Added support for [animation weights](http://doc.babylonjs.com/babylon101/animations#animation-weights). Demo [here](https://www.babylonjs-playground.com/#IQN716#9) ([deltakosh](https://github.com/deltakosh))
 - Added [sub emitters for particle system](http://doc.babylonjs.com/babylon101/particles#sub-emitters) which will spawn new particle systems when particles dies. Demo [here](https://www.babylonjs-playground.com/frame.html#9NHBCC#1) ([IbraheemOsama](https://github.com/IbraheemOsama))
 - New [Babylon.js](http://doc.babylonjs.com/resources/maya) and [glTF](http://doc.babylonjs.com/resources/maya_to_gltf) exporter for Autodesk Maya ([Noalak](https://github.com/Noalak))
@@ -23,7 +23,8 @@
 - Introduces [PCF](https://doc.babylonjs.com/babylon101/shadows#percentage-closer-filtering-webgl2-only) and [PCSS](https://doc.babylonjs.com/babylon101/shadows#contact-hardening-shadow-webgl2-only) shadow support in Webgl 2 ([sebavan](https://github.com/sebavan)))
 
 ## Documentation
-- Tons of functions and classes received the code comments they deserved (All the community)
+
+- Tons of functions and classes received the code comments they deserved (All the community with a special thanks to [John King](https://github.com/BabylonJSGuide))
 - Moved the class API documentation to Typedoc ([deltakosh](https://github.com/deltakosh))
 
 ## Updates
@@ -107,6 +108,8 @@
 - Shadows - Introduces [Normal Bias](https://doc.babylonjs.com/babylon101/shadows#normal-bias-since-32) ([sebavan](https://github.com/sebavan)))
 - Earcut is an external, optional dependency. ([RaananW](https://github.com/RaananW))
 - Return animation groups when calling `SceneLoader.ImportMesh`. ([bghgary](https://github.com/bghgary)]
+- Add support for normalized and non-float data to `Buffer` and `VertexBuffer`. ([bghgary](https://github.com/bghgary)]
+- Added unlit material extension support to glTF 2.0 loader. ([bghgary](https://github.com/bghgary))
 
 ## Bug fixes
 

+ 15 - 2
inspector/src/adapters/CameraAdapter.ts

@@ -29,14 +29,27 @@ module INSPECTOR {
         
         public getTools() : Array<AbstractTreeTool> {
             let tools = [];
-            // tools.push(new Checkbox(this));
             tools.push(new CameraPOV(this));
             return tools;
         }
 
+        // Set the point of view of the chosen camera
         public setPOV() {
-           (this._obj as BABYLON.Camera).getScene().activeCamera = this._obj;
+           (this._obj as BABYLON.Camera).getScene().switchActiveCamera(this._obj);
         }
+
+        // Return the name of the current active camera
+        public getCurrentActiveCamera() {
+            let activeCamera = (this._obj as BABYLON.Camera).getScene().activeCamera;
+            if(activeCamera != null)
+            {
+                return activeCamera.name;
+            }else{
+                return "0";
+            }
+        }
+
+
         
     }
 }

+ 0 - 18
inspector/src/tabs/SceneTab.ts

@@ -67,24 +67,6 @@ module INSPECTOR {
                 wireframe.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = true; });
                 solid.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = false; });
 
-                // Cameras
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Cameras';
-                let cameraRadioButtons = [];
-                for (let camera of this._inspector.scene.cameras) {
-                    let cameraRadio = Helpers.CreateDiv('action-radio', this._actions);
-                    cameraRadio.textContent = camera.name;
-                    if(this._inspector.scene.activeCamera == camera)
-                    {
-                        cameraRadio.classList.add('active');
-                    }
-                    cameraRadioButtons.push(cameraRadio);
-                    cameraRadio.addEventListener('click', () => { this._inspector.scene.switchActiveCamera(camera);});
-                }
-
-                this._generateRadioAction(cameraRadioButtons);
-                
-
                 // Textures
                 title = Helpers.CreateDiv('actions-title', this._actions);
                 title.textContent = 'Textures channels';

+ 26 - 10
inspector/src/treetools/CameraPOV.ts

@@ -1,7 +1,9 @@
 module INSPECTOR {
 
     export interface ICameraPOV {
-        setPOV: () => void
+        setPOV: () => void,
+        getCurrentActiveCamera: () => string,
+        id: () => string
     }
 
     /**
@@ -13,7 +15,16 @@ module INSPECTOR {
         constructor(camera: ICameraPOV) {
             super();
             this.cameraPOV = camera;
-            this._elem.classList.add('fa-video-camera');
+
+            // Setting the id of the line with the name of the camera
+            this._elem.id = this.cameraPOV.id();
+
+            // Put the right icon 
+            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera()){
+                this._elem.classList.add('fa-check-circle');
+            }else{
+                this._elem.classList.add('fa-circle');
+            }
         }
 
         protected action() {
@@ -22,18 +33,23 @@ module INSPECTOR {
         }
 
         private _gotoPOV() {
-
-            let actives = Inspector.DOCUMENT.querySelectorAll(".fa-video-camera.active");
-            console.log(actives);
+            // Uncheck all the radio buttons
+            let actives = Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
             for (let i = 0; i < actives.length; i++) {
-                actives[i].classList.remove('active');
+                actives[i].classList.remove('fa-check-circle');
+                actives[i].classList.add('fa-circle');
             }
-            //if (this._on) {
-                // set icon camera
-                this._elem.classList.add('active');
-            //}
+            
+            // setting the point off view to the right camera
             this.cameraPOV.setPOV();
 
+            // Check the right radio button
+            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera())
+            {
+                this._elem.classList.remove('fa-circle');
+                this._elem.classList.add('fa-check-circle');
+            }
+
         }
     }
 }

+ 6 - 6
inspector/test/index.js

@@ -36,17 +36,17 @@ var Test = (function () {
         var scene = new BABYLON.Scene(this.engine);
         var canvas = scene.getEngine().getRenderingCanvas();
 
-        var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 0, 0), scene); 
+        var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 2, -2), scene); 
         
-        var camera2 = new BABYLON.ArcRotateCamera("Camera2", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera2 = new BABYLON.ArcRotateCamera("Camera2", 0, 0, 5, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera3 = new BABYLON.ArcRotateCamera("Camera3", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera3 = new BABYLON.ArcRotateCamera("Camera3", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera4 = new BABYLON.ArcRotateCamera("Camera4", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera4 = new BABYLON.ArcRotateCamera("Camera4", 0, 0, 15, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera5 = new BABYLON.ArcRotateCamera("Camera5", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera5 = new BABYLON.ArcRotateCamera("Camera5", 0, 0, 20, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera6 = new BABYLON.ArcRotateCamera("Camera6", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera6 = new BABYLON.ArcRotateCamera("Camera6", 0, 0, 25, new BABYLON.Vector3(0, 0, 0), scene);
 
         scene.activeCamera = camera2;
         

+ 7 - 3
loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts

@@ -32,8 +32,8 @@ module BABYLON.GLTF2.Extensions {
             super.dispose();
         }
 
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>> {
-            return this._loadExtensionAsync<IKHRDracoMeshCompression, VertexData>(context, primitive, (extensionContext, extension) => {
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
+            return this._loadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, (extensionContext, extension) => {
                 if (primitive.mode != undefined) {
                     if (primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP &&
                         primitive.mode !== MeshPrimitiveMode.TRIANGLES) {
@@ -77,7 +77,11 @@ module BABYLON.GLTF2.Extensions {
                             this._dracoCompression = new DracoCompression();
                         }
 
-                        return this._dracoCompression.decodeMeshAsync(data, attributes);
+                        return this._dracoCompression.decodeMeshAsync(data, attributes).then(babylonVertexData => {
+                            const babylonGeometry = new Geometry(babylonMesh.name, this._loader._babylonScene);
+                            babylonVertexData.applyToGeometry(babylonGeometry);
+                            return babylonGeometry;
+                        });
                     }
                     catch (e) {
                         throw new Error(`${context}: ${e.message}`);

+ 9 - 9
loaders/src/glTF/2.0/Extensions/KHR_lights.ts

@@ -35,12 +35,12 @@ module BABYLON.GLTF2.Extensions {
         public readonly name = NAME;
 
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>> { 
-            return this._loadExtensionAsync<ILightReference>(context, scene, (context, extension) => {
-                const promise = this._loader._loadSceneAsync(context, scene);
+            return this._loadExtensionAsync<ILightReference>(context, scene, (extensionContext, extension) => {
+                const promise = this._loader._loadSceneAsync(extensionContext, scene);
 
-                const light = GLTFLoader._GetProperty(context, this._lights, extension.light);
+                const light = GLTFLoader._GetProperty(extensionContext, this._lights, extension.light);
                 if (light.type !== LightType.AMBIENT) {
-                    throw new Error(`${context}: Only ambient lights are allowed on a scene`);
+                    throw new Error(`${extensionContext}: Only ambient lights are allowed on a scene`);
                 }
 
                 this._loader._babylonScene.ambientColor = light.color ? Color3.FromArray(light.color) : Color3.Black();
@@ -50,16 +50,16 @@ module BABYLON.GLTF2.Extensions {
         }
 
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>> { 
-            return this._loadExtensionAsync<ILightReference>(context, node, (context, extension) => {
-                const promise = this._loader._loadNodeAsync(context, node);
+            return this._loadExtensionAsync<ILightReference>(context, node, (extensionContext, extension) => {
+                const promise = this._loader._loadNodeAsync(extensionContext, node);
 
                 let babylonLight: Light;
 
-                const light = GLTFLoader._GetProperty(context, this._lights, extension.light);
+                const light = GLTFLoader._GetProperty(extensionContext, this._lights, extension.light);
                 const name = node._babylonMesh!.name;
                 switch (light.type) {
                     case LightType.AMBIENT: {
-                        throw new Error(`${context}: Ambient lights are not allowed on a node`);
+                        throw new Error(`${extensionContext}: Ambient lights are not allowed on a node`);
                     }
                     case LightType.DIRECTIONAL: {
                         babylonLight = new DirectionalLight(name, Vector3.Forward(), this._loader._babylonScene);
@@ -78,7 +78,7 @@ module BABYLON.GLTF2.Extensions {
                         break;
                     }
                     default: {
-                        throw new Error(`${context}: Invalid light type (${light.type})`);
+                        throw new Error(`${extensionContext}: Invalid light type (${light.type})`);
                     }
                 }
 

+ 2 - 2
loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts

@@ -17,7 +17,7 @@ module BABYLON.GLTF2.Extensions {
         public readonly name = NAME;
 
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
-            return this._loadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, (context, extension) => {
+            return this._loadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, (extensionContext, extension) => {
                 material._babylonData = material._babylonData || {};
                 let babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
@@ -27,7 +27,7 @@ module BABYLON.GLTF2.Extensions {
                     const babylonMaterial = this._loader._createMaterial(PBRMaterial, name, babylonDrawMode);
 
                     promises.push(this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                    promises.push(this._loadSpecularGlossinessPropertiesAsync(context, material, extension, babylonMaterial));
+                    promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
 
                     this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
 

+ 76 - 0
loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts

@@ -0,0 +1,76 @@
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF2.Extensions {
+    // https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit
+
+    const NAME = "KHR_materials_unlit";
+
+    export class KHR_materials_unlit extends GLTFLoaderExtension {
+        public readonly name = NAME;
+
+        protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
+            return this._loadExtensionAsync<{}>(context, material, () => {
+                material._babylonData = material._babylonData || {};
+                let babylonData = material._babylonData[babylonDrawMode];
+                if (!babylonData) {
+                    const name = material.name || `materialUnlit_${material._index}`;
+                    const babylonMaterial = this._loader._createMaterial(PBRMaterial, name, babylonDrawMode);
+                    babylonMaterial.unlit = true;
+
+                    const promise = this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+
+                    this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+
+                    babylonData = {
+                        material: babylonMaterial,
+                        meshes: [],
+                        loaded: promise
+                    };
+
+                    material._babylonData[babylonDrawMode] = babylonData;
+                }
+
+                babylonData.meshes.push(babylonMesh);
+
+                assign(babylonData.material);
+                return babylonData.loaded;
+            });
+        }
+
+        private _loadUnlitPropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
+            const promises = new Array<Promise<void>>();
+
+            // Ensure metallic workflow
+            babylonMaterial.metallic = 1;
+            babylonMaterial.roughness = 1;
+
+            const properties = material.pbrMetallicRoughness;
+            if (properties) {
+                if (properties.baseColorFactor) {
+                    babylonMaterial.albedoColor = Color3.FromArray(properties.baseColorFactor);
+                    babylonMaterial.alpha = properties.baseColorFactor[3];
+                }
+                else {
+                    babylonMaterial.albedoColor = Color3.White();
+                }
+
+                if (properties.baseColorTexture) {
+                    promises.push(this._loader._loadTextureAsync(`${context}/baseColorTexture`, properties.baseColorTexture, texture => {
+                        babylonMaterial.albedoTexture = texture;
+                    }));
+                }
+            }
+
+            if (material.doubleSided) {
+                babylonMaterial.backFaceCulling = false;
+                babylonMaterial.twoSidedLighting = true;
+            }
+
+            this._loader._loadMaterialAlphaProperties(context, material, babylonMaterial);
+
+            return Promise.all(promises).then(() => {});
+        }
+    }
+
+    GLTFLoader._Register(NAME, loader => new KHR_materials_unlit(loader));
+}

+ 4 - 4
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -24,10 +24,10 @@ module BABYLON.GLTF2.Extensions {
         private _loadMaterialSignals: { [materialIndex: number]: Deferred<void> } = {};
 
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>> {
-            return this._loadExtensionAsync<IMSFTLOD>(context, node, (context, extension) => {
+            return this._loadExtensionAsync<IMSFTLOD>(context, node, (extensionContext, extension) => {
                 let firstPromise: Promise<void>;
 
-                const nodeLODs = this._getLODs(context, node, this._loader._gltf.nodes, extension.ids);
+                const nodeLODs = this._getLODs(extensionContext, node, this._loader._gltf.nodes, extension.ids);
                 for (let indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) {
                     const nodeLOD = nodeLODs[indexLOD];
 
@@ -77,10 +77,10 @@ module BABYLON.GLTF2.Extensions {
                 return null;
             }
 
-            return this._loadExtensionAsync<IMSFTLOD>(context, material, (context, extension) => {
+            return this._loadExtensionAsync<IMSFTLOD>(context, material, (extensionContext, extension) => {
                 let firstPromise: Promise<void>;
 
-                const materialLODs = this._getLODs(context, material, this._loader._gltf.materials, extension.ids);
+                const materialLODs = this._getLODs(extensionContext, material, this._loader._gltf.materials, extension.ids);
                 for (let indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) {
                     const materialLOD = materialLODs[indexLOD];
 

+ 97 - 157
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -7,15 +7,6 @@ module BABYLON.GLTF2 {
         _total?: number;
     }
 
-    interface TypedArrayConstructor<T extends TypedArray> {
-        readonly prototype: T;
-        new(length: number): T;
-        new(array: ArrayLike<number>): T;
-        new(buffer: ArrayBuffer, byteOffset?: number, length?: number): T;
-
-        readonly BYTES_PER_ELEMENT: number;
-    }
-
     export interface MaterialConstructor<T extends Material> {
         readonly prototype: T;
         new(name: string, scene: Scene): T;
@@ -483,10 +474,10 @@ module BABYLON.GLTF2 {
             const promises = new Array<Promise<void>>();
 
             this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
-
-            promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(babylonVertexData => {
-                new Geometry(babylonMesh.name, this._babylonScene, babylonVertexData, false, babylonMesh);
-                return this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonVertexData);
+            promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(babylonGeometry => {
+                return this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(() => {
+                    babylonGeometry.applyToMesh(babylonMesh);
+                });
             }));
 
             const babylonDrawMode = GLTFLoader._GetDrawMode(context, primitive.mode);
@@ -503,7 +494,7 @@ module BABYLON.GLTF2 {
             return Promise.all(promises).then(() => {});
         }
 
-        private _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Promise<VertexData> {
+        private _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Promise<Geometry> {
             const promise = GLTFLoaderExtension._LoadVertexDataAsync(this, context, primitive, babylonMesh);
             if (promise) {
                 return promise;
@@ -516,26 +507,19 @@ module BABYLON.GLTF2 {
 
             const promises = new Array<Promise<void>>();
 
-            const babylonVertexData = new VertexData();
+            const babylonGeometry = new Geometry(babylonMesh.name, this._babylonScene);
 
             if (primitive.indices == undefined) {
-                const positionAccessorIndex = attributes["POSITION"];
-                if (positionAccessorIndex != undefined) {
-                    const accessor = GLTFLoader._GetProperty(`${context}/attributes/POSITION`, this._gltf.accessors, positionAccessorIndex);
-                    babylonVertexData.indices = new Uint32Array(accessor.count);
-                    for (let i = 0; i < babylonVertexData.indices.length; i++) {
-                        babylonVertexData.indices[i] = i;
-                    }
-                }
+                babylonMesh.isUnIndexed = true;
             }
             else {
-                const indicesAccessor = GLTFLoader._GetProperty(`${context}/indices`, this._gltf.accessors, primitive.indices);
-                promises.push(this._loadAccessorAsync(`#/accessors/${indicesAccessor._index}`, indicesAccessor).then(data => {
-                    babylonVertexData.indices = data as IndicesArray;
+                const accessor = GLTFLoader._GetProperty(context + "/indices", this._gltf.accessors, primitive.indices);
+                promises.push(this._loadAccessorAsync("#/accessors/" + accessor._index, accessor).then(data => {
+                    babylonGeometry.setIndices(data as IndicesArray);
                 }));
             }
 
-            const loadAttribute = (attribute: string, kind: string) => {
+            const loadAttribute = (attribute: string, kind: string, callback?: (accessor: ILoaderAccessor) => void) => {
                 if (attributes[attribute] == undefined) {
                     return;
                 }
@@ -545,22 +529,14 @@ module BABYLON.GLTF2 {
                     babylonMesh._delayInfo.push(kind);
                 }
 
-                if (attribute === "COLOR_0") {
-                    // Assume vertex color has alpha on the mesh. The alphaMode of the material controls whether the material should use alpha or not.
-                    babylonMesh.hasVertexAlpha = true;
-                }
-
-                const accessor = GLTFLoader._GetProperty(`${context}/attributes/${attribute}`, this._gltf.accessors, attributes[attribute]);
-
-                promises.push(this._loadAccessorAsync(`#/accessors/${accessor._index}`, accessor).then(data => {
-                    let attributeData = GLTFLoader._ConvertToFloat32Array(context, accessor, data);
-
-                    if (attribute === "COLOR_0" && accessor.type === "VEC3") {
-                        attributeData = GLTFLoader._ConvertVec3ToVec4(context, attributeData);
-                    }
-
-                    babylonVertexData.set(attributeData, kind);
+                const accessor = GLTFLoader._GetProperty(context + "/attributes/" + attribute, this._gltf.accessors, attributes[attribute]);
+                promises.push(this._loadVertexAccessorAsync("#/accessors/" + accessor._index, accessor, kind).then(babylonVertexBuffer => {
+                    babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
                 }));
+
+                if (callback) {
+                    callback(accessor);
+                }
             };
 
             loadAttribute("POSITION", VertexBuffer.PositionKind);
@@ -570,10 +546,14 @@ module BABYLON.GLTF2 {
             loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
             loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
             loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
-            loadAttribute("COLOR_0", VertexBuffer.ColorKind);
+            loadAttribute("COLOR_0", VertexBuffer.ColorKind, accessor => {
+                if (accessor.type === AccessorType.VEC4) {
+                    babylonMesh.hasVertexAlpha = true;
+                }
+            });
 
             return Promise.all(promises).then(() => {
-                return babylonVertexData;
+                return babylonGeometry;
             });
         }
 
@@ -597,7 +577,7 @@ module BABYLON.GLTF2 {
             }
         }
 
-        private _loadMorphTargetsAsync(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh, babylonVertexData: VertexData): Promise<void> {
+        private _loadMorphTargetsAsync(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh, babylonGeometry: Geometry): Promise<void> {
             if (!primitive.targets) {
                 return Promise.resolve();
             }
@@ -607,108 +587,67 @@ module BABYLON.GLTF2 {
             const morphTargetManager = babylonMesh.morphTargetManager!;
             for (let index = 0; index < morphTargetManager.numTargets; index++) {
                 const babylonMorphTarget = morphTargetManager.getTarget(index);
-                promises.push(this._loadMorphTargetVertexDataAsync(`${context}/targets/${index}`, babylonVertexData, primitive.targets[index], babylonMorphTarget));
+                promises.push(this._loadMorphTargetVertexDataAsync(`${context}/targets/${index}`, babylonGeometry, primitive.targets[index], babylonMorphTarget));
             }
 
             return Promise.all(promises).then(() => {});
         }
 
-        private _loadMorphTargetVertexDataAsync(context: string, babylonVertexData: VertexData, attributes: { [name: string]: number }, babylonMorphTarget: MorphTarget): Promise<void> {
+        private _loadMorphTargetVertexDataAsync(context: string, babylonGeometry: Geometry, attributes: { [name: string]: number }, babylonMorphTarget: MorphTarget): Promise<void> {
             const promises = new Array<Promise<void>>();
 
-            const loadAttribute = (attribute: string, setData: (data: Float32Array) => void) => {
+            const loadAttribute = (attribute: string, kind: string, setData: (babylonVertexBuffer: VertexBuffer, data: Float32Array) => void) => {
                 if (attributes[attribute] == undefined) {
                     return;
                 }
 
+                const babylonVertexBuffer = babylonGeometry.getVertexBuffer(kind);
+                if (!babylonVertexBuffer) {
+                    return;
+                }
+
                 const accessor = GLTFLoader._GetProperty(`${context}/${attribute}`, this._gltf.accessors, attributes[attribute]);
                 promises.push(this._loadAccessorAsync(`#/accessors/${accessor._index}`, accessor).then(data => {
-                    setData(data as Float32Array);
+                    if (!(data instanceof Float32Array)) {
+                        throw new Error(`${context}: Morph target accessor must have float data`);
+                    }
+
+                    setData(babylonVertexBuffer, data);
                 }));
             };
 
-            loadAttribute("POSITION", data => {
-                if (babylonVertexData.positions) {
-                    for (let i = 0; i < data.length; i++) {
-                        data[i] += babylonVertexData.positions[i];
-                    }
-                    babylonMorphTarget.setPositions(data);
-                }
+            loadAttribute("POSITION", VertexBuffer.PositionKind, (babylonVertexBuffer, data) => {
+                babylonVertexBuffer.forEach(data.length, (value, index) => {
+                    data[index] += value;
+                });
+
+                babylonMorphTarget.setPositions(data);
             });
 
-            loadAttribute("NORMAL", data => {
-                if (babylonVertexData.normals) {
-                    for (let i = 0; i < data.length; i++) {
-                        data[i] += babylonVertexData.normals[i];
-                    }
-                    babylonMorphTarget.setNormals(data);
-                }
+            loadAttribute("NORMAL", VertexBuffer.NormalKind, (babylonVertexBuffer, data) => {
+                babylonVertexBuffer.forEach(data.length, (value, index) => {
+                    data[index] += value;
+                });
+
+                babylonMorphTarget.setNormals(data);
             });
 
-            loadAttribute("TANGENT", data => {
-                if (babylonVertexData.tangents) {
+            loadAttribute("TANGENT", VertexBuffer.TangentKind, (babylonVertexBuffer, data) => {
+                let dataIndex = 0;
+                babylonVertexBuffer.forEach(data.length, (value, index) => {
                     // Tangent data for morph targets is stored as xyz delta.
                     // The vertexData.tangent is stored as xyzw.
                     // So we need to skip every fourth vertexData.tangent.
-                    for (let i = 0, j = 0; i < data.length; i++) {
-                        data[i] += babylonVertexData.tangents[j++];
-                        if ((i + 1) % 3 == 0) {
-                            j++;
-                        }
+                    if (((index + 1) % 4) !== 0) {
+                        data[dataIndex++] += value;
                     }
-                    babylonMorphTarget.setTangents(data);
-                }
+                });
+                babylonMorphTarget.setTangents(data);
             });
 
             return Promise.all(promises).then(() => {});
         }
 
-        private static _ConvertToFloat32Array(context: string, accessor: ILoaderAccessor, data: TypedArray): Float32Array {
-            if (accessor.componentType == AccessorComponentType.FLOAT) {
-                return data as Float32Array;
-            }
-
-            let factor = 1;
-            if (accessor.normalized) {
-                switch (accessor.componentType) {
-                    case AccessorComponentType.UNSIGNED_BYTE: {
-                        factor = 1 / 255;
-                        break;
-                    }
-                    case AccessorComponentType.UNSIGNED_SHORT: {
-                        factor = 1 / 65535;
-                        break;
-                    }
-                    default: {
-                        throw new Error(`${context}: Invalid component type (${accessor.componentType})`);
-                    }
-                }
-            }
-
-            const result = new Float32Array(accessor.count * GLTFLoader._GetNumComponents(context, accessor.type));
-            for (let i = 0; i < result.length; i++) {
-                result[i] = data[i] * factor;
-            }
-
-            return result;
-        }
-
-        private static _ConvertVec3ToVec4(context: string, data: Float32Array): Float32Array {
-            const result = new Float32Array(data.length / 3 * 4);
-
-            let offset = 0;
-            for (let i = 0; i < result.length; i++) {
-                if ((i + 1) % 4 === 0) {
-                    result[i] = 1;
-                }
-                else {
-                    result[i] = data[offset++];
-                }
-            }
-
-            return result;
-        }
-
         private static _LoadTransform(node: ILoaderNode, babylonNode: TransformNode): void {
             let position = Vector3.Zero();
             let rotation = Quaternion.Identity();
@@ -1066,10 +1005,10 @@ module BABYLON.GLTF2 {
                 return bufferView._data;
             }
 
-            const buffer = GLTFLoader._GetProperty(`${context}/buffer`, this._gltf.buffers, bufferView.buffer);
-            bufferView._data = this._loadBufferAsync(`#/buffers/${buffer._index}`, buffer).then(bufferData => {
+            const buffer = GLTFLoader._GetProperty(context + "/buffer", this._gltf.buffers, bufferView.buffer);
+            bufferView._data = this._loadBufferAsync("#/buffers/" + buffer._index, buffer).then(data => {
                 try {
-                    return new Uint8Array(bufferData.buffer, bufferData.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
+                    return new Uint8Array(data.buffer, data.byteOffset + (bufferView.byteOffset || 0), bufferView.byteLength);
                 }
                 catch (e) {
                     throw new Error(`${context}: ${e.message}`);
@@ -1079,7 +1018,7 @@ module BABYLON.GLTF2 {
             return bufferView._data;
         }
 
-        private _loadAccessorAsync(context: string, accessor: ILoaderAccessor): Promise<TypedArray> {
+        private _loadAccessorAsync(context: string, accessor: ILoaderAccessor): Promise<ArrayBufferView> {
             if (accessor.sparse) {
                 throw new Error(`${context}: Sparse accessors are not currently supported`);
             }
@@ -1088,73 +1027,74 @@ module BABYLON.GLTF2 {
                 return accessor._data;
             }
 
-            const bufferView = GLTFLoader._GetProperty(`${context}/bufferView`, this._gltf.bufferViews, accessor.bufferView);
-            accessor._data = this._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView).then(bufferViewData => {
-                const numComponents = GLTFLoader._GetNumComponents(context, accessor.type);
-                const byteOffset = accessor.byteOffset || 0;
-                const byteStride = bufferView.byteStride;
-
-                if (byteStride === 0) {
-                    Tools.Warn(`${context}: Byte stride of 0 is not valid`);
-                }
+            const bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+            accessor._data = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(data => {
+                const buffer = data.buffer;
+                const byteOffset = data.byteOffset + (accessor.byteOffset || 0);
+                const length = GLTFLoader._GetNumComponents(context, accessor.type) * accessor.count;
 
                 try {
                     switch (accessor.componentType) {
                         case AccessorComponentType.BYTE: {
-                            return this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Int8Array(buffer, byteOffset, length);
                         }
                         case AccessorComponentType.UNSIGNED_BYTE: {
-                            return this._buildArrayBuffer(Uint8Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Uint8Array(buffer, byteOffset, length);
                         }
                         case AccessorComponentType.SHORT: {
-                            return this._buildArrayBuffer(Int16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Int16Array(buffer, byteOffset, length);
                         }
                         case AccessorComponentType.UNSIGNED_SHORT: {
-                            return this._buildArrayBuffer(Uint16Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Uint16Array(buffer, byteOffset, length);
                         }
                         case AccessorComponentType.UNSIGNED_INT: {
-                            return this._buildArrayBuffer(Uint32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Uint32Array(buffer, byteOffset, length);
                         }
                         case AccessorComponentType.FLOAT: {
-                            return this._buildArrayBuffer(Float32Array, bufferViewData, byteOffset, accessor.count, numComponents, byteStride);
+                            return new Float32Array(buffer, byteOffset, length);
                         }
                         default: {
-                            throw new Error(`${context}: Invalid component type (${accessor.componentType})`);
+                            throw new Error(`${context}: Invalid accessor component type ${accessor.componentType}`);
                         }
                     }
                 }
                 catch (e) {
-                    throw new Error(`${context}: ${e.messsage}`);
+                    throw new Error(`${context}: ${e}`);
                 }
             });
 
             return accessor._data;
         }
 
-        private _buildArrayBuffer<T extends TypedArray>(typedArray: TypedArrayConstructor<T>, data: ArrayBufferView, byteOffset: number, count: number, numComponents: number, byteStride?: number): T {
-            byteOffset += data.byteOffset;
+        public _loadVertexBufferViewAsync(context: string, bufferView: ILoaderBufferView, kind: string): Promise<Buffer> {
+            if (bufferView._babylonBuffer) {
+                return bufferView._babylonBuffer;
+            }
+
+            bufferView._babylonBuffer = this._loadBufferViewAsync(context, bufferView).then(data => {
+                return new Buffer(this._babylonScene.getEngine(), data, false);
+            });
 
-            const targetLength = count * numComponents;
+            return bufferView._babylonBuffer;
+        }
 
-            if (!byteStride || byteStride === numComponents * typedArray.BYTES_PER_ELEMENT) {
-                return new typedArray(data.buffer, byteOffset, targetLength);
+        private _loadVertexAccessorAsync(context: string, accessor: ILoaderAccessor, kind: string): Promise<VertexBuffer> {
+            if (accessor.sparse) {
+                throw new Error(`${context}: Sparse accessors are not currently supported`);
             }
 
-            const elementStride = byteStride / typedArray.BYTES_PER_ELEMENT;
-            const sourceBuffer = new typedArray(data.buffer, byteOffset, elementStride * count);
-            const targetBuffer = new typedArray(targetLength);
-            let sourceIndex = 0;
-            let targetIndex = 0;
-
-            while (targetIndex < targetLength) {
-                for (let componentIndex = 0; componentIndex < numComponents; componentIndex++) {
-                    targetBuffer[targetIndex] = sourceBuffer[sourceIndex + componentIndex];
-                    targetIndex++;
-                }
-                sourceIndex += elementStride;
+            if (accessor._babylonVertexBuffer) {
+                return accessor._babylonVertexBuffer;
             }
 
-            return targetBuffer;
+            const bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
+            accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView, kind).then(buffer => {
+                const size = GLTFLoader._GetNumComponents(context, accessor.type);
+                return new VertexBuffer(this._babylonScene.getEngine(), buffer, kind, false, false, bufferView.byteStride,
+                    false, accessor.byteOffset, size, accessor.componentType, accessor.normalized, true);
+            });
+
+            return accessor._babylonVertexBuffer;
         }
 
         private _getDefaultMaterial(drawMode: number): Material {

+ 3 - 3
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -24,7 +24,7 @@ module BABYLON.GLTF2 {
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>> { return null; }
 
         /** Override this method to modify the default behavior for loading mesh primitive vertex data. */
-        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>> { return null; }
+        protected _loadVertexDataAsync(context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> { return null; }
 
         /** Override this method to modify the default behavior for loading materials. */
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> { return null; }
@@ -35,7 +35,7 @@ module BABYLON.GLTF2 {
         // #endregion
 
         /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (context: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>> {
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>> {
             if (!property.extensions) {
                 return null;
             }
@@ -70,7 +70,7 @@ module BABYLON.GLTF2 {
         }
 
         /** Helper method called by the loader to allow extensions to override loading mesh primitive vertex data. */
-        public static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<VertexData>> {
+        public static _LoadVertexDataAsync(loader: GLTFLoader, context: string, primitive: ILoaderMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
             return loader._applyExtensions(extension => extension._loadVertexDataAsync(context, primitive, babylonMesh));
         }
 

+ 3 - 1
loaders/src/glTF/2.0/babylon.glTFLoaderInterfaces.ts

@@ -3,7 +3,8 @@
 
 module BABYLON.GLTF2 {
     export interface ILoaderAccessor extends IAccessor, IArrayItem {
-        _data?: Promise<TypedArray>;
+        _data?: Promise<ArrayBufferView>;
+        _babylonVertexBuffer?: Promise<VertexBuffer>;
     }
 
     export interface ILoaderAnimationChannel extends IAnimationChannel, IArrayItem {
@@ -32,6 +33,7 @@ module BABYLON.GLTF2 {
 
     export interface ILoaderBufferView extends IBufferView, IArrayItem {
         _data?: Promise<ArrayBufferView>;
+        _babylonBuffer?: Promise<Buffer>;
     }
 
     export interface ILoaderCamera extends ICamera, IArrayItem {

+ 0 - 4
loaders/src/glTF/2.0/babylon.glTFLoaderUtilities.ts

@@ -1,10 +1,6 @@
 /// <reference path="../../../../dist/preview release/babylon.d.ts"/>
 
 module BABYLON.GLTF2 {
-    export interface TypedArray extends ArrayBufferView {
-        [index: number]: number;
-    }
-
     export interface IArrayItem {
         _index: number;
     }

+ 64 - 84
serializers/src/glTF/2.0/babylon.glTFExporter.ts

@@ -239,20 +239,20 @@ module BABYLON.GLTF2 {
          * Returns the bytelength of the data.
          * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
          * @param meshAttributeArray - Array containing the attribute data. 
-         * @param strideSize - Represents the offset between consecutive attributes
          * @param byteOffset - The offset to start counting bytes from.
          * @param dataBuffer - The buffer to write the binary data to.
          * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, strideSize: number, vertexBufferOffset: number, byteOffset: number, dataBuffer: DataView): number {
+        private writeAttributeData(vertexBufferKind: string, meshAttributeArray: FloatArray, byteOffset: number, dataBuffer: DataView): number {
             let byteOff = byteOffset;
 
-            const end = meshAttributeArray.length / strideSize;
+            const stride = VertexBuffer.DeduceStride(vertexBufferKind);
+            const end = meshAttributeArray.length / stride;
 
             let byteLength = 0;
 
             for (let k = 0; k < end; ++k) {
-                const index = k * strideSize;
+                const index = k * stride;
                 let vector: number[] = [];
 
                 if (vertexBufferKind === VertexBuffer.PositionKind || vertexBufferKind === VertexBuffer.NormalKind) {
@@ -533,36 +533,22 @@ module BABYLON.GLTF2 {
                 bufferMesh = (babylonMesh as InstancedMesh).sourceMesh;
             }
             if (bufferMesh) {
-                let vertexBuffer = null;
-                let vertexBufferOffset = null;
-                let vertexData = null;
-                let vertexStrideSize = null;
-                if (bufferMesh.isVerticesDataPresent(kind)) {
-                    vertexBuffer = bufferMesh.getVertexBuffer(kind);
-                    if (vertexBuffer) {
-                        vertexBufferOffset = vertexBuffer.getOffset();
-                        vertexData = vertexBuffer.getData();
-                        if (vertexData) {
-                            vertexStrideSize = vertexBuffer.getStrideSize();
-
-                            if (dataBuffer && vertexData) { // write data to buffer
-                                byteLength = this.writeAttributeData(
-                                    kind,
-                                    vertexData,
-                                    vertexStrideSize,
-                                    vertexBufferOffset,
-                                    byteOffset,
-                                    dataBuffer,
-                                );
-                                byteOffset += byteLength;
-                            }
-                            else {
-                                byteLength = vertexData.length * 4;
-                                const bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, kind + " - " + bufferMesh.name);
-                                byteOffset += byteLength;
-                                this.bufferViews.push(bufferView);
-                            }
-                        }
+                const vertexData = bufferMesh.getVerticesData(kind);
+                if (vertexData) {
+                    if (dataBuffer && vertexData) { // write data to buffer
+                        byteLength = this.writeAttributeData(
+                            kind,
+                            vertexData,
+                            byteOffset,
+                            dataBuffer,
+                        );
+                        byteOffset += byteLength;
+                    }
+                    else {
+                        byteLength = vertexData.length * 4;
+                        const bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, kind + " - " + bufferMesh.name);
+                        byteOffset += byteLength;
+                        this.bufferViews.push(bufferView);
                     }
                 }
             }
@@ -638,57 +624,51 @@ module BABYLON.GLTF2 {
                         if (!dataBuffer) {
                             for (const attribute of attributeData) {
                                 const attributeKind = attribute.kind;
+                                const vertexData = bufferMesh.getVerticesData(attributeKind);
+                                if (vertexData) {
+                                    const stride = VertexBuffer.DeduceStride(attributeKind);
+                                    let minMax: Nullable<{ min: number[], max: number[] }>;
+                                    let min = null;
+                                    let max = null;
+                                    const bufferViewIndex = attribute.bufferViewIndex;
+                                    if (bufferViewIndex != undefined) { // check to see if bufferviewindex has a numeric value assigned.
+                                        if (attributeKind == VertexBuffer.PositionKind) {
+                                            minMax = this.calculateMinMaxPositions(vertexData, 0, vertexData.length / stride);
+                                            min = minMax.min;
+                                            max = minMax.max;
+                                        }
+                                        const accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, AccessorComponentType.FLOAT, vertexData.length / stride, 0, min, max);
+                                        this.accessors.push(accessor);
 
-                                if (bufferMesh.isVerticesDataPresent(attributeKind)) {
-                                    const vertexBuffer = bufferMesh.getVertexBuffer(attributeKind);
-                                    if (vertexBuffer) {
-                                        const bufferData = vertexBuffer.getData();
-                                        if (bufferData) {
-                                            const strideSize = vertexBuffer.getStrideSize();
-                                            let minMax: Nullable<{ min: number[], max: number[] }>;
-                                            let min = null;
-                                            let max = null;
-                                            const bufferViewIndex = attribute.bufferViewIndex;
-                                            if (bufferViewIndex != undefined) { // check to see if bufferviewindex has a numeric value assigned.
-                                                if (attributeKind == VertexBuffer.PositionKind) {
-                                                    minMax = this.calculateMinMaxPositions(bufferData, 0, bufferData.length / strideSize);
-                                                    min = minMax.min;
-                                                    max = minMax.max;
-                                                }
-                                                const accessor = this.createAccessor(bufferViewIndex, attributeKind + " - " + babylonMesh.name, attribute.accessorType, AccessorComponentType.FLOAT, bufferData.length / strideSize, 0, min, max);
-                                                this.accessors.push(accessor);
-
-                                                switch (attributeKind) {
-                                                    case VertexBuffer.PositionKind: {
-                                                        meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                                                        break;
-                                                    }
-                                                    case VertexBuffer.NormalKind: {
-                                                        meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
-                                                        break;
-                                                    }
-                                                    case VertexBuffer.ColorKind: {
-                                                        meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                                                        break;
-                                                    }
-                                                    case VertexBuffer.TangentKind: {
-                                                        meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                                                        break;
-                                                    }
-                                                    case VertexBuffer.UVKind: {
-                                                        meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                                                        uvCoordsPresent = true;
-                                                        break;
-                                                    }
-                                                    case VertexBuffer.UV2Kind: {
-                                                        meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                                                        uvCoordsPresent = true;
-                                                        break;
-                                                    }
-                                                    default: {
-                                                        Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
-                                                    }
-                                                }
+                                        switch (attributeKind) {
+                                            case VertexBuffer.PositionKind: {
+                                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
+                                                break;
+                                            }
+                                            case VertexBuffer.NormalKind: {
+                                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                                                break;
+                                            }
+                                            case VertexBuffer.ColorKind: {
+                                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
+                                                break;
+                                            }
+                                            case VertexBuffer.TangentKind: {
+                                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
+                                                break;
+                                            }
+                                            case VertexBuffer.UVKind: {
+                                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
+                                                uvCoordsPresent = true;
+                                                break;
+                                            }
+                                            case VertexBuffer.UV2Kind: {
+                                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
+                                                uvCoordsPresent = true;
+                                                break;
+                                            }
+                                            default: {
+                                                Tools.Warn("Unsupported Vertex Buffer Type: " + attributeKind);
                                             }
                                         }
                                     }

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

@@ -370,7 +370,10 @@
 
             serializationObject.name = this.name;
             serializationObject.id = this.id;
-            serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();
+
+            if (this.dimensionsAtRest) {
+                serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();
+            }
 
             serializationObject.bones = [];
 

+ 1 - 1
src/Cameras/Inputs/babylon.arcRotateCameraPointersInput.ts

@@ -114,7 +114,7 @@ module BABYLON {
                     //but emptying completly pointers collection is required to fix a bug on iPhone : 
                     //when changing orientation while pinching camera, one pointer stay pressed forever if we don't release all pointers  
                     //will be ok to put back pointers.remove(evt.pointerId); when iPhone bug corrected
-                    if (engine.badOS) {
+                    if (engine._badOS) {
                         pointA = pointB = null;
                     }
                     else {

+ 101 - 0
src/Debug/babylon.axesViewer.ts

@@ -0,0 +1,101 @@
+/**
+ * Module Debug contains the (visual) components to debug a scene correctly
+ */
+module BABYLON.Debug {
+
+    /**
+     * The Axes viewer will show 3 axes in a specific point in space
+     */
+    export class AxesViewer {
+
+        private _xline = [Vector3.Zero(), Vector3.Zero()];
+        private _yline = [Vector3.Zero(), Vector3.Zero()];
+        private _zline = [Vector3.Zero(), Vector3.Zero()];
+
+        private _xmesh: Nullable<LinesMesh>;
+        private _ymesh: Nullable<LinesMesh>;
+        private _zmesh: Nullable<LinesMesh>;
+
+        public scene: Nullable<Scene>;
+        public scaleLines = 1;
+
+        constructor(scene: Scene, scaleLines = 1) {
+
+            this.scaleLines = scaleLines;
+
+            this._xmesh = Mesh.CreateLines("xline", this._xline, scene, true);
+            this._ymesh = Mesh.CreateLines("yline", this._yline, scene, true);
+            this._zmesh = Mesh.CreateLines("zline", this._zline, scene, true);
+
+            this._xmesh.renderingGroupId = 2;
+            this._ymesh.renderingGroupId = 2;
+            this._zmesh.renderingGroupId = 2;
+
+            this._xmesh.material.checkReadyOnlyOnce = true;
+            this._xmesh.color = new Color3(1, 0, 0);
+            this._ymesh.material.checkReadyOnlyOnce = true;
+            this._ymesh.color = new Color3(0, 1, 0);
+            this._zmesh.material.checkReadyOnlyOnce = true;
+            this._zmesh.color = new Color3(0, 0, 1);
+
+            this.scene = scene;
+
+        }
+
+        public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {
+
+            var scaleLines = this.scaleLines;
+
+            if (this._xmesh) {
+                this._xmesh.position.copyFrom(position);
+            }
+            if (this._ymesh) {
+                this._ymesh.position.copyFrom(position);
+            }
+            if (this._zmesh) {
+                this._zmesh.position.copyFrom(position);
+            }
+
+            var point2 = this._xline[1];
+            point2.x = xaxis.x * scaleLines;
+            point2.y = xaxis.y * scaleLines;
+            point2.z = xaxis.z * scaleLines;
+            Mesh.CreateLines("", this._xline, null, false, this._xmesh);
+
+            point2 = this._yline[1];
+            point2.x = yaxis.x * scaleLines;
+            point2.y = yaxis.y * scaleLines;
+            point2.z = yaxis.z * scaleLines;
+            Mesh.CreateLines("", this._yline, null, false, this._ymesh);
+
+            point2 = this._zline[1];
+            point2.x = zaxis.x * scaleLines;
+            point2.y = zaxis.y * scaleLines;
+            point2.z = zaxis.z * scaleLines;
+            Mesh.CreateLines("", this._zline, null, false, this._zmesh);
+
+        }
+
+        public dispose() {
+
+            if (this._xmesh) {
+                this._xmesh.dispose();
+            }
+
+            if (this._ymesh) {
+                this._ymesh.dispose();
+            }
+
+            if (this._zmesh) {
+                this._zmesh.dispose();
+            }
+
+            this._xmesh = null;
+            this._ymesh = null;
+            this._zmesh = null;
+
+            this.scene = null;
+        }
+
+    }
+}

+ 53 - 0
src/Debug/babylon.boneAxesViewer.ts

@@ -0,0 +1,53 @@
+module BABYLON.Debug {
+
+    /**
+     * The BoneAxesViewer will attach 3 axes to a specific bone of a specific mesh
+     */
+    export class BoneAxesViewer extends AxesViewer {
+
+        public mesh: Nullable<Mesh>;
+        public bone: Nullable<Bone>;
+
+        public pos = Vector3.Zero();
+        public xaxis = Vector3.Zero();
+        public yaxis = Vector3.Zero();
+        public zaxis = Vector3.Zero();
+
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines = 1) {
+
+            super(scene, scaleLines);
+
+            this.mesh = mesh;
+            this.bone = bone;
+
+        }
+
+        public update(): void {
+
+            if (!this.mesh || !this.bone) {
+                return;
+            }
+
+            var bone = this.bone;
+            bone.getAbsolutePositionToRef(this.mesh, this.pos);
+            bone.getDirectionToRef(Axis.X, this.mesh, this.xaxis);
+            bone.getDirectionToRef(Axis.Y, this.mesh, this.yaxis);
+            bone.getDirectionToRef(Axis.Z, this.mesh, this.zaxis);
+
+            super.update(this.pos, this.xaxis, this.yaxis, this.zaxis);
+
+        }
+
+        public dispose() {
+
+            if (this.mesh) {
+                this.mesh = null;
+                this.bone = null;
+
+                super.dispose();
+
+            }
+        }
+
+    }
+}

+ 0 - 461
src/Debug/babylon.debugModules.ts

@@ -1,461 +0,0 @@
-module BABYLON {
-    export class Debug {
-        public static AxesViewer = class AxesViewer {
-            _xline = [Vector3.Zero(), Vector3.Zero()];
-            _yline = [Vector3.Zero(), Vector3.Zero()];
-            _zline = [Vector3.Zero(), Vector3.Zero()];
-
-            _xmesh: Nullable<LinesMesh>;
-            _ymesh: Nullable<LinesMesh>;
-            _zmesh: Nullable<LinesMesh>;
-
-            public scene: Nullable<Scene>;
-            public scaleLines = 1;
-
-            constructor(scene: Scene, scaleLines = 1) {
-
-                this.scaleLines = scaleLines;
-
-                this._xmesh = Mesh.CreateLines("xline", this._xline, scene, true);
-                this._ymesh = Mesh.CreateLines("yline", this._yline, scene, true);
-                this._zmesh = Mesh.CreateLines("zline", this._zline, scene, true);
-
-                this._xmesh.renderingGroupId = 2;
-                this._ymesh.renderingGroupId = 2;
-                this._zmesh.renderingGroupId = 2;
-
-                this._xmesh.material.checkReadyOnlyOnce = true;
-                this._xmesh.color = new Color3(1, 0, 0);
-                this._ymesh.material.checkReadyOnlyOnce = true;
-                this._ymesh.color = new Color3(0, 1, 0);
-                this._zmesh.material.checkReadyOnlyOnce = true;
-                this._zmesh.color = new Color3(0, 0, 1);
-
-                this.scene = scene;
-
-            }
-
-            public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {
-
-                var scaleLines = this.scaleLines;
-
-                if (this._xmesh) {
-                    this._xmesh.position.copyFrom(position);
-                }
-                if (this._ymesh) {
-                    this._ymesh.position.copyFrom(position);
-                }
-                if (this._zmesh) {
-                    this._zmesh.position.copyFrom(position);
-                }
-
-                var point2 = this._xline[1];
-                point2.x = xaxis.x * scaleLines;
-                point2.y = xaxis.y * scaleLines;
-                point2.z = xaxis.z * scaleLines;
-                Mesh.CreateLines("", this._xline, null, false, this._xmesh);
-
-                point2 = this._yline[1];
-                point2.x = yaxis.x * scaleLines;
-                point2.y = yaxis.y * scaleLines;
-                point2.z = yaxis.z * scaleLines;
-                Mesh.CreateLines("", this._yline, null, false, this._ymesh);
-
-                point2 = this._zline[1];
-                point2.x = zaxis.x * scaleLines;
-                point2.y = zaxis.y * scaleLines;
-                point2.z = zaxis.z * scaleLines;
-                Mesh.CreateLines("", this._zline, null, false, this._zmesh);
-
-            }
-
-            public dispose() {
-
-                if (this._xmesh) {
-                    this._xmesh.dispose();
-                }
-
-                if (this._ymesh) {
-                    this._ymesh.dispose();
-                }
-
-                if (this._zmesh) {
-                    this._zmesh.dispose();
-                }
-
-                this._xmesh = null;
-                this._ymesh = null;
-                this._zmesh = null;
-
-                this.scene = null;
-            }
-        }
-
-        public static BoneAxesViewer = class BoneAxesViewer extends Debug.AxesViewer {
-
-            public mesh: Nullable<Mesh>;
-            public bone: Nullable<Bone>;
-
-            public pos = Vector3.Zero();
-            public xaxis = Vector3.Zero();
-            public yaxis = Vector3.Zero();
-            public zaxis = Vector3.Zero();
-
-            constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines = 1) {
-
-                super(scene, scaleLines);
-
-                this.mesh = mesh;
-                this.bone = bone;
-
-            }
-
-            public update(): void {
-
-                if (!this.mesh || !this.bone) {
-                    return;
-                }
-
-                var bone = this.bone;
-                bone.getAbsolutePositionToRef(this.mesh, this.pos);
-                bone.getDirectionToRef(Axis.X, this.mesh, this.xaxis);
-                bone.getDirectionToRef(Axis.Y, this.mesh, this.yaxis);
-                bone.getDirectionToRef(Axis.Z, this.mesh, this.zaxis);
-
-                super.update(this.pos, this.xaxis, this.yaxis, this.zaxis);
-
-            }
-
-            public dispose() {
-
-                if (this.mesh) {
-                    this.mesh = null;
-                    this.bone = null;
-
-                    super.dispose();
-
-                }
-            }
-
-        }
-
-        public static PhysicsViewer = class PhysicsViewer {
-
-            _impostors: Array<Nullable<PhysicsImpostor>> = [];
-            _meshes: Array<Nullable<AbstractMesh>> = [];
-            _scene: Nullable<Scene>;
-            _numMeshes = 0;
-            _physicsEnginePlugin: Nullable<IPhysicsEnginePlugin>;
-            _renderFunction: () => void;
-
-            _debugBoxMesh: Mesh;
-            _debugSphereMesh: Mesh;
-            _debugMaterial: StandardMaterial;
-
-            constructor(scene: Scene) {
-                this._scene = scene || Engine.LastCreatedScene;
-                let physicEngine = this._scene.getPhysicsEngine();
-
-                if (physicEngine) {
-                    this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
-                }
-            }
-
-            _updateDebugMeshes(): void {
-
-                var plugin = this._physicsEnginePlugin;
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    let impostor = this._impostors[i];
-
-                    if (!impostor) {
-                        continue;
-                    }
-
-                    if (impostor.isDisposed) {
-                        this.hideImpostor(this._impostors[i--]);
-                    } else {
-                        let mesh = this._meshes[i];
-
-                        if (mesh && plugin) {
-                            plugin.syncMeshWithImpostor(mesh, impostor);
-                        }
-                    }
-                }
-
-            }
-
-            public showImpostor(impostor: PhysicsImpostor): void {
-
-                if (!this._scene) {
-                    return;
-                }
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    if (this._impostors[i] == impostor) {
-                        return;
-                    }
-                }
-
-                var debugMesh = this._getDebugMesh(impostor, this._scene);
-
-                if (debugMesh) {
-                    this._impostors[this._numMeshes] = impostor;
-                    this._meshes[this._numMeshes] = debugMesh;
-
-                    if (this._numMeshes === 0) {
-                        this._renderFunction = this._updateDebugMeshes.bind(this);
-                        this._scene.registerBeforeRender(this._renderFunction);
-                    }
-
-                    this._numMeshes++;
-                }
-
-            }
-
-            public hideImpostor(impostor: Nullable<PhysicsImpostor>) {
-
-                if (!impostor || !this._scene) {
-                    return;
-                }
-
-                var removed = false;
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    if (this._impostors[i] == impostor) {
-                        let mesh = this._meshes[i];
-
-                        if (!mesh) {
-                            continue;
-                        }
-
-                        this._scene.removeMesh(mesh);
-                        mesh.dispose();
-                        this._numMeshes--;
-                        if (this._numMeshes > 0) {
-                            this._meshes[i] = this._meshes[this._numMeshes];
-                            this._impostors[i] = this._impostors[this._numMeshes];
-                            this._meshes[this._numMeshes] = null;
-                            this._impostors[this._numMeshes] = null;
-                        } else {
-                            this._meshes[0] = null;
-                            this._impostors[0] = null;
-                        }
-                        removed = true;
-                        break;
-                    }
-                }
-
-                if (removed && this._numMeshes === 0) {
-                    this._scene.unregisterBeforeRender(this._renderFunction);
-                }
-
-            }
-
-            _getDebugMaterial(scene: Scene): Material {
-                if (!this._debugMaterial) {
-                    this._debugMaterial = new StandardMaterial('', scene);
-                    this._debugMaterial.wireframe = true;
-                }
-
-                return this._debugMaterial;
-            }
-
-            _getDebugBoxMesh(scene: Scene): AbstractMesh {
-                if (!this._debugBoxMesh) {
-                    this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
-                    this._debugBoxMesh.renderingGroupId = 1;
-                    this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
-                    this._debugBoxMesh.material = this._getDebugMaterial(scene);
-                    scene.removeMesh(this._debugBoxMesh);
-                }
-
-                return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
-            }
-
-            _getDebugSphereMesh(scene: Scene): AbstractMesh {
-                if (!this._debugSphereMesh) {
-                    this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
-                    this._debugSphereMesh.renderingGroupId = 1;
-                    this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
-                    this._debugSphereMesh.material = this._getDebugMaterial(scene);
-                    scene.removeMesh(this._debugSphereMesh);
-                }
-
-                return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
-            }
-
-            _getDebugMesh(impostor: PhysicsImpostor, scene: Scene): Nullable<AbstractMesh> {
-                var mesh: Nullable<AbstractMesh> = null;
-
-                if (impostor.type == PhysicsImpostor.BoxImpostor) {
-                    mesh = this._getDebugBoxMesh(scene);
-                    impostor.getBoxSizeToRef(mesh.scaling);
-                } else if (impostor.type == PhysicsImpostor.SphereImpostor) {
-                    mesh = this._getDebugSphereMesh(scene);
-                    var radius = impostor.getRadius();
-                    mesh.scaling.x = radius * 2;
-                    mesh.scaling.y = radius * 2;
-                    mesh.scaling.z = radius * 2;
-                }
-
-                return mesh;
-            }
-
-            public dispose() {
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    this.hideImpostor(this._impostors[i]);
-                }
-
-                if (this._debugBoxMesh) {
-                    this._debugBoxMesh.dispose();
-                }
-                if (this._debugSphereMesh) {
-                    this._debugSphereMesh.dispose();
-                }
-                if (this._debugMaterial) {
-                    this._debugMaterial.dispose();
-                }
-
-                this._impostors.length = 0;
-                this._scene = null;
-                this._physicsEnginePlugin = null;
-
-            }
-
-        }
-
-        public static SkeletonViewer = class SkeletonViewer {
-            public color: Color3 = Color3.White();
-
-            _scene: Scene;
-            _debugLines = new Array<Array<Vector3>>();
-            _debugMesh: Nullable<LinesMesh>;
-            _isEnabled = false;
-            _renderFunction: () => void;
-
-            constructor(public skeleton: Skeleton, public mesh: AbstractMesh, scene: Scene, public autoUpdateBonesMatrices = true, public renderingGroupId = 1) {
-                this._scene = scene;
-
-                this.update();
-
-                this._renderFunction = this.update.bind(this);
-            }
-
-            public set isEnabled(value: boolean) {
-                if (this._isEnabled === value) {
-                    return;
-                }
-
-                this._isEnabled = value;
-
-                if (value) {
-                    this._scene.registerBeforeRender(this._renderFunction);
-                } else {
-                    this._scene.unregisterBeforeRender(this._renderFunction);
-                }
-            }
-
-            public get isEnabled(): boolean {
-                return this._isEnabled;
-            }
-
-            _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {
-                var tmat = Tmp.Matrix[0];
-                var parentBone = bone.getParent();
-                tmat.copyFrom(bone.getLocalMatrix());
-
-                if (x !== 0 || y !== 0 || z !== 0) {
-                    var tmat2 = Tmp.Matrix[1];
-                    Matrix.IdentityToRef(tmat2);
-                    tmat2.m[12] = x;
-                    tmat2.m[13] = y;
-                    tmat2.m[14] = z;
-                    tmat2.multiplyToRef(tmat, tmat);
-                }
-
-                if (parentBone) {
-                    tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
-                }
-
-                tmat.multiplyToRef(meshMat, tmat);
-
-                position.x = tmat.m[12];
-                position.y = tmat.m[13];
-                position.z = tmat.m[14];
-            }
-
-            _getLinesForBonesWithLength(bones: Bone[], meshMat: Matrix): void {
-                var len = bones.length;
-                var meshPos = this.mesh.position;
-                for (var i = 0; i < len; i++) {
-                    var bone = bones[i];
-                    var points = this._debugLines[i];
-                    if (!points) {
-                        points = [Vector3.Zero(), Vector3.Zero()];
-                        this._debugLines[i] = points;
-                    }
-                    this._getBonePosition(points[0], bone, meshMat);
-                    this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
-                    points[0].subtractInPlace(meshPos);
-                    points[1].subtractInPlace(meshPos);
-                }
-            }
-
-            _getLinesForBonesNoLength(bones: Bone[], meshMat: Matrix): void {
-                var len = bones.length;
-                var boneNum = 0;
-                var meshPos = this.mesh.position;
-                for (var i = len - 1; i >= 0; i--) {
-                    var childBone = bones[i];
-                    var parentBone = childBone.getParent();
-                    if (!parentBone) {
-                        continue;
-                    }
-                    var points = this._debugLines[boneNum];
-                    if (!points) {
-                        points = [Vector3.Zero(), Vector3.Zero()];
-                        this._debugLines[boneNum] = points;
-                    }
-                    childBone.getAbsolutePositionToRef(this.mesh, points[0]);
-                    parentBone.getAbsolutePositionToRef(this.mesh, points[1]);
-                    points[0].subtractInPlace(meshPos);
-                    points[1].subtractInPlace(meshPos);
-                    boneNum++;
-                }
-            }
-
-            public update() {
-                if (this.autoUpdateBonesMatrices) {
-                    this.skeleton.computeAbsoluteTransforms();
-                }
-
-                if (this.skeleton.bones[0].length === undefined) {
-                    this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
-                } else {
-                    this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
-                }
-
-                if (!this._debugMesh) {
-                    this._debugMesh = MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, this._scene);
-                    this._debugMesh.renderingGroupId = this.renderingGroupId;
-                } else {
-                    MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
-                }
-                this._debugMesh.position.copyFrom(this.mesh.position);
-                this._debugMesh.color = this.color;
-            }
-
-            public dispose() {
-                if (this._debugMesh) {
-                    this.isEnabled = false;
-                    this._debugMesh.dispose();
-                    this._debugMesh = null;
-                }
-            }
-        }
-    }
-
-
-}

+ 192 - 0
src/Debug/babylon.physicsViewer.ts

@@ -0,0 +1,192 @@
+module BABYLON.Debug {
+
+    /**
+     * Used to show the physics impostor around the specific mesh.
+     */
+    export class PhysicsViewer {
+
+        protected _impostors: Array<Nullable<PhysicsImpostor>> = [];
+        protected _meshes: Array<Nullable<AbstractMesh>> = [];
+        protected _scene: Nullable<Scene>;
+        protected _numMeshes = 0;
+        protected _physicsEnginePlugin: Nullable<IPhysicsEnginePlugin>;
+        private _renderFunction: () => void;
+
+        private _debugBoxMesh: Mesh;
+        private _debugSphereMesh: Mesh;
+        private _debugMaterial: StandardMaterial;
+
+        constructor(scene: Scene) {
+            this._scene = scene || Engine.LastCreatedScene;
+            let physicEngine = this._scene.getPhysicsEngine();
+
+            if (physicEngine) {
+                this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
+            }
+        }
+
+        protected _updateDebugMeshes(): void {
+
+            var plugin = this._physicsEnginePlugin;
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                let impostor = this._impostors[i];
+
+                if (!impostor) {
+                    continue;
+                }
+
+                if (impostor.isDisposed) {
+                    this.hideImpostor(this._impostors[i--]);
+                } else {
+                    let mesh = this._meshes[i];
+
+                    if (mesh && plugin) {
+                        plugin.syncMeshWithImpostor(mesh, impostor);
+                    }
+                }
+            }
+
+        }
+
+        public showImpostor(impostor: PhysicsImpostor): void {
+
+            if (!this._scene) {
+                return;
+            }
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                if (this._impostors[i] == impostor) {
+                    return;
+                }
+            }
+
+            var debugMesh = this._getDebugMesh(impostor, this._scene);
+
+            if (debugMesh) {
+                this._impostors[this._numMeshes] = impostor;
+                this._meshes[this._numMeshes] = debugMesh;
+
+                if (this._numMeshes === 0) {
+                    this._renderFunction = this._updateDebugMeshes.bind(this);
+                    this._scene.registerBeforeRender(this._renderFunction);
+                }
+
+                this._numMeshes++;
+            }
+
+        }
+
+        public hideImpostor(impostor: Nullable<PhysicsImpostor>) {
+
+            if (!impostor || !this._scene) {
+                return;
+            }
+
+            var removed = false;
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                if (this._impostors[i] == impostor) {
+                    let mesh = this._meshes[i];
+
+                    if (!mesh) {
+                        continue;
+                    }
+
+                    this._scene.removeMesh(mesh);
+                    mesh.dispose();
+                    this._numMeshes--;
+                    if (this._numMeshes > 0) {
+                        this._meshes[i] = this._meshes[this._numMeshes];
+                        this._impostors[i] = this._impostors[this._numMeshes];
+                        this._meshes[this._numMeshes] = null;
+                        this._impostors[this._numMeshes] = null;
+                    } else {
+                        this._meshes[0] = null;
+                        this._impostors[0] = null;
+                    }
+                    removed = true;
+                    break;
+                }
+            }
+
+            if (removed && this._numMeshes === 0) {
+                this._scene.unregisterBeforeRender(this._renderFunction);
+            }
+
+        }
+
+        private _getDebugMaterial(scene: Scene): Material {
+            if (!this._debugMaterial) {
+                this._debugMaterial = new StandardMaterial('', scene);
+                this._debugMaterial.wireframe = true;
+            }
+
+            return this._debugMaterial;
+        }
+
+        private _getDebugBoxMesh(scene: Scene): AbstractMesh {
+            if (!this._debugBoxMesh) {
+                this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
+                this._debugBoxMesh.renderingGroupId = 1;
+                this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
+                this._debugBoxMesh.material = this._getDebugMaterial(scene);
+                scene.removeMesh(this._debugBoxMesh);
+            }
+
+            return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
+        }
+
+        private _getDebugSphereMesh(scene: Scene): AbstractMesh {
+            if (!this._debugSphereMesh) {
+                this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
+                this._debugSphereMesh.renderingGroupId = 1;
+                this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
+                this._debugSphereMesh.material = this._getDebugMaterial(scene);
+                scene.removeMesh(this._debugSphereMesh);
+            }
+
+            return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
+        }
+
+        private _getDebugMesh(impostor: PhysicsImpostor, scene: Scene): Nullable<AbstractMesh> {
+            var mesh: Nullable<AbstractMesh> = null;
+
+            if (impostor.type == PhysicsImpostor.BoxImpostor) {
+                mesh = this._getDebugBoxMesh(scene);
+                impostor.getBoxSizeToRef(mesh.scaling);
+            } else if (impostor.type == PhysicsImpostor.SphereImpostor) {
+                mesh = this._getDebugSphereMesh(scene);
+                var radius = impostor.getRadius();
+                mesh.scaling.x = radius * 2;
+                mesh.scaling.y = radius * 2;
+                mesh.scaling.z = radius * 2;
+            }
+
+            return mesh;
+        }
+
+        public dispose() {
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                this.hideImpostor(this._impostors[i]);
+            }
+
+            if (this._debugBoxMesh) {
+                this._debugBoxMesh.dispose();
+            }
+            if (this._debugSphereMesh) {
+                this._debugSphereMesh.dispose();
+            }
+            if (this._debugMaterial) {
+                this._debugMaterial.dispose();
+            }
+
+            this._impostors.length = 0;
+            this._scene = null;
+            this._physicsEnginePlugin = null;
+
+        }
+
+    }
+}

+ 134 - 0
src/Debug/babylon.skeletonViewer.ts

@@ -0,0 +1,134 @@
+module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    export class SkeletonViewer {
+        public color: Color3 = Color3.White();
+
+        private _scene: Scene;
+        private _debugLines = new Array<Array<Vector3>>();
+        private _debugMesh: Nullable<LinesMesh>;
+        private _isEnabled = false;
+        private _renderFunction: () => void;
+
+        constructor(public skeleton: Skeleton, public mesh: AbstractMesh, scene: Scene, public autoUpdateBonesMatrices = true, public renderingGroupId = 1) {
+            this._scene = scene;
+
+            this.update();
+
+            this._renderFunction = this.update.bind(this);
+        }
+
+        public set isEnabled(value: boolean) {
+            if (this._isEnabled === value) {
+                return;
+            }
+
+            this._isEnabled = value;
+
+            if (value) {
+                this._scene.registerBeforeRender(this._renderFunction);
+            } else {
+                this._scene.unregisterBeforeRender(this._renderFunction);
+            }
+        }
+
+        public get isEnabled(): boolean {
+            return this._isEnabled;
+        }
+
+        private _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {
+            var tmat = Tmp.Matrix[0];
+            var parentBone = bone.getParent();
+            tmat.copyFrom(bone.getLocalMatrix());
+
+            if (x !== 0 || y !== 0 || z !== 0) {
+                var tmat2 = Tmp.Matrix[1];
+                BABYLON.Matrix.IdentityToRef(tmat2);
+                tmat2.m[12] = x;
+                tmat2.m[13] = y;
+                tmat2.m[14] = z;
+                tmat2.multiplyToRef(tmat, tmat);
+            }
+
+            if (parentBone) {
+                tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
+            }
+
+            tmat.multiplyToRef(meshMat, tmat);
+
+            position.x = tmat.m[12];
+            position.y = tmat.m[13];
+            position.z = tmat.m[14];
+        }
+
+        private _getLinesForBonesWithLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            var meshPos = this.mesh.position;
+            for (var i = 0; i < len; i++) {
+                var bone = bones[i];
+                var points = this._debugLines[i];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[i] = points;
+                }
+                this._getBonePosition(points[0], bone, meshMat);
+                this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
+                points[0].subtractInPlace(meshPos);
+                points[1].subtractInPlace(meshPos);
+            }
+        }
+
+        private _getLinesForBonesNoLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            var boneNum = 0;
+            var meshPos = this.mesh.position;
+            for (var i = len - 1; i >= 0; i--) {
+                var childBone = bones[i];
+                var parentBone = childBone.getParent();
+                if (!parentBone) {
+                    continue;
+                }
+                var points = this._debugLines[boneNum];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[boneNum] = points;
+                }
+                childBone.getAbsolutePositionToRef(this.mesh, points[0]);
+                parentBone.getAbsolutePositionToRef(this.mesh, points[1]);
+                points[0].subtractInPlace(meshPos);
+                points[1].subtractInPlace(meshPos);
+                boneNum++;
+            }
+        }
+
+        public update() {
+            if (this.autoUpdateBonesMatrices) {
+                this.skeleton.computeAbsoluteTransforms();
+            }
+
+            if (this.skeleton.bones[0].length === undefined) {
+                this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            } else {
+                this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            }
+
+            if (!this._debugMesh) {
+                this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, this._scene);
+                this._debugMesh.renderingGroupId = this.renderingGroupId;
+            } else {
+                BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
+            }
+            this._debugMesh.position.copyFrom(this.mesh.position);
+            this._debugMesh.color = this.color;
+        }
+
+        public dispose() {
+            if (this._debugMesh) {
+                this.isEnabled = false;
+                this._debugMesh.dispose();
+                this._debugMesh = null;
+            }
+        }
+    }
+}

Файловите разлики са ограничени, защото са твърде много
+ 1332 - 112
src/Engine/babylon.engine.ts


+ 11 - 1
src/Engine/babylon.nullEngine.ts

@@ -290,6 +290,9 @@
             return {};
         }
 
+        public _releaseTexture(texture: InternalTexture): void {
+        }
+
         public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null, buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_URL);
             var url = String(urlArg);
@@ -392,7 +395,14 @@
         public updateDynamicIndexBuffer(indexBuffer: WebGLBuffer, indices: IndicesArray, offset: number = 0): void {
         }
 
-        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, offset?: number, count?: number): void {
+        /**
+         * Updates a dynamic vertex buffer.
+         * @param vertexBuffer the vertex buffer to update
+         * @param data the data used to update the vertex buffer
+         * @param byteOffset the byte offset of the data (optional)
+         * @param byteLength the byte length of the data (optional)
+         */
+        public updateDynamicVertexBuffer(vertexBuffer: WebGLBuffer, vertices: FloatArray, byteOffset?: number, byteLength?: number): void {
         }
 
         protected _bindTextureDirectly(target: number, texture: InternalTexture): void {

+ 6 - 6
src/Instrumentation/babylon.sceneInstrumentation.ts

@@ -123,20 +123,20 @@ module BABYLON {
             this._captureRenderTargetsRenderTime = value;
 
             if (value) {
-                this._onBeforeRenderTargetsRenderObserver = this.scene.OnBeforeRenderTargetsRenderObservable.add(() => {
+                this._onBeforeRenderTargetsRenderObserver = this.scene.onBeforeRenderTargetsRenderObservable.add(() => {
                     Tools.StartPerformanceCounter("Render targets rendering");
                     this._renderTargetsRenderTime.beginMonitoring();
                 });
 
-                this._onAfterRenderTargetsRenderObserver = this.scene.OnAfterRenderTargetsRenderObservable.add(() => {
+                this._onAfterRenderTargetsRenderObserver = this.scene.onAfterRenderTargetsRenderObservable.add(() => {
                     Tools.EndPerformanceCounter("Render targets rendering");
                     this._renderTargetsRenderTime.endMonitoring(false);
                 });
             } else {
-                this.scene.OnBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
+                this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
                 this._onBeforeRenderTargetsRenderObserver = null;
 
-                this.scene.OnAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
+                this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
                 this._onAfterRenderTargetsRenderObserver = null;
             }
         }
@@ -466,10 +466,10 @@ module BABYLON {
             this.scene.onAfterActiveMeshesEvaluationObservable.remove(this._onAfterActiveMeshesEvaluationObserver);
             this._onAfterActiveMeshesEvaluationObserver = null;
 
-            this.scene.OnBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
+            this.scene.onBeforeRenderTargetsRenderObservable.remove(this._onBeforeRenderTargetsRenderObserver);
             this._onBeforeRenderTargetsRenderObserver = null;
 
-            this.scene.OnAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
+            this.scene.onAfterRenderTargetsRenderObservable.remove(this._onAfterRenderTargetsRenderObserver);
             this._onAfterRenderTargetsRenderObserver = null;
 
             this.scene.onBeforeAnimationsObservable.remove(this._onBeforeAnimationsObserver);

+ 20 - 1
src/Layer/babylon.effectLayer.ts

@@ -54,18 +54,27 @@
         protected _emissiveTextureAndColor: { texture: Nullable<BaseTexture>, color: Color4 } = { texture: null, color: new Color4() };
 
         /**
+         * The name of the layer
+         */
+        @serialize()
+        public name: string;
+
+        /**
          * The clear color of the texture used to generate the glow map.
          */
+        @serializeAsColor4()
         public neutralColor: Color4 = new Color4();
 
         /**
          * Specifies wether the highlight layer is enabled or not.
          */
+        @serialize()
         public isEnabled: boolean = true;
 
         /**
          * Gets the camera attached to the layer.
          */
+        @serializeAsCameraReference()
         public get camera(): Nullable<Camera> {
             return this._effectLayerOptions.camera;
         }
@@ -102,8 +111,10 @@
          */
         constructor(
             /** The Friendly of the effect in the scene */
-            public name: string, 
+            name: string,
             scene: Scene) {
+            this.name = name;
+
             this._scene = scene || Engine.LastCreatedScene;
             this._engine = scene.getEngine();
             this._maxSize = this._engine.getCaps().maxTextureSize;
@@ -651,5 +662,13 @@
             this.onAfterComposeObservable.clear();
             this.onSizeChangedObservable.clear();
         }
+
+        /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+         public getClassName(): string {
+            return "EffectLayer";
+        }
     }
 } 

+ 78 - 1
src/Layer/babylon.glowLayer.ts

@@ -68,6 +68,7 @@
         /**
          * Gets the kernel size of the blur.
          */
+        @serialize()
         public get blurKernelSize(): number {
             return this._horizontalBlurPostprocess1.kernel;
         }
@@ -82,11 +83,14 @@
         /**
          * Gets the glow intensity.
          */
+        @serialize()
         public get intensity(): number {
             return this._intensity;
         }
 
+        @serialize('options')
         private _options: IGlowLayerOptions;
+
         private _intensity: number = 1.0;
         private _horizontalBlurPostprocess1: BlurPostProcess;
         private _verticalBlurPostprocess1: BlurPostProcess;
@@ -115,7 +119,7 @@
          * @param scene The scene to use the layer in
          * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)
          */
-        constructor(public name: string, scene: Scene, options?: Partial<IGlowLayerOptions>) {
+        constructor(name: string, scene: Scene, options?: Partial<IGlowLayerOptions>) {
             super(name, scene);
             this.neutralColor = new Color4(0, 0, 0, 1);
 
@@ -441,5 +445,78 @@
             this.removeIncludedOnlyMesh(mesh);
             this.removeExcludedMesh(mesh);
         }
+
+        /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+         public getClassName(): string {
+            return "GlowLayer";
+        }
+
+        /**
+         * Serializes this glow layer
+         * @returns a serialized glow layer object
+         */
+        public serialize(): any {
+            var serializationObject = SerializationHelper.Serialize(this);
+            var index;
+
+            // Included meshes
+            serializationObject.includedMeshes = [];
+
+            if (this._includedOnlyMeshes.length) {
+                for (index = 0; index < this._includedOnlyMeshes.length; index++) {
+                    var mesh = this._scene.getMeshByUniqueID(this._includedOnlyMeshes[index]);
+                    if (mesh) {
+                        serializationObject.includedMeshes.push(mesh.id);
+                    }
+                }
+            }
+
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+
+            if (this._excludedMeshes.length) {
+                for (index = 0; index < this._excludedMeshes.length; index++) {
+                    var mesh = this._scene.getMeshByUniqueID(this._excludedMeshes[index]);
+                    if (mesh) {
+                        serializationObject.excludedMeshes.push(mesh.id);
+                    }
+                }
+            }
+
+            return serializationObject;
+        }
+
+        /**
+         * Creates a Glow Layer from parsed glow layer data
+         * @param parsedGlowLayer defines glow layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the glow layer information
+         * @returns a parsed Glow Layer
+         */
+        public static Parse(parsedGlowLayer: any, scene: Scene, rootUrl: string): GlowLayer {
+            var gl = SerializationHelper.Parse(() => new GlowLayer(parsedGlowLayer.name, scene, parsedGlowLayer.options), parsedGlowLayer, scene, rootUrl);
+            var index;
+
+            // Excluded meshes
+            for (index = 0; index < parsedGlowLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedGlowLayer.excludedMeshes[index]);
+                if (mesh) {
+                    gl.addExcludedMesh(<Mesh>mesh);
+                }
+            }
+
+            // Included meshes
+            for (index = 0; index < parsedGlowLayer.includedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedGlowLayer.includedMeshes[index]);
+                if (mesh) {
+                    gl.addIncludedOnlyMesh(<Mesh>mesh);
+                }
+            }
+
+            return gl;
+        }
     }
 } 

+ 3 - 3
src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts

@@ -33,7 +33,7 @@
         constructor(name: string, size: any, fragment: any, scene: Scene, fallbackTexture: Nullable<Texture> = null, generateMipMaps = true, public isCube = false) {
             super(null, scene, !generateMipMaps);
 
-            scene._proceduralTextures.push(this);
+            scene.proceduralTextures.push(this);
 
             this._engine = scene.getEngine();
 
@@ -384,10 +384,10 @@
                 return;
             }
 
-            var index = scene._proceduralTextures.indexOf(this);
+            var index = scene.proceduralTextures.indexOf(this);
 
             if (index >= 0) {
-                scene._proceduralTextures.splice(index, 1);
+                scene.proceduralTextures.splice(index, 1);
             }
 
             var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];

+ 43 - 29
src/Mesh/babylon.buffer.ts

@@ -2,12 +2,26 @@
     export class Buffer {
         private _engine: Engine;
         private _buffer: Nullable<WebGLBuffer>;
-        private _data: Nullable<FloatArray>;
+        private _data: Nullable<DataArray>;
         private _updatable: boolean;
-        private _strideSize: number;
         private _instanced: boolean;
 
-        constructor(engine: any, data: FloatArray, updatable: boolean, stride: number, postponeInternalCreation?: boolean, instanced: boolean = false) {
+        /**
+         * Gets the byte stride.
+         */
+        public readonly byteStride: number;
+
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this buffer
+         * @param updatable whether the data is updatable
+         * @param stride the stride (optional)
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param useBytes set to true if the stride in in bytes (optional)
+         */
+        constructor(engine: any, data: DataArray, updatable: boolean, stride = 0, postponeInternalCreation = false, instanced = false, useBytes = false) {
             if (engine instanceof Mesh) { // old versions of BABYLON.VertexBuffer accepted 'mesh' instead of 'engine'
                 this._engine = engine.getScene().getEngine();
             }
@@ -20,7 +34,7 @@
 
             this._data = data;
 
-            this._strideSize = stride;
+            this.byteStride = useBytes ? stride : stride * 4;
 
             if (!postponeInternalCreation) { // by default
                 this.create();
@@ -34,11 +48,15 @@
          * @param size defines the size in floats of attributes (position is 3 for instance)
          * @param stride defines the stride size in floats in the buffer (the offset to apply to reach next value when data is interleaved)
          * @param instanced defines if the vertex buffer contains indexed data
+         * @param useBytes defines if the offset and stride are in bytes
          * @returns the new vertex buffer
          */
-        public createVertexBuffer(kind: string, offset: number, size: number, stride?: number, instanced?: boolean): VertexBuffer {
+        public createVertexBuffer(kind: string, offset: number, size: number, stride?: number, instanced?: boolean, useBytes = false): VertexBuffer {
+            const byteOffset = useBytes ? offset : offset * 4;
+            const byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
+
             // a lot of these parameters are ignored as they are overriden by the buffer
-            return new VertexBuffer(this._engine, this, kind, this._updatable, true, stride ? stride : this._strideSize, instanced === undefined ? this._instanced : instanced, offset, size);
+            return new VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
         }
 
         // Properties
@@ -46,7 +64,7 @@
             return this._updatable;
         }
 
-        public getData(): Nullable<FloatArray> {
+        public getData(): Nullable<DataArray> {
             return this._data;
         }
 
@@ -54,29 +72,18 @@
             return this._buffer;
         }
 
+        /**
+         * Gets the stride in float32 units (i.e. byte stride / 4).
+         * May not be an integer if the byte stride is not divisible by 4.
+         * DEPRECATED. Use byteStride instead.
+         * @returns the stride in float32 units
+         */
         public getStrideSize(): number {
-            return this._strideSize;
+            return this.byteStride / 4;
         }
 
-        // public getIsInstanced(): boolean {
-        //     return this._instanced;
-        // }
-
-        // public get instanceDivisor(): number {
-        //     return this._instanceDivisor;
-        // }
-
-        // public set instanceDivisor(value: number) {
-        //     this._instanceDivisor = value;
-        //     if (value == 0) {
-        //         this._instanced = false;
-        //     } else {
-        //         this._instanced = true;
-        //     }
-        // }
-
         // Methods
-        public create(data: Nullable<FloatArray> = null): void {
+        public create(data: Nullable<DataArray> = null): void {
             if (!data && this._buffer) {
                 return; // nothing to do
             }
@@ -105,17 +112,24 @@
             this.create(this._data);
         }
 
-        public update(data: FloatArray): void {
+        public update(data: DataArray): void {
             this.create(data);
         }
 
-        public updateDirectly(data: Float32Array, offset: number, vertexCount?: number): void {
+        /**
+         * Updates the data directly.
+         * @param data the new data
+         * @param offset the new offset
+         * @param vertexCount the vertex count (optional)
+         * @param useBytes set to true if the offset is in bytes
+         */
+        public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes = false): void {
             if (!this._buffer) {
                 return;
             }
 
             if (this._updatable) { // update buffer
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, offset, (vertexCount ? vertexCount * this.getStrideSize() : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         }

+ 56 - 32
src/Mesh/babylon.geometry.ts

@@ -65,7 +65,7 @@
 
             this._boundingBias = value.clone();
 
-            this.updateBoundingInfo(true, null);
+            this._updateBoundingInfo(true, null);
         }
 
         /**
@@ -116,7 +116,7 @@
             if (mesh) {
                 if (mesh.getClassName() === "LinesMesh") {
                     this.boundingBias = new Vector2(0, (<LinesMesh>mesh).intersectionThreshold);
-                    this.updateExtend();
+                    this._updateExtend();
                 }
 
                 this.applyToMesh(mesh);
@@ -204,8 +204,11 @@
          * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified
          */
         public setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): void {
-            var buffer = new VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
+            if (kind === VertexBuffer.PositionKind) {
+                this._totalVertices = data.length / (stride || 3);
+            }
 
+            var buffer = new VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
             this.setVerticesBuffer(buffer);
         }
 
@@ -223,8 +226,9 @@
         /**
          * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
          * @param buffer defines the vertex buffer to use
+         * @param totalVertices defines the total number of vertices for position kind (could be null)
          */
-        public setVerticesBuffer(buffer: VertexBuffer): void {
+        public setVerticesBuffer(buffer: VertexBuffer, totalVertices: Nullable<number> = null): void {
             var kind = buffer.getKind();
             if (this._vertexBuffers[kind]) {
                 this._vertexBuffers[kind].dispose();
@@ -233,12 +237,11 @@
             this._vertexBuffers[kind] = buffer;
 
             if (kind === VertexBuffer.PositionKind) {
-                var data = <FloatArray>buffer.getData();
-                var stride = buffer.getStrideSize();
-
-                this._totalVertices = data.length / stride;
+                if (totalVertices != null) {
+                    this._totalVertices = totalVertices;
+                }
 
-                this.updateExtend(data, stride);
+                this._updateExtend();
                 this._resetPointsArrayCache();
 
                 var meshes = this._meshes;
@@ -285,7 +288,7 @@
          * @param kind defines the data kind (Position, normal, etc...)
          * @param data defines the data to use 
          * @param updateExtends defines if the geometry extends must be recomputed (false by default)
-         */        
+         */
         public updateVerticesData(kind: string, data: FloatArray, updateExtends: boolean = false): void {
             var vertexBuffer = this.getVertexBuffer(kind);
 
@@ -296,18 +299,14 @@
             vertexBuffer.update(data);
 
             if (kind === VertexBuffer.PositionKind) {
-
-                var stride = vertexBuffer.getStrideSize();
-                this._totalVertices = data.length / stride;
-
-                this.updateBoundingInfo(updateExtends, data);
+                this._updateBoundingInfo(updateExtends, data);
             }
             this.notifyUpdate(kind);
         }
 
-        private updateBoundingInfo(updateExtends: boolean, data: Nullable<FloatArray>) {
+        private _updateBoundingInfo(updateExtends: boolean, data: Nullable<FloatArray>) {
             if (updateExtends) {
-                this.updateExtend(data);
+                this._updateExtend(data);
             }
 
             var meshes = this._meshes;
@@ -369,28 +368,53 @@
         }
 
         /**
-         * Gets a specific vertex data attached to this geometry
+         * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
          * @param kind defines the data kind (Position, normal, etc...)
          * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
          * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
          * @returns a float array containing vertex data
          */
         public getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray> {
-            var vertexBuffer = this.getVertexBuffer(kind);
+            const vertexBuffer = this.getVertexBuffer(kind);
             if (!vertexBuffer) {
                 return null;
             }
-            var orig = <FloatArray>vertexBuffer.getData();
-            if (!forceCopy && (!copyWhenShared || this._meshes.length === 1)) {
-                return orig;
-            } else {
-                var len = orig.length;
-                var copy = [];
-                for (var i = 0; i < len; i++) {
-                    copy.push(orig[i]);
-                }
+
+            let data = vertexBuffer.getData();
+            if (!data) {
+                 return null;
+            }
+
+            const defaultStride = VertexBuffer.DeduceStride(vertexBuffer.getKind());
+            const defaultByteStride = defaultStride * VertexBuffer.GetTypeByteLength(vertexBuffer.type);
+            const count = this._totalVertices * defaultStride;
+
+            if (vertexBuffer.type !== VertexBuffer.FLOAT || vertexBuffer.byteStride !== defaultByteStride) {
+                const copy = new Array<number>(count);
+                vertexBuffer.forEach(count, (value, index) => {
+                    copy[index] = value;
+                });
                 return copy;
             }
+
+            if (!(data instanceof Array || data instanceof Float32Array) || vertexBuffer.byteOffset !== 0 || data.length !== count) {
+                if (data instanceof Array) {
+                    const offset = vertexBuffer.byteOffset / 4;
+                    return Tools.Slice(data, offset, offset + count);
+                }
+                else if (data instanceof ArrayBuffer) {
+                    return new Float32Array(data, vertexBuffer.byteOffset, count);
+                }
+                else {
+                    return new Float32Array(data.buffer, data.byteOffset + vertexBuffer.byteOffset, count);
+                }
+            }
+
+            if (forceCopy || (copyWhenShared && this._meshes.length !== 1)) {
+                return Tools.Slice(data);
+            }
+
+            return data;
         }
 
         /**
@@ -624,12 +648,12 @@
             }
         }
 
-        private updateExtend(data: Nullable<FloatArray> = null, stride?: number) {
+        private _updateExtend(data: Nullable<FloatArray> = null) {
             if (!data) {
-                data = <FloatArray>this._vertexBuffers[VertexBuffer.PositionKind].getData();
+                data = this.getVerticesData(VertexBuffer.PositionKind)!;
             }
 
-            this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, stride);
+            this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
         }
 
         private _applyToMesh(mesh: Mesh): void {
@@ -646,7 +670,7 @@
 
                 if (kind === VertexBuffer.PositionKind) {
                     if (!this._extend) {
-                        this.updateExtend(this._vertexBuffers[kind].getData());
+                        this._updateExtend();
                     }
                     mesh._boundingInfo = new BoundingInfo(this._extend.minimum, this._extend.maximum);
 

+ 1 - 1
src/Mesh/babylon.linesMesh.ts

@@ -105,7 +105,7 @@
         }
 
         public _draw(subMesh: SubMesh, fillMode: number, instancesCount?: number): LinesMesh {
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
 

+ 2 - 2
src/Mesh/babylon.mesh.ts

@@ -1123,7 +1123,7 @@
         }
 
         public _draw(subMesh: SubMesh, fillMode: number, instancesCount?: number, alternate = false): Mesh {
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
 
@@ -1359,7 +1359,7 @@
             }
 
             // Checking geometry state
-            if (!this._geometry || !this._geometry.getVertexBuffers() || !this._geometry.getIndexBuffer()) {
+            if (!this._geometry || !this._geometry.getVertexBuffers() || (!this._unIndexed && !this._geometry.getIndexBuffer())) {
                 return this;
             }
 

+ 224 - 29
src/Mesh/babylon.vertexBuffer.ts

@@ -2,14 +2,47 @@
     export class VertexBuffer {
         private _buffer: Buffer;
         private _kind: string;
-        private _offset: number;
         private _size: number;
-        private _stride: number;
         private _ownsBuffer: boolean;
-        private _instanced: boolean;        
+        private _instanced: boolean;
         private _instanceDivisor: number;
 
         /**
+         * The byte type.
+         */
+        public static readonly BYTE = 5120;
+
+        /**
+         * The unsigned byte type.
+         */
+        public static readonly UNSIGNED_BYTE = 5121;
+
+        /**
+         * The short type.
+         */
+        public static readonly SHORT = 5122;
+
+        /**
+         * The unsigned short type.
+         */
+        public static readonly UNSIGNED_SHORT = 5123;
+
+        /**
+         * The integer type.
+         */
+        public static readonly INT = 5124;
+
+        /**
+         * The unsigned integer type.
+         */
+        public static readonly UNSIGNED_INT = 5125;
+
+        /**
+         * The float type.
+         */
+        public static readonly FLOAT = 5126;
+
+        /**
          * Gets or sets the instance divisor when in instanced mode
          */
         public get instanceDivisor(): number {
@@ -23,31 +56,85 @@
             } else {
                 this._instanced = true;
             }
-        }        
+        }
+
+        /**
+         * Gets the byte stride.
+         */
+        public readonly byteStride: number;
+
+        /**
+         * Gets the byte offset.
+         */
+        public readonly byteOffset: number;
+
+        /**
+         * Gets whether integer data values should be normalized into a certain range when being casted to a float.
+         */
+        public readonly normalized: boolean;
 
-        constructor(engine: any, data: FloatArray | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number, instanced?: boolean, offset?: number, size?: number) {
+        /**
+         * Gets the data type of each component in the array.
+         */
+        public readonly type: number;
+
+        /**
+         * Constructor
+         * @param engine the engine
+         * @param data the data to use for this vertex buffer
+         * @param kind the vertex buffer kind
+         * @param updatable whether the data is updatable
+         * @param postponeInternalCreation whether to postpone creating the internal WebGL buffer (optional)
+         * @param stride the stride (optional)
+         * @param instanced whether the buffer is instanced (optional)
+         * @param offset the offset of the data (optional)
+         * @param size the number of components (optional)
+         * @param type the type of the component (optional)
+         * @param normalized whether the data contains normalized data (optional)
+         * @param useBytes set to true if stride and offset are in bytes (optional)
+         */
+        constructor(engine: any, data: DataArray | Buffer, kind: string, updatable: boolean, postponeInternalCreation?: boolean, stride?: number, instanced?: boolean, offset?: number, size?: number, type?: number, normalized = false, useBytes = false) {
             if (data instanceof Buffer) {
-                if (!stride) {
-                    stride = data.getStrideSize();
-                }
                 this._buffer = data;
                 this._ownsBuffer = false;
             } else {
-                if (!stride) {
-                    stride = VertexBuffer.DeduceStride(kind);
-                }
-                this._buffer = new Buffer(engine, <FloatArray>data, updatable, stride, postponeInternalCreation, instanced);
+                this._buffer = new Buffer(engine, data, updatable, stride, postponeInternalCreation, instanced, useBytes);
                 this._ownsBuffer = true;
             }
 
-            this._stride = stride;
-            this._instanced = instanced !== undefined ? instanced : false;
-            this._instanceDivisor = instanced ? 1 : 0;
+            this._kind = kind;
 
-            this._offset = offset ? offset : 0;
-            this._size = size ? size : stride;
+            if (type == undefined) {
+                const data = this.getData();
+                this.type = VertexBuffer.FLOAT;
+                if (data instanceof Int8Array) this.type = VertexBuffer.BYTE;
+                else if (data instanceof Uint8Array) this.type = VertexBuffer.UNSIGNED_BYTE;
+                else if (data instanceof Int16Array) this.type = VertexBuffer.SHORT;
+                else if (data instanceof Uint16Array) this.type = VertexBuffer.UNSIGNED_SHORT;
+                else if (data instanceof Int32Array) this.type = VertexBuffer.INT;
+                else if (data instanceof Uint32Array) this.type = VertexBuffer.UNSIGNED_INT;
+            }
+            else {
+                this.type = type;
+            }
 
-            this._kind = kind;
+            const typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
+
+            if (useBytes) {
+                this._size = size || (stride ? (stride / typeByteLength) : VertexBuffer.DeduceStride(kind));
+                this.byteStride = stride || this._buffer.byteStride || (this._size * typeByteLength);
+                this.byteOffset = offset || 0;
+            }
+            else {
+                this._size = size || stride || VertexBuffer.DeduceStride(kind);
+                this.byteStride = stride ? (stride * typeByteLength) : (this._buffer.byteStride || (this._size * typeByteLength));
+                this.byteOffset = (offset || 0) * typeByteLength;
+            }
+
+            this.normalized = normalized;
+
+            this._instanced = instanced !== undefined ? instanced : false;
+            this._instanceDivisor = instanced ? 1 : 0;
         }
 
         public _rebuild(): void {
@@ -74,9 +161,9 @@
         }
 
         /**
-         * Returns an array of numbers or a Float32Array containing the VertexBuffer data.  
+         * Returns an array of numbers or a typed array containing the VertexBuffer data.  
          */
-        public getData(): Nullable<FloatArray> {
+        public getData(): Nullable<DataArray> {
             return this._buffer.getData();
         }
 
@@ -88,21 +175,23 @@
         }
 
         /**
-         * Returns the stride of the VertexBuffer (integer).  
+         * Returns the stride as a multiple of the type byte length.
+         * DEPRECATED. Use byteStride instead.
          */
         public getStrideSize(): number {
-            return this._stride;
+            return this.byteStride / VertexBuffer.GetTypeByteLength(this.type);
         }
 
         /**
-         * Returns the offset (integer).  
+         * Returns the offset as a multiple of the type byte length.
+         * DEPRECATED. Use byteOffset instead.
          */
         public getOffset(): number {
-            return this._offset;
+            return this.byteOffset / VertexBuffer.GetTypeByteLength(this.type);
         }
 
         /**
-         * Returns the VertexBuffer total size (integer).  
+         * Returns the number of components per vertex attribute (integer).  
          */
         public getSize(): number {
             return this._size;
@@ -128,7 +217,7 @@
          * Creates the underlying WebGLBuffer from the passed numeric array or Float32Array.  
          * Returns the created WebGLBuffer.   
          */
-        public create(data?: FloatArray): void {
+        public create(data?: DataArray): void {
             return this._buffer.create(data);
         }
 
@@ -137,7 +226,7 @@
          * This function will create a new buffer if the current one is not updatable
          * Returns the updated WebGLBuffer.  
          */
-        public update(data: FloatArray): void {
+        public update(data: DataArray): void {
             return this._buffer.update(data);
         }
 
@@ -145,7 +234,7 @@
          * Updates directly the underlying WebGLBuffer according to the passed numeric array or Float32Array.  
          * Returns the directly updated WebGLBuffer. 
          */
-        public updateDirectly(data: Float32Array, offset: number): void {
+        public updateDirectly(data: DataArray, offset: number): void {
             return this._buffer.updateDirectly(data, offset);
         }
 
@@ -158,6 +247,15 @@
             }
         }
 
+        /**
+         * Enumerates each value of this vertex buffer as numbers.
+         * @param count the number of values to enumerate
+         * @param callback the callback function called for each value
+         */
+        public forEach(count: number, callback: (value: number, index: number) => void): void {
+            VertexBuffer.ForEach(this._buffer.getData()!, this.byteOffset, this.byteStride, this._size, this.type, count, this.normalized, callback);
+        }
+
         // Enums
         private static _PositionKind = "position";
         private static _NormalKind = "normal";
@@ -258,5 +356,102 @@
                     throw new Error("Invalid kind '" + kind + "'");
             }
         }
+
+        /**
+         * Gets the byte length of the given type.
+         * @param type the type
+         * @returns the number of bytes
+         */
+        public static GetTypeByteLength(type: number): number {
+            switch (type) {
+                case VertexBuffer.BYTE:
+                case VertexBuffer.UNSIGNED_BYTE:
+                    return 1;
+                case VertexBuffer.SHORT:
+                case VertexBuffer.UNSIGNED_SHORT:
+                    return 2;
+                case VertexBuffer.INT:
+                case VertexBuffer.FLOAT:
+                    return 4;
+                default:
+                    throw new Error(`Invalid type '${type}'`);
+            }
+        }
+
+        /**
+         * Enumerates each value of the given parameters as numbers.
+         * @param data the data to enumerate
+         * @param byteOffset the byte offset of the data
+         * @param byteStride the byte stride of the data
+         * @param componentCount the number of components per element
+         * @param componentType the type of the component
+         * @param count the total number of components
+         * @param normalized whether the data is normalized
+         * @param callback the callback function called for each value
+         */
+        public static ForEach(data: DataArray, byteOffset: number, byteStride: number, componentCount: number, componentType: number, count: number, normalized: boolean, callback: (value: number, index: number) => void): void {
+            if (data instanceof Array) {
+                let offset = byteOffset / 4;
+                const stride = byteStride / 4;
+                for (let index = 0; index < count; index += componentCount) {
+                    for (let componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        callback(data[offset + componentIndex], index + componentIndex);
+                    }
+                    offset += stride;
+                }
+            }
+            else {
+                const dataView = data instanceof ArrayBuffer ? new DataView(data) : new DataView(data.buffer, data.byteOffset, data.byteLength);
+                const componentByteLength = VertexBuffer.GetTypeByteLength(componentType);
+                for (let index = 0; index < count; index += componentCount) {
+                    let componentByteOffset = byteOffset;
+                    for (let componentIndex = 0; componentIndex < componentCount; componentIndex++) {
+                        const value = VertexBuffer._GetFloatValue(dataView, componentType, componentByteOffset, normalized);
+                        callback(value, index + componentIndex);
+                        componentByteOffset += componentByteLength;
+                    }
+                    byteOffset += byteStride;
+                }
+            }
+        }
+
+        private static _GetFloatValue(dataView: DataView, type: number, byteOffset: number, normalized: boolean): number {
+            switch (type) {
+                case VertexBuffer.BYTE: {
+                    let value = dataView.getInt8(byteOffset);
+                    if (normalized) {
+                        value = (value + 0.5) / 127.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_BYTE: {
+                    let value = dataView.getUint8(byteOffset);
+                    if (normalized) {
+                        value = value / 255;
+                    }
+                    return value;
+                }
+                case VertexBuffer.SHORT: {
+                    let value = dataView.getInt16(byteOffset, true);
+                    if (normalized) {
+                        value = (value + 0.5) / 16383.5;
+                    }
+                    return value;
+                }
+                case VertexBuffer.UNSIGNED_SHORT: {
+                    let value = dataView.getUint16(byteOffset, true);
+                    if (normalized) {
+                        value = value / 65535;
+                    }
+                    return value;
+                }
+                case VertexBuffer.FLOAT: {
+                    return dataView.getFloat32(byteOffset, true);
+                }
+                default: {
+                    throw new Error(`Invalid component type ${type}`);
+                }
+            }
+        }
     }
-} 
+}

+ 189 - 178
src/PostProcess/babylon.blurPostProcess.ts

@@ -1,80 +1,84 @@
 module BABYLON {
-	/**
-	 * The Blur Post Process which blurs an image based on a kernel and direction. 
-	 * Can be used twice in x and y directions to perform a guassian blur in two passes.
+    /**
+     * The Blur Post Process which blurs an image based on a kernel and direction. 
+     * Can be used twice in x and y directions to perform a guassian blur in two passes.
      */
     export class BlurPostProcess extends PostProcess {
-		protected _kernel: number;
-		protected _idealKernel: number;
-		protected _packedFloat: boolean	= false;
-		private _staticDefines:string = ""
-		/**
-		 * Sets the length in pixels of the blur sample region
-		 */
-		public set kernel(v: number) {
-			if (this._idealKernel === v) {
-				return;
-			}
-
-			v = Math.max(v, 1);
-			this._idealKernel = v;
-			this._kernel = this._nearestBestKernel(v);
-			if(!this.blockCompilation){
-				this._updateParameters();
-			}
-		}
-
-		/**
-		 * Gets the length in pixels of the blur sample region
-		 */
-		public get kernel(): number {
-			return this._idealKernel;
-		}
-
-		/**
-		 * Sets wether or not the blur needs to unpack/repack floats
-		 */
-		public set packedFloat(v: boolean) {
-			if (this._packedFloat === v) {
-				return;
-			}
-			this._packedFloat = v;
+        protected _kernel: number;
+        protected _idealKernel: number;
+        protected _packedFloat: boolean	= false;
+        private _staticDefines:string = ""
+        /**
+         * Sets the length in pixels of the blur sample region
+         */
+        public set kernel(v: number) {
+            if (this._idealKernel === v) {
+                return;
+            }
+
+            v = Math.max(v, 1);
+            this._idealKernel = v;
+            this._kernel = this._nearestBestKernel(v);
+            if(!this.blockCompilation){
+                this._updateParameters();
+            }
+        }
+
+        /**
+         * Gets the length in pixels of the blur sample region
+         */
+        public get kernel(): number {
+            return this._idealKernel;
+        }
+
+        /**
+         * Sets wether or not the blur needs to unpack/repack floats
+         */
+        public set packedFloat(v: boolean) {
+            if (this._packedFloat === v) {
+                return;
+            }
+            this._packedFloat = v;
             if(!this.blockCompilation){
-				this._updateParameters();
-			}
-		}
-
-		/**
-		 * Gets wether or not the blur is unpacking/repacking floats
-		 */
-		public get packedFloat(): boolean {
-			return this._packedFloat;
-		}
-
-		/**
+                this._updateParameters();
+            }
+        }
+
+        /**
+         * Gets wether or not the blur is unpacking/repacking floats
+         */
+        public get packedFloat(): boolean {
+            return this._packedFloat;
+        }
+
+        /**
          * Creates a new instance BlurPostProcess
          * @param name The name of the effect.
          * @param direction The direction in which to blur the image.
-		 * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
          * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
          * @param camera The camera to apply the render pass to.
          * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
          * @param engine The engine which the post process will be applied. (default: current engine)
          * @param reusable If the post process can be reused on the same frame. (default: false)
          * @param textureType Type of textures used when performing the post process. (default: 0)
-		 * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
+         * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
         constructor(name: string, /** The direction in which to blur the image. */ public direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, defines = "", private blockCompilation = false) {
-			super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
-			this._staticDefines = defines;
-			this.onApplyObservable.add((effect: Effect) => {
-				effect.setFloat2('delta', (1 / this.width) * this.direction.x, (1 / this.height) * this.direction.y);
-			});
+            super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
+            this._staticDefines = defines;
+            this.onApplyObservable.add((effect: Effect) => {
+                if(this._outputTexture){
+                    effect.setFloat2('delta', (1 / this._outputTexture.width) * this.direction.x, (1 / this._outputTexture.height) * this.direction.y);
+                }else{
+                    effect.setFloat2('delta', (1 / this.width) * this.direction.x, (1 / this.height) * this.direction.y);
+                }
+            });
 
             this.kernel = kernel;
         }
 
-		/**
+        /**
          * Updates the effect with the current post process compile time values and recompiles the shader.
          * @param defines Define statements that should be added at the beginning of the shader. (default: null)
          * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
@@ -90,144 +94,151 @@
 
         protected _updateParameters(onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): void {
             // Generate sampling offsets and weights
-			let N = this._kernel;
-			let centerIndex = (N - 1) / 2;
-
-			// Generate Gaussian sampling weights over kernel
-			let offsets = [];
-			let weights = [];
-			let totalWeight = 0;
-			for (let i = 0; i < N; i++) {
-				let u = i / (N - 1);
-				let w = this._gaussianWeight(u * 2.0 - 1);
-				offsets[i] = (i - centerIndex);
-				weights[i] = w;
-				totalWeight += w;
-			}
-
-			// Normalize weights
-			for (let i = 0; i < weights.length; i++) {
-				weights[i] /= totalWeight;
-			}
-
-			// Optimize: combine samples to take advantage of hardware linear sampling
-			// Walk from left to center, combining pairs (symmetrically)
-			let linearSamplingWeights = [];
-			let linearSamplingOffsets = [];
-
-			let linearSamplingMap = [];
-
-			for (let i = 0; i <= centerIndex; i += 2) {
-				let j = Math.min(i + 1, Math.floor(centerIndex));
-
-				let singleCenterSample = i === j;
-
-				if (singleCenterSample) {
-					linearSamplingMap.push({ o: offsets[i], w: weights[i] });
-				} else {
-					let sharedCell = j === centerIndex;
-
-					let weightLinear = (weights[i] + weights[j] * (sharedCell ? .5 : 1.));
-					let offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);
-
-					if (offsetLinear === 0) {
-						linearSamplingMap.push({ o: offsets[i], w: weights[i] });
-						linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });
-					} else {
-						linearSamplingMap.push({ o: offsetLinear, w: weightLinear });
-						linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });
-					}
-
-				}
-			}
-
-			for (let i = 0; i < linearSamplingMap.length; i++) {
-				linearSamplingOffsets[i] = linearSamplingMap[i].o;
-				linearSamplingWeights[i] = linearSamplingMap[i].w;
-			}
-
-			// Replace with optimized
-			offsets = linearSamplingOffsets;
-			weights = linearSamplingWeights;
-
-			// Generate shaders
-			let maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
-			let freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
+            let N = this._kernel;
+            let centerIndex = (N - 1) / 2;
+
+            // Generate Gaussian sampling weights over kernel
+            let offsets = [];
+            let weights = [];
+            let totalWeight = 0;
+            for (let i = 0; i < N; i++) {
+                let u = i / (N - 1);
+                let w = this._gaussianWeight(u * 2.0 - 1);
+                offsets[i] = (i - centerIndex);
+                weights[i] = w;
+                totalWeight += w;
+            }
+
+            // Normalize weights
+            for (let i = 0; i < weights.length; i++) {
+                weights[i] /= totalWeight;
+            }
+
+            // Optimize: combine samples to take advantage of hardware linear sampling
+            // Walk from left to center, combining pairs (symmetrically)
+            let linearSamplingWeights = [];
+            let linearSamplingOffsets = [];
+
+            let linearSamplingMap = [];
+
+            for (let i = 0; i <= centerIndex; i += 2) {
+                let j = Math.min(i + 1, Math.floor(centerIndex));
+
+                let singleCenterSample = i === j;
+
+                if (singleCenterSample) {
+                    linearSamplingMap.push({ o: offsets[i], w: weights[i] });
+                } else {
+                    let sharedCell = j === centerIndex;
+
+                    let weightLinear = (weights[i] + weights[j] * (sharedCell ? .5 : 1.));
+                    let offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);
+
+                    if (offsetLinear === 0) {
+                        linearSamplingMap.push({ o: offsets[i], w: weights[i] });
+                        linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });
+                    } else {
+                        linearSamplingMap.push({ o: offsetLinear, w: weightLinear });
+                        linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });
+                    }
+
+                }
+            }
+
+            for (let i = 0; i < linearSamplingMap.length; i++) {
+                linearSamplingOffsets[i] = linearSamplingMap[i].o;
+                linearSamplingWeights[i] = linearSamplingMap[i].w;
+            }
+
+            // Replace with optimized
+            offsets = linearSamplingOffsets;
+            weights = linearSamplingWeights;
+
+            // Generate shaders
+            let maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
+            let freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
 
             let varyingCount = Math.min(offsets.length, freeVaryingVec2);
-        
-			let defines = "";
-			defines+=this._staticDefines;
+
+            let defines = "";
+            defines+=this._staticDefines;
+
+            // The DOF fragment should ignore the center pixel when looping as it is handled manualy in the fragment shader.
+            if(this._staticDefines.indexOf("DOF") != -1){
+                defines += `#define CENTER_WEIGHT ${this._glslFloat(weights[varyingCount-1])}\r\n`;
+                varyingCount--;
+            }
+            
             for (let i = 0; i < varyingCount; i++) {
                 defines += `#define KERNEL_OFFSET${i} ${this._glslFloat(offsets[i])}\r\n`;
                 defines += `#define KERNEL_WEIGHT${i} ${this._glslFloat(weights[i])}\r\n`;
-			}
+            }
 
             let depCount = 0;
             for (let i = freeVaryingVec2; i < offsets.length; i++) {
                 defines += `#define KERNEL_DEP_OFFSET${depCount} ${this._glslFloat(offsets[i])}\r\n`;
                 defines += `#define KERNEL_DEP_WEIGHT${depCount} ${this._glslFloat(weights[i])}\r\n`;
                 depCount++;
-			}
+            }
 
-			if (this.packedFloat) {
-				defines += `#define PACKEDFLOAT 1`;
-			}
+            if (this.packedFloat) {
+                defines += `#define PACKEDFLOAT 1`;
+            }
 
-			this.blockCompilation = false;
+            this.blockCompilation = false;
             super.updateEffect(defines, null, null, {
-				varyingCount: varyingCount,
-				depCount: depCount
-			}, onCompiled, onError);
+                varyingCount: varyingCount,
+                depCount: depCount
+            }, onCompiled, onError);
         }
 
         /**
-		 * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.
-		 * Other odd kernels optimize correctly but require proportionally more samples, even kernels are
-		 * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we
-		 * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.
-		 * The gaps between physical kernels are compensated for in the weighting of the samples
-		 * @param idealKernel Ideal blur kernel.
-		 * @return Nearest best kernel.
-		 */
-		protected _nearestBestKernel(idealKernel: number): number {
-			let v = Math.round(idealKernel);
-			for (let k of [v, v - 1, v + 1, v - 2, v + 2]) {
-				if (((k % 2) !== 0) && ((Math.floor(k / 2) % 2) === 0) && k > 0) {
-					return Math.max(k, 3);
-				}
-			}
-			return Math.max(v, 3);
-		}
-
-		/**
-		 * Calculates the value of a Gaussian distribution with sigma 3 at a given point.
-		 * @param x The point on the Gaussian distribution to sample.
-		 * @return the value of the Gaussian function at x.
-		 */
-		protected _gaussianWeight(x: number): number {
-			//reference: Engine/ImageProcessingBlur.cpp #dcc760
-			// We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],
-			// so we truncate at three standard deviations by setting stddev (sigma) to 1/3.
-			// The choice of 3-sigma truncation is common but arbitrary, and means that the signal is
-			// truncated at around 1.3% of peak strength.
-
-			//the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size
-			let sigma = (1 / 3);
-			let denominator = Math.sqrt(2.0 * Math.PI) * sigma;
-			let exponent = -((x * x) / (2.0 * sigma * sigma));
-			let weight = (1.0 / denominator) * Math.exp(exponent);
-			return weight;
-		}      
+         * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.
+         * Other odd kernels optimize correctly but require proportionally more samples, even kernels are
+         * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we
+         * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.
+         * The gaps between physical kernels are compensated for in the weighting of the samples
+         * @param idealKernel Ideal blur kernel.
+         * @return Nearest best kernel.
+         */
+        protected _nearestBestKernel(idealKernel: number): number {
+            let v = Math.round(idealKernel);
+            for (let k of [v, v - 1, v + 1, v - 2, v + 2]) {
+                if (((k % 2) !== 0) && ((Math.floor(k / 2) % 2) === 0) && k > 0) {
+                    return Math.max(k, 3);
+                }
+            }
+            return Math.max(v, 3);
+        }
+
+        /**
+         * Calculates the value of a Gaussian distribution with sigma 3 at a given point.
+         * @param x The point on the Gaussian distribution to sample.
+         * @return the value of the Gaussian function at x.
+         */
+        protected _gaussianWeight(x: number): number {
+            //reference: Engine/ImageProcessingBlur.cpp #dcc760
+            // We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],
+            // so we truncate at three standard deviations by setting stddev (sigma) to 1/3.
+            // The choice of 3-sigma truncation is common but arbitrary, and means that the signal is
+            // truncated at around 1.3% of peak strength.
+
+            //the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size
+            let sigma = (1 / 3);
+            let denominator = Math.sqrt(2.0 * Math.PI) * sigma;
+            let exponent = -((x * x) / (2.0 * sigma * sigma));
+            let weight = (1.0 / denominator) * Math.exp(exponent);
+            return weight;
+        }      
 
        /**
-		 * Generates a string that can be used as a floating point number in GLSL.
-		 * @param x Value to print.
-		 * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).
-		 * @return GLSL float string.
-		 */
-		protected _glslFloat(x: number, decimalFigures = 8) {
-			return x.toFixed(decimalFigures).replace(/0+$/, '');
-		}      
+         * Generates a string that can be used as a floating point number in GLSL.
+         * @param x Value to print.
+         * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).
+         * @return GLSL float string.
+         */
+        protected _glslFloat(x: number, decimalFigures = 8) {
+            return x.toFixed(decimalFigures).replace(/0+$/, '');
+        }      
     }
 } 

+ 5 - 3
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -109,10 +109,12 @@ module BABYLON {
                 }
             }
             var adjustedKernelSize = kernelSize/Math.pow(2, blurCount-1);
+            var ratio = 1.0;
             for(var i = 0;i<blurCount;i++){
-                var blurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), adjustedKernelSize, 1.0/Math.pow(2, i), null, this._circleOfConfusion, i == 0 ? this._circleOfConfusion : null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                var blurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), adjustedKernelSize, ratio, null, this._circleOfConfusion, i == 0 ? this._circleOfConfusion : null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
                 blurY.autoClear = false;
-                var blurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), adjustedKernelSize, 1.0/Math.pow(2, i), null,  this._circleOfConfusion, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                ratio = 0.75/Math.pow(2, i);
+                var blurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), adjustedKernelSize, ratio, null,  this._circleOfConfusion, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
                 blurX.autoClear = false;
                 this._depthOfFieldBlurY.push(blurY);
                 this._depthOfFieldBlurX.push(blurX);
@@ -126,7 +128,7 @@ module BABYLON {
             }
 
             // Merge blurred images with original image based on circleOfConfusion
-            this._dofMerge = new DepthOfFieldMergePostProcess("dofMerge", this._circleOfConfusion, this._circleOfConfusion, this._depthOfFieldBlurX, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+            this._dofMerge = new DepthOfFieldMergePostProcess("dofMerge", this._circleOfConfusion, this._circleOfConfusion, this._depthOfFieldBlurX, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
             this._dofMerge.autoClear = false;
             this._effects.push(this._dofMerge);
         }

+ 2 - 2
src/PostProcess/babylon.depthOfFieldMergePostProcess.ts

@@ -42,13 +42,13 @@ module BABYLON {
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
         constructor(name: string, originalFromInput:PostProcess, circleOfConfusion:PostProcess, private blurSteps:Array<PostProcess>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
-            super(name, "depthOfFieldMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
+            super(name, "depthOfFieldMerge", [], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
             this.onApplyObservable.add((effect: Effect) => {
                 effect.setTextureFromPostProcess("textureSampler", originalFromInput);
                 effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", circleOfConfusion);
                 blurSteps.forEach((step,index)=>{
                     effect.setTextureFromPostProcessOutput("blurStep"+(blurSteps.length-index-1), step);
-                });    
+                });  
             });
 
             if(!blockCompilation){

+ 2 - 0
src/PostProcess/babylon.postProcessManager.ts

@@ -154,8 +154,10 @@
                 } else {
                     if (targetTexture) {
                         engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport);
+                        pp._outputTexture = targetTexture;
                     } else {
                         engine.restoreDefaultFramebuffer();
+                        pp._outputTexture = null;
                     }
                 }
 

+ 1 - 2
src/Shaders/ShadersInclude/kernelBlurFragment.fx

@@ -1,6 +1,5 @@
 #ifdef DOF
-    sampleDepth = sampleDistance(sampleCoord{X});
-    factor = clamp(1.0-((centerSampleDepth - sampleDepth)/centerSampleDepth),0.0,1.0);
+    factor = sampleCoC(sampleCoord{X});    
     computedWeight = KERNEL_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 1 - 2
src/Shaders/ShadersInclude/kernelBlurFragment2.fx

@@ -1,6 +1,5 @@
 #ifdef DOF
-    sampleDepth = sampleDistance(sampleCoord{X});
-    factor = clamp(1.0-((centerSampleDepth - sampleDepth)/centerSampleDepth),0.0,1.0);
+    factor = sampleCoC(sampleCenter + delta * KERNEL_DEP_OFFSET{X});
     computedWeight = KERNEL_DEP_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 3 - 7
src/Shaders/circleOfConfusion.fragment.fx

@@ -11,15 +11,11 @@ uniform vec2 cameraMinMaxZ;
 uniform float focusDistance;
 uniform float cocPrecalculation;
 
-float sampleDistance(const in vec2 offset) {
-    float depth = texture2D(depthSampler, offset).r;	// depth value from DepthRenderer: 0 to 1
-	return (cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth)*1000.0;		            // actual distance from the lens in scene units/1000 (eg. millimeter)
-}
-
 void main(void)
 {
-    float pixelDistance = sampleDistance(vUV);
+    float depth = texture2D(depthSampler, vUV).r;
+    float pixelDistance = (cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth)*1000.0;	// actual distance from the lens in scene units/1000 (eg. millimeter)
     float coc = abs(cocPrecalculation* ((focusDistance - pixelDistance)/pixelDistance));
     coc = clamp(coc, 0.0, 1.0);
-    gl_FragColor = vec4(coc, texture2D(depthSampler, vUV).r, coc, 1.0);
+    gl_FragColor = vec4(coc, depth, coc, 1.0);
 }

+ 11 - 8
src/Shaders/depthOfFieldMerge.fragment.fx

@@ -13,32 +13,35 @@ uniform sampler2D blurStep2;
 
 void main(void)
 {
-    gl_FragColor = texture2D(textureSampler, vUV);
-
     float coc = texture2D(circleOfConfusionSampler, vUV).r;
-    vec4 original = texture2D(textureSampler, vUV);
 #if BLUR_LEVEL == 0
+    vec4 original = texture2D(textureSampler, vUV);
     vec4 blurred0 = texture2D(blurStep0, vUV);
     gl_FragColor = mix(original, blurred0, coc);
 #endif
 #if BLUR_LEVEL == 1
-    vec4 blurred0 = texture2D(blurStep0, vUV);   
-    vec4 blurred1 = texture2D(blurStep1, vUV);
     if(coc < 0.5){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(original, blurred1, coc/0.5);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);   
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.5)/0.5);
     }
 #endif
 #if BLUR_LEVEL == 2
-    vec4 blurred0 = texture2D(blurStep0, vUV);
-    vec4 blurred1 = texture2D(blurStep1, vUV);
-    vec4 blurred2 = texture2D(blurStep2, vUV);
     if(coc < 0.33){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(original, blurred2, coc/0.33);
     }else if(coc < 0.66){
+        vec4 blurred1 = texture2D(blurStep1, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(blurred2, blurred1, (coc-0.33)/0.33);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.66)/0.34);
     }
 #endif

+ 0 - 0
src/Shaders/kernelBlur.fragment.fx


Някои файлове не бяха показани, защото твърде много файлове са промени