浏览代码

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

# Conflicts:
#	src/Materials/Background/babylon.backgroundMaterial.ts
David 7 年之前
父节点
当前提交
a67e96fe41
共有 100 个文件被更改,包括 41392 次插入143597 次删除
  1. 8241 6707
      Playground/babylon.d.txt
  2. 80 5
      Tools/Gulp/config.json
  3. 51 15
      Tools/Gulp/gulpfile.js
  4. 3 3
      Tools/Publisher/index.js
  5. 48 0
      Viewer/dist/loadModelManually.html
  6. 69 112077
      Viewer/dist/viewer.js
  7. 69 1
      Viewer/dist/viewer.min.js
  8. 1 8
      Viewer/package.json
  9. 68 9
      Viewer/src/configuration/configuration.ts
  10. 20 14
      Viewer/src/configuration/loader.ts
  11. 10 14
      Viewer/src/configuration/types/default.ts
  12. 3 1
      Viewer/src/index.ts
  13. 69 17
      Viewer/src/templateManager.ts
  14. 0 39
      Viewer/src/util/promiseObservable.ts
  15. 61 21
      Viewer/src/viewer/defaultViewer.ts
  16. 322 36
      Viewer/src/viewer/viewer.ts
  17. 21 9
      Viewer/tsconfig.json
  18. 13 9
      Viewer/webpack.config.js
  19. 1 1
      Viewer/webpack.gulp.config.js
  20. 20 23
      dist/babylon.glTFInterface.d.ts
  21. 12790 11271
      dist/preview release/babylon.d.ts
  22. 51 51
      dist/preview release/babylon.js
  23. 2341 585
      dist/preview release/babylon.max.js
  24. 52 52
      dist/preview release/babylon.worker.js
  25. 7294 5770
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  26. 55 55
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  27. 2430 601
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  28. 2432 603
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  29. 2343 587
      dist/preview release/es6.js
  30. 1 1
      dist/preview release/gui/package.json
  31. 1 1
      dist/preview release/inspector/package.json
  32. 15 0
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  33. 134 0
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  34. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  35. 15 0
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  36. 134 0
      dist/preview release/loaders/babylon.glTFFileLoader.js
  37. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  38. 125 0
      dist/preview release/loaders/babylonjs.loaders.js
  39. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  40. 15 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  41. 1 1
      dist/preview release/loaders/package.json
  42. 2 2
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  43. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.min.js
  44. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  45. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  46. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  47. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  48. 2 2
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  49. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  50. 2 2
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  51. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  52. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  53. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  54. 2 2
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  55. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  56. 2 2
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  57. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  58. 2 2
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  59. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  60. 2 2
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  61. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  62. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.js
  63. 1 1
      dist/preview release/materialsLibrary/babylon.skyMaterial.min.js
  64. 2 2
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  65. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  66. 2 2
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  67. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  68. 2 2
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  69. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  70. 25 25
      dist/preview release/materialsLibrary/babylonjs.materials.js
  71. 6 6
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  72. 1 1
      dist/preview release/materialsLibrary/package.json
  73. 1 1
      dist/preview release/postProcessesLibrary/package.json
  74. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  75. 57 49
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  76. 384 302
      dist/preview release/serializers/babylon.glTF2Serializer.js
  77. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  78. 381 299
      dist/preview release/serializers/babylonjs.serializers.js
  79. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  80. 57 49
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  81. 1 1
      dist/preview release/serializers/package.json
  82. 787 4139
      dist/preview release/typedocValidationBaseline.json
  83. 64 64
      dist/preview release/viewer/babylon.viewer.js
  84. 1 1
      dist/preview release/viewer/package.json
  85. 23 4
      dist/preview release/what's new.md
  86. 119 0
      loaders/src/glTF/2.0/Extensions/KHR_lights.ts
  87. 5 0
      loaders/src/glTF/2.0/babylon.glTFLoader.ts
  88. 12 0
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  89. 2 2
      materialsLibrary/src/cell/babylon.cellMaterial.ts
  90. 2 2
      materialsLibrary/src/custom/babylon.customMaterial.ts
  91. 1 1
      materialsLibrary/src/fire/babylon.fireMaterial.ts
  92. 2 2
      materialsLibrary/src/fur/babylon.furMaterial.ts
  93. 2 2
      materialsLibrary/src/gradient/babylon.gradientMaterial.ts
  94. 1 1
      materialsLibrary/src/grid/babylon.gridmaterial.ts
  95. 2 2
      materialsLibrary/src/lava/babylon.lavaMaterial.ts
  96. 2 2
      materialsLibrary/src/normal/babylon.normalMaterial.ts
  97. 2 2
      materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts
  98. 2 2
      materialsLibrary/src/simple/babylon.simpleMaterial.ts
  99. 1 1
      materialsLibrary/src/sky/babylon.skyMaterial.ts
  100. 0 0
      materialsLibrary/src/terrain/babylon.terrainMaterial.ts

文件差异内容过多而无法显示
+ 8241 - 6707
Playground/babylon.d.txt


+ 80 - 5
Tools/Gulp/config.json

@@ -57,7 +57,11 @@
             "geometryBufferRenderer",
             "additionalPostProcesses",
             "additionalPostProcess_blur",
+            "additionalPostProcess_depthOfFieldBlur",
             "additionalPostProcess_fxaa",
+            "additionalPostProcess_circleOfConfusion",
+            "additionalPostProcess_depthOfFieldMerge",
+            "additionalPostProcess_depthOfFieldEffect",
             "additionalPostProcess_imageProcessing",
             "bones",
             "hdr",
@@ -723,6 +727,51 @@
                 "kernelBlurVertex"
             ]
         },
+        "additionalPostProcess_depthOfFieldBlur": {
+            "files": [
+                "../../src/PostProcess/babylon.depthOfFieldBlurPostProcess.js"
+            ],
+            "dependUpon": [
+                "postProcesses"
+            ],
+            "shaders": [
+                "kernelBlur.vertex",
+                "kernelBlur.fragment"
+            ],
+            "shaderIncludes": [
+                "kernelBlurFragment",
+                "kernelBlurFragment2",
+                "kernelBlurVaryingDeclaration",
+                "kernelBlurVertex"
+            ]
+        },
+        "additionalPostProcess_circleOfConfusion": {
+            "files": [
+                "../../src/PostProcess/babylon.circleOfConfusionPostProcess.js"
+            ],
+            "dependUpon": [
+                "postProcesses"
+            ],
+            "shaders": [
+                "circleOfConfusion.fragment"
+            ]
+        },
+        "additionalPostProcess_depthOfFieldMerge": {
+            "files": [
+                "../../src/PostProcess/babylon.depthOfFieldMergePostProcess.js"
+            ],
+            "dependUpon": [
+                "postProcesses"
+            ],
+            "shaders": [
+                "depthOfFieldMerge.fragment"
+            ]
+        },
+        "additionalPostProcess_depthOfFieldEffect": {
+            "files": [
+                "../../src/PostProcess/babylon.depthOfFieldEffect.js"
+            ]
+        },
         "additionalPostProcess_fxaa": {
             "files": [
                 "../../src/PostProcess/babylon.fxaaPostProcess.js"
@@ -793,7 +842,6 @@
         "renderingPipeline": {
             "files": [
                 "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipelineManager.js",
-                "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPass.js",
                 "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.js",
                 "../../src/PostProcess/RenderPipeline/babylon.postProcessRenderPipeline.js"
             ],
@@ -828,7 +876,10 @@
             ],
             "dependUpon": [
                 "renderingPipeline",
-                "additionalPostProcess_fxaa"
+                "additionalPostProcess_fxaa",
+                "additionalPostProcess_circleOfConfusion",
+                "additionalPostProcess_depthOfFieldMerge",
+                "additionalPostProcess_depthOfFieldEffect"
             ]
         },
         "bones": {
@@ -1425,7 +1476,8 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "doNotIncludeInBundle": true,
                 "output": "babylon.glTF2FileLoader.js"
@@ -1444,7 +1496,8 @@
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderUtils.ts",
                     "../../loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts",
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
-                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts"
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "output": "babylon.glTFFileLoader.js"
             }
@@ -1611,7 +1664,29 @@
         ],
         "build": {
             "srcOutputDirectory": "../../Viewer/",
-            "distOutputDirectory": "/viewer/"
+            "outputs": [
+                {
+                    "destination": [
+                        {
+                            "filename": "viewer.min.js",
+                            "outputDirectory": "/../../Viewer/dist/"
+                        },
+                        {
+                            "filename": "babylon.viewer.js",
+                            "outputDirectory": "/viewer/"
+                        }
+                    ],
+                    "minified": true
+                },
+                {
+                    "destination": [
+                        {
+                            "filename": "viewer.js",
+                            "outputDirectory": "/../../Viewer/dist/"
+                        }
+                    ]
+                }
+            ]
         }
     }
 }

+ 51 - 15
Tools/Gulp/gulpfile.js

@@ -60,7 +60,12 @@ var tsConfig = {
     noUnusedLocals: true,
     strictNullChecks: true,
     strictFunctionTypes: true,
-    types: []
+    types: [],
+    lib: [
+        "dom",
+        "es2015.promise",
+        "es5"
+    ]
 };
 var tsProject = typescript.createProject(tsConfig);
 
@@ -76,7 +81,12 @@ var externalTsConfig = {
     noImplicitThis: true,
     noUnusedLocals: true,
     strictNullChecks: true,
-    types: []
+    types: [],
+    lib: [
+        "dom",
+        "es2015.promise",
+        "es5"
+    ]
 };
 
 var minimist = require("minimist");
@@ -416,14 +426,40 @@ var buildExternalLibrary = function (library, settings, watch) {
         }
 
         if (library.webpack) {
-            return waitAll.on("end", function () {
-                return webpack(require(library.webpack))
-                    .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
-                    .pipe(addModuleExports(library.moduleDeclaration, false, false, true))
-                    .pipe(uglify())
-                    .pipe(optimisejs())
-                    .pipe(gulp.dest(outputDirectory))
-            });
+            let sequence = [waitAll];
+            let wpBuild = webpack(require(library.webpack));
+            if (settings.build.outputs) {
+                let build = wpBuild
+                    .pipe(addModuleExports(library.moduleDeclaration, false, false, true));
+
+                settings.build.outputs.forEach(out => {
+                    let outBuild = build;
+                    if (out.minified) {
+                        outBuild = build
+                            .pipe(uglify())
+                            .pipe(optimisejs())
+                    }
+
+                    out.destination.forEach(dest => {
+                        var outputDirectory = config.build.outputDirectory + dest.outputDirectory;
+                        let destBuild = outBuild
+                            .pipe(rename(dest.filename.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
+                            .pipe(gulp.dest(outputDirectory));
+                        sequence.push(destBuild);
+                    });
+                })
+            } else {
+                sequence.push(
+                    wpBuild
+                        .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
+                        .pipe(addModuleExports(library.moduleDeclaration, false, false, true))
+                        .pipe(uglify())
+                        .pipe(optimisejs())
+                        .pipe(gulp.dest(outputDirectory))
+                )
+            }
+
+            return merge2(sequence);
         }
         else {
             return waitAll;
@@ -901,14 +937,14 @@ gulp.task("tests-unit-transpile", function (done) {
 
     var tsResult = gulp.src("../../tests/unit/**/*.ts", { base: "../../" })
         .pipe(tsProject());
-    
+
     tsResult.once("error", function () {
         tsResult.once("finish", function () {
             console.log("Typescript compile failed");
             process.exit(1);
         });
     });
- 
+
     return tsResult.js.pipe(gulp.dest("../../"));
 });
 
@@ -941,7 +977,7 @@ gulp.task("tests-unit", ["tests-unit-transpile"], function (done) {
     server.start();
 });
 
-gulp.task("tests-whatsnew", function(done) {
+gulp.task("tests-whatsnew", function (done) {
     // Only checks on Travis
     if (!process.env.TRAVIS) {
         done();
@@ -970,12 +1006,12 @@ gulp.task("tests-whatsnew", function(done) {
             oldData += data;
         });
         res.on("end", () => {
-            fs.readFile("../../dist/preview release/what's new.md", "utf-8", function(err, newData) {
+            fs.readFile("../../dist/preview release/what's new.md", "utf-8", function (err, newData) {
                 if (err || oldData != newData) {
                     done();
                     return;
                 }
-                
+
                 console.error("What's new file did not change.");
                 process.exit(1);
             });

+ 3 - 3
Tools/Publisher/index.js

@@ -55,6 +55,7 @@ function updateEngineVersion(newVersion) {
 
 function runGulp() {
     // run gulp typescript-all
+    console.log("Running gulp compilation");
     let exec = shelljs.exec("gulp typescript-all --gulpfile ../Gulp/gulpfile.js");
     if (exec.code) {
         console.log("error during compilation, aborting");
@@ -62,7 +63,7 @@ function runGulp() {
     }
 }
 
-function processPackages() {
+function processPackages(version) {
     packages.forEach((package) => {
         if (package.name === "core") {
             processCore(package, version);
@@ -82,7 +83,6 @@ function processPackages() {
 //check if logged in
 console.log("Using npm user:");
 let loginCheck = shelljs.exec('npm whoami');
-console.log("Not that I can check, but - did you run gulp typescript-all?");
 if (loginCheck.code === 0) {
     prompt.start();
 
@@ -90,7 +90,7 @@ if (loginCheck.code === 0) {
         let version = result.version;
         updateEngineVersion(version);
         runGulp();
-        processPackages();
+        processPackages(version);
 
         console.log("done, please tag git with " + version);
     });

+ 48 - 0
Viewer/dist/loadModelManually.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+
+    <head>
+        <meta charset="UTF-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1.0">
+        <meta http-equiv="X-UA-Compatible" content="ie=edge">
+        <title>BabylonJS Viewer - Basic usage</title>
+        <style>
+            babylon {
+                max-width: 800px;
+                max-height: 500px;
+                width: 100%;
+                height: 600px;
+            }
+        </style>
+    </head>
+
+    <body>
+        <babylon id="babylon-viewer" camera.behaviors.auto-rotate="0"></babylon>
+        <script src="viewer.js"></script>
+        <script>
+            BabylonViewer.viewerManager.getViewerPromiseById('babylon-viewer').then(function (viewer) {
+                // this will resolve only after the viewer with this specific ID is initialized
+
+                viewer.onEngineInitObservable.add(function (scene) {
+                    viewer.loadModel({
+                        title: "Helmet",
+                        subtitle: "BabylonJS",
+                        thumbnail: "https://www.babylonjs.com/img/favicon/apple-icon-144x144.png",
+                        url: "https://www.babylonjs.com/Assets/DamagedHelmet/glTF/DamagedHelmet.gltf"
+                    });
+                });
+
+                // load another model after 20 seconds. Just for fun.
+                setTimeout(() => {
+                    viewer.loadModel({
+                        title: "Rabbit",
+                        subtitle: "BabylonJS",
+                        thumbnail: "https://www.babylonjs.com/img/favicon/apple-icon-144x144.png",
+                        url: "https://playground.babylonjs.com/scenes/Rabbit.babylon"
+                    });
+                }, 20000)
+            });
+        </script>
+    </body>
+
+</html>

文件差异内容过多而无法显示
+ 69 - 112077
Viewer/dist/viewer.js


文件差异内容过多而无法显示
+ 69 - 1
Viewer/dist/viewer.min.js


+ 1 - 8
Viewer/package.json

@@ -32,12 +32,5 @@
         "uglifyjs-webpack-plugin": "^1.1.6",
         "webpack": "^3.10.0",
         "webpack-dev-server": "^2.11.0"
-    },
-    "dependencies": {
-        "babylonjs": "^3.2.0-alpha4",
-        "babylonjs-loaders": "^3.2.0-alpha4",
-        "deepmerge": "^2.0.1",
-        "es6-promise": "^4.2.2",
-        "handlebars": "^4.0.11"
     }
-}
+}

+ 68 - 9
Viewer/src/configuration/configuration.ts

@@ -46,6 +46,24 @@ export interface ViewerConfiguration {
         defaultLight?: boolean;
         clearColor?: { r: number, g: number, b: number, a: number };
         imageProcessingConfiguration?: IImageProcessingConfiguration;
+        environmentTexture?: string;
+    },
+    optimizer?: {
+        targetFrameRate?: number;
+        trackerDuration?: number;
+        autoGeneratePriorities?: boolean;
+        improvementMode?: boolean;
+        degradation?: string; // low, moderate, high
+        types?: {
+            texture?: SceneOptimizerParameters;
+            hardwareScaling?: SceneOptimizerParameters;
+            shadow?: SceneOptimizerParameters;
+            postProcess?: SceneOptimizerParameters;
+            lensFlare?: SceneOptimizerParameters;
+            particles?: SceneOptimizerParameters;
+            renderTarget?: SceneOptimizerParameters;
+            mergeMeshes?: SceneOptimizerParameters;
+        }
     },
     // at the moment, support only a single camera.
     camera?: {
@@ -66,14 +84,15 @@ export interface ViewerConfiguration {
         [propName: string]: any;
     },
     skybox?: {
-        cubeTexture: {
+        cubeTexture?: {
             noMipMap?: boolean;
             gammaSpace?: boolean;
-            url: string | Array<string>;
+            url?: string | Array<string>;
         };
-        pbr?: boolean;
+        color?: { r: number, g: number, b: number };
+        pbr?: boolean; // deprecated
         scale?: number;
-        blur?: number;
+        blur?: number; // deprecated
         material?: {
             imageProcessingConfiguration?: IImageProcessingConfiguration;
         };
@@ -84,11 +103,23 @@ export interface ViewerConfiguration {
     ground?: boolean | {
         size?: number;
         receiveShadows?: boolean;
-        shadowOnly?: boolean;
-        mirror?: boolean;
-        material?: {
+        shadowLevel?: number;
+        shadowOnly?: boolean; // deprecated
+        mirror?: boolean | {
+            sizeRatio?: number;
+            blurKernel?: number;
+            amount?: number;
+            fresnelWeight?: number;
+            fallOffDistance?: number;
+            textureType?: number;
+        };
+        texture?: string;
+        color?: { r: number, g: number, b: number };
+        opacity?: number;
+        material?: { // deprecated!
             [propName: string]: any;
-        }
+        };
+
     };
     lights?: {
         [name: string]: {
@@ -133,7 +164,35 @@ export interface ViewerConfiguration {
         main: ITemplateConfiguration,
         [key: string]: ITemplateConfiguration
     };
-    // nodes?
+
+    customShaders?: {
+        shaders?: {
+            [key: string]: string;
+        };
+        includes?: {
+            [key: string]: string;
+        }
+    }
+
+    // features that are being tested.
+    // those features' syntax will change and move out! 
+    // Don't use in production (or be ready to make the changes :) )
+    lab?: {
+        flashlight?: boolean | {
+            exponent?: number;
+            angle?: number;
+            intensity?: number;
+            diffuse?: { r: number, g: number, b: number };
+            specular?: { r: number, g: number, b: number };
+        }
+        hideLoadingDelay?: number;
+    }
+}
+
+export interface SceneOptimizerParameters {
+    priority?: number;
+    maximumSize?: number;
+    step?: number;
 }
 
 export interface IImageProcessingConfiguration {

+ 20 - 14
Viewer/src/configuration/loader.ts

@@ -14,9 +14,9 @@ export class ConfigurationLoader {
 
     public loadConfiguration(initConfig: ViewerConfiguration = {}): Promise<ViewerConfiguration> {
 
-        let loadedConfig = deepmerge({}, initConfig);
+        let loadedConfig: ViewerConfiguration = deepmerge({}, initConfig);
 
-        let extendedConfiguration = getConfigurationType(loadedConfig && loadedConfig.extends);
+        let extendedConfiguration = getConfigurationType(loadedConfig.extends || "");
 
         loadedConfig = deepmerge(extendedConfiguration, loadedConfig);
 
@@ -24,23 +24,33 @@ export class ConfigurationLoader {
 
             let mapperType = "json";
             return Promise.resolve().then(() => {
-                if (typeof loadedConfig.configuration === "string" || loadedConfig.configuration.url) {
+                if (typeof loadedConfig.configuration === "string" || (loadedConfig.configuration && loadedConfig.configuration.url)) {
                     // a file to load
-                    let url = loadedConfig.configuration;
+
+                    let url: string = '';
+                    if (typeof loadedConfig.configuration === "string") {
+                        url = loadedConfig.configuration;
+                    }
 
                     // if configuration is an object
-                    if (loadedConfig.configuration.url) {
+                    if (typeof loadedConfig.configuration === "object" && loadedConfig.configuration.url) {
                         url = loadedConfig.configuration.url;
-                        mapperType = loadedConfig.configuration.mapper;
-                        if (!mapperType) {
+                        let type = loadedConfig.configuration.mapper;
+                        // empty string?
+                        if (!type) {
                             // load mapper type from filename / url
-                            mapperType = loadedConfig.configuration.url.split('.').pop();
+                            type = loadedConfig.configuration.url.split('.').pop();
                         }
+                        mapperType = type || mapperType;
                     }
                     return this.loadFile(url);
                 } else {
-                    mapperType = loadedConfig.configuration.mapper || mapperType;
-                    return loadedConfig.configuration.payload || {};
+                    if (typeof loadedConfig.configuration === "object") {
+                        mapperType = loadedConfig.configuration.mapper || mapperType;
+                        return loadedConfig.configuration.payload || {};
+                    }
+                    return {};
+
                 }
             }).then((data: any) => {
                 let mapper = mapperManager.getMapper(mapperType);
@@ -52,10 +62,6 @@ export class ConfigurationLoader {
         }
     }
 
-    public getConfigurationType(type: string) {
-
-    }
-
     private loadFile(url: string): Promise<any> {
         let cacheReference = this.configurationCache;
         if (cacheReference[url]) {

+ 10 - 14
Viewer/src/configuration/types/default.ts

@@ -1,9 +1,7 @@
 import { ViewerConfiguration } from './../configuration';
 
 export let defaultConfiguration: ViewerConfiguration = {
-    version: "0.1",
-    //eventPrefix: 'babylonviewer-',
-    //events: true,
+    version: "3.2.0-alpha4",
     templates: {
         main: {
             html: require("../../../assets/templates/default/defaultTemplate.html")
@@ -71,12 +69,12 @@ export let defaultConfiguration: ViewerConfiguration = {
             }
         }
     },
-    /*lights: [
-        {
+    /*lights: {
+        "default": {
             type: 1,
             shadowEnabled: true,
-            direction: { x: -0.2, y: -1, z: 0 },
-            position: { x: 0.017, y: 50, z: 0 },
+            direction: { x: -0.2, y: -0.8, z: 0 },
+            position: { x: 10, y: 10, z: 0 },
             intensity: 4.5,
             shadowConfig: {
                 useBlurExponentialShadowMap: true,
@@ -85,16 +83,16 @@ export let defaultConfiguration: ViewerConfiguration = {
                 blurScale: 4
             }
         }
-    ],*/
+    },*/
     skybox: {
-        cubeTexture: {
+        /*cubeTexture: {
             url: 'https://playground.babylonjs.com/textures/environment.dds',
             gammaSpace: false
-        },
+        },*/
         pbr: true,
         blur: 0.7,
         infiniteDIstance: false,
-        material: {
+        /*material: {
             imageProcessingConfiguration: {
                 colorCurves: {
                     globalDensity: 89,
@@ -110,7 +108,7 @@ export let defaultConfiguration: ViewerConfiguration = {
                 vignetteColor: { r: 0.8, g: 0.6, b: 0.4 },
                 vignetteM: true
             }
-        }
+        }*/
     },
     ground: true,
     engine: {
@@ -122,7 +120,5 @@ export let defaultConfiguration: ViewerConfiguration = {
             contrast: 1.66,
             toneMappingEnabled: true
         }
-        //autoRotate: true,
-        //rotationSpeed: 0.1
     }
 }

+ 3 - 1
Viewer/src/index.ts

@@ -15,10 +15,12 @@ import 'babylonjs';
 import 'babylonjs-loaders';
 import '../assets/pep.min';
 
+import { PromisePolyfill } from 'babylonjs';
+
 import { InitTags } from './initializer';
 
 // promise polyfill, if needed!
-global.Promise = typeof Promise === 'undefined' ? require('es6-promise').Promise : Promise;
+PromisePolyfill.Apply();
 
 export let disableInit: boolean = false;
 document.addEventListener("DOMContentLoaded", function (event) {

+ 69 - 17
Viewer/src/templateManager.ts

@@ -110,7 +110,10 @@ export class TemplateManager {
      * @memberof TemplateManager
      */
     private buildHTMLTree(templates: { [key: string]: ITemplateConfiguration }): Promise<object> {
-        let promises = Object.keys(templates).map(name => {
+        let promises: Array<Promise<Template | boolean>> = Object.keys(templates).map(name => {
+            // if the template was overridden
+            if (!templates[name]) return Promise.resolve(false);
+            // else - we have a template, let's do our job!
             let template = new Template(name, templates[name]);
             // make sure the global onEventTriggered is called as well
             template.onEventTriggered.add(eventData => this.onEventTriggered.notifyObservers(eventData));
@@ -154,11 +157,23 @@ export class TemplateManager {
         }
     }
 
+    public dispose() {
+        // dispose all templates
+        Object.keys(this.templates).forEach(template => {
+            this.templates[template].dispose();
+        });
+
+        this.onInit.clear();
+        this.onAllLoaded.clear();
+        this.onEventTriggered.clear();
+        this.onLoaded.clear();
+        this.onStateChange.clear();
+    }
+
 }
 
 
 import * as Handlebars from '../assets/handlebars.min.js';
-import { PromiseObservable } from './util/promiseObservable';
 import { EventManager } from './eventManager';
 // register a new helper. modified https://stackoverflow.com/questions/9838925/is-there-any-method-to-iterate-a-map-with-handlebars-js
 Handlebars.registerHelper('eachInMap', function (map, block) {
@@ -195,6 +210,7 @@ export class Template {
     public initPromise: Promise<Template>;
 
     private fragment: DocumentFragment;
+    private htmlTemplate: string;
 
     constructor(public name: string, private _configuration: ITemplateConfiguration) {
         this.onInit = new Observable<Template>();
@@ -216,6 +232,7 @@ export class Template {
 
         this.initPromise = htmlContentPromise.then(htmlTemplate => {
             if (htmlTemplate) {
+                this.htmlTemplate = htmlTemplate;
                 let compiledTemplate = Handlebars.compile(htmlTemplate);
                 let config = this._configuration.params || {};
                 let rawHtml = compiledTemplate(config);
@@ -228,6 +245,21 @@ export class Template {
         });
     }
 
+    public updateParams(params: { [key: string]: string | number | boolean | object }) {
+        this._configuration.params = params;
+        // update the template
+        if (this.isLoaded) {
+            this.dispose();
+        }
+        let compiledTemplate = Handlebars.compile(this.htmlTemplate);
+        let config = this._configuration.params || {};
+        let rawHtml = compiledTemplate(config);
+        this.fragment = document.createRange().createContextualFragment(rawHtml);
+        if (this.parent) {
+            this.appendTo(this.parent, true);
+        }
+    }
+
     public get configuration(): ITemplateConfiguration {
         return this._configuration;
     }
@@ -246,23 +278,25 @@ export class Template {
         return childrenArray;
     }
 
-    public appendTo(parent: HTMLElement) {
+    public appendTo(parent: HTMLElement, forceRemove?: boolean) {
         if (this.parent) {
-            console.error('Already appanded to ', this.parent);
-        } else {
-            this.parent = parent;
-
-            if (this._configuration.id) {
-                this.parent.id = this._configuration.id;
+            if (forceRemove) {
+                this.parent.removeChild(this.fragment);
+            } else {
+                return;
             }
-            this.parent.appendChild(this.fragment);
-            // appended only one frame after.
-            setTimeout(() => {
-                this.registerEvents();
-                this.onAppended.notifyObservers(this);
-            });
         }
+        this.parent = parent;
 
+        if (this._configuration.id) {
+            this.parent.id = this._configuration.id;
+        }
+        this.fragment = this.parent.appendChild(this.fragment);
+        // appended only one frame after.
+        setTimeout(() => {
+            this.registerEvents();
+            this.onAppended.notifyObservers(this);
+        });
     }
 
     public show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
@@ -304,10 +338,21 @@ export class Template {
         this.onLoaded.clear();
         this.onStateChange.clear();
         this.isLoaded = false;
+        // remove from parent
+        this.parent.removeChild(this.fragment);
     }
 
+    private registeredEvents: Array<{ htmlElement: HTMLElement, eventName: string, function: EventListenerOrEventListenerObject }>;
+
     // TODO - Should events be removed as well? when are templates disposed?
     private registerEvents() {
+        this.registeredEvents = this.registeredEvents || [];
+        if (this.registeredEvents.length) {
+            // first remove the registered events
+            this.registeredEvents.forEach(evt => {
+                evt.htmlElement.removeEventListener(evt.eventName, evt.function);
+            });
+        }
         if (this._configuration.events) {
             for (let eventName in this._configuration.events) {
                 if (this._configuration.events && this._configuration.events[eventName]) {
@@ -327,14 +372,21 @@ export class Template {
                                 selector = '#' + selector;
                             }
                             let htmlElement = <HTMLElement>this.parent.querySelector(selector);
-                            htmlElement && htmlElement.addEventListener(eventName, functionToFire.bind(this, selector), false)
+                            if (htmlElement) {
+                                let binding = functionToFire.bind(this, selector);
+                                htmlElement.addEventListener(eventName, binding, false);
+                                this.registeredEvents.push({
+                                    htmlElement: htmlElement,
+                                    eventName: eventName,
+                                    function: binding
+                                });
+                            }
                         });
                     }
                 }
             }
         }
     }
-
 }
 
 export function getTemplateAsHtml(templateConfig: ITemplateConfiguration): Promise<string> {

+ 0 - 39
Viewer/src/util/promiseObservable.ts

@@ -1,39 +0,0 @@
-import { Observable } from 'babylonjs';
-
-export class PromiseObservable<T> extends Observable<T> {
-
-    public notifyWithPromise(eventData: T, mask: number = -1, target?: any, currentTarget?: any): Promise<any> {
-
-        let p = Promise.resolve();
-
-        if (!this._observers.length) {
-            return p;
-        }
-
-        let state = this['_eventState'];
-        state.mask = mask;
-        state.target = target;
-        state.currentTarget = currentTarget;
-        state.skipNextObservers = false;
-
-        this._observers.forEach(obs => {
-            if (state.skipNextObservers) {
-                return;
-            }
-            if (obs.mask & mask) {
-                if (obs.scope) {
-                    // TODO - I can add the variable from the last function here. Requires changing callback sig
-                    p = p.then(() => {
-                        return obs.callback.apply(obs.scope, [eventData, state]);
-                    });
-                } else {
-                    p = p.then(() => {
-                        return obs.callback(eventData, state);
-                    });
-                }
-            }
-        });
-
-        return p;
-    }
-}

+ 61 - 21
Viewer/src/viewer/defaultViewer.ts

@@ -3,7 +3,7 @@
 import { ViewerConfiguration } from './../configuration/configuration';
 import { Template, EventCallback } from './../templateManager';
 import { AbstractViewer } from './viewer';
-import { MirrorTexture, Plane, ShadowGenerator, Texture, BackgroundMaterial, Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
+import { SpotLight, MirrorTexture, Plane, ShadowGenerator, Texture, BackgroundMaterial, Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
 import { CameraBehavior } from '../interfaces';
 
 export class DefaultViewer extends AbstractViewer {
@@ -121,9 +121,13 @@ export class DefaultViewer extends AbstractViewer {
         this.setModelMetaData();
 
         // with a short timeout, making sure everything is there already.
+        let hideLoadingDelay = 500;
+        if (this.configuration.lab && this.configuration.lab.hideLoadingDelay !== undefined) {
+            hideLoadingDelay = this.configuration.lab.hideLoadingDelay;
+        }
         setTimeout(() => {
             this.hideLoadingScreen();
-        }, 500);
+        }, hideLoadingDelay);
 
 
         // recreate the camera
@@ -135,7 +139,7 @@ export class DefaultViewer extends AbstractViewer {
         this.setupCamera(meshes);
         this.setupLights(meshes);
 
-        return this.initEnvironment(meshes);
+        return; //this.initEnvironment(meshes);
     }
 
     private setModelMetaData() {
@@ -167,7 +171,7 @@ export class DefaultViewer extends AbstractViewer {
 
     }
 
-    public initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
+    /*protected initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
         if (this.configuration.skybox) {
             // Define a general environment textue
             let texture;
@@ -267,7 +271,7 @@ export class DefaultViewer extends AbstractViewer {
         }
 
         return Promise.resolve(this.scene);
-    }
+    }*/
 
     public showOverlayScreen(subScreen: string) {
         let template = this.templateManager.getTemplate('overlay');
@@ -360,6 +364,52 @@ export class DefaultViewer extends AbstractViewer {
 
         let sceneConfig = this.configuration.scene || { defaultLight: true };
 
+        // labs feature - flashlight
+        if (this.configuration.lab && this.configuration.lab.flashlight) {
+            let pointerPosition = BABYLON.Vector3.Zero();
+            let lightTarget;
+            let angle = 0.5;
+            let exponent = Math.PI / 2;
+            if (typeof this.configuration.lab.flashlight === "object") {
+                exponent = this.configuration.lab.flashlight.exponent || exponent;
+                angle = this.configuration.lab.flashlight.angle || angle;
+            }
+            var flashlight = new SpotLight("flashlight", Vector3.Zero(),
+                Vector3.Zero(), exponent, angle, this.scene);
+            if (typeof this.configuration.lab.flashlight === "object") {
+                flashlight.intensity = this.configuration.lab.flashlight.intensity || flashlight.intensity;
+                if (this.configuration.lab.flashlight.diffuse) {
+                    flashlight.diffuse.r = this.configuration.lab.flashlight.diffuse.r;
+                    flashlight.diffuse.g = this.configuration.lab.flashlight.diffuse.g;
+                    flashlight.diffuse.b = this.configuration.lab.flashlight.diffuse.b;
+                }
+                if (this.configuration.lab.flashlight.specular) {
+                    flashlight.specular.r = this.configuration.lab.flashlight.specular.r;
+                    flashlight.specular.g = this.configuration.lab.flashlight.specular.g;
+                    flashlight.specular.b = this.configuration.lab.flashlight.specular.b;
+                }
+
+            }
+            this.scene.constantlyUpdateMeshUnderPointer = true;
+            this.scene.onPointerObservable.add((eventData, eventState) => {
+                if (eventData.type === 4 && eventData.pickInfo) {
+                    lightTarget = (eventData.pickInfo.pickedPoint);
+                } else {
+                    lightTarget = undefined;
+                }
+            });
+            let updateFlashlightFunction = () => {
+                if (this.camera && flashlight) {
+                    flashlight.position.copyFrom(this.camera.position);
+                    if (lightTarget) {
+                        lightTarget.subtractToRef(flashlight.position, flashlight.direction);
+                    }
+                }
+            }
+            this.scene.registerBeforeRender(updateFlashlightFunction);
+            this.registeredOnBeforerenderFunctions.push(updateFlashlightFunction);
+        }
+
         if (!sceneConfig.defaultLight && (this.configuration.lights && Object.keys(this.configuration.lights).length)) {
             // remove old lights
             this.scene.lights.forEach(l => {
@@ -382,7 +432,7 @@ export class DefaultViewer extends AbstractViewer {
 
                 //position. Some lights don't support shadows
                 if (light instanceof ShadowLight) {
-                    if (lightConfig.shadowEnabled) {
+                    if (lightConfig.shadowEnabled && this.maxShadows) {
                         var shadowGenerator = new ShadowGenerator(512, light);
                         this.extendClassWithConfig(shadowGenerator, lightConfig.shadowConfig || {});
                         // add the focues meshes to the shadow list
@@ -430,6 +480,11 @@ export class DefaultViewer extends AbstractViewer {
         if (sceneConfig.autoRotate) {
             this.camera.useAutoRotationBehavior = true;
         }
+
+        const sceneExtends = this.scene.getWorldExtends();
+        const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
+        const sceneDiagonalLenght = sceneDiagonal.length();
+        this.camera.upperRadiusLimit = sceneDiagonalLenght * 3;
     }
 
     private setCameraBehavior(behaviorConfig: number | {
@@ -481,19 +536,4 @@ export class DefaultViewer extends AbstractViewer {
                 break;
         }
     }
-
-    private extendClassWithConfig(object: any, config: any) {
-        if (!config) return;
-        Object.keys(config).forEach(key => {
-            if (key in object && typeof object[key] !== 'function') {
-                if (typeof object[key] === 'function') return;
-                // if it is an object, iterate internally until reaching basic types
-                if (typeof object[key] === 'object') {
-                    this.extendClassWithConfig(object[key], config[key]);
-                } else {
-                    object[key] = config[key];
-                }
-            }
-        });
-    }
 }

+ 322 - 36
Viewer/src/viewer/viewer.ts

@@ -1,9 +1,8 @@
 import { viewerManager } from './viewerManager';
 import { TemplateManager } from './../templateManager';
 import configurationLoader from './../configuration/loader';
-import { Observable, Engine, Scene, ArcRotateCamera, Vector3, SceneLoader, AbstractMesh, Mesh, HemisphericLight, Database } from 'babylonjs';
+import { CubeTexture, Color3, IEnvironmentHelperOptions, EnvironmentHelper, Effect, SceneOptimizer, SceneOptimizerOptions, Observable, Engine, Scene, ArcRotateCamera, Vector3, SceneLoader, AbstractMesh, Mesh, HemisphericLight, Database, SceneLoaderProgressEvent, ISceneLoaderPlugin, ISceneLoaderPluginAsync } from 'babylonjs';
 import { ViewerConfiguration } from '../configuration/configuration';
-import { PromiseObservable } from '../util/promiseObservable';
 
 export abstract class AbstractViewer {
 
@@ -11,16 +10,37 @@ export abstract class AbstractViewer {
 
     public engine: Engine;
     public scene: Scene;
+    public sceneOptimizer: SceneOptimizer;
     public baseId: string;
 
+    /**
+     * The last loader used to load a model. 
+     * 
+     * @type {(ISceneLoaderPlugin | ISceneLoaderPluginAsync)}
+     * @memberof AbstractViewer
+     */
+    public lastUsedLoader: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+
     protected configuration: ViewerConfiguration;
+    protected environmentHelper: EnvironmentHelper;
+
+    protected defaultHighpTextureType: number;
+    protected shadowGeneratorBias: number;
+    protected defaultPipelineTextureType: number;
+    protected maxShadows: number;
+
 
     // observables
-    public onSceneInitObservable: PromiseObservable<Scene>;
-    public onEngineInitObservable: PromiseObservable<Engine>;
-    public onModelLoadedObservable: PromiseObservable<AbstractMesh[]>;
+    public onSceneInitObservable: Observable<Scene>;
+    public onEngineInitObservable: Observable<Engine>;
+    public onModelLoadedObservable: Observable<AbstractMesh[]>;
+    public onModelLoadProgressObservable: Observable<SceneLoaderProgressEvent>;
+    public onLoaderInitObservable: Observable<ISceneLoaderPlugin | ISceneLoaderPluginAsync>;
+    public onInitDoneObservable: Observable<AbstractViewer>;
 
-    private canvas: HTMLCanvasElement;
+    protected canvas: HTMLCanvasElement;
+
+    protected registeredOnBeforerenderFunctions: Array<() => void>;
 
     constructor(public containerElement: HTMLElement, initialConfiguration: ViewerConfiguration = {}) {
         // if exists, use the container id. otherwise, generate a random string.
@@ -30,9 +50,14 @@ export abstract class AbstractViewer {
             this.baseId = containerElement.id = 'bjs' + Math.random().toString(32).substr(2, 8);
         }
 
-        this.onSceneInitObservable = new PromiseObservable();
-        this.onEngineInitObservable = new PromiseObservable();
-        this.onModelLoadedObservable = new PromiseObservable();
+        this.onSceneInitObservable = new Observable();
+        this.onEngineInitObservable = new Observable();
+        this.onModelLoadedObservable = new Observable();
+        this.onModelLoadProgressObservable = new Observable();
+        this.onInitDoneObservable = new Observable();
+        this.onLoaderInitObservable = new Observable();
+
+        this.registeredOnBeforerenderFunctions = [];
 
         // add this viewer to the viewer manager
         viewerManager.addViewer(this);
@@ -68,10 +93,12 @@ export abstract class AbstractViewer {
                 if (canvas) {
                     this.canvas = canvas;
                 }
-                this.onTemplatesLoaded();
+                this._onTemplateLoaded();
             });
         });
 
+        //this.onModelLoadedObservable.add(this.initEnvironment.bind(this));
+
     }
 
     public getBaseId(): string {
@@ -101,6 +128,18 @@ export abstract class AbstractViewer {
 
     public dispose() {
         window.removeEventListener('resize', this.resize);
+
+        this.sceneOptimizer.stop();
+        this.sceneOptimizer.dispose();
+
+        if (this.scene.activeCamera) {
+            this.scene.activeCamera.detachControl(this.canvas);
+        }
+
+        this.scene.dispose();
+        this.engine.dispose();
+
+        this.templateManager.dispose();
     }
 
     protected abstract prepareContainerElement();
@@ -114,15 +153,33 @@ export abstract class AbstractViewer {
      * @memberof AbstractViewer
      */
     protected onTemplatesLoaded(): Promise<AbstractViewer> {
-        return this.initEngine().then(() => {
-            if (this.configuration.model) {
-                return this.loadModel();
-            } else {
-                return this.scene;
-            }
-        }).then(() => {
-            return this;
-        });
+        return Promise.resolve(this);
+    }
+
+    /**
+     * This will force the creation of an engine and a scene.
+     * It will also load a model if preconfigured.
+     * But first - it will load the extendible onTemplateLoaded()!
+     */
+    private _onTemplateLoaded(): Promise<AbstractViewer> {
+        return this.onTemplatesLoaded().then(() => {
+            let autoLoadModel = !!this.configuration.model;
+            return this.initEngine().then((engine) => {
+                return this.onEngineInitObservable.notifyObserversWithPromise(engine);
+            }).then(() => {
+                if (autoLoadModel) {
+                    return this.loadModel();
+                } else {
+                    return this.scene || this.initScene();
+                }
+            }).then((scene) => {
+                return this.onSceneInitObservable.notifyObserversWithPromise(scene);
+            }).then(() => {
+                return this.onInitDoneObservable.notifyObserversWithPromise(this);
+            }).then(() => {
+                return this;
+            });
+        })
     }
 
     /**
@@ -133,6 +190,10 @@ export abstract class AbstractViewer {
      * @memberof Viewer
      */
     protected initEngine(): Promise<Engine> {
+
+        // init custom shaders
+        this.injectCustomShaders();
+
         let canvasElement = this.templateManager.getCanvas();
         if (!canvasElement) {
             return Promise.reject('Canvas element not found!');
@@ -156,9 +217,10 @@ export abstract class AbstractViewer {
             this.engine.setHardwareScalingLevel(scale);
         }
 
-        return this.onEngineInitObservable.notifyWithPromise(this.engine).then(() => {
-            return this.engine;
-        });
+        // set hardware limitations for scene initialization
+        this.handleHardwareLimitations();
+
+        return Promise.resolve(this.engine);
     }
 
     protected initScene(): Promise<Scene> {
@@ -172,12 +234,48 @@ export abstract class AbstractViewer {
         this.scene = new Scene(this.engine);
         // make sure there is a default camera and light.
         this.scene.createDefaultCameraOrLight(true, true, true);
-        if (this.configuration.scene && this.configuration.scene.debug) {
-            this.scene.debugLayer.show();
+        if (this.configuration.scene) {
+            if (this.configuration.scene.debug) {
+                this.scene.debugLayer.show();
+            }
+
+            // Scene optimizer
+            if (this.configuration.optimizer) {
+
+                let optimizerConfig = this.configuration.optimizer;
+                let optimizerOptions: SceneOptimizerOptions = new SceneOptimizerOptions(optimizerConfig.targetFrameRate, optimizerConfig.trackerDuration);
+                // check for degradation
+                if (optimizerConfig.degradation) {
+                    switch (optimizerConfig.degradation) {
+                        case "low":
+                            optimizerOptions = SceneOptimizerOptions.LowDegradationAllowed(optimizerConfig.targetFrameRate);
+                            break;
+                        case "moderate":
+                            optimizerOptions = SceneOptimizerOptions.ModerateDegradationAllowed(optimizerConfig.targetFrameRate);
+                            break;
+                        case "hight":
+                            optimizerOptions = SceneOptimizerOptions.HighDegradationAllowed(optimizerConfig.targetFrameRate);
+                            break;
+                    }
+                }
+
+                this.sceneOptimizer = new SceneOptimizer(this.scene, optimizerOptions, optimizerConfig.autoGeneratePriorities, optimizerConfig.improvementMode);
+                this.sceneOptimizer.start();
+            }
+
+            // image processing configuration - optional.
+            if (this.configuration.scene.imageProcessingConfiguration) {
+                this.extendClassWithConfig(this.scene.imageProcessingConfiguration, this.configuration.scene.imageProcessingConfiguration);
+            }
+            if (this.configuration.scene.environmentTexture) {
+                const environmentTexture = CubeTexture.CreateFromPrefilteredData(this.configuration.scene.environmentTexture, this.scene);
+                this.scene.environmentTexture = environmentTexture;
+            }
         }
-        return this.onSceneInitObservable.notifyWithPromise(this.scene).then(() => {
-            return this.scene;
-        });
+
+
+
+        return Promise.resolve(this.scene);
     }
 
     public loadModel(model: any = this.configuration.model, clearScene: boolean = true): Promise<Scene> {
@@ -188,22 +286,210 @@ export abstract class AbstractViewer {
         let base = parts.join('/') + '/';
         let plugin = (typeof model === 'string') ? undefined : model.loader;
 
-        return Promise.resolve().then(() => {
-            if (!this.scene || clearScene) return this.initScene();
-            else return this.scene;
+        return Promise.resolve(this.scene).then((scene) => {
+            if (!scene || clearScene) return this.initScene();
+            else return this.scene!;
         }).then(() => {
             return new Promise<Array<AbstractMesh>>((resolve, reject) => {
-                SceneLoader.ImportMesh(undefined, base, filename, this.scene, (meshes) => {
+                this.lastUsedLoader = SceneLoader.ImportMesh(undefined, base, filename, this.scene, (meshes) => {
                     resolve(meshes);
-                }, undefined, (e, m, exception) => {
-                    console.log(m, exception);
+                }, (progressEvent) => {
+                    this.onModelLoadProgressObservable.notifyObserversWithPromise(progressEvent);
+                }, (e, m, exception) => {
+                    // console.log(m, exception);
                     reject(m);
-                }, plugin);
+                }, plugin)!;
+                this.onLoaderInitObservable.notifyObserversWithPromise(this.lastUsedLoader);
             });
         }).then((meshes: Array<AbstractMesh>) => {
-            return this.onModelLoadedObservable.notifyWithPromise(meshes).then(() => {
-                return this.scene;
+            return this.onModelLoadedObservable.notifyObserversWithPromise(meshes)
+                .then(() => {
+                    this.initEnvironment();
+                }).then(() => {
+                    return this.scene;
+                });
+        });
+    }
+
+    protected initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
+        if (!this.configuration.skybox && !this.configuration.ground) {
+            if (this.environmentHelper) {
+                this.environmentHelper.dispose();
+            };
+            return Promise.resolve(this.scene);
+        }
+
+        const options: Partial<IEnvironmentHelperOptions> = {
+            createGround: !!this.configuration.ground,
+            createSkybox: !!this.configuration.skybox,
+            setupImageProcessing: false // will be done at the scene level!
+        };
+
+        if (this.configuration.ground) {
+            let groundConfig = (typeof this.configuration.ground === 'boolean') ? {} : this.configuration.ground;
+
+            let groundSize = groundConfig.size || (this.configuration.skybox && this.configuration.skybox.scale);
+            if (groundSize) {
+                options.groundSize = groundSize;
+            }
+
+            options.enableGroundShadow = this.configuration.ground === true || groundConfig.receiveShadows;
+            if (groundConfig.shadowLevel) {
+                options.groundShadowLevel = groundConfig.shadowLevel;
+            }
+            options.enableGroundMirror = !!groundConfig.mirror;
+            if (groundConfig.texture) {
+                options.groundTexture = groundConfig.texture;
+            }
+            if (groundConfig.color) {
+                options.groundColor = new Color3(groundConfig.color.r, groundConfig.color.g, groundConfig.color.b)
+            }
+
+            if (groundConfig.mirror) {
+                options.enableGroundMirror = true;
+                // to prevent undefines
+                if (typeof groundConfig.mirror === "object") {
+                    if (groundConfig.mirror.amount)
+                        options.groundMirrorAmount = groundConfig.mirror.amount;
+                    if (groundConfig.mirror.sizeRatio)
+                        options.groundMirrorSizeRatio = groundConfig.mirror.sizeRatio;
+                    if (groundConfig.mirror.blurKernel)
+                        options.groundMirrorBlurKernel = groundConfig.mirror.blurKernel;
+                    if (groundConfig.mirror.fresnelWeight)
+                        options.groundMirrorFresnelWeight = groundConfig.mirror.fresnelWeight;
+                    if (groundConfig.mirror.fallOffDistance)
+                        options.groundMirrorFallOffDistance = groundConfig.mirror.fallOffDistance;
+                    if (this.defaultHighpTextureType !== undefined)
+                        options.groundMirrorTextureType = this.defaultHighpTextureType;
+                }
+            }
+
+        }
+
+        let postInitSkyboxMaterial = false;
+        if (this.configuration.skybox) {
+            let conf = this.configuration.skybox;
+            if (conf.material && conf.material.imageProcessingConfiguration) {
+                options.setupImageProcessing = false; // will be configured later manually.
+            }
+            let skyboxSize = this.configuration.skybox.scale;
+            if (skyboxSize) {
+                options.skyboxSize = skyboxSize;
+            }
+            options.sizeAuto = !options.skyboxSize;
+            if (conf.color) {
+                options.skyboxColor = new Color3(conf.color.r, conf.color.g, conf.color.b)
+            }
+            if (conf.cubeTexture && conf.cubeTexture.url) {
+                if (typeof conf.cubeTexture.url === "string") {
+                    options.skyboxTexture = conf.cubeTexture.url;
+                } else {
+                    // init later!
+                    postInitSkyboxMaterial = true;
+                }
+            }
+
+            if (conf.material && conf.material.imageProcessingConfiguration) {
+                postInitSkyboxMaterial = true;
+            }
+        }
+
+        if (!this.environmentHelper) {
+            this.environmentHelper = this.scene.createDefaultEnvironment(options)!;
+        }
+        else {
+            // there might be a new scene! we need to dispose.
+            // Need to decide if a scene should stay or be disposed.
+            this.environmentHelper.dispose();
+            //this.environmentHelper.updateOptions(options);
+            this.environmentHelper = this.scene.createDefaultEnvironment(options)!;
+        }
+        console.log(options);
+
+        if (postInitSkyboxMaterial) {
+            let skyboxMaterial = this.environmentHelper.skyboxMaterial;
+            if (skyboxMaterial) {
+                if (this.configuration.skybox && this.configuration.skybox.material && this.configuration.skybox.material.imageProcessingConfiguration) {
+                    this.extendClassWithConfig(skyboxMaterial.imageProcessingConfiguration, this.configuration.skybox.material.imageProcessingConfiguration);
+                }
+            }
+        }
+
+        return Promise.resolve(this.scene);
+    }
+
+    /**
+		 * Alters render settings to reduce features based on hardware feature limitations
+		 * @param options Viewer options to modify
+		 */
+    protected handleHardwareLimitations() {
+        //flip rendering settings switches based on hardware support
+        let maxVaryingRows = this.engine.getCaps().maxVaryingVectors;
+        let maxFragmentSamplers = this.engine.getCaps().maxTexturesImageUnits;
+
+        //shadows are disabled if there's not enough varyings for a single shadow
+        if ((maxVaryingRows < 8) || (maxFragmentSamplers < 8)) {
+            this.maxShadows = 0;
+        } else {
+            this.maxShadows = 3;
+        }
+
+        //can we render to any >= 16-bit targets (required for HDR)
+        let caps = this.engine.getCaps();
+        let linearHalfFloatTargets = caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering;
+        let linearFloatTargets = caps.textureFloatRender && caps.textureFloatLinearFiltering;
+
+        let supportsHDR: boolean = !!(linearFloatTargets || linearHalfFloatTargets);
+
+        if (linearHalfFloatTargets) {
+            this.defaultHighpTextureType = Engine.TEXTURETYPE_HALF_FLOAT;
+            this.shadowGeneratorBias = 0.002;
+        } else if (linearFloatTargets) {
+            this.defaultHighpTextureType = Engine.TEXTURETYPE_FLOAT;
+            this.shadowGeneratorBias = 0.001;
+        } else {
+            this.defaultHighpTextureType = Engine.TEXTURETYPE_UNSIGNED_INT;
+            this.shadowGeneratorBias = 0.001;
+        }
+
+        this.defaultPipelineTextureType = supportsHDR ? this.defaultHighpTextureType : Engine.TEXTURETYPE_UNSIGNED_INT;
+    }
+
+    /**
+     * Injects all the spectre shader in the babylon shader store
+     */
+    protected injectCustomShaders(): void {
+        let customShaders = this.configuration.customShaders;
+        // Inject all the spectre shader in the babylon shader store.
+        if (!customShaders) {
+            return;
+        }
+        if (customShaders.shaders) {
+            Object.keys(customShaders.shaders).forEach(key => {
+                // typescript considers a callback "unsafe", so... '!'
+                Effect.ShadersStore[key] = customShaders!.shaders![key];
+            });
+        }
+        if (customShaders.includes) {
+            Object.keys(customShaders.includes).forEach(key => {
+                // typescript considers a callback "unsafe", so... '!'
+                Effect.IncludesShadersStore[key] = customShaders!.includes![key];
             });
+        }
+    }
+
+    protected extendClassWithConfig(object: any, config: any) {
+        if (!config) return;
+        Object.keys(config).forEach(key => {
+            if (key in object && typeof object[key] !== 'function') {
+                if (typeof object[key] === 'function') return;
+                // if it is an object, iterate internally until reaching basic types
+                if (typeof object[key] === 'object') {
+                    this.extendClassWithConfig(object[key], config[key]);
+                } else {
+                    object[key] = config[key];
+                }
+            }
         });
     }
 }

+ 21 - 9
Viewer/tsconfig.json

@@ -2,25 +2,37 @@
     "compilerOptions": {
         "target": "es5",
         "module": "commonjs",
-        "noResolve": true,
+        "noResolve": false,
         "noImplicitAny": false, //mainly due to usage of external libs without typings.
         "strictNullChecks": true,
         "removeComments": true,
         "preserveConstEnums": true,
-        "sourceMap": true,
+        "sourceMap": false,
         "experimentalDecorators": true,
         "isolatedModules": false,
+        "declaration": false,
         "lib": [
             "dom",
             "es2015.promise",
             "es5"
         ],
-        //"declaration": true,
-        "outDir": "./temp/",
         "types": [
-            "node",
-            "babylonjs",
-            "babylonjs-loaders"
-        ]
-    }
+            "node"
+        ],
+        "baseUrl": ".",
+        "paths": {
+            "babylonjs": [
+                "../dist/preview release/babylon.max.js",
+                "../dist/preview release/babylon.d.ts"
+            ],
+            "babylonjs-loaders": [
+                "../dist/preview release/loaders/babylonjs.loaders.js",
+                "../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
+            ]
+        }
+    },
+    "exclude": [
+        "node_modules",
+        "dist"
+    ]
 }

+ 13 - 9
Viewer/webpack.config.js

@@ -1,11 +1,9 @@
-const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
 const path = require('path');
 const webpack = require('webpack');
 
 module.exports = {
     entry: {
-        'viewer': './src/index.ts',
-        'viewer.min': './src/index.ts',
+        'viewer': './src/index.ts'
     },
     output: {
         path: path.resolve(__dirname, 'dist'),
@@ -16,17 +14,23 @@ module.exports = {
         devtoolModuleFilenameTemplate: '[absolute-resource-path]'
     },
     resolve: {
-        extensions: ['.ts', '.tsx', '.js']
+        extensions: ['.ts', '.js'],
+        alias: {
+            "babylonjs": __dirname + '/../dist/preview release/babylon.max.js',
+            "babylonjs-materials": __dirname + '/../dist/preview release/materialsLibrary/babylonjs.materials.js',
+            "babylonjs-loaders": __dirname + '/../dist/preview release/loaders/babylonjs.loaders.js',
+            "deepmerge": __dirname + '/assets/deepmerge.min.js'
+        }
+    },
+    externals: {
+        // until physics will be integrated in the viewer, ignore cannon
+        cannon: 'CANNON'
     },
     devtool: 'source-map',
     plugins: [
         new webpack.WatchIgnorePlugin([
             /\.d\.ts$/
-        ]),
-        new UglifyJSPlugin({
-            parallel: true,
-            test: /\.min\.js$/i,
-        })
+        ])
     ],
     module: {
         loaders: [{

+ 1 - 1
Viewer/webpack.gulp.config.js

@@ -19,7 +19,7 @@ module.exports = {
             "babylonjs": __dirname + '/../dist/preview release/babylon.max.js',
             "babylonjs-materials": __dirname + '/../dist/preview release/materialsLibrary/babylonjs.materials.js',
             "babylonjs-loaders": __dirname + '/../dist/preview release/loaders/babylonjs.loaders.js',
-            "es6-promise": __dirname + '/assets/es6-promise.min.js',
+            // "es6-promise": __dirname + '/assets/es6-promise.min.js',
             "deepmerge": __dirname + '/assets/deepmerge.min.js',
         }
     },

+ 20 - 23
dist/babylon.glTFInterface.d.ts

@@ -1,7 +1,12 @@
 declare module BABYLON.GLTF2 {
-    /**
-     * Specifies if the attribute is a scalar, vector, or matrix.
-     */
+    const enum AccessorComponentType {
+        BYTE = 5120,
+        UNSIGNED_BYTE = 5121,
+        SHORT = 5122,
+        UNSIGNED_SHORT = 5123,
+        UNSIGNED_INT = 5125,
+        FLOAT = 5126,
+    }
     const enum AccessorType {
         SCALAR = "SCALAR",
         VEC2 = "VEC2",
@@ -11,33 +16,29 @@ declare module BABYLON.GLTF2 {
         MAT3 = "MAT3",
         MAT4 = "MAT4",
     }
-    const enum MaterialAlphaMode {
-        OPAQUE = "OPAQUE",
-        MASK = "MASK",
-        BLEND = "BLEND",
-    }
     const enum AnimationChannelTargetPath {
         TRANSLATION = "translation",
         ROTATION = "rotation",
         SCALE = "scale",
         WEIGHTS = "weights",
     }
+    const enum AnimationInterpolation {
+        LINEAR = "LINEAR",
+        STEP = "STEP",
+        CUBICSPLINE = "CUBICSPLINE",
+    }
     const enum CameraType {
         PERSPECTIVE = "perspective",
         ORTHOGRAPHIC = "orthographic",
     }
-    const enum AccessorComponentType {
-        BYTE = 5120,
-        UNSIGNED_BYTE = 5121,
-        SHORT = 5122,
-        UNSIGNED_SHORT = 5123,
-        UNSIGNED_INT = 5125,
-        FLOAT = 5126,
+    const enum ImageMimeType {
+        JPEG = "image/jpeg",
+        PNG = "image/png",
     }
-    const enum AnimationInterpolation {
-        LINEAR = "LINEAR",
-        STEP = "STEP",
-        CUBICSPLINE = "CUBICSPLINE",
+    const enum MaterialAlphaMode {
+        OPAQUE = "OPAQUE",
+        MASK = "MASK",
+        BLEND = "BLEND",
     }
     const enum MeshPrimitiveMode {
         POINTS = 0,
@@ -48,10 +49,6 @@ declare module BABYLON.GLTF2 {
         TRIANGLE_STRIP = 5,
         TRIANGLE_FAN = 6,
     }
-    const enum ImageMimeType {
-        JPEG = "image/jpeg",
-        PNG = "image/png",
-    }
     const enum TextureMagFilter {
         NEAREST = 9728,
         LINEAR = 9729,

文件差异内容过多而无法显示
+ 12790 - 11271
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 51 - 51
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 2341 - 585
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 52 - 52
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 7294 - 5770
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 55 - 55
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


文件差异内容过多而无法显示
+ 2430 - 601
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


文件差异内容过多而无法显示
+ 2432 - 603
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


文件差异内容过多而无法显示
+ 2343 - 587
dist/preview release/es6.js


+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 15 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -521,10 +521,14 @@ declare module BABYLON.GLTF2 {
         readonly abstract name: string;
         protected _traverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean;
         static _Extensions: GLTFLoaderExtension[];
         static TraverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
+        static LoadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        static LoadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
         static LoadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         private static _ApplyExtensions(action);
@@ -555,3 +559,14 @@ declare module BABYLON.GLTF2.Extensions {
         private _loadSpecularGlossinessProperties(loader, context, material, properties);
     }
 }
+
+
+declare module BABYLON.GLTF2.Extensions {
+    class KHRLights extends GLTFLoaderExtension {
+        readonly name: string;
+        private applyCommonProperties(light, lightInfo);
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
+        protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+    }
+}

+ 134 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -626,6 +626,8 @@ var BABYLON;
                 GLTFLoader._AssignIndices(this._gltf.scenes);
                 GLTFLoader._AssignIndices(this._gltf.skins);
                 GLTFLoader._AssignIndices(this._gltf.textures);
+                // Handle global extensions as they may add their own data types.
+                GLTF2.GLTFLoaderExtension.LoadRoot(this, "#/", this._gltf);
                 if (data.bin) {
                     var buffers = this._gltf.buffers;
                     if (buffers && buffers[0] && !buffers[0].uri) {
@@ -709,6 +711,7 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadScene = function (context, scene, nodeNames) {
                 var _this = this;
+                GLTF2.GLTFLoaderExtension.LoadScene(this, context, scene);
                 this._rootNode = { babylonMesh: new BABYLON.Mesh("__root__", this._babylonScene) };
                 switch (this.coordinateSystemMode) {
                     case BABYLON.GLTFLoaderCoordinateSystemMode.AUTO: {
@@ -2153,6 +2156,8 @@ var BABYLON;
             }
             GLTFLoaderExtension.prototype._traverseNode = function (loader, context, node, action, parentNode) { return false; };
             GLTFLoaderExtension.prototype._loadNode = function (loader, context, node) { return false; };
+            GLTFLoaderExtension.prototype._loadRoot = function (loader, context, root) { return false; };
+            GLTFLoaderExtension.prototype._loadScene = function (loader, context, scene) { return false; };
             GLTFLoaderExtension.prototype._loadMaterial = function (loader, context, material, assign) { return false; };
             GLTFLoaderExtension.prototype._loadExtension = function (context, property, action) {
                 var _this = this;
@@ -2174,6 +2179,12 @@ var BABYLON;
             GLTFLoaderExtension.TraverseNode = function (loader, context, node, action, parentNode) {
                 return this._ApplyExtensions(function (extension) { return extension._traverseNode(loader, context, node, action, parentNode); });
             };
+            GLTFLoaderExtension.LoadRoot = function (loader, context, root) {
+                return this._ApplyExtensions(function (extension) { return extension._loadRoot(loader, context, root); });
+            };
+            GLTFLoaderExtension.LoadScene = function (loader, context, scene) {
+                return this._ApplyExtensions(function (extension) { return extension._loadScene(loader, context, scene); });
+            };
             GLTFLoaderExtension.LoadNode = function (loader, context, node) {
                 return this._ApplyExtensions(function (extension) { return extension._loadNode(loader, context, node); });
             };
@@ -2419,3 +2430,126 @@ var BABYLON;
 })(BABYLON || (BABYLON = {}));
 
 //# sourceMappingURL=KHR_materials_pbrSpecularGlossiness.js.map
+
+/// <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) {
+            var KHRLights = /** @class */ (function (_super) {
+                __extends(KHRLights, _super);
+                function KHRLights() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(KHRLights.prototype, "name", {
+                    get: function () {
+                        return "KHR_lights";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                KHRLights.prototype.applyCommonProperties = function (light, lightInfo) {
+                    if (lightInfo.color) {
+                        light.diffuse.copyFromFloats(lightInfo.color[0], lightInfo.color[1], lightInfo.color[2]);
+                    }
+                    else {
+                        light.diffuse.copyFromFloats(1, 1, 1);
+                    }
+                    if (lightInfo.intensity !== undefined) {
+                        light.intensity = lightInfo.intensity;
+                    }
+                    else {
+                        light.intensity = 1;
+                    }
+                };
+                KHRLights.prototype._loadScene = function (loader, context, scene) {
+                    return this._loadExtension(context, scene, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            if (lightInfo.type !== 'ambient') {
+                                return;
+                            }
+                            var lightColor = lightInfo.color ? lightInfo.color : [1, 1, 1];
+                            loader._babylonScene.ambientColor.copyFromFloats(lightColor[0], lightColor[1], lightColor[2]);
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadNode = function (loader, context, node) {
+                    var _this = this;
+                    return this._loadExtension(context, node, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            var name_1 = node.name || 'Light';
+                            var matrix = void 0;
+                            if (node.matrix) {
+                                matrix = BABYLON.Matrix.FromArray(node.matrix);
+                            }
+                            else {
+                                matrix = BABYLON.Matrix.Identity();
+                            }
+                            var direction = new BABYLON.Vector3(0, 0, 1);
+                            if (lightInfo.type == 'directional' || lightInfo.type == 'spot') {
+                                var rotationMatrix = matrix.getRotationMatrix();
+                                BABYLON.Vector3.TransformCoordinatesToRef(direction, rotationMatrix, direction);
+                            }
+                            var light = void 0;
+                            if (lightInfo.type == 'directional') {
+                                light = new BABYLON.DirectionalLight(name_1, direction, loader._babylonScene);
+                            }
+                            else {
+                                var position = matrix.getTranslation();
+                                if (lightInfo.type == 'spot') {
+                                    var angle = lightInfo.spot && lightInfo.spot.outerConeAngle ? lightInfo.spot.outerConeAngle : Math.PI / 2;
+                                    light = new BABYLON.SpotLight(name_1, position, direction, angle, 2, loader._babylonScene);
+                                }
+                                else {
+                                    light = new BABYLON.PointLight(name_1, position, loader._babylonScene);
+                                }
+                            }
+                            _this.applyCommonProperties(light, lightInfo);
+                            extension.babylonLight = light;
+                            extension.babylonLight.parent = node.parent ? node.parent.babylonMesh : null;
+                            if (node.children) {
+                                for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                                    var index = _a[_i];
+                                    var childNode = GLTF2.GLTFLoader._GetProperty(loader._gltf.nodes, index);
+                                    if (!childNode) {
+                                        throw new Error(context + ": Failed to find child node " + index);
+                                    }
+                                    loader._loadNode("#/nodes/" + index, childNode);
+                                }
+                            }
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadRoot = function (loader, context, root) {
+                    return this._loadExtension(context, root, function (context, extension, onComplete) {
+                        extension.lights.forEach(function (light, idx) {
+                            light.index = idx;
+                        });
+                        onComplete();
+                    });
+                };
+                return KHRLights;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHRLights = KHRLights;
+            GLTF2.GLTFLoader.RegisterExtension(new KHRLights());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_lights.js.map

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 15 - 0
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -1078,10 +1078,14 @@ declare module BABYLON.GLTF2 {
         readonly abstract name: string;
         protected _traverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean;
         static _Extensions: GLTFLoaderExtension[];
         static TraverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
+        static LoadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        static LoadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
         static LoadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         private static _ApplyExtensions(action);
@@ -1112,3 +1116,14 @@ declare module BABYLON.GLTF2.Extensions {
         private _loadSpecularGlossinessProperties(loader, context, material, properties);
     }
 }
+
+
+declare module BABYLON.GLTF2.Extensions {
+    class KHRLights extends GLTFLoaderExtension {
+        readonly name: string;
+        private applyCommonProperties(light, lightInfo);
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
+        protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+    }
+}

+ 134 - 0
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2792,6 +2792,8 @@ var BABYLON;
                 GLTFLoader._AssignIndices(this._gltf.scenes);
                 GLTFLoader._AssignIndices(this._gltf.skins);
                 GLTFLoader._AssignIndices(this._gltf.textures);
+                // Handle global extensions as they may add their own data types.
+                GLTF2.GLTFLoaderExtension.LoadRoot(this, "#/", this._gltf);
                 if (data.bin) {
                     var buffers = this._gltf.buffers;
                     if (buffers && buffers[0] && !buffers[0].uri) {
@@ -2875,6 +2877,7 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadScene = function (context, scene, nodeNames) {
                 var _this = this;
+                GLTF2.GLTFLoaderExtension.LoadScene(this, context, scene);
                 this._rootNode = { babylonMesh: new BABYLON.Mesh("__root__", this._babylonScene) };
                 switch (this.coordinateSystemMode) {
                     case BABYLON.GLTFLoaderCoordinateSystemMode.AUTO: {
@@ -4319,6 +4322,8 @@ var BABYLON;
             }
             GLTFLoaderExtension.prototype._traverseNode = function (loader, context, node, action, parentNode) { return false; };
             GLTFLoaderExtension.prototype._loadNode = function (loader, context, node) { return false; };
+            GLTFLoaderExtension.prototype._loadRoot = function (loader, context, root) { return false; };
+            GLTFLoaderExtension.prototype._loadScene = function (loader, context, scene) { return false; };
             GLTFLoaderExtension.prototype._loadMaterial = function (loader, context, material, assign) { return false; };
             GLTFLoaderExtension.prototype._loadExtension = function (context, property, action) {
                 var _this = this;
@@ -4340,6 +4345,12 @@ var BABYLON;
             GLTFLoaderExtension.TraverseNode = function (loader, context, node, action, parentNode) {
                 return this._ApplyExtensions(function (extension) { return extension._traverseNode(loader, context, node, action, parentNode); });
             };
+            GLTFLoaderExtension.LoadRoot = function (loader, context, root) {
+                return this._ApplyExtensions(function (extension) { return extension._loadRoot(loader, context, root); });
+            };
+            GLTFLoaderExtension.LoadScene = function (loader, context, scene) {
+                return this._ApplyExtensions(function (extension) { return extension._loadScene(loader, context, scene); });
+            };
             GLTFLoaderExtension.LoadNode = function (loader, context, node) {
                 return this._ApplyExtensions(function (extension) { return extension._loadNode(loader, context, node); });
             };
@@ -4585,3 +4596,126 @@ var BABYLON;
 })(BABYLON || (BABYLON = {}));
 
 //# sourceMappingURL=KHR_materials_pbrSpecularGlossiness.js.map
+
+/// <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) {
+            var KHRLights = /** @class */ (function (_super) {
+                __extends(KHRLights, _super);
+                function KHRLights() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(KHRLights.prototype, "name", {
+                    get: function () {
+                        return "KHR_lights";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                KHRLights.prototype.applyCommonProperties = function (light, lightInfo) {
+                    if (lightInfo.color) {
+                        light.diffuse.copyFromFloats(lightInfo.color[0], lightInfo.color[1], lightInfo.color[2]);
+                    }
+                    else {
+                        light.diffuse.copyFromFloats(1, 1, 1);
+                    }
+                    if (lightInfo.intensity !== undefined) {
+                        light.intensity = lightInfo.intensity;
+                    }
+                    else {
+                        light.intensity = 1;
+                    }
+                };
+                KHRLights.prototype._loadScene = function (loader, context, scene) {
+                    return this._loadExtension(context, scene, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            if (lightInfo.type !== 'ambient') {
+                                return;
+                            }
+                            var lightColor = lightInfo.color ? lightInfo.color : [1, 1, 1];
+                            loader._babylonScene.ambientColor.copyFromFloats(lightColor[0], lightColor[1], lightColor[2]);
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadNode = function (loader, context, node) {
+                    var _this = this;
+                    return this._loadExtension(context, node, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            var name_1 = node.name || 'Light';
+                            var matrix = void 0;
+                            if (node.matrix) {
+                                matrix = BABYLON.Matrix.FromArray(node.matrix);
+                            }
+                            else {
+                                matrix = BABYLON.Matrix.Identity();
+                            }
+                            var direction = new BABYLON.Vector3(0, 0, 1);
+                            if (lightInfo.type == 'directional' || lightInfo.type == 'spot') {
+                                var rotationMatrix = matrix.getRotationMatrix();
+                                BABYLON.Vector3.TransformCoordinatesToRef(direction, rotationMatrix, direction);
+                            }
+                            var light = void 0;
+                            if (lightInfo.type == 'directional') {
+                                light = new BABYLON.DirectionalLight(name_1, direction, loader._babylonScene);
+                            }
+                            else {
+                                var position = matrix.getTranslation();
+                                if (lightInfo.type == 'spot') {
+                                    var angle = lightInfo.spot && lightInfo.spot.outerConeAngle ? lightInfo.spot.outerConeAngle : Math.PI / 2;
+                                    light = new BABYLON.SpotLight(name_1, position, direction, angle, 2, loader._babylonScene);
+                                }
+                                else {
+                                    light = new BABYLON.PointLight(name_1, position, loader._babylonScene);
+                                }
+                            }
+                            _this.applyCommonProperties(light, lightInfo);
+                            extension.babylonLight = light;
+                            extension.babylonLight.parent = node.parent ? node.parent.babylonMesh : null;
+                            if (node.children) {
+                                for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                                    var index = _a[_i];
+                                    var childNode = GLTF2.GLTFLoader._GetProperty(loader._gltf.nodes, index);
+                                    if (!childNode) {
+                                        throw new Error(context + ": Failed to find child node " + index);
+                                    }
+                                    loader._loadNode("#/nodes/" + index, childNode);
+                                }
+                            }
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadRoot = function (loader, context, root) {
+                    return this._loadExtension(context, root, function (context, extension, onComplete) {
+                        extension.lights.forEach(function (light, idx) {
+                            light.index = idx;
+                        });
+                        onComplete();
+                    });
+                };
+                return KHRLights;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHRLights = KHRLights;
+            GLTF2.GLTFLoader.RegisterExtension(new KHRLights());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_lights.js.map

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 125 - 0
dist/preview release/loaders/babylonjs.loaders.js

@@ -3766,6 +3766,8 @@ var BABYLON;
                 GLTFLoader._AssignIndices(this._gltf.scenes);
                 GLTFLoader._AssignIndices(this._gltf.skins);
                 GLTFLoader._AssignIndices(this._gltf.textures);
+                // Handle global extensions as they may add their own data types.
+                GLTF2.GLTFLoaderExtension.LoadRoot(this, "#/", this._gltf);
                 if (data.bin) {
                     var buffers = this._gltf.buffers;
                     if (buffers && buffers[0] && !buffers[0].uri) {
@@ -3849,6 +3851,7 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadScene = function (context, scene, nodeNames) {
                 var _this = this;
+                GLTF2.GLTFLoaderExtension.LoadScene(this, context, scene);
                 this._rootNode = { babylonMesh: new BABYLON.Mesh("__root__", this._babylonScene) };
                 switch (this.coordinateSystemMode) {
                     case BABYLON.GLTFLoaderCoordinateSystemMode.AUTO: {
@@ -5293,6 +5296,8 @@ var BABYLON;
             }
             GLTFLoaderExtension.prototype._traverseNode = function (loader, context, node, action, parentNode) { return false; };
             GLTFLoaderExtension.prototype._loadNode = function (loader, context, node) { return false; };
+            GLTFLoaderExtension.prototype._loadRoot = function (loader, context, root) { return false; };
+            GLTFLoaderExtension.prototype._loadScene = function (loader, context, scene) { return false; };
             GLTFLoaderExtension.prototype._loadMaterial = function (loader, context, material, assign) { return false; };
             GLTFLoaderExtension.prototype._loadExtension = function (context, property, action) {
                 var _this = this;
@@ -5314,6 +5319,12 @@ var BABYLON;
             GLTFLoaderExtension.TraverseNode = function (loader, context, node, action, parentNode) {
                 return this._ApplyExtensions(function (extension) { return extension._traverseNode(loader, context, node, action, parentNode); });
             };
+            GLTFLoaderExtension.LoadRoot = function (loader, context, root) {
+                return this._ApplyExtensions(function (extension) { return extension._loadRoot(loader, context, root); });
+            };
+            GLTFLoaderExtension.LoadScene = function (loader, context, scene) {
+                return this._ApplyExtensions(function (extension) { return extension._loadScene(loader, context, scene); });
+            };
             GLTFLoaderExtension.LoadNode = function (loader, context, node) {
                 return this._ApplyExtensions(function (extension) { return extension._loadNode(loader, context, node); });
             };
@@ -5543,6 +5554,120 @@ var BABYLON;
 //# sourceMappingURL=KHR_materials_pbrSpecularGlossiness.js.map
 
 
+
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
+            var KHRLights = /** @class */ (function (_super) {
+                __extends(KHRLights, _super);
+                function KHRLights() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(KHRLights.prototype, "name", {
+                    get: function () {
+                        return "KHR_lights";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                KHRLights.prototype.applyCommonProperties = function (light, lightInfo) {
+                    if (lightInfo.color) {
+                        light.diffuse.copyFromFloats(lightInfo.color[0], lightInfo.color[1], lightInfo.color[2]);
+                    }
+                    else {
+                        light.diffuse.copyFromFloats(1, 1, 1);
+                    }
+                    if (lightInfo.intensity !== undefined) {
+                        light.intensity = lightInfo.intensity;
+                    }
+                    else {
+                        light.intensity = 1;
+                    }
+                };
+                KHRLights.prototype._loadScene = function (loader, context, scene) {
+                    return this._loadExtension(context, scene, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            if (lightInfo.type !== 'ambient') {
+                                return;
+                            }
+                            var lightColor = lightInfo.color ? lightInfo.color : [1, 1, 1];
+                            loader._babylonScene.ambientColor.copyFromFloats(lightColor[0], lightColor[1], lightColor[2]);
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadNode = function (loader, context, node) {
+                    var _this = this;
+                    return this._loadExtension(context, node, function (context, extension, onComplete) {
+                        if (extension.light >= 0 && loader._gltf.extensions) {
+                            var lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                            var name_1 = node.name || 'Light';
+                            var matrix = void 0;
+                            if (node.matrix) {
+                                matrix = BABYLON.Matrix.FromArray(node.matrix);
+                            }
+                            else {
+                                matrix = BABYLON.Matrix.Identity();
+                            }
+                            var direction = new BABYLON.Vector3(0, 0, 1);
+                            if (lightInfo.type == 'directional' || lightInfo.type == 'spot') {
+                                var rotationMatrix = matrix.getRotationMatrix();
+                                BABYLON.Vector3.TransformCoordinatesToRef(direction, rotationMatrix, direction);
+                            }
+                            var light = void 0;
+                            if (lightInfo.type == 'directional') {
+                                light = new BABYLON.DirectionalLight(name_1, direction, loader._babylonScene);
+                            }
+                            else {
+                                var position = matrix.getTranslation();
+                                if (lightInfo.type == 'spot') {
+                                    var angle = lightInfo.spot && lightInfo.spot.outerConeAngle ? lightInfo.spot.outerConeAngle : Math.PI / 2;
+                                    light = new BABYLON.SpotLight(name_1, position, direction, angle, 2, loader._babylonScene);
+                                }
+                                else {
+                                    light = new BABYLON.PointLight(name_1, position, loader._babylonScene);
+                                }
+                            }
+                            _this.applyCommonProperties(light, lightInfo);
+                            extension.babylonLight = light;
+                            extension.babylonLight.parent = node.parent ? node.parent.babylonMesh : null;
+                            if (node.children) {
+                                for (var _i = 0, _a = node.children; _i < _a.length; _i++) {
+                                    var index = _a[_i];
+                                    var childNode = GLTF2.GLTFLoader._GetProperty(loader._gltf.nodes, index);
+                                    if (!childNode) {
+                                        throw new Error(context + ": Failed to find child node " + index);
+                                    }
+                                    loader._loadNode("#/nodes/" + index, childNode);
+                                }
+                            }
+                        }
+                        onComplete();
+                    });
+                };
+                KHRLights.prototype._loadRoot = function (loader, context, root) {
+                    return this._loadExtension(context, root, function (context, extension, onComplete) {
+                        extension.lights.forEach(function (light, idx) {
+                            light.index = idx;
+                        });
+                        onComplete();
+                    });
+                };
+                return KHRLights;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHRLights = KHRLights;
+            GLTF2.GLTFLoader.RegisterExtension(new KHRLights());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=KHR_lights.js.map
+
+
 (function universalModuleDefinition(root, factory) {
                 var f = factory();
                 if (root && root["BABYLON"]) {

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 15 - 0
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1179,10 +1179,14 @@ declare module BABYLON.GLTF2 {
         readonly abstract name: string;
         protected _traverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean;
         static _Extensions: GLTFLoaderExtension[];
         static TraverseNode(loader: GLTFLoader, context: string, node: IGLTFNode, action: (node: IGLTFNode, parentNode: IGLTFNode) => boolean, parentNode: IGLTFNode): boolean;
+        static LoadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+        static LoadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
         static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
         static LoadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean;
         private static _ApplyExtensions(action);
@@ -1213,3 +1217,14 @@ declare module BABYLON.GLTF2.Extensions {
         private _loadSpecularGlossinessProperties(loader, context, material, properties);
     }
 }
+
+
+declare module BABYLON.GLTF2.Extensions {
+    class KHRLights extends GLTFLoaderExtension {
+        readonly name: string;
+        private applyCommonProperties(light, lightInfo);
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean;
+        protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean;
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean;
+    }
+}

+ 1 - 1
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 2 - 2
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -98,11 +98,11 @@ var BABYLON;
             // High level
             defines.CELLBASIC = !this.computeHighLevel;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -563,11 +563,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -94,7 +94,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -143,11 +143,11 @@ var BABYLON;
                 defines.markAsUnprocessed();
             }
             // Misc.   
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -118,8 +118,8 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.js

@@ -110,7 +110,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -131,11 +131,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -125,11 +125,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -86,8 +86,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -92,11 +92,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.js

@@ -76,7 +76,7 @@ var BABYLON;
                     return true;
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.skyMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -98,11 +98,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -117,11 +117,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -228,8 +228,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                     defines.FRESNELSEPARATE = true;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


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

@@ -96,8 +96,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
@@ -326,8 +326,8 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
@@ -611,11 +611,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -922,11 +922,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1234,11 +1234,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1642,8 +1642,8 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
                     defines.FRESNELSEPARATE = true;
@@ -2124,7 +2124,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
@@ -2494,11 +2494,11 @@ var BABYLON;
                 defines.markAsUnprocessed();
             }
             // Misc.   
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -2911,11 +2911,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -3317,11 +3317,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -3658,7 +3658,7 @@ var BABYLON;
                     return true;
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);
             // Get correct effect      
@@ -3907,7 +3907,7 @@ var BABYLON;
                 defines.PREMULTIPLYALPHA = !defines.PREMULTIPLYALPHA;
                 defines.markAsUnprocessed();
             }
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -4559,11 +4559,11 @@ var BABYLON;
                 }
             }
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -6149,11 +6149,11 @@ var BABYLON;
             // High level
             defines.CELLBASIC = !this.computeHighLevel;
             // Misc.
-            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

文件差异内容过多而无法显示
+ 6 - 6
dist/preview release/materialsLibrary/babylonjs.materials.min.js


+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 57 - 49
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -107,12 +107,14 @@ declare module BABYLON.GLTF2 {
         constructor(babylonScene: Scene, options?: IExporterOptions);
         /**
          * Creates a buffer view based on teh supplied arguments
-         * @param {number} bufferIndex - index value of the specified buffer
-         * @param {number} byteOffset - byte offset value
-         * @param {number} byteLength - byte length of the bufferView
+         * @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, name?);
+        private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
          * @param bufferviewIndex
@@ -124,43 +126,41 @@ declare module BABYLON.GLTF2 {
          * @param max
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
         /**
          * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff
-         * @param vertexStart
-         * @param vertexCount
-         * @param arrayOffset
-         * @param stride
-         * @returns - min number array and max number array
+         * @param buff - Data to check for min and max values.
+         * @param vertexStart - Start offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @param stride - Offset between consecutive attributes.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, arrayOffset, stride);
+        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
         /**
-         * Write mesh attribute data to buffer.
+         * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
-         * @param vertexBufferType
-         * @param submesh
-         * @param meshAttributeArray
-         * @param strideSize
-         * @param byteOffset
-         * @param dataBuffer
-         * @param useRightHandedSystem
-         * @returns - byte length
+         * @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.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
         /**
          * Generates glTF json data
-         * @param glb
-         * @param glTFPrefix
-         * @param prettyPrint
+         * @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(glb, glTFPrefix?, prettyPrint?);
+        private generateJSON(shouldUseGlb, glTFPrefix?, prettyPrint?);
         /**
          * Generates data for .gltf and .bin files based on the glTF prefix string
-         * @param glTFPrefix
-         * @returns - object with glTF json tex filename
-         * and binary file name as keys and their data as values
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
          */
         _generateGLTF(glTFPrefix: string): _GLTFData;
         /**
@@ -169,7 +169,7 @@ declare module BABYLON.GLTF2 {
          */
         private generateBinary();
         /**
-         * Pads the number to a power of 4
+         * Pads the number to a multiple of 4
          * @param num - number to pad
          * @returns - padded number
          */
@@ -177,45 +177,53 @@ declare module BABYLON.GLTF2 {
         /**
          * 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 jsonText
-         * @param binaryBuffer
          * @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
-         * @param babylonMesh
-         * @param useRightHandedSystem
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
         private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
         /**
          *
-         * @param babylonTexture
-         * @return - glTF texture, or null if the texture format is not supported
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @return - glTF texture, or null if the texture format is not supported.
          */
         private exportTexture(babylonTexture, mimeType?);
         /**
+         * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        /**
          * Sets data for the primitive attributes of each submesh
-         * @param mesh
-         * @param babylonMesh
-         * @param byteOffset
-         * @param useRightHandedSystem
-         * @param dataBuffer
-         * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+         * @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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @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, useRightHandedSystem, dataBuffer?);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
         /**
          * Creates a glTF scene based on the array of meshes.
          * Returns the the total byte offset.
-         * @param gltf
-         * @param byteOffset
-         * @param buffer
-         * @param dataBuffer
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer?);
+        private createScene(babylonScene, byteOffset, dataBuffer);
     }
 }
 

+ 384 - 302
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -50,7 +50,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.glTFSerializer.js.map
 
-/// <reference path="../../../../dist/babylon.glTFInterface.d.ts"/>
+/// <reference path="../../../../dist/babylon.glTF2Interface.d.ts"/>
 /**
  * Module for the Babylon glTF 2.0 exporter.  Should ONLY be used internally.
  * @ignore - capitalization of GLTF2 module.
@@ -78,22 +78,25 @@ var BABYLON;
                 this.nodes = new Array();
                 this.images = new Array();
                 this.materials = new Array();
+                this.textures = new Array();
                 this.imageData = {};
                 if (options !== undefined) {
                     this.options = options;
                 }
                 var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength);
+                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
                 this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
-             * @param {number} bufferIndex - index value of the specified buffer
-             * @param {number} byteOffset - byte offset value
-             * @param {number} byteLength - byte length of the bufferView
+             * @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
              */
-            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, name) {
+            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
                 if (byteOffset > 0) {
                     bufferview.byteOffset = byteOffset;
@@ -101,6 +104,9 @@ var BABYLON;
                 if (name) {
                     bufferview.name = name;
                 }
+                if (byteStride) {
+                    bufferview.byteStride = byteStride;
+                }
                 return bufferview;
             };
             /**
@@ -114,7 +120,7 @@ var BABYLON;
              * @param max
              * @returns - accessor for glTF
              */
-            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, min, max) {
+            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
                 var accessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };
                 if (min) {
                     accessor.min = min;
@@ -122,30 +128,38 @@ var BABYLON;
                 if (max) {
                     accessor.max = max;
                 }
+                if (byteOffset) {
+                    accessor.byteOffset = byteOffset;
+                }
                 return accessor;
             };
             /**
              * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff
-             * @param vertexStart
-             * @param vertexCount
-             * @param arrayOffset
-             * @param stride
-             * @returns - min number array and max number array
+             * @param buff - Data to check for min and max values.
+             * @param vertexStart - Start offset to calculate min and max values.
+             * @param vertexCount - Number of vertices to check for min and max values.
+             * @param stride - Offset between consecutive attributes.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, arrayOffset, stride) {
+            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
                 var end = vertexStart + vertexCount;
                 if (vertexCount > 0) {
                     for (var i = vertexStart; i < end; ++i) {
                         var index = stride * i;
+                        var scale = 1;
                         for (var j = 0; j < stride; ++j) {
-                            if (buff[index] < min[j]) {
-                                min[j] = buff[index];
+                            if (j === (stride - 1) && !useRightHandedSystem) {
+                                scale = -1;
                             }
-                            if (buff[index] > max[j]) {
-                                max[j] = buff[index];
+                            var num = scale * buff[index];
+                            if (num < min[j]) {
+                                min[j] = num;
+                            }
+                            if (num > max[j]) {
+                                max[j] = num;
                             }
                             ++index;
                         }
@@ -154,24 +168,24 @@ var BABYLON;
                 return { min: min, max: max };
             };
             /**
-             * Write mesh attribute data to buffer.
+             * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
-             * @param vertexBufferType
-             * @param submesh
-             * @param meshAttributeArray
-             * @param strideSize
-             * @param byteOffset
-             * @param dataBuffer
-             * @param useRightHandedSystem
-             * @returns - byte length
+             * @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.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
                 var byteOff = byteOffset;
-                var end = submesh.verticesStart + submesh.verticesCount;
+                var start = 0;
+                var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferType) {
+                switch (vertexBufferKind) {
                     case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -185,11 +199,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -203,11 +217,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = submesh.indexStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -223,11 +237,11 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -238,45 +252,45 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferType);
+                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
                     }
                 }
                 return byteLength;
             };
             /**
              * Generates glTF json data
-             * @param glb
-             * @param glTFPrefix
-             * @param prettyPrint
+             * @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
              */
-            _Exporter.prototype.generateJSON = function (glb, glTFPrefix, prettyPrint) {
+            _Exporter.prototype.generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
                 var buffer = { byteLength: this.totalByteLength };
                 var glTF = {
                     asset: this.asset
@@ -307,7 +321,7 @@ var BABYLON;
                     glTF.textures = this.textures;
                 }
                 if (this.images && this.images.length !== 0) {
-                    if (!glb) {
+                    if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
                     else {
@@ -320,7 +334,7 @@ var BABYLON;
                             if (image.uri !== undefined) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
-                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, imageName);
+                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
                                 byteOffset += imageData.data.buffer.byteLength;
                                 this.bufferViews.push(bufferView);
                                 image.bufferView = this.bufferViews.length - 1;
@@ -333,7 +347,7 @@ var BABYLON;
                         buffer.byteLength = byteOffset;
                     }
                 }
-                if (!glb) {
+                if (!shouldUseGlb) {
                     buffer.uri = glTFPrefix + ".bin";
                 }
                 var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
@@ -341,9 +355,8 @@ var BABYLON;
             };
             /**
              * Generates data for .gltf and .bin files based on the glTF prefix string
-             * @param glTFPrefix
-             * @returns - object with glTF json tex filename
-             * and binary file name as keys and their data as values
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
                 var jsonText = this.generateJSON(false, glTFPrefix, true);
@@ -373,7 +386,7 @@ var BABYLON;
                 return binaryBuffer;
             };
             /**
-             * Pads the number to a power of 4
+             * Pads the number to a multiple of 4
              * @param num - number to pad
              * @returns - padded number
              */
@@ -385,8 +398,6 @@ var BABYLON;
             /**
              * 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 jsonText
-             * @param binaryBuffer
              * @param glTFPrefix
              * @returns - object with glb filename as key and data as value
              */
@@ -403,7 +414,8 @@ var BABYLON;
                 }
                 var jsonPadding = this._getPadding(jsonLength);
                 var binPadding = this._getPadding(binaryBuffer.byteLength);
-                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength;
+                var imagePadding = this._getPadding(imageByteLength);
+                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
                 //header
                 var headerBuffer = new ArrayBuffer(headerLength);
                 var headerBufferView = new DataView(headerBuffer);
@@ -428,7 +440,7 @@ var BABYLON;
                 //binary chunk
                 var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
                 var binaryChunkBufferView = new DataView(binaryChunkBuffer);
-                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength, true);
+                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
                 binaryChunkBufferView.setUint32(4, 0x004E4942, true);
                 // binary padding
                 var binPaddingBuffer = new ArrayBuffer(binPadding);
@@ -436,12 +448,18 @@ var BABYLON;
                 for (var i = 0; i < binPadding; ++i) {
                     binPaddingView[i] = 0;
                 }
+                var imagePaddingBuffer = new ArrayBuffer(imagePadding);
+                var imagePaddingView = new Uint8Array(imagePaddingBuffer);
+                for (var i = 0; i < imagePadding; ++i) {
+                    imagePaddingView[i] = 0;
+                }
                 var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
                 // binary data
                 for (var key in this.imageData) {
                     glbData.push(this.imageData[key].data.buffer);
                 }
                 glbData.push(binPaddingBuffer);
+                glbData.push(imagePaddingBuffer);
                 var glbFile = new Blob(glbData, { type: 'application/octet-stream' });
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glbFileName] = glbFile;
@@ -449,9 +467,9 @@ var BABYLON;
             };
             /**
              * Sets the TRS for each node
-             * @param node
-             * @param babylonMesh
-             * @param useRightHandedSystem
+             * @param node - glTF Node for storing the transformation data.
+             * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
@@ -485,8 +503,9 @@ var BABYLON;
             };
             /**
              *
-             * @param babylonTexture
-             * @return - glTF texture, or null if the texture format is not supported
+             * @param babylonTexture - Babylon texture to extract.
+             * @param mimeType - Mime Type of the babylonTexture.
+             * @return - glTF texture, or null if the texture format is not supported.
              */
             _Exporter.prototype.exportTexture = function (babylonTexture, mimeType) {
                 if (mimeType === void 0) { mimeType = "image/jpeg" /* JPEG */; }
@@ -561,289 +580,352 @@ var BABYLON;
                 return textureInfo;
             };
             /**
-             * Sets data for the primitive attributes of each submesh
-             * @param mesh
-             * @param babylonMesh
-             * @param byteOffset
-             * @param useRightHandedSystem
-             * @param dataBuffer
-             * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+             * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - The buffer to write the bufferview data to.
+             * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var bufferMesh = null;
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (babylonMesh instanceof BABYLON.Mesh) {
-                        bufferMesh = babylonMesh;
-                    }
-                    else if (babylonMesh instanceof BABYLON.InstancedMesh) {
-                        bufferMesh = babylonMesh.sourceMesh;
-                    }
-                    // Loop through each attribute of the submesh (mesh primitive)
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                        var positionVertexBufferOffset = positionVertexBuffer.getOffset();
-                        var positions = positionVertexBuffer.getData();
-                        var positionStrideSize = positionVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.PositionKind, submesh, positions, positionStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Positions");
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                var byteLength = 0;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                if (bufferMesh !== null) {
+                    var vertexBuffer = null;
+                    var vertexBufferOffset = null;
+                    var vertexData = null;
+                    var vertexStrideSize = null;
+                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
+                        vertexBufferOffset = vertexBuffer.getOffset();
+                        vertexData = vertexBuffer.getData();
+                        vertexStrideSize = vertexBuffer.getStrideSize();
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var result = this.calculateMinMax(positions, submesh.verticesStart, submesh.verticesCount, positionVertexBufferOffset, positionStrideSize);
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount, result.min, result.max);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                        }
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                        var normals = normalVertexBuffer.getData();
-                        var normalStrideSize = normalVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.NormalKind, submesh, normals, normalStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
                         }
                         else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Normals");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                            var bufferViewName = null;
+                            switch (kind) {
+                                case BABYLON.VertexBuffer.PositionKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Position - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.NormalKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Normal - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.TangentKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Tangent - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.ColorKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Color - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UVKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UV2Kind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
+                                    break;
+                                }
+                                default: {
+                                    console.warn("Unsupported VertexBuffer kind: " + kind);
+                                }
+                            }
+                            if (bufferViewName !== null) {
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                            }
                         }
                     }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                        var tangents = tangentVertexBuffer.getData();
-                        var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.TangentKind, submesh, tangents, tangentStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Tangents");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                        }
+                }
+                return byteLength;
+            };
+            /**
+             * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - Buffer to write the attribute data to.
+             * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+             */
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                var positionBufferViewIndex = null;
+                var normalBufferViewIndex = null;
+                var colorBufferViewIndex = null;
+                var tangentBufferViewIndex = null;
+                var texCoord0BufferViewIndex = null;
+                var texCoord1BufferViewIndex = null;
+                var indexBufferViewIndex = null;
+                if (bufferMesh !== null) {
+                    // For each BabylonMesh, create bufferviews for each 'kind'
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        positionBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        normalBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                        var colors = colorVertexBuffer.getData();
-                        var colorStrideSize = colorVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.ColorKind, submesh, colors, colorStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Colors");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                        var texCoords0 = texCoord0VertexBuffer.getData();
-                        var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UVKind, submesh, texCoords0, texCoord0StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords0");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                        var texCoords1 = texCoord1VertexBuffer.getData();
-                        var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UV2Kind, submesh, texCoords1, texCoord1StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords 1");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.getTotalIndices() > 0) {
+                        var indices = bufferMesh.getIndices();
                         if (dataBuffer) {
-                            var indices = bufferMesh.getIndices();
-                            var start = submesh.indexStart;
-                            var end = submesh.indexCount + start;
+                            var end = indices.length;
                             var byteOff = byteOffset;
-                            for (var k = start; k < end; k = k + 3) {
+                            for (var k = 0; k < end; ++k) {
                                 dataBuffer.setUint32(byteOff, indices[k], true);
                                 byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 1], true);
-                                byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 2], true);
-                                byteOff += 4;
                             }
-                            var byteLength = submesh.indexCount * 4;
-                            byteOffset += byteLength;
+                            byteOffset = byteOff;
                         }
                         else {
-                            // Create bufferview
-                            var indicesCount = submesh.indexCount;
-                            var byteLength = indicesCount * 4;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Indices");
+                            var byteLength = indices.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, indicesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.indices = this.accessors.length - 1;
+                            this.bufferViews.push(bufferView);
+                            indexBufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                    if (bufferMesh.material) {
-                        if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
-                            var babylonStandardMaterial = bufferMesh.material;
-                            var glTFMaterial = { name: babylonStandardMaterial.name };
-                            if (!babylonStandardMaterial.backFaceCulling) {
-                                glTFMaterial.doubleSided = true;
-                            }
-                            if (babylonStandardMaterial.bumpTexture) {
-                                var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
-                                }
-                            }
-                            if (babylonStandardMaterial.emissiveTexture) {
-                                var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
-                                if (glTFEmissiveTexture) {
-                                    glTFMaterial.emissiveTexture = glTFEmissiveTexture;
-                                }
-                                glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                }
+                // go through all mesh primitives (submeshes)
+                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
+                    var submesh = babylonMesh.subMeshes[j];
+                    var meshPrimitive = { attributes: {} };
+                    if (bufferMesh !== null) {
+                        // Create a bufferview storing all the positions
+                        if (!dataBuffer) {
+                            // Loop through each attribute of the submesh (mesh primitive)
+                            if (positionBufferViewIndex !== null) {
+                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
+                                var positions = positionVertexBuffer.getData();
+                                var positionStrideSize = positionVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
+                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
                             }
-                            if (babylonStandardMaterial.ambientTexture) {
-                                var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
-                                if (glTFOcclusionTexture) {
-                                    glTFMaterial.occlusionTexture = glTFOcclusionTexture;
-                                }
+                            if (normalBufferViewIndex !== null) {
+                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
+                                var normals = normalVertexBuffer.getData();
+                                var normalStrideSize = normalVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
                             }
-                            // Spec Gloss
-                            var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
-                        }
-                        else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                            if (!this.textures) {
-                                this.textures = new Array();
+                            if (tangentBufferViewIndex !== null) {
+                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
+                                var tangents = tangentVertexBuffer.getData();
+                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
                             }
-                            var babylonPBRMaterial = bufferMesh.material;
-                            var glTFPbrMetallicRoughness = {};
-                            if (babylonPBRMaterial.baseColor) {
-                                glTFPbrMetallicRoughness.baseColorFactor = [
-                                    babylonPBRMaterial.baseColor.r,
-                                    babylonPBRMaterial.baseColor.g,
-                                    babylonPBRMaterial.baseColor.b,
-                                    babylonPBRMaterial.alpha
-                                ];
+                            if (colorBufferViewIndex !== null) {
+                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
+                                var colors = colorVertexBuffer.getData();
+                                var colorStrideSize = colorVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.baseTexture !== undefined) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
-                                if (glTFTexture !== null) {
-                                    glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                                }
-                                glTFPbrMetallicRoughness.baseColorTexture;
+                            if (texCoord0BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
+                                var texCoord0s = texCoord0VertexBuffer.getData();
+                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.metallic !== undefined) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            if (texCoord1BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
+                                var texCoord1s = texCoord1VertexBuffer.getData();
+                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.roughness !== undefined) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            if (indexBufferViewIndex) {
+                                // Create accessor
+                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
+                                this.accessors.push(accessor);
+                                meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            var glTFMaterial = {
-                                name: babylonPBRMaterial.name
-                            };
-                            if (babylonPBRMaterial.doubleSided) {
-                                glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
-                            }
-                            if (babylonPBRMaterial.normalTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
+                        }
+                        if (bufferMesh.material) {
+                            if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
+                                console.warn("Standard Material is currently not fully supported/implemented in glTF serializer");
+                                var babylonStandardMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                                var glTFMaterial = { name: babylonStandardMaterial.name };
+                                if (!babylonStandardMaterial.backFaceCulling) {
+                                    glTFMaterial.doubleSided = true;
                                 }
-                            }
-                            if (babylonPBRMaterial.occlusionTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.occlusionTexture = glTFTexture;
-                                    if (babylonPBRMaterial.occlusionStrength !== undefined) {
-                                        glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                if (babylonStandardMaterial.diffuseTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.diffuseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
                                 }
-                            }
-                            if (babylonPBRMaterial.emissiveTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
-                                if (glTFTexture !== null) {
-                                    glTFMaterial.emissiveTexture = glTFTexture;
+                                if (babylonStandardMaterial.bumpTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
                                 }
+                                if (babylonStandardMaterial.emissiveTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
+                                    if (glTFEmissiveTexture) {
+                                        glTFMaterial.emissiveTexture = glTFEmissiveTexture;
+                                    }
+                                    glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                                }
+                                if (babylonStandardMaterial.ambientTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
+                                    if (glTFOcclusionTexture) {
+                                        glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                                    }
+                                }
+                                if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
+                                    if (babylonStandardMaterial.alphaMode === BABYLON.Engine.ALPHA_COMBINE) {
+                                        glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                                    }
+                                    else {
+                                        console.warn("glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
                             }
-                            if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
-                                glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
-                            }
-                            if (babylonPBRMaterial.transparencyMode) {
-                                var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                                    glTFMaterial.alphaMode = alphaMode;
-                                    if (alphaMode === "BLEND" /* BLEND */) {
-                                        glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                            else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                var babylonPBRMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = {};
+                                if (babylonPBRMaterial.baseColor) {
+                                    glTFPbrMetallicRoughness.baseColorFactor = [
+                                        babylonPBRMaterial.baseColor.r,
+                                        babylonPBRMaterial.baseColor.g,
+                                        babylonPBRMaterial.baseColor.b,
+                                        babylonPBRMaterial.alpha
+                                    ];
+                                }
+                                if (babylonPBRMaterial.baseTexture !== undefined) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
+                                    glTFPbrMetallicRoughness.baseColorTexture;
                                 }
+                                if (babylonPBRMaterial.metallic !== undefined) {
+                                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                                }
+                                if (babylonPBRMaterial.roughness !== undefined) {
+                                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                                }
+                                var glTFMaterial = {
+                                    name: babylonPBRMaterial.name
+                                };
+                                if (babylonPBRMaterial.doubleSided) {
+                                    glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
+                                }
+                                if (babylonPBRMaterial.normalTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
+                                }
+                                if (babylonPBRMaterial.occlusionTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.occlusionTexture = glTFTexture;
+                                        if (babylonPBRMaterial.occlusionStrength !== undefined) {
+                                            glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                        }
+                                    }
+                                }
+                                if (babylonPBRMaterial.emissiveTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFMaterial.emissiveTexture = glTFTexture;
+                                    }
+                                }
+                                if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
+                                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                                }
+                                if (babylonPBRMaterial.transparencyMode) {
+                                    var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
+                                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                                        glTFMaterial.alphaMode = alphaMode;
+                                        if (alphaMode === "BLEND" /* BLEND */) {
+                                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                                        }
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
+                            }
+                            else {
+                                console.warn("Material type is not yet implemented in glTF serializer: " + bufferMesh.material.name);
                             }
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
                         }
+                        mesh.primitives.push(meshPrimitive);
                     }
-                    mesh.primitives.push(meshPrimitive);
                 }
                 return byteOffset;
             };
             /**
              * Creates a glTF scene based on the array of meshes.
              * Returns the the total byte offset.
-             * @param gltf
-             * @param byteOffset
-             * @param buffer
-             * @param dataBuffer
+             * @param babylonScene - Babylon scene to get the mesh data from.
+             * @param byteOffset - Offset to start from in bytes.
+             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
             _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
@@ -889,7 +971,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.glTFExporter.js.map
 
-/// <reference path="../../../../dist/babylon.glTFInterface.d.ts"/>
+/// <reference path="../../../../dist/babylon.glTF2Interface.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
     /**
@@ -948,7 +1030,7 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.glTFData.js.map
 
-/// <reference path="../../../../dist/babylon.glTFInterface.d.ts"/>
+/// <reference path="../../../../dist/babylon.glTF2Interface.d.ts"/>
 var BABYLON;
 (function (BABYLON) {
     var GLTF2;
@@ -996,7 +1078,7 @@ var BABYLON;
                 var diffuse = babylonSpecularGlossiness.diffuse;
                 var opacity = babylonSpecularGlossiness.opacity;
                 var specular = babylonSpecularGlossiness.specular;
-                var glossiness = babylonSpecularGlossiness.glossiness;
+                var glossiness = BABYLON.Scalar.Clamp(babylonSpecularGlossiness.glossiness);
                 var oneMinusSpecularStrength = 1 - Math.max(specular.r, Math.max(specular.g, specular.b));
                 var diffusePerceivedBrightness = _GLTFMaterial.PerceivedBrightness(diffuse);
                 var specularPerceivedBrightness = _GLTFMaterial.PerceivedBrightness(specular);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 381 - 299
dist/preview release/serializers/babylonjs.serializers.js

@@ -222,22 +222,25 @@ var BABYLON;
                 this.nodes = new Array();
                 this.images = new Array();
                 this.materials = new Array();
+                this.textures = new Array();
                 this.imageData = {};
                 if (options !== undefined) {
                     this.options = options;
                 }
                 var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength);
+                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
                 this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
-             * @param {number} bufferIndex - index value of the specified buffer
-             * @param {number} byteOffset - byte offset value
-             * @param {number} byteLength - byte length of the bufferView
+             * @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
              */
-            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, name) {
+            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
                 if (byteOffset > 0) {
                     bufferview.byteOffset = byteOffset;
@@ -245,6 +248,9 @@ var BABYLON;
                 if (name) {
                     bufferview.name = name;
                 }
+                if (byteStride) {
+                    bufferview.byteStride = byteStride;
+                }
                 return bufferview;
             };
             /**
@@ -258,7 +264,7 @@ var BABYLON;
              * @param max
              * @returns - accessor for glTF
              */
-            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, min, max) {
+            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
                 var accessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };
                 if (min) {
                     accessor.min = min;
@@ -266,30 +272,38 @@ var BABYLON;
                 if (max) {
                     accessor.max = max;
                 }
+                if (byteOffset) {
+                    accessor.byteOffset = byteOffset;
+                }
                 return accessor;
             };
             /**
              * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff
-             * @param vertexStart
-             * @param vertexCount
-             * @param arrayOffset
-             * @param stride
-             * @returns - min number array and max number array
+             * @param buff - Data to check for min and max values.
+             * @param vertexStart - Start offset to calculate min and max values.
+             * @param vertexCount - Number of vertices to check for min and max values.
+             * @param stride - Offset between consecutive attributes.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, arrayOffset, stride) {
+            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
                 var end = vertexStart + vertexCount;
                 if (vertexCount > 0) {
                     for (var i = vertexStart; i < end; ++i) {
                         var index = stride * i;
+                        var scale = 1;
                         for (var j = 0; j < stride; ++j) {
-                            if (buff[index] < min[j]) {
-                                min[j] = buff[index];
+                            if (j === (stride - 1) && !useRightHandedSystem) {
+                                scale = -1;
                             }
-                            if (buff[index] > max[j]) {
-                                max[j] = buff[index];
+                            var num = scale * buff[index];
+                            if (num < min[j]) {
+                                min[j] = num;
+                            }
+                            if (num > max[j]) {
+                                max[j] = num;
                             }
                             ++index;
                         }
@@ -298,24 +312,24 @@ var BABYLON;
                 return { min: min, max: max };
             };
             /**
-             * Write mesh attribute data to buffer.
+             * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
-             * @param vertexBufferType
-             * @param submesh
-             * @param meshAttributeArray
-             * @param strideSize
-             * @param byteOffset
-             * @param dataBuffer
-             * @param useRightHandedSystem
-             * @returns - byte length
+             * @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.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
                 var byteOff = byteOffset;
-                var end = submesh.verticesStart + submesh.verticesCount;
+                var start = 0;
+                var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferType) {
+                switch (vertexBufferKind) {
                     case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -329,11 +343,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -347,11 +361,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = submesh.indexStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -367,11 +381,11 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -382,45 +396,45 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferType);
+                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
                     }
                 }
                 return byteLength;
             };
             /**
              * Generates glTF json data
-             * @param glb
-             * @param glTFPrefix
-             * @param prettyPrint
+             * @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
              */
-            _Exporter.prototype.generateJSON = function (glb, glTFPrefix, prettyPrint) {
+            _Exporter.prototype.generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
                 var buffer = { byteLength: this.totalByteLength };
                 var glTF = {
                     asset: this.asset
@@ -451,7 +465,7 @@ var BABYLON;
                     glTF.textures = this.textures;
                 }
                 if (this.images && this.images.length !== 0) {
-                    if (!glb) {
+                    if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
                     else {
@@ -464,7 +478,7 @@ var BABYLON;
                             if (image.uri !== undefined) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
-                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, imageName);
+                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
                                 byteOffset += imageData.data.buffer.byteLength;
                                 this.bufferViews.push(bufferView);
                                 image.bufferView = this.bufferViews.length - 1;
@@ -477,7 +491,7 @@ var BABYLON;
                         buffer.byteLength = byteOffset;
                     }
                 }
-                if (!glb) {
+                if (!shouldUseGlb) {
                     buffer.uri = glTFPrefix + ".bin";
                 }
                 var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
@@ -485,9 +499,8 @@ var BABYLON;
             };
             /**
              * Generates data for .gltf and .bin files based on the glTF prefix string
-             * @param glTFPrefix
-             * @returns - object with glTF json tex filename
-             * and binary file name as keys and their data as values
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
                 var jsonText = this.generateJSON(false, glTFPrefix, true);
@@ -517,7 +530,7 @@ var BABYLON;
                 return binaryBuffer;
             };
             /**
-             * Pads the number to a power of 4
+             * Pads the number to a multiple of 4
              * @param num - number to pad
              * @returns - padded number
              */
@@ -529,8 +542,6 @@ var BABYLON;
             /**
              * 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 jsonText
-             * @param binaryBuffer
              * @param glTFPrefix
              * @returns - object with glb filename as key and data as value
              */
@@ -547,7 +558,8 @@ var BABYLON;
                 }
                 var jsonPadding = this._getPadding(jsonLength);
                 var binPadding = this._getPadding(binaryBuffer.byteLength);
-                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength;
+                var imagePadding = this._getPadding(imageByteLength);
+                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
                 //header
                 var headerBuffer = new ArrayBuffer(headerLength);
                 var headerBufferView = new DataView(headerBuffer);
@@ -572,7 +584,7 @@ var BABYLON;
                 //binary chunk
                 var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
                 var binaryChunkBufferView = new DataView(binaryChunkBuffer);
-                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength, true);
+                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
                 binaryChunkBufferView.setUint32(4, 0x004E4942, true);
                 // binary padding
                 var binPaddingBuffer = new ArrayBuffer(binPadding);
@@ -580,12 +592,18 @@ var BABYLON;
                 for (var i = 0; i < binPadding; ++i) {
                     binPaddingView[i] = 0;
                 }
+                var imagePaddingBuffer = new ArrayBuffer(imagePadding);
+                var imagePaddingView = new Uint8Array(imagePaddingBuffer);
+                for (var i = 0; i < imagePadding; ++i) {
+                    imagePaddingView[i] = 0;
+                }
                 var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
                 // binary data
                 for (var key in this.imageData) {
                     glbData.push(this.imageData[key].data.buffer);
                 }
                 glbData.push(binPaddingBuffer);
+                glbData.push(imagePaddingBuffer);
                 var glbFile = new Blob(glbData, { type: 'application/octet-stream' });
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glbFileName] = glbFile;
@@ -593,9 +611,9 @@ var BABYLON;
             };
             /**
              * Sets the TRS for each node
-             * @param node
-             * @param babylonMesh
-             * @param useRightHandedSystem
+             * @param node - glTF Node for storing the transformation data.
+             * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
@@ -629,8 +647,9 @@ var BABYLON;
             };
             /**
              *
-             * @param babylonTexture
-             * @return - glTF texture, or null if the texture format is not supported
+             * @param babylonTexture - Babylon texture to extract.
+             * @param mimeType - Mime Type of the babylonTexture.
+             * @return - glTF texture, or null if the texture format is not supported.
              */
             _Exporter.prototype.exportTexture = function (babylonTexture, mimeType) {
                 if (mimeType === void 0) { mimeType = "image/jpeg" /* JPEG */; }
@@ -705,289 +724,352 @@ var BABYLON;
                 return textureInfo;
             };
             /**
-             * Sets data for the primitive attributes of each submesh
-             * @param mesh
-             * @param babylonMesh
-             * @param byteOffset
-             * @param useRightHandedSystem
-             * @param dataBuffer
-             * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+             * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - The buffer to write the bufferview data to.
+             * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var bufferMesh = null;
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (babylonMesh instanceof BABYLON.Mesh) {
-                        bufferMesh = babylonMesh;
-                    }
-                    else if (babylonMesh instanceof BABYLON.InstancedMesh) {
-                        bufferMesh = babylonMesh.sourceMesh;
-                    }
-                    // Loop through each attribute of the submesh (mesh primitive)
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                        var positionVertexBufferOffset = positionVertexBuffer.getOffset();
-                        var positions = positionVertexBuffer.getData();
-                        var positionStrideSize = positionVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.PositionKind, submesh, positions, positionStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Positions");
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                var byteLength = 0;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                if (bufferMesh !== null) {
+                    var vertexBuffer = null;
+                    var vertexBufferOffset = null;
+                    var vertexData = null;
+                    var vertexStrideSize = null;
+                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
+                        vertexBufferOffset = vertexBuffer.getOffset();
+                        vertexData = vertexBuffer.getData();
+                        vertexStrideSize = vertexBuffer.getStrideSize();
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var result = this.calculateMinMax(positions, submesh.verticesStart, submesh.verticesCount, positionVertexBufferOffset, positionStrideSize);
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount, result.min, result.max);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                        }
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                        var normals = normalVertexBuffer.getData();
-                        var normalStrideSize = normalVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.NormalKind, submesh, normals, normalStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
                         }
                         else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Normals");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                            var bufferViewName = null;
+                            switch (kind) {
+                                case BABYLON.VertexBuffer.PositionKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Position - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.NormalKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Normal - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.TangentKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Tangent - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.ColorKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Color - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UVKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UV2Kind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
+                                    break;
+                                }
+                                default: {
+                                    console.warn("Unsupported VertexBuffer kind: " + kind);
+                                }
+                            }
+                            if (bufferViewName !== null) {
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                            }
                         }
                     }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                        var tangents = tangentVertexBuffer.getData();
-                        var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.TangentKind, submesh, tangents, tangentStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Tangents");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                        }
+                }
+                return byteLength;
+            };
+            /**
+             * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - Buffer to write the attribute data to.
+             * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+             */
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                var positionBufferViewIndex = null;
+                var normalBufferViewIndex = null;
+                var colorBufferViewIndex = null;
+                var tangentBufferViewIndex = null;
+                var texCoord0BufferViewIndex = null;
+                var texCoord1BufferViewIndex = null;
+                var indexBufferViewIndex = null;
+                if (bufferMesh !== null) {
+                    // For each BabylonMesh, create bufferviews for each 'kind'
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        positionBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        normalBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                        var colors = colorVertexBuffer.getData();
-                        var colorStrideSize = colorVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.ColorKind, submesh, colors, colorStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Colors");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                        var texCoords0 = texCoord0VertexBuffer.getData();
-                        var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UVKind, submesh, texCoords0, texCoord0StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords0");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                        var texCoords1 = texCoord1VertexBuffer.getData();
-                        var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UV2Kind, submesh, texCoords1, texCoord1StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords 1");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.getTotalIndices() > 0) {
+                        var indices = bufferMesh.getIndices();
                         if (dataBuffer) {
-                            var indices = bufferMesh.getIndices();
-                            var start = submesh.indexStart;
-                            var end = submesh.indexCount + start;
+                            var end = indices.length;
                             var byteOff = byteOffset;
-                            for (var k = start; k < end; k = k + 3) {
+                            for (var k = 0; k < end; ++k) {
                                 dataBuffer.setUint32(byteOff, indices[k], true);
                                 byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 1], true);
-                                byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 2], true);
-                                byteOff += 4;
                             }
-                            var byteLength = submesh.indexCount * 4;
-                            byteOffset += byteLength;
+                            byteOffset = byteOff;
                         }
                         else {
-                            // Create bufferview
-                            var indicesCount = submesh.indexCount;
-                            var byteLength = indicesCount * 4;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Indices");
+                            var byteLength = indices.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, indicesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.indices = this.accessors.length - 1;
+                            this.bufferViews.push(bufferView);
+                            indexBufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                    if (bufferMesh.material) {
-                        if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
-                            var babylonStandardMaterial = bufferMesh.material;
-                            var glTFMaterial = { name: babylonStandardMaterial.name };
-                            if (!babylonStandardMaterial.backFaceCulling) {
-                                glTFMaterial.doubleSided = true;
-                            }
-                            if (babylonStandardMaterial.bumpTexture) {
-                                var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
-                                }
-                            }
-                            if (babylonStandardMaterial.emissiveTexture) {
-                                var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
-                                if (glTFEmissiveTexture) {
-                                    glTFMaterial.emissiveTexture = glTFEmissiveTexture;
-                                }
-                                glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                }
+                // go through all mesh primitives (submeshes)
+                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
+                    var submesh = babylonMesh.subMeshes[j];
+                    var meshPrimitive = { attributes: {} };
+                    if (bufferMesh !== null) {
+                        // Create a bufferview storing all the positions
+                        if (!dataBuffer) {
+                            // Loop through each attribute of the submesh (mesh primitive)
+                            if (positionBufferViewIndex !== null) {
+                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
+                                var positions = positionVertexBuffer.getData();
+                                var positionStrideSize = positionVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
+                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
                             }
-                            if (babylonStandardMaterial.ambientTexture) {
-                                var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
-                                if (glTFOcclusionTexture) {
-                                    glTFMaterial.occlusionTexture = glTFOcclusionTexture;
-                                }
+                            if (normalBufferViewIndex !== null) {
+                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
+                                var normals = normalVertexBuffer.getData();
+                                var normalStrideSize = normalVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
                             }
-                            // Spec Gloss
-                            var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
-                        }
-                        else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                            if (!this.textures) {
-                                this.textures = new Array();
+                            if (tangentBufferViewIndex !== null) {
+                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
+                                var tangents = tangentVertexBuffer.getData();
+                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
                             }
-                            var babylonPBRMaterial = bufferMesh.material;
-                            var glTFPbrMetallicRoughness = {};
-                            if (babylonPBRMaterial.baseColor) {
-                                glTFPbrMetallicRoughness.baseColorFactor = [
-                                    babylonPBRMaterial.baseColor.r,
-                                    babylonPBRMaterial.baseColor.g,
-                                    babylonPBRMaterial.baseColor.b,
-                                    babylonPBRMaterial.alpha
-                                ];
+                            if (colorBufferViewIndex !== null) {
+                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
+                                var colors = colorVertexBuffer.getData();
+                                var colorStrideSize = colorVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.baseTexture !== undefined) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
-                                if (glTFTexture !== null) {
-                                    glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                                }
-                                glTFPbrMetallicRoughness.baseColorTexture;
+                            if (texCoord0BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
+                                var texCoord0s = texCoord0VertexBuffer.getData();
+                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.metallic !== undefined) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            if (texCoord1BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
+                                var texCoord1s = texCoord1VertexBuffer.getData();
+                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.roughness !== undefined) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            if (indexBufferViewIndex) {
+                                // Create accessor
+                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
+                                this.accessors.push(accessor);
+                                meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            var glTFMaterial = {
-                                name: babylonPBRMaterial.name
-                            };
-                            if (babylonPBRMaterial.doubleSided) {
-                                glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
-                            }
-                            if (babylonPBRMaterial.normalTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
+                        }
+                        if (bufferMesh.material) {
+                            if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
+                                console.warn("Standard Material is currently not fully supported/implemented in glTF serializer");
+                                var babylonStandardMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                                var glTFMaterial = { name: babylonStandardMaterial.name };
+                                if (!babylonStandardMaterial.backFaceCulling) {
+                                    glTFMaterial.doubleSided = true;
                                 }
-                            }
-                            if (babylonPBRMaterial.occlusionTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.occlusionTexture = glTFTexture;
-                                    if (babylonPBRMaterial.occlusionStrength !== undefined) {
-                                        glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                if (babylonStandardMaterial.diffuseTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.diffuseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
                                 }
-                            }
-                            if (babylonPBRMaterial.emissiveTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
-                                if (glTFTexture !== null) {
-                                    glTFMaterial.emissiveTexture = glTFTexture;
+                                if (babylonStandardMaterial.bumpTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
                                 }
+                                if (babylonStandardMaterial.emissiveTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
+                                    if (glTFEmissiveTexture) {
+                                        glTFMaterial.emissiveTexture = glTFEmissiveTexture;
+                                    }
+                                    glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                                }
+                                if (babylonStandardMaterial.ambientTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
+                                    if (glTFOcclusionTexture) {
+                                        glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                                    }
+                                }
+                                if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
+                                    if (babylonStandardMaterial.alphaMode === BABYLON.Engine.ALPHA_COMBINE) {
+                                        glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                                    }
+                                    else {
+                                        console.warn("glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
                             }
-                            if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
-                                glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
-                            }
-                            if (babylonPBRMaterial.transparencyMode) {
-                                var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                                    glTFMaterial.alphaMode = alphaMode;
-                                    if (alphaMode === "BLEND" /* BLEND */) {
-                                        glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                            else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                var babylonPBRMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = {};
+                                if (babylonPBRMaterial.baseColor) {
+                                    glTFPbrMetallicRoughness.baseColorFactor = [
+                                        babylonPBRMaterial.baseColor.r,
+                                        babylonPBRMaterial.baseColor.g,
+                                        babylonPBRMaterial.baseColor.b,
+                                        babylonPBRMaterial.alpha
+                                    ];
+                                }
+                                if (babylonPBRMaterial.baseTexture !== undefined) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
+                                    glTFPbrMetallicRoughness.baseColorTexture;
                                 }
+                                if (babylonPBRMaterial.metallic !== undefined) {
+                                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                                }
+                                if (babylonPBRMaterial.roughness !== undefined) {
+                                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                                }
+                                var glTFMaterial = {
+                                    name: babylonPBRMaterial.name
+                                };
+                                if (babylonPBRMaterial.doubleSided) {
+                                    glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
+                                }
+                                if (babylonPBRMaterial.normalTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
+                                }
+                                if (babylonPBRMaterial.occlusionTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.occlusionTexture = glTFTexture;
+                                        if (babylonPBRMaterial.occlusionStrength !== undefined) {
+                                            glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                        }
+                                    }
+                                }
+                                if (babylonPBRMaterial.emissiveTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFMaterial.emissiveTexture = glTFTexture;
+                                    }
+                                }
+                                if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
+                                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                                }
+                                if (babylonPBRMaterial.transparencyMode) {
+                                    var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
+                                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                                        glTFMaterial.alphaMode = alphaMode;
+                                        if (alphaMode === "BLEND" /* BLEND */) {
+                                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                                        }
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
+                            }
+                            else {
+                                console.warn("Material type is not yet implemented in glTF serializer: " + bufferMesh.material.name);
                             }
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
                         }
+                        mesh.primitives.push(meshPrimitive);
                     }
-                    mesh.primitives.push(meshPrimitive);
                 }
                 return byteOffset;
             };
             /**
              * Creates a glTF scene based on the array of meshes.
              * Returns the the total byte offset.
-             * @param gltf
-             * @param byteOffset
-             * @param buffer
-             * @param dataBuffer
+             * @param babylonScene - Babylon scene to get the mesh data from.
+             * @param byteOffset - Offset to start from in bytes.
+             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
             _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
@@ -1140,7 +1222,7 @@ var BABYLON;
                 var diffuse = babylonSpecularGlossiness.diffuse;
                 var opacity = babylonSpecularGlossiness.opacity;
                 var specular = babylonSpecularGlossiness.specular;
-                var glossiness = babylonSpecularGlossiness.glossiness;
+                var glossiness = BABYLON.Scalar.Clamp(babylonSpecularGlossiness.glossiness);
                 var oneMinusSpecularStrength = 1 - Math.max(specular.r, Math.max(specular.g, specular.b));
                 var diffusePerceivedBrightness = _GLTFMaterial.PerceivedBrightness(diffuse);
                 var specularPerceivedBrightness = _GLTFMaterial.PerceivedBrightness(specular);

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 57 - 49
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -121,12 +121,14 @@ declare module BABYLON.GLTF2 {
         constructor(babylonScene: Scene, options?: IExporterOptions);
         /**
          * Creates a buffer view based on teh supplied arguments
-         * @param {number} bufferIndex - index value of the specified buffer
-         * @param {number} byteOffset - byte offset value
-         * @param {number} byteLength - byte length of the bufferView
+         * @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, name?);
+        private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
          * @param bufferviewIndex
@@ -138,43 +140,41 @@ declare module BABYLON.GLTF2 {
          * @param max
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
         /**
          * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff
-         * @param vertexStart
-         * @param vertexCount
-         * @param arrayOffset
-         * @param stride
-         * @returns - min number array and max number array
+         * @param buff - Data to check for min and max values.
+         * @param vertexStart - Start offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @param stride - Offset between consecutive attributes.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, arrayOffset, stride);
+        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
         /**
-         * Write mesh attribute data to buffer.
+         * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
-         * @param vertexBufferType
-         * @param submesh
-         * @param meshAttributeArray
-         * @param strideSize
-         * @param byteOffset
-         * @param dataBuffer
-         * @param useRightHandedSystem
-         * @returns - byte length
+         * @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.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
         /**
          * Generates glTF json data
-         * @param glb
-         * @param glTFPrefix
-         * @param prettyPrint
+         * @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(glb, glTFPrefix?, prettyPrint?);
+        private generateJSON(shouldUseGlb, glTFPrefix?, prettyPrint?);
         /**
          * Generates data for .gltf and .bin files based on the glTF prefix string
-         * @param glTFPrefix
-         * @returns - object with glTF json tex filename
-         * and binary file name as keys and their data as values
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
          */
         _generateGLTF(glTFPrefix: string): _GLTFData;
         /**
@@ -183,7 +183,7 @@ declare module BABYLON.GLTF2 {
          */
         private generateBinary();
         /**
-         * Pads the number to a power of 4
+         * Pads the number to a multiple of 4
          * @param num - number to pad
          * @returns - padded number
          */
@@ -191,45 +191,53 @@ declare module BABYLON.GLTF2 {
         /**
          * 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 jsonText
-         * @param binaryBuffer
          * @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
-         * @param babylonMesh
-         * @param useRightHandedSystem
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
         private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
         /**
          *
-         * @param babylonTexture
-         * @return - glTF texture, or null if the texture format is not supported
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @return - glTF texture, or null if the texture format is not supported.
          */
         private exportTexture(babylonTexture, mimeType?);
         /**
+         * 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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        /**
          * Sets data for the primitive attributes of each submesh
-         * @param mesh
-         * @param babylonMesh
-         * @param byteOffset
-         * @param useRightHandedSystem
-         * @param dataBuffer
-         * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+         * @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 useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @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, useRightHandedSystem, dataBuffer?);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
         /**
          * Creates a glTF scene based on the array of meshes.
          * Returns the the total byte offset.
-         * @param gltf
-         * @param byteOffset
-         * @param buffer
-         * @param dataBuffer
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer?);
+        private createScene(babylonScene, byteOffset, dataBuffer);
     }
 }
 

+ 1 - 1
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

文件差异内容过多而无法显示
+ 787 - 4139
dist/preview release/typedocValidationBaseline.json


文件差异内容过多而无法显示
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


+ 1 - 1
dist/preview release/viewer/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-viewer",
     "description": "A simple-to-use viewer based on BabylonJS to display 3D elements natively",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -6,11 +6,13 @@
 - New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
 - `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
 - New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
+- Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
+- Introduced Projection Texture on SpotLight (`spotLight.projectedLightTexture`) ([lostink](https://github.com/lostink))
 
 ## Updates
 - Tons of functions and classes received the code comments they deserved (All the community)
 - Added support for all RGBA orders (BGR, RGB, etc..) for the DDS loader ([deltakosh](https://github.com/deltakosh))
-- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adapatability ([deltakosh](https://github.com/deltakosh))
+- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adaptability ([deltakosh](https://github.com/deltakosh))
 - Improved `scene.isReady()` function which now takes in account shadows and LOD ([deltakosh](https://github.com/deltakosh))
 - New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
 - Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
@@ -23,12 +25,29 @@
    ([carloslanderas](https://github.com/carloslanderas))
 - VRHelper now exposes onNewMeshPicked observable that will notify a PickingInfo object after meshSelectionPredicate evaluation
    ([carloslanderas](https://github.com/carloslanderas))
-- `AssetsManager` will now clear its `tasks` list from all successfully loaded tasks ([deltakosh](https://github.com/deltakosh))
+- `AssetsManager` will now clear its `tasks` lsit from all successfully loaded tasks ([deltakosh](https://github.com/deltakosh))tasks ([deltakosh](https://github.com/deltakosh))
 - Added documentation to WebVRCamera and VRExperienceHelper ([trevordev](https://github.com/trevordev))
 - Introduced `isStroke` on `HighlightLayerOptions` which makes the highlight solid ([PixelsCommander](https://github.com/pixelscommander))
+- (Viewer) There is now an option to paste payload instead of a URL for configuration ([RaananW](https://github.com/RaananW))
+- (Viewer) Models can be loaded async using JavaScript ([RaananW](https://github.com/RaananW))
+- VRHelper will notify now onSelectedMeshUnselected observable to subscribers when the applied ray selection predicate does not produce a hit and a mesh compliant with the meshSelectionPredicate was previously selected
+   ([carloslanderas](https://github.com/carloslanderas))
+- (Viewer) initScene and initEngine can now be extended. onProgress during model loading is implemented as observable. ([RaananW](https://github.com/RaananW))
+- glTF loader now supports the KHR_lights extension ([MiiBond](https://github.com/MiiBond))
+- Added depth of field effect to default pipeline ([trevordev](https://github.com/trevordev))
+- The observable can now notify observers using promise-based callback chain. ([RaananW](https://github.com/RaananW))
+- Added base64 helper functions to `Tools` ([bghgary](https://github.com/bghgary))
+- Added `createDefaultCamera` and `createDefaultLight` functions to `Scene` ([bghgary](https://github.com/bghgary))
+- Gulp process now supports multiple outputs when using webpack. ([RaananW](https://github.com/RaananW))
+- (Viewer) Scene Optimizer intergrated in viewer. ([RaananW](https://github.com/RaananW))
+- (Viewer) The viewer supports custom shaders in the configuration. ([RaananW](https://github.com/RaananW))
+- Documented PostProcessRenderEffect, DefaultRenderingPipeline, BlurPostProcess, DepthOfFieldEffect, PostProcess, PostProcessManager classes ([trevordev](https://github.com/trevordev))
+- SPS internal storage of each solid particle rotation matrix ([jbousquie](https://github.com/jbousquie)) 
+- (Viewer) Introducing the viewer labs - testing new features. ([RaananW](https://github.com/RaananW))
 
 ## Bug fixes
+- Texture extension detection in `Engine.CreateTexture` ([sebavan](https://github.com/sebavan))
+- Fixed a bug with merging vertex data ([bghgary](https://github.com/bghgary))
 
 ## Breaking changes
-
-
+- Removed unused PostProcessRenderPass class and extended postProcessingRenderingEffect to support multiple PostProcesses ([trevordev](https://github.com/trevordev))

+ 119 - 0
loaders/src/glTF/2.0/Extensions/KHR_lights.ts

@@ -0,0 +1,119 @@
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF2.Extensions {
+    interface IGLTFLight {
+        type: "directional" | "point" | "spot";
+        color: [number, number, number];
+        intensity: number;
+        // Runtime values
+        index: number;
+    }
+
+    interface IKHRLights {
+        lights: IGLTFLight[];
+    }
+
+    interface IGLTFLightReference {
+        light: number;
+        // Runtime values
+        babylonLight: Light;
+    }
+
+    export class KHRLights extends GLTFLoaderExtension {
+        public get name(): string {
+            return "KHR_lights";
+        }
+
+        private applyCommonProperties(light: Light, lightInfo: IGLTFLight): void {
+            if (lightInfo.color) {
+                light.diffuse.copyFromFloats(lightInfo.color[0], lightInfo.color[1], lightInfo.color[2]);
+            } else {
+                light.diffuse.copyFromFloats(1, 1, 1);
+            }
+
+            if (lightInfo.intensity !== undefined) {
+                light.intensity = lightInfo.intensity;
+            } else {
+                light.intensity = 1;
+            }
+        }
+
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean { 
+            return this._loadExtension<IGLTFLightReference>(context, scene, (context, extension, onComplete) => {
+                if (extension.light >= 0 && loader._gltf.extensions) {
+                    const lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                    if (lightInfo.type !== 'ambient') {
+                        return;
+                    }
+
+                    const lightColor = lightInfo.color ? lightInfo.color : [1, 1, 1];
+                    loader._babylonScene.ambientColor.copyFromFloats(lightColor[0], lightColor[1], lightColor[2]);
+                }
+                
+                onComplete();
+            });
+        }
+
+        protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean { 
+            return this._loadExtension<IGLTFLightReference>(context, node, (context, extension, onComplete) => {
+                if (extension.light >= 0 && loader._gltf.extensions) {
+                    const lightInfo = loader._gltf.extensions.KHR_lights.lights[extension.light];
+                    const name = node.name || 'Light';
+                    let matrix: Matrix;
+                    if (node.matrix) {
+                        matrix = Matrix.FromArray(node.matrix);
+                    } else {
+                        matrix = Matrix.Identity();
+                    }
+
+                    const direction = new Vector3(0, 0, 1);
+                    if (lightInfo.type == 'directional' || lightInfo.type == 'spot') {
+                        const rotationMatrix = matrix.getRotationMatrix();
+                        Vector3.TransformCoordinatesToRef(direction, rotationMatrix, direction);
+                    }
+
+                    let light: Light;
+                    if (lightInfo.type == 'directional') {
+                        light = new DirectionalLight(name, direction, loader._babylonScene);
+                    } else {
+                        const position = matrix.getTranslation();
+                        if (lightInfo.type == 'spot') {
+                            const angle = lightInfo.spot && lightInfo.spot.outerConeAngle ? lightInfo.spot.outerConeAngle : Math.PI / 2;
+                            light = new SpotLight(name, position, direction, angle, 2, loader._babylonScene);
+                        } else {
+                            light = new PointLight(name, position, loader._babylonScene);
+                        }
+                    } 
+
+                    this.applyCommonProperties(light, lightInfo);
+                    
+                    extension.babylonLight = light;
+                    extension.babylonLight.parent = node.parent ? node.parent.babylonMesh : null;
+                    
+                    if (node.children) {
+                        for (const index of node.children) {
+                            const childNode = GLTFLoader._GetProperty(loader._gltf.nodes, index);
+                            if (!childNode) {
+                                throw new Error(context + ": Failed to find child node " + index);
+                            }
+        
+                            loader._loadNode("#/nodes/" + index, childNode);
+                        }
+                    }
+                }
+                onComplete();
+            });
+        }
+
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean {
+            return this._loadExtension<IKHRLights>(context, root, (context, extension, onComplete) => {
+                extension.lights.forEach((light: IGLTFLight, idx: number) => {
+                    light.index = idx;
+                });
+                onComplete();
+            });
+        }
+    }
+
+    GLTFLoader.RegisterExtension(new KHRLights());
+}

+ 5 - 0
loaders/src/glTF/2.0/babylon.glTFLoader.ts

@@ -198,6 +198,9 @@ module BABYLON.GLTF2 {
             GLTFLoader._AssignIndices(this._gltf.skins);
             GLTFLoader._AssignIndices(this._gltf.textures);
 
+            // Handle global extensions as they may add their own data types.
+            GLTFLoaderExtension.LoadRoot(this, "#/", this._gltf);
+
             if (data.bin) {
                 const buffers = this._gltf.buffers;
                 if (buffers && buffers[0] && !buffers[0].uri) {
@@ -290,6 +293,8 @@ module BABYLON.GLTF2 {
         }
 
         private _loadScene(context: string, scene: IGLTFScene, nodeNames: any): void {
+            GLTFLoaderExtension.LoadScene(this, context, scene);
+            
             this._rootNode = { babylonMesh: new Mesh("__root__", this._babylonScene) } as IGLTFNode;
 
             switch (this.coordinateSystemMode) {

+ 12 - 0
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -10,6 +10,10 @@ module BABYLON.GLTF2 {
 
         protected _loadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean { return false; }
 
+        protected _loadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean { return false; }
+
+        protected _loadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean { return false; }
+
         protected _loadMaterial(loader: GLTFLoader, context: string, material: IGLTFMaterial, assign: (babylonMaterial: Material, isNew: boolean) => void): boolean { return false; }
 
         protected _loadExtension<T>(context: string, property: IGLTFProperty, action: (context: string, extension: T, onComplete: () => void) => void): boolean {
@@ -43,6 +47,14 @@ module BABYLON.GLTF2 {
             return this._ApplyExtensions(extension => extension._traverseNode(loader, context, node, action, parentNode));
         }
 
+        public static LoadRoot(loader: GLTFLoader, context: string, root: BABYLON.GLTF2._IGLTF): boolean {
+            return this._ApplyExtensions(extension => extension._loadRoot(loader, context, root));
+        }
+
+        public static LoadScene(loader: GLTFLoader, context: string, scene: IGLTFScene): boolean {
+            return this._ApplyExtensions(extension => extension._loadScene(loader, context, scene));
+        }
+
         public static LoadNode(loader: GLTFLoader, context: string, node: IGLTFNode): boolean {
             return this._ApplyExtensions(extension => extension._loadNode(loader, context, node));
         }

+ 2 - 2
materialsLibrary/src/cell/babylon.cellMaterial.ts

@@ -110,13 +110,13 @@ module BABYLON {
             defines.CELLBASIC = !this.computeHighLevel;
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/custom/babylon.customMaterial.ts

@@ -719,13 +719,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Get correct effect      
             if (defines.isDirty) {

+ 1 - 1
materialsLibrary/src/fire/babylon.fireMaterial.ts

@@ -107,7 +107,7 @@ module BABYLON {
             }
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);

+ 2 - 2
materialsLibrary/src/fur/babylon.furMaterial.ts

@@ -181,13 +181,13 @@ module BABYLON {
             }
 
             // Misc.   
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/gradient/babylon.gradientMaterial.ts

@@ -128,9 +128,9 @@ module BABYLON {
 
             var engine = scene.getEngine();
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
 

+ 1 - 1
materialsLibrary/src/grid/babylon.gridmaterial.ts

@@ -120,7 +120,7 @@ module BABYLON {
                 defines.markAsUnprocessed();
             }
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
 
             // Get correct effect      
             if (defines.isDirty) {

+ 2 - 2
materialsLibrary/src/lava/babylon.lavaMaterial.ts

@@ -153,13 +153,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/normal/babylon.normalMaterial.ts

@@ -132,13 +132,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 2 - 2
materialsLibrary/src/shadowOnly/babylon.shadowOnlyMaterial.ts

@@ -86,9 +86,9 @@ module BABYLON {
                 }
             }
 
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
 

+ 2 - 2
materialsLibrary/src/simple/babylon.simpleMaterial.ts

@@ -99,13 +99,13 @@ module BABYLON {
             }
 
             // Misc.
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, this._shouldTurnAlphaTestOn(mesh), defines);
 
             // Lights
             defines._needNormals = MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
 
             // Values that need to be evaluated on every frame
-            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
+            MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
 
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);

+ 1 - 1
materialsLibrary/src/sky/babylon.skyMaterial.ts

@@ -88,7 +88,7 @@ module BABYLON {
                 }
             }
 
-            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
+            MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, false, defines);
             
             // Attribs
             MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, false);

+ 0 - 0
materialsLibrary/src/terrain/babylon.terrainMaterial.ts


部分文件因为文件数量过多而无法显示