Browse Source

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 7 năm trước cách đây
mục cha
commit
b7244a6497
100 tập tin đã thay đổi với 32165 bổ sung28247 xóa
  1. 1 1
      .vscode/tasks.json
  2. 10 2
      Playground/js/frame.js
  3. 13 2
      Playground/js/index.js
  4. 10 2
      Playground/scripts/ssao 2.js
  5. 10 2
      Playground/scripts/ssao rendering pipeline.js
  6. 0 0
      Playground/textures/ColorGrading.3DL
  7. 0 0
      Playground/textures/colorGrade.png
  8. 0 0
      Playground/textures/environment.hdr
  9. 0 0
      Playground/textures/fire/diffuse.png
  10. 0 0
      Playground/textures/fire/distortion.png
  11. 0 0
      Playground/textures/fire/opacity.png
  12. 0 0
      Playground/textures/lava/cloud.png
  13. 0 0
      Playground/textures/lava/lavatile.jpg
  14. 75 22
      Tools/Gulp/config.json
  15. 26 11
      Tools/Gulp/gulp-addModuleExports.js
  16. 59 47
      Tools/Gulp/gulpfile.js
  17. 20 19
      Tools/Gulp/package.json
  18. 4 0
      Tools/Publisher/index.js
  19. 4 1
      Viewer/dist/basicExample.html
  20. 67 0
      Viewer/dist/eventsExample.html
  21. 3453 1657
      Viewer/dist/viewer.js
  22. 8 8
      Viewer/package.json
  23. 12 3
      Viewer/src/configuration/configuration.ts
  24. 2 2
      Viewer/src/configuration/types/default.ts
  25. 39 0
      Viewer/src/util/promiseObservable.ts
  26. 7 1
      Viewer/src/viewer/defaultViewer.ts
  27. 40 12
      Viewer/src/viewer/viewer.ts
  28. 23 0
      Viewer/src/viewer/viewerManager.ts
  29. 2 0
      assets/_headers
  30. BIN
      assets/environments/backgroundGround.png
  31. BIN
      assets/environments/backgroundSkybox.dds
  32. 0 0
      assets/environments/environmentSpecular.dds
  33. BIN
      assets/meshes/0.jpg
  34. 0 1
      assets/meshes/Cat.babylon
  35. BIN
      assets/meshes/Dude/0.jpg
  36. BIN
      assets/meshes/Dude/1.jpg
  37. BIN
      assets/meshes/Dude/2.jpg
  38. BIN
      assets/meshes/Dude/3.jpg
  39. 0 1
      assets/meshes/Dude/dude.babylon
  40. 0 1
      assets/meshes/Rabbit.babylon
  41. 0 1
      assets/meshes/Rabbit.babylon.manifest
  42. BIN
      assets/meshes/Tree/Tree.tga
  43. 0 5
      assets/meshes/Tree/tree.babylon
  44. 0 5
      assets/meshes/skull.babylon
  45. 0 95
      assets/refs/dat.gui.min.js
  46. BIN
      assets/textures/16testSpecularHDR.dds
  47. BIN
      assets/textures/Brdf.dds
  48. BIN
      assets/textures/DefaultEnvironmentMap.dds
  49. BIN
      assets/textures/Ground.jpg
  50. 0 4916
      assets/textures/LateSunset.3dl
  51. BIN
      assets/textures/SpecularHDR.dds
  52. BIN
      assets/textures/albedo.png
  53. BIN
      assets/textures/amiga.jpg
  54. BIN
      assets/textures/babylonjs.mp4
  55. BIN
      assets/textures/babylonjs.webm
  56. BIN
      assets/textures/floor.png
  57. BIN
      assets/textures/floor_bump.PNG
  58. BIN
      assets/textures/grass.dds
  59. BIN
      assets/textures/grass.jpg
  60. BIN
      assets/textures/grass.png
  61. BIN
      assets/textures/grassn.png
  62. BIN
      assets/textures/hdr/room.hdr
  63. BIN
      assets/textures/heightMap.png
  64. BIN
      assets/textures/leopard_fur.JPG
  65. BIN
      assets/textures/misc.jpg
  66. BIN
      assets/textures/mixMap.png
  67. BIN
      assets/textures/player.png
  68. BIN
      assets/textures/reflectivity.png
  69. BIN
      assets/textures/rock.png
  70. BIN
      assets/textures/rockn.png
  71. BIN
      assets/textures/room.hdr
  72. BIN
      assets/textures/skybox/TropicalSunnyDay_nx.jpg
  73. BIN
      assets/textures/skybox/TropicalSunnyDay_ny.jpg
  74. BIN
      assets/textures/skybox/TropicalSunnyDay_nz.jpg
  75. BIN
      assets/textures/skybox/TropicalSunnyDay_px.jpg
  76. BIN
      assets/textures/skybox/TropicalSunnyDay_py.jpg
  77. BIN
      assets/textures/skybox/TropicalSunnyDay_pz.jpg
  78. BIN
      assets/textures/skybox/snow_nx.jpg
  79. BIN
      assets/textures/skybox/snow_ny.jpg
  80. BIN
      assets/textures/skybox/snow_nz.jpg
  81. BIN
      assets/textures/skybox/snow_px.jpg
  82. BIN
      assets/textures/skybox/snow_py.jpg
  83. BIN
      assets/textures/skybox/snow_pz.jpg
  84. BIN
      assets/textures/sparkle2.jpg
  85. BIN
      assets/textures/speckles.jpg
  86. BIN
      assets/textures/sun.png
  87. BIN
      assets/textures/test.png
  88. BIN
      assets/textures/testSpecularHDR.dds
  89. BIN
      assets/textures/tree.png
  90. BIN
      assets/textures/waterbump.png
  91. 3180 2369
      dist/preview release/babylon.d.ts
  92. 53 51
      dist/preview release/babylon.js
  93. 8425 6299
      dist/preview release/babylon.max.js
  94. 3180 2369
      dist/preview release/babylon.module.d.ts
  95. 55 53
      dist/preview release/babylon.worker.js
  96. 5257 4428
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  97. 55 54
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  98. 2818 1379
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  99. 5257 4428
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts
  100. 0 0
      dist/preview release/gui/babylon.gui.d.ts

+ 1 - 1
.vscode/tasks.json

@@ -26,7 +26,7 @@
                     "code": 4,
                     "message": 5
                 },
-                "watching": {
+                "background": {
                     "activeOnStart": true,
                     "beginsPattern": "Starting \\'watch\\'",
                     "endsPattern": "Finished \\'run\\'"

+ 10 - 2
Playground/js/frame.js

@@ -63,7 +63,6 @@
             var canvas = document.getElementById("renderCanvas");
             engine = new BABYLON.Engine(canvas, true, { stencil: true });
             BABYLON.Camera.ForceAttachControlToAlwaysPreventDefault = true;
-
             engine.runRenderLoop(function () {
                 if (engine.scenes.length === 0) {
                     return;
@@ -85,7 +84,16 @@
             });
 
             var scene;
-            if (code.indexOf("createScene") !== -1) { // createScene
+            if (code.indexOf("delayCreateScene") !== -1) { // createScene
+                eval(code);
+                scene = delayCreateScene();
+                if (!scene) {
+                    showError("delayCreateScene function must return a scene.", null);
+                    return;
+                }
+
+                zipCode = code + "\r\n\r\nvar scene = createScene();";
+            } if (code.indexOf("createScene") !== -1) { // createScene
                 eval(code);
                 scene = createScene();
                 if (!scene) {

+ 13 - 2
Playground/js/index.js

@@ -356,6 +356,7 @@
                 document.getElementById("errorZone").style.display = 'none';
                 document.getElementById("errorZone").innerHTML = "";
                 document.getElementById("statusBar").innerHTML = "Loading assets...Please wait";
+                var checkCamera = true;
 
                 engine.runRenderLoop(function () {
                     if (engine.scenes.length === 0) {
@@ -378,7 +379,17 @@
 
                 var code = jsEditor.getValue();
                 var scene;
-                if (code.indexOf("createScene") !== -1) { // createScene
+                if (code.indexOf("delayCreateScene") !== -1) { // createScene
+                    eval(code);
+                    scene = delayCreateScene();
+                    checkCamera = false;
+                    if (!scene) {
+                        showError("delayCreateScene function must return a scene.", null);
+                        return;
+                    }
+
+                    zipCode = code + "\r\n\r\nvar scene = createScene();";
+                } else if (code.indexOf("createScene") !== -1) { // createScene
                     eval(code);
                     scene = createScene();
                     if (!scene) {
@@ -418,7 +429,7 @@
                     return;
                 }
 
-                if (engine.scenes[0].activeCamera == null) {
+                if (checkCamera && engine.scenes[0].activeCamera == null) {
                     showError("You must at least create a camera.", null);
                     return;
                 }

+ 10 - 2
Playground/scripts/ssao 2.js

@@ -40,19 +40,27 @@ var createScene = function () {
         scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
 
         // Manage SSAO
+        var isAttached = true;
         window.addEventListener("keydown", function (evt) {
             // draw SSAO with scene when pressed "1"
             if (evt.keyCode === 49) {
-                scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+                if (!isAttached) {
+                    isAttached = true;
+                    scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+                }
                 scene.postProcessRenderPipelineManager.enableEffectInPipeline("ssao", ssao.SSAOCombineRenderEffect, camera);
             }
                 // draw without SSAO when pressed "2"
             else if (evt.keyCode === 50) {
+                isAttached = false;
                 scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline("ssao", camera);
             }
                 // draw only SSAO when pressed "2"
             else if (evt.keyCode === 51) {
-                scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+                if (!isAttached) {
+                    isAttached = true;
+                    scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+                }
                 scene.postProcessRenderPipelineManager.disableEffectInPipeline("ssao", ssao.SSAOCombineRenderEffect, camera);
             }
         });

+ 10 - 2
Playground/scripts/ssao rendering pipeline.js

@@ -40,19 +40,27 @@
     scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
 
     // Manage SSAO
+    var isAttached = true;
     window.addEventListener("keydown", function (evt) {
         // draw SSAO with scene when pressed "1"
         if (evt.keyCode === 49) {
-            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+            if (!isAttached) {
+                isAttached = true;
+                scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+            }
             scene.postProcessRenderPipelineManager.enableEffectInPipeline("ssao", ssao.SSAOCombineRenderEffect, camera);
         }
             // draw without SSAO when pressed "2"
         else if (evt.keyCode === 50) {
+            isAttached = false;
             scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline("ssao", camera);
         }
             // draw only SSAO when pressed "2"
         else if (evt.keyCode === 51) {
-            scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+            if (!isAttached) {
+                isAttached = true;
+                scene.postProcessRenderPipelineManager.attachCamerasToRenderPipeline("ssao", camera);
+            }
             scene.postProcessRenderPipelineManager.disableEffectInPipeline("ssao", ssao.SSAOCombineRenderEffect, camera);
         }
     });

assets/textures/ColorGrading.3DL → Playground/textures/ColorGrading.3DL


assets/textures/colorGrade.png → Playground/textures/colorGrade.png


assets/textures/hdr/environment.hdr → Playground/textures/environment.hdr


assets/textures/fire/diffuse.png → Playground/textures/fire/diffuse.png


assets/textures/fire/distortion.png → Playground/textures/fire/distortion.png


assets/textures/fire/opacity.png → Playground/textures/fire/opacity.png


assets/textures/lava/cloud.png → Playground/textures/lava/cloud.png


assets/textures/lava/lavatile.jpg → Playground/textures/lava/lavatile.jpg


+ 75 - 22
Tools/Gulp/config.json

@@ -74,7 +74,9 @@
             "textureTools",
             "cameraBehaviors",
             "nullEngine",
-            "instrumentation"
+            "instrumentation",
+            "backgroundMaterial",
+            "environmentHelper"
         ],
         "minimal": [
             "standardMaterial",
@@ -149,8 +151,9 @@
             "textureTools",
             "cameraBehaviors",
             "instrumentation",
+            "backgroundMaterial",
+            "environmentHelper",
             "materialsLibrary/babylon.gridMaterial.js",
-            "materialsLibrary/babylon.backgroundMaterial.js",
             "loaders/babylon.glTFFileLoader.js"
         ],
         "distributed": [
@@ -178,6 +181,7 @@
                 "../../src/Culling/babylon.boundingSphere.js",
                 "../../src/Culling/babylon.boundingBox.js",
                 "../../src/Culling/babylon.boundingInfo.js",
+                "../../src/Mesh/babylon.transformNode.js",
                 "../../src/Mesh/babylon.abstractMesh.js",
                 "../../src/Lights/babylon.light.js",
                 "../../src/Cameras/babylon.camera.js",
@@ -242,7 +246,7 @@
             "dependUpon": [
                 "core"
             ]
-        },    
+        },
         "instrumentation": {
             "files": [
                 "../../src/Instrumentation/babylon.engineInstrumentation.js",
@@ -252,7 +256,7 @@
             "dependUpon": [
                 "core"
             ]
-        },      
+        },
         "cameraBehaviors": {
             "files": [
                 "../../src/Behaviors/Cameras/babylon.framingBehavior.js",
@@ -405,7 +409,7 @@
                 "defaultUboDeclaration",
                 "shadowsFragmentFunctions",
                 "fresnelFunction",
-                "reflectionFunction",                
+                "reflectionFunction",
                 "imageProcessingDeclaration",
                 "imageProcessingFunctions",
                 "bumpFragmentFunctions",
@@ -461,7 +465,7 @@
                 "shadowsFragmentFunctions",
                 "pbrFunctions",
                 "imageProcessingDeclaration",
-                "imageProcessingFunctions",                
+                "imageProcessingFunctions",
                 "harmonicsFunctions",
                 "pbrLightFunctions",
                 "helperFunctions",
@@ -1080,6 +1084,69 @@
                 "layer.vertex",
                 "layer.fragment"
             ]
+        },
+        "backgroundMaterial": {
+            "files": [
+                "../../src/Materials/Background/babylon.backgroundMaterial.js"
+            ],
+            "dependUpon": [
+                "core"
+            ],
+            "shaders": [
+                "background.vertex",
+                "background.fragment"
+            ],
+            "shaderIncludes": [
+                "bonesDeclaration",
+                "instancesDeclaration",
+                "pointCloudVertexDeclaration",
+                "bumpVertexDeclaration",
+                "clipPlaneVertexDeclaration",
+                "fogVertexDeclaration",
+                "morphTargetsVertexGlobalDeclaration",
+                "morphTargetsVertexDeclaration",
+                "logDepthDeclaration",
+                "morphTargetsVertex",
+                "instancesVertex",
+                "bonesVertex",
+                "bumpVertex",
+                "clipPlaneVertex",
+                "fogVertex",
+                "shadowsVertex",
+                "pointCloudVertex",
+                "logDepthVertex",
+                "helperFunctions",
+                "lightFragmentDeclaration",
+                "lightsFragmentFunctions",
+                "lightUboDeclaration",
+                "backgroundVertexDeclaration",
+                "backgroundFragmentDeclaration",
+                "backgroundUboDeclaration",
+                "shadowsFragmentFunctions",
+                "fresnelFunction",
+                "reflectionFunction",
+                "imageProcessingDeclaration",
+                "imageProcessingFunctions",
+                "bumpFragmentFunctions",
+                "clipPlaneFragmentDeclaration",
+                "logDepthDeclaration",
+                "fogFragmentDeclaration",
+                "clipPlaneFragment",
+                "bumpFragment",
+                "lightFragment",
+                "logDepthFragment",
+                "fogFragment"
+            ]
+        },
+        "environmentHelper": {
+            "files": [
+                "../../src/Helpers/babylon.environmentHelper.js"
+            ],
+            "dependUpon": [
+                "core",
+                "backgroundMaterial",
+                "additionalTextures"
+            ]
         }
     },
     "typescript": [
@@ -1243,21 +1310,6 @@
                     "../../materialsLibrary/src/cell/cell.fragment.fx"
                 ],
                 "output": "babylon.cellMaterial.js"
-            },
-            {
-                "files": [
-                    "../../materialsLibrary/src/background/babylon.backgroundMaterial.ts"
-                ],
-                "shaderFiles": [
-                    "../../materialsLibrary/src/background/background.vertex.fx",
-                    "../../materialsLibrary/src/background/background.fragment.fx"
-                ],
-                "shadersIncludeFiles": [
-                    "../../materialsLibrary/src/background/backgroundFragmentDeclaration.fx",
-                    "../../materialsLibrary/src/background/backgroundUboDeclaration.fx",
-                    "../../materialsLibrary/src/background/backgroundVertexDeclaration.fx"
-                ],
-                "output": "babylon.backgroundMaterial.js"
             }
         ],
         "build": {
@@ -1594,7 +1646,8 @@
                 ],
                 "output": "babylon.inspector.js",
                 "webpack": "../../inspector/webpack.config.js",
-                "bundle": "true"
+                "bundle": "true",
+                "moduleDeclaration": "INSPECTOR"
             }
         ],
         "build": {

+ 26 - 11
Tools/Gulp/gulp-addModuleExports.js

@@ -1,34 +1,45 @@
 var gutil = require('gulp-util');
 var through = require('through2');
 
-module.exports = function (varName, subModule, extendsRoot) {
+/**
+ * The parameters for this function has grown during development.
+ * Eventually, this function will need to be reorganized. 
+ */
+module.exports = function (varName, subModule, extendsRoot, externalUsingBabylon) {
     return through.obj(function (file, enc, cb) {
 
-        var optionalRequire = `var babylonDependency; try { babylonDependency = BABYLON || (typeof require !== 'undefined' && require("../babylon.max")); } catch (e) { babylonDependency = BABYLON || (typeof require !== 'undefined' && require("babylonjs")); } 
+        var optionalRequire = `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+var babylonDependency = (globalObject && globalObject.BABYLON) || BABYLON || (typeof require !== 'undefined' && require("babylonjs"));
 var BABYLON = babylonDependency;
 `;
         function moduleExportAddition(varName) {
 
-            let basicInit = `root["BABYLON"]${(subModule && !extendsRoot) ? '["' + varName + '"]' : ''} = factory();`;
+            let base = subModule ? 'BABYLON' : varName;
+
+            let basicInit = `root["${base}"]${(subModule && !extendsRoot) ? '["' + varName + '"]' : ''} = f;`;
+            let sadGlobalPolution = (!subModule) ? `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+globalObject["${base}"] = f;` : '';
             /*if (extendsRoot) {
                 basicInit = `__extends(root["BABYLON"], factory()); `
             }*/
 
             return `\n\n(function universalModuleDefinition(root, factory) {
-                if (root && root["BABYLON"]) {
+                var f = factory();
+                if (root && root["${base}"]) {
                     return;
                 }
+                ${sadGlobalPolution}
     if(typeof exports === 'object' && typeof module === 'object')
-        module.exports = factory();
+        module.exports = f;
     else if(typeof define === 'function' && define.amd)
-        define([], factory);
+        define(["${varName}"], factory);
     else if(typeof exports === 'object')
-        exports["${varName}"] = factory();
+        exports["${varName}"] = f;
     else {
         ${basicInit}
     }
 })(this, function() {
-    return BABYLON${(subModule && !extendsRoot) ? '.' + varName : ''};
+    return ${base}${(subModule && !extendsRoot) ? '.' + varName : ''};
 });
 `;
         }
@@ -65,10 +76,14 @@ var BABYLON = babylonDependency;
         }
 
         try {
-            let pretext = subModule ? optionalRequire : '';
-            file.contents = new Buffer(pretext.concat(decorateAddition).concat(new Buffer(extendsAddition.concat(String(file.contents)).concat(moduleExportAddition(varName)))));
+            if (externalUsingBabylon) {
+                //file.contents = new Buffer(optionalRequire.concat(String(file.contents)));
+                file.contents = new Buffer(optionalRequire.concat(new Buffer(String(file.contents).concat(moduleExportAddition(varName)))));
+            } else {
+                let pretext = subModule ? optionalRequire : '';
+                file.contents = new Buffer(pretext.concat(decorateAddition).concat(new Buffer(extendsAddition.concat(String(file.contents)).concat(moduleExportAddition(varName)))));
+            }
             this.push(file);
-
         } catch (err) {
             this.emit('error', new gutil.PluginError('gulp-add-module-exports', err, { fileName: file.path }));
         }

+ 59 - 47
Tools/Gulp/gulpfile.js

@@ -9,23 +9,23 @@ var addModuleExports = require("./gulp-addModuleExports");
 var merge2 = require("merge2");
 var concat = require("gulp-concat");
 var rename = require("gulp-rename");
-var cleants = require('gulp-clean-ts-extends');
-var changedInPlace = require('gulp-changed-in-place');
-var runSequence = require('run-sequence');
+var cleants = require("gulp-clean-ts-extends");
+var changedInPlace = require("gulp-changed-in-place");
+var runSequence = require("run-sequence");
 var replace = require("gulp-replace");
 var uncommentShader = require("./gulp-removeShaderComments");
-var expect = require('gulp-expect-file');
-var optimisejs = require('gulp-optimize-js');
-var webserver = require('gulp-webserver');
-var path = require('path');
-var sass = require('gulp-sass');
-var webpack = require('webpack-stream');
+var expect = require("gulp-expect-file");
+var optimisejs = require("gulp-optimize-js");
+var webserver = require("gulp-webserver");
+var path = require("path");
+var sass = require("gulp-sass");
+var webpack = require("webpack-stream");
 
 var config = require("./config.json");
 
-var del = require('del');
+var del = require("del");
 
-var debug = require('gulp-debug');
+var debug = require("gulp-debug");
 var includeShadersStream;
 var shadersStream;
 var workersStream;
@@ -39,9 +39,9 @@ var referenceSearchRegex = /\/\/\/ <reference.*/g;
  */
 var tsConfig = {
     noResolve: true,
-    target: 'ES5',
+    target: "ES5",
     declarationFiles: true,
-    typescript: require('typescript'),
+    typescript: require("typescript"),
     experimentalDecorators: true,
     isolatedModules: false,
     noImplicitAny: true,
@@ -54,9 +54,9 @@ var tsProject = typescript.createProject(tsConfig);
 
 var externalTsConfig = {
     noResolve: false,
-    target: 'ES5',
+    target: "ES5",
     declarationFiles: true,
-    typescript: require('typescript'),
+    typescript: require("typescript"),
     experimentalDecorators: true,
     isolatedModules: false,
     noImplicitAny: true,
@@ -66,6 +66,11 @@ var externalTsConfig = {
     strictNullChecks: true
 };
 
+var minimist = require("minimist");
+var commandLineOptions = minimist(process.argv.slice(2), {
+    boolean: "public"
+});
+
 function processDependency(kind, dependency, filesToLoad) {
     if (dependency.dependUpon) {
         for (var i = 0; i < dependency.dependUpon.length; i++) {
@@ -125,13 +130,13 @@ function determineFilesToProcess(kind) {
  */
 function shadersName(filename) {
     return path.basename(filename)
-        .replace('.fragment', 'Pixel')
-        .replace('.vertex', 'Vertex')
-        .replace('.fx', 'Shader');
+        .replace(".fragment", "Pixel")
+        .replace(".vertex", "Vertex")
+        .replace(".fx", "Shader");
 }
 
 function includeShadersName(filename) {
-    return path.basename(filename).replace('.fx', '');
+    return path.basename(filename).replace(".fx", "");
 }
 
 /*
@@ -218,7 +223,7 @@ gulp.task("build", ["shaders"], function () {
 /*
 * Compiles all typescript files and creating a js and a declaration file.
 */
-gulp.task('typescript-compile', function () {
+gulp.task("typescript-compile", function () {
     var tsResult = gulp.src(config.typescript)
         .pipe(sourcemaps.init())
         .pipe(tsProject());
@@ -226,11 +231,11 @@ gulp.task('typescript-compile', function () {
     //If this gulp task is running on travis, file the build!
     if (process.env.TRAVIS) {
         var error = false;
-        tsResult.on('error', function () {
+        tsResult.on("error", function () {
             error = true;
-        }).on('end', function () {
+        }).on("end", function () {
             if (error) {
-                console.log('Typescript compile failed');
+                console.log("Typescript compile failed");
                 process.exit(1);
             }
         });
@@ -249,7 +254,7 @@ gulp.task('typescript-compile', function () {
                 {
                     includeContent: false,
                     sourceRoot: (filePath) => {
-                        return '';
+                        return "";
                     }
                 }))
             .pipe(gulp.dest(config.build.srcOutputDirectory))
@@ -267,7 +272,7 @@ var buildExternalLibraries = function (settings) {
     let mergedTasks = merge2(tasks);
 
     if (settings.build.buildAsModule) {
-        mergedTasks.on('end', function () {
+        mergedTasks.on("end", function () {
             //generate js file list
             let files = settings.libraries.filter(function (lib) {
                 return !lib.doNotIncludeInBundle;
@@ -278,7 +283,7 @@ var buildExternalLibraries = function (settings) {
             var outputDirectory = config.build.outputDirectory + settings.build.distOutputDirectory;
 
             let srcTask = gulp.src(files)
-                .pipe(concat(settings.build.outputFilename + '.js'))
+                .pipe(concat(settings.build.outputFilename + ".js"))
                 .pipe(replace(extendsSearchRegex, ""))
                 .pipe(replace(decorateSearchRegex, ""))
                 .pipe(replace(referenceSearchRegex, ""))
@@ -295,7 +300,7 @@ var buildExternalLibraries = function (settings) {
             });
 
             let dtsTask = gulp.src(dtsFiles)
-                .pipe(concat(settings.build.outputFilename + '.module.d.ts'))
+                .pipe(concat(settings.build.outputFilename + ".module.d.ts"))
                 .pipe(replace(referenceSearchRegex, ""))
                 .pipe(addDtsExport(settings.build.moduleDeclaration, settings.build.moduleName, true, settings.build.extendsRoot))
                 .pipe(gulp.dest(outputDirectory));
@@ -314,25 +319,25 @@ var buildExternalLibrary = function (library, settings, watch) {
 
     var includeShader = gulp.src(library.shadersIncludeFiles || [], { base: settings.build.srcOutputDirectory })
         .pipe(uncommentShader())
-        .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, library.output + '.include.fx'))
+        .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, library.output + ".include.fx"))
         .pipe(gulp.dest(settings.build.srcOutputDirectory));
 
     var shader = gulp.src(library.shaderFiles || [], { base: settings.build.srcOutputDirectory })
         .pipe(uncommentShader())
-        .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, library.output + '.fx'))
+        .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, library.output + ".fx"))
         .pipe(gulp.dest(settings.build.srcOutputDirectory));
 
     var dev = tsProcess.js
         .pipe(sourcemaps.write("./", {
             includeContent: false,
             sourceRoot: (filePath) => {
-                return '';
+                return "";
             }
         })).pipe(gulp.dest(settings.build.srcOutputDirectory));
 
     var outputDirectory = config.build.outputDirectory + settings.build.distOutputDirectory;
     var css = gulp.src(library.sassFiles || [])
-        .pipe(sass().on('error', sass.logError))
+        .pipe(sass().on("error", sass.logError))
         .pipe(concat(library.output.replace(".js", ".css")))
         .pipe(gulp.dest(outputDirectory));
 
@@ -394,9 +399,10 @@ var buildExternalLibrary = function (library, settings, watch) {
         }
 
         if (library.webpack) {
-            return waitAll.on('end', function () {
+            return waitAll.on("end", function () {
                 webpack(require(library.webpack))
                     .pipe(rename(library.output.replace(".js", ".bundle.js")))
+                    .pipe(addModuleExports(library.moduleDeclaration, false, false, true))
                     .pipe(gulp.dest(outputDirectory))
             });
         }
@@ -467,22 +473,23 @@ gulp.task("typescript-all", function (cb) {
 /**
  * Watch ts files and fire repective tasks.
  */
-gulp.task('watch', [], function () {
-    var tasks = [gulp.watch(config.typescript, ['typescript-compile'])];
+gulp.task("watch", [], function () {
+    var interval = 1000;
+    var tasks = [gulp.watch(config.typescript, { interval: interval }, ["typescript-compile"])];
 
     config.modules.map(function (module) {
         config[module].libraries.map(function (library) {
-            tasks.push(gulp.watch(library.files, function () {
+            tasks.push(gulp.watch(library.files, { interval: interval }, function () {
                 console.log(library.output);
                 return buildExternalLibrary(library, config[module], true)
                     .pipe(debug());
             }));
-            tasks.push(gulp.watch(library.shaderFiles, function () {
+            tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
                 console.log(library.output);
                 return buildExternalLibrary(library, config[module], true)
                     .pipe(debug())
             }));
-            tasks.push(gulp.watch(library.sassFiles, function () {
+            tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
                 console.log(library.output);
                 return buildExternalLibrary(library, config[module], true)
                     .pipe(debug())
@@ -496,30 +503,35 @@ gulp.task('watch', [], function () {
 /**
  * Embedded local dev env management.
  */
-gulp.task('deployLocalDev', function () {
-    gulp.src('../../localDev/template/**.*')
-        .pipe(gulp.dest('../../localDev/src/'));
+gulp.task("deployLocalDev", function () {
+    gulp.src("../../localDev/template/**.*")
+        .pipe(gulp.dest("../../localDev/src/"));
 });
 
 /**
  * Embedded webserver for test convenience.
  */
-gulp.task('webserver', function () {
-    gulp.src('../../.').pipe(webserver({
-        host: '0.0.0.0',
+gulp.task("webserver", function () {
+    var options = {
         port: 1338,
         livereload: false
-    }));
+    };
+
+    if (commandLineOptions.public) {
+        options.host = "0.0.0.0";
+    }
+
+    gulp.src("../../.").pipe(webserver(options));
 });
 
 /**
  * Combine Webserver and Watch as long as vscode does not handle multi tasks.
  */
-gulp.task('run', ['watch', 'webserver'], function () {
+gulp.task("run", ["watch", "webserver"], function () {
 });
 
-gulp.task('clean-JS-MAP', function () {
+gulp.task("clean-JS-MAP", function () {
     return del([
-        '../../src/**/*.js.map', '../../src/**/*.js'
+        "../../src/**/*.js.map", "../../src/**/*.js"
     ], { force: true });
 });

+ 20 - 19
Tools/Gulp/package.json

@@ -9,32 +9,33 @@
   "readme": "https://github.com/BabylonJS/Babylon.js/edit/master/readme.md",
   "license": "(Apache-2.0)",
   "devDependencies": {
+    "css-loader": "^0.25.0",
+    "del": "2.2.2",
+    "exports-loader": "^0.6.3",
     "gulp": "^3.8.11",
-    "gulp-uglify": "^2.1.2",
-    "gulp-sourcemaps": "~1.9.1",
-    "typescript": "~2.5.3",
-    "gulp-typescript": "^3.2.2",
-    "through2": "~0.6.5",
-    "gulp-util": "~3.0.4",
-    "gulp-concat": "~2.5.2",
-    "merge2": "~0.3.5",
-    "gulp-rename": "~1.2.2",
-    "gulp-clean-ts-extends": "~0.1.1",
     "gulp-changed-in-place": "2.0.3",
-    "run-sequence": "~1.1.0",
-    "gulp-replace": "~0.5.3",
+    "gulp-clean-ts-extends": "~0.1.1",
+    "gulp-concat": "~2.5.2",
     "gulp-content-to-variable": "^0.1.0",
+    "gulp-debug": "^3.0.0",
     "gulp-expect-file": "^0.0.7",
     "gulp-optimize-js": "^1.0.2",
-    "gulp-webserver": "^0.9.1",
-    "gulp-debug": "^3.0.0",
+    "gulp-rename": "~1.2.2",
+    "gulp-replace": "~0.5.3",
     "gulp-sass": "3.1.0",
-    "webpack-stream": "^3.2.0",
-    "css-loader": "^0.25.0",
-    "style-loader": "^0.13.1",
-    "exports-loader": "^0.6.3",
+    "gulp-sourcemaps": "~1.9.1",
+    "gulp-typescript": "^3.2.2",
+    "gulp-uglify": "^2.1.2",
+    "gulp-util": "~3.0.4",
+    "gulp-webserver": "^0.9.1",
     "imports-loader": "^0.7.0",
-    "del": "2.2.2"
+    "merge2": "~0.3.5",
+    "minimist": "^1.2.0",
+    "run-sequence": "~1.1.0",
+    "style-loader": "^0.13.1",
+    "through2": "~0.6.5",
+    "typescript": "~2.5.3",
+    "webpack-stream": "^3.2.0"
   },
   "scripts": {
     "install": "npm --prefix ../../Playground/ install ../../Playground/ && gulp typescript-compile && gulp typescript-libraries && gulp deployLocalDev"

+ 4 - 0
Tools/Publisher/index.js

@@ -35,6 +35,10 @@ let packages = [
     {
         name: 'proceduralTextures',
         path: basePath + '/proceduralTexturesLibrary/'
+    },
+    {
+        name: 'inspector',
+        path: basePath + '/inspector/'
     }
 ];
 

+ 4 - 1
Viewer/dist/basicExample.html

@@ -11,7 +11,7 @@
                 max-width: 800px;
                 max-height: 500px;
                 width: 100%;
-                height: 100%;
+                height: 600px;
             }
         </style>
     </head>
@@ -21,6 +21,9 @@
             model.url="https://playground.babylonjs.com/scenes/Rabbit.babylon" camera.behaviors.auto-rotate="0" templates.nav-bar.params.disable-on-fullscreen="true"></babylon>
         <script src="viewer.js"></script>
         <script>
+            // The following lines are redundant. 
+            // They are only here to show how you could achive the tag initialization on your own.
+
             // a simple way of disabling auto init 
             BabylonViewer.disableInit = true;
             // Initializing the viewer on specific HTML tags.

+ 67 - 0
Viewer/dist/eventsExample.html

@@ -0,0 +1,67 @@
+<!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" model.title="Amazing Rabbit" model.subtitle="BabylonJS" model.thumbnail="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png"
+            model.url="https://playground.babylonjs.com/scenes/Rabbit.babylon" observers.on-scene-init="globalSceneInitCallback"></babylon>
+        <script src="viewer.js"></script>
+        <script>
+            //get by id ONLY after viewer init
+            var willNotWork = BabylonViewer.viewerManager.getViewerById('babylon-viewer');
+            console.log('viewer not yet initialized');
+
+            // Pomise-based API:
+            BabylonViewer.viewerManager.getViewerPromiseById('babylon-viewer').then(function (viewer) {
+                // this will resolve only after the viewer with this specific ID is initialized
+                console.log('Using promises: ', 'viewer - ' + viewer.getBaseId());
+
+                viewerObservables(viewer);
+            });
+
+            // call back variant:
+            BabylonViewer.viewerManager.onViewerAdded = function (viewer) {
+                console.log('Using viewerManager.onViewerAdded: ', 'viewer - ' + viewer.getBaseId());
+            }
+
+            // using observers:
+            BabylonViewer.viewerManager.onViewerAddedObservable.add(function (viewer) {
+                console.log('Using viewerManager.onViewerAddedObservable: ', 'viewer - ' + viewer.getBaseId());
+            });
+
+            function viewerObservables(viewer) {
+                viewer.onEngineInitObservable.add(function (engine) {
+                    console.log('Engine initialized');
+                });
+
+                viewer.onSceneInitObservable.add(function (scene) {
+                    console.log('Scene initialized');
+                });
+
+                viewer.onModelLoadedObservable.add(function (meshes) {
+                    console.log('Model loaded');
+                });
+            }
+
+            function globalSceneInitCallback(scene) {
+                console.log('scene-init function defined in the configuration');
+            }
+
+        </script>
+    </body>
+
+</html>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3453 - 1657
Viewer/dist/viewer.js


+ 8 - 8
Viewer/package.json

@@ -1,6 +1,6 @@
 {
     "name": "babylonjs-viewer",
-    "version": "0.1.0",
+    "version": "0.2.0",
     "description": "A viewer using BabylonJS to display 3D elements natively",
     "scripts": {
         "start:server": "webpack-dev-server",
@@ -23,7 +23,7 @@
     },
     "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
     "devDependencies": {
-        "@types/node": "^8.0.47",
+        "@types/node": "^8.0.51",
         "base64-image-loader": "^1.2.0",
         "html-loader": "^0.5.1",
         "json-loader": "^0.5.7",
@@ -34,15 +34,15 @@
         "webpack-dev-server": "^2.9.4"
     },
     "dependencies": {
-        "babylonjs": "^3.1.0-alpha3.7",
-        "babylonjs-loaders": "^3.1.0-alpha3.7",
-        "babylonjs-materials": "^3.1.0-alpha3.7",
-        "babylonjs-post-process": "^3.1.0-alpha3.7",
-        "babylonjs-procedural-textures": "^3.1.0-alpha3.7",
+        "babylonjs": "^3.1.0-beta1.1.1",
+        "babylonjs-loaders": "^3.1.0-beta1.1",
+        "babylonjs-materials": "^3.1.0-beta1.1",
+        "babylonjs-post-process": "^3.1.0-beta1.1",
+        "babylonjs-procedural-textures": "^3.1.0-beta1.1",
         "es6-promise": "^4.1.1",
         "handlebars": "^4.0.11",
         "lodash": "^4.17.4",
         "lodash.merge": "^4.6.0",
         "promise-polyfill": "^6.0.2"
     }
-}
+}

+ 12 - 3
Viewer/src/configuration/configuration.ts

@@ -13,7 +13,8 @@ export interface ViewerConfiguration {
         mapper?: string; // json (default), html, yaml, xml, etc'. if not provided, file extension will be used.
     };
 
-    // native (!!!) javascript events. Mainly used in the JSON-format.
+    // Deprecated
+    /*// native (!!!) javascript events. Mainly used in the JSON-format.
     // those events will be triggered by the container element (the <babylon> tag);
     events?: {
         load: boolean | string;
@@ -23,8 +24,15 @@ export interface ViewerConfiguration {
         pointerup: boolean | string;
         pointermove: boolean | string;
         // load: 'onViewerLoaded' // will trigger the event prefix-onViewerLoaded instead of prefix-onLoad (and ONLY this event).
-    } | boolean; //events: true - fire all events
-    eventPrefix?: string;
+    } | boolean; //events: true - fire all events*/
+    //eventPrefix?: string;
+
+    // names of functions in the window context.
+    observers?: {
+        onEngineInit?: string;
+        onSceneInit?: string;
+        onModelLoaded?: string;
+    }
 
     canvasElement?: string; // if there is a need to override the standard implementation - ID of HTMLCanvasElement
 
@@ -46,6 +54,7 @@ export interface ViewerConfiguration {
     };
 
     scene?: {
+        debug?: boolean;
         autoRotate?: boolean;
         rotationSpeed?: number;
         defaultCamera?: boolean;

+ 2 - 2
Viewer/src/configuration/types/default.ts

@@ -2,8 +2,8 @@ import { ViewerConfiguration } from './../configuration';
 
 export let defaultConfiguration: ViewerConfiguration = {
     version: "0.1",
-    eventPrefix: 'babylonviewer-',
-    events: true,
+    //eventPrefix: 'babylonviewer-',
+    //events: true,
     templates: {
         main: {
             html: require("../../../assets/templates/default/defaultTemplate.html")

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

@@ -0,0 +1,39 @@
+import { Observable, Nullable, Observer } 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;
+    }
+}

+ 7 - 1
Viewer/src/viewer/defaultViewer.ts

@@ -1,3 +1,4 @@
+import { ViewerConfiguration } from './../configuration/configuration';
 import { Template } from './../templateManager';
 import { AbstractViewer } from './viewer';
 import { Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ShadowOnlyMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
@@ -11,6 +12,11 @@ export class DefaultViewer extends AbstractViewer {
 
     public camera: ArcRotateCamera;
 
+    constructor(public containerElement: HTMLElement, initialConfiguration: ViewerConfiguration = { extends: 'default' }) {
+        super(containerElement, initialConfiguration);
+        this.onModelLoadedObservable.add(this.onModelLoaded);
+    }
+
     public initScene(): Promise<Scene> {
         return super.initScene().then(() => {
             this.extendClassWithConfig(this.scene, this.configuration.scene);
@@ -132,7 +138,7 @@ export class DefaultViewer extends AbstractViewer {
         });
     }
 
-    public onModelLoaded(meshes: Array<AbstractMesh>) {
+    private onModelLoaded = (meshes: Array<AbstractMesh>) => {
 
         // here we could set the navbar's model information:
         this.setModelMetaData();

+ 40 - 12
Viewer/src/viewer/viewer.ts

@@ -1,8 +1,9 @@
 import { viewerManager } from './viewerManager';
 import { TemplateManager } from './../templateManager';
 import configurationLoader from './../configuration/loader';
-import { Observable, Engine, Scene, ArcRotateCamera, Vector3, SceneLoader, AbstractMesh, Mesh, HemisphericLight } from 'babylonjs';
+import { Observable, Engine, Scene, ArcRotateCamera, Vector3, SceneLoader, AbstractMesh, Mesh, HemisphericLight, Database } from 'babylonjs';
 import { ViewerConfiguration } from '../configuration/configuration';
+import { PromiseObservable } from '../util/promiseObservable';
 
 export abstract class AbstractViewer {
 
@@ -14,6 +15,11 @@ export abstract class AbstractViewer {
 
     protected configuration: ViewerConfiguration;
 
+    // observables
+    public onSceneInitObservable: PromiseObservable<Scene>;
+    public onEngineInitObservable: PromiseObservable<Engine>;
+    public onModelLoadedObservable: PromiseObservable<AbstractMesh[]>;
+
     constructor(public containerElement: HTMLElement, initialConfiguration: ViewerConfiguration = {}) {
         // if exists, use the container id. otherwise, generate a random string.
         if (containerElement.id) {
@@ -22,6 +28,10 @@ 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();
+
         // add this viewer to the viewer manager
         viewerManager.addViewer(this);
 
@@ -33,6 +43,20 @@ export abstract class AbstractViewer {
         // extend the configuration
         configurationLoader.loadConfiguration(initialConfiguration).then((configuration) => {
             this.configuration = configuration;
+
+            // adding preconfigured functions
+            if (this.configuration.observers) {
+                if (this.configuration.observers.onEngineInit) {
+                    this.onEngineInitObservable.add(window[this.configuration.observers.onEngineInit]);
+                }
+                if (this.configuration.observers.onSceneInit) {
+                    this.onSceneInitObservable.add(window[this.configuration.observers.onSceneInit]);
+                }
+                if (this.configuration.observers.onModelLoaded) {
+                    this.onModelLoadedObservable.add(window[this.configuration.observers.onModelLoaded]);
+                }
+            }
+
             // initialize the templates
             let templateConfiguration = this.configuration.templates || {};
             this.templateManager.initTemplate(templateConfiguration);
@@ -82,6 +106,9 @@ export abstract class AbstractViewer {
         // TDO enable further configuration
         this.engine = new Engine(canvasElement, !!config.antialiasing);
 
+        // Disable manifest checking
+        Database.IDBStorageEnabled = false;
+
         window.addEventListener('resize', () => {
             this.engine.resize();
         });
@@ -93,7 +120,9 @@ export abstract class AbstractViewer {
         var scale = Math.max(0.5, 1 / (window.devicePixelRatio || 2));
         this.engine.setHardwareScalingLevel(scale);
 
-        return Promise.resolve(this.engine);
+        return this.onEngineInitObservable.notifyWithPromise(this.engine).then(() => {
+            return this.engine;
+        });
     }
 
     protected initScene(): Promise<Scene> {
@@ -107,7 +136,12 @@ 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);
-        return Promise.resolve(this.scene);
+        if (this.configuration.scene && this.configuration.scene.debug) {
+            this.scene.debugLayer.show();
+        }
+        return this.onSceneInitObservable.notifyWithPromise(this.scene).then(() => {
+            return this.scene;
+        });
     }
 
     public loadModel(model: any = this.configuration.model, clearScene: boolean = true): Promise<Scene> {
@@ -130,15 +164,9 @@ export abstract class AbstractViewer {
                 }, plugin);
             });
         }).then((meshes: Array<AbstractMesh>) => {
-            return this.onModelLoaded(meshes);
+            return this.onModelLoadedObservable.notifyWithPromise(meshes).then(() => {
+                return this.scene;
+            });
         });
     }
-
-    protected onModelLoaded(meshes: Array<AbstractMesh>): Promise<Scene> {
-        console.log("model loaded");
-        return Promise.resolve(this.scene);
-    }
-
-    public abstract initEnvironment(): Promise<Scene>;
-
 }

+ 23 - 0
Viewer/src/viewer/viewerManager.ts

@@ -1,15 +1,21 @@
+import { Observable } from 'babylonjs';
 import { AbstractViewer } from './viewer';
 
 class ViewerManager {
 
     private viewers: { [key: string]: AbstractViewer };
 
+    public onViewerAdded: (viewer: AbstractViewer) => void;
+    public onViewerAddedObservable: Observable<AbstractViewer>;
+
     constructor() {
         this.viewers = {};
+        this.onViewerAddedObservable = new Observable();
     }
 
     public addViewer(viewer: AbstractViewer) {
         this.viewers[viewer.getBaseId()] = viewer;
+        this._onViewerAdded(viewer);
     }
 
     public getViewerById(id: string): AbstractViewer {
@@ -23,6 +29,23 @@ class ViewerManager {
             }
         }
     }
+
+    public getViewerPromiseById(id: string): Promise<AbstractViewer> {
+        return new Promise((resolve, reject) => {
+            let viewerFunction = (viewer: AbstractViewer) => {
+                if (viewer.getBaseId() === id) {
+                    resolve(viewer);
+                    this.onViewerAddedObservable.removeCallback(viewerFunction);
+                }
+            }
+            this.onViewerAddedObservable.add(viewerFunction);
+        });
+    }
+
+    private _onViewerAdded(viewer: AbstractViewer) {
+        this.onViewerAdded && this.onViewerAdded(viewer);
+        this.onViewerAddedObservable.notifyObservers(viewer);
+    }
 }
 
 export let viewerManager = new ViewerManager();

+ 2 - 0
assets/_headers

@@ -0,0 +1,2 @@
+/*
+	Access-Control-Allow-Origin: *

BIN
assets/environments/backgroundGround.png


BIN
assets/environments/backgroundSkybox.dds


assets/textures/environment.dds → assets/environments/environmentSpecular.dds


BIN
assets/meshes/0.jpg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
assets/meshes/Cat.babylon


BIN
assets/meshes/Dude/0.jpg


BIN
assets/meshes/Dude/1.jpg


BIN
assets/meshes/Dude/2.jpg


BIN
assets/meshes/Dude/3.jpg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
assets/meshes/Dude/dude.babylon


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 1
assets/meshes/Rabbit.babylon


+ 0 - 1
assets/meshes/Rabbit.babylon.manifest

@@ -1 +0,0 @@
-{"version" : 1,    "enableSceneOffline" : true,    "enableTexturesOffline" : true}

BIN
assets/meshes/Tree/Tree.tga


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 5
assets/meshes/Tree/tree.babylon


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 5
assets/meshes/skull.babylon


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 95
assets/refs/dat.gui.min.js


BIN
assets/textures/16testSpecularHDR.dds


BIN
assets/textures/Brdf.dds


BIN
assets/textures/DefaultEnvironmentMap.dds


BIN
assets/textures/Ground.jpg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 4916
assets/textures/LateSunset.3dl


BIN
assets/textures/SpecularHDR.dds


BIN
assets/textures/albedo.png


BIN
assets/textures/amiga.jpg


BIN
assets/textures/babylonjs.mp4


BIN
assets/textures/babylonjs.webm


BIN
assets/textures/floor.png


BIN
assets/textures/floor_bump.PNG


BIN
assets/textures/grass.dds


BIN
assets/textures/grass.jpg


BIN
assets/textures/grass.png


BIN
assets/textures/grassn.png


BIN
assets/textures/hdr/room.hdr


BIN
assets/textures/heightMap.png


BIN
assets/textures/leopard_fur.JPG


BIN
assets/textures/misc.jpg


BIN
assets/textures/mixMap.png


BIN
assets/textures/player.png


BIN
assets/textures/reflectivity.png


BIN
assets/textures/rock.png


BIN
assets/textures/rockn.png


BIN
assets/textures/room.hdr


BIN
assets/textures/skybox/TropicalSunnyDay_nx.jpg


BIN
assets/textures/skybox/TropicalSunnyDay_ny.jpg


BIN
assets/textures/skybox/TropicalSunnyDay_nz.jpg


BIN
assets/textures/skybox/TropicalSunnyDay_px.jpg


BIN
assets/textures/skybox/TropicalSunnyDay_py.jpg


BIN
assets/textures/skybox/TropicalSunnyDay_pz.jpg


BIN
assets/textures/skybox/snow_nx.jpg


BIN
assets/textures/skybox/snow_ny.jpg


BIN
assets/textures/skybox/snow_nz.jpg


BIN
assets/textures/skybox/snow_px.jpg


BIN
assets/textures/skybox/snow_py.jpg


BIN
assets/textures/skybox/snow_pz.jpg


BIN
assets/textures/sparkle2.jpg


BIN
assets/textures/speckles.jpg


BIN
assets/textures/sun.png


BIN
assets/textures/test.png


BIN
assets/textures/testSpecularHDR.dds


BIN
assets/textures/tree.png


BIN
assets/textures/waterbump.png


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3180 - 2369
dist/preview release/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 53 - 51
dist/preview release/babylon.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 8425 - 6299
dist/preview release/babylon.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 3180 - 2369
dist/preview release/babylon.module.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 55 - 53
dist/preview release/babylon.worker.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5257 - 4428
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 55 - 54
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2818 - 1379
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5257 - 4428
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.module.d.ts


+ 0 - 0
dist/preview release/gui/babylon.gui.d.ts


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác