Browse Source

Add folder back

Christopher Yovanovitch 7 năm trước cách đây
mục cha
commit
0e15783687
100 tập tin đã thay đổi với 52042 bổ sung24419 xóa
  1. 1 0
      CNAME
  2. 21192 21104
      Playground/babylon.d.txt
  3. 3 3
      Playground/index.html
  4. 2 0
      Playground/js/libs/dat.gui.min.js
  5. 5 0
      Playground/js/libs/jquery.min.js
  6. 206 0
      Playground/js/libs/pep.min.js
  7. 67 28
      Playground/scripts/webvr.js
  8. BIN
      Viewer/assets/babylon.woff
  9. 13 2
      Viewer/assets/templates/default/navbar.html
  10. 5 1
      Viewer/src/configuration/configuration.ts
  11. 48 0
      Viewer/src/configuration/configurationCompatibility.ts
  12. 1 0
      Viewer/src/configuration/index.ts
  13. 3 0
      Viewer/src/configuration/loader.ts
  14. 1 1
      Viewer/src/configuration/mappers.ts
  15. 2 2
      Viewer/src/configuration/types/default.ts
  16. 2 0
      Viewer/src/index.ts
  17. 3 2
      Viewer/src/viewer/defaultViewer.ts
  18. 18 26
      Viewer/src/viewer/sceneManager.ts
  19. 12 6
      Viewer/src/viewer/viewer.ts
  20. 5 0
      Viewer/src/viewer/viewerManager.ts
  21. 55 0
      Viewer/tests/unit/src/configuration/loader.ts
  22. 97 0
      Viewer/tests/unit/src/configuration/mappers.ts
  23. 84 0
      Viewer/tests/unit/src/helper.ts
  24. 5 1
      Viewer/tests/unit/src/index.ts
  25. 46 31
      Viewer/tests/unit/src/viewer/viewer.ts
  26. 86 0
      Viewer/tests/unit/src/viewer/viewerManager.ts
  27. BIN
      Viewer/tests/validation/ReferenceImages/BrainStem.png
  28. BIN
      Viewer/tests/validation/ReferenceImages/BrainStemEnv.png
  29. BIN
      Viewer/tests/validation/ReferenceImages/BrainStemTransformation.png
  30. BIN
      Viewer/tests/validation/ReferenceImages/CameraContrast0.png
  31. BIN
      Viewer/tests/validation/ReferenceImages/CameraContrast1.png
  32. BIN
      Viewer/tests/validation/ReferenceImages/CameraExposure0.png
  33. BIN
      Viewer/tests/validation/ReferenceImages/CameraExposure1.png
  34. BIN
      Viewer/tests/validation/ReferenceImages/Control.png
  35. BIN
      Viewer/tests/validation/ReferenceImages/ControlDefault.png
  36. BIN
      Viewer/tests/validation/ReferenceImages/Diffuse.png
  37. BIN
      Viewer/tests/validation/ReferenceImages/Emissive.png
  38. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv0-0.png
  39. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv0-100.png
  40. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv0-50.png
  41. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv100-0.png
  42. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv100-100.png
  43. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv100-50.png
  44. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv50-0.png
  45. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv50-100.png
  46. BIN
      Viewer/tests/validation/ReferenceImages/MainColorEnv50-50.png
  47. BIN
      Viewer/tests/validation/ReferenceImages/Specular0-0.png
  48. BIN
      Viewer/tests/validation/ReferenceImages/Specular0-100.png
  49. BIN
      Viewer/tests/validation/ReferenceImages/Specular0-25.png
  50. BIN
      Viewer/tests/validation/ReferenceImages/Specular0-50.png
  51. BIN
      Viewer/tests/validation/ReferenceImages/Specular0-75.png
  52. BIN
      Viewer/tests/validation/ReferenceImages/Specular100-0.png
  53. BIN
      Viewer/tests/validation/ReferenceImages/Specular100-100.png
  54. BIN
      Viewer/tests/validation/ReferenceImages/Specular100-25.png
  55. BIN
      Viewer/tests/validation/ReferenceImages/Specular100-50.png
  56. BIN
      Viewer/tests/validation/ReferenceImages/Specular100-75.png
  57. BIN
      Viewer/tests/validation/ReferenceImages/Specular25-0.png
  58. BIN
      Viewer/tests/validation/ReferenceImages/Specular25-100.png
  59. BIN
      Viewer/tests/validation/ReferenceImages/Specular25-25.png
  60. BIN
      Viewer/tests/validation/ReferenceImages/Specular25-50.png
  61. BIN
      Viewer/tests/validation/ReferenceImages/Specular25-75.png
  62. BIN
      Viewer/tests/validation/ReferenceImages/Specular50-0.png
  63. BIN
      Viewer/tests/validation/ReferenceImages/Specular50-100.png
  64. BIN
      Viewer/tests/validation/ReferenceImages/Specular50-25.png
  65. BIN
      Viewer/tests/validation/ReferenceImages/Specular50-50.png
  66. BIN
      Viewer/tests/validation/ReferenceImages/Specular50-75.png
  67. BIN
      Viewer/tests/validation/ReferenceImages/Specular75-0.png
  68. BIN
      Viewer/tests/validation/ReferenceImages/Specular75-100.png
  69. BIN
      Viewer/tests/validation/ReferenceImages/Specular75-25.png
  70. BIN
      Viewer/tests/validation/ReferenceImages/Specular75-50.png
  71. BIN
      Viewer/tests/validation/ReferenceImages/Specular75-75.png
  72. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv0-0.png
  73. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv0-100.png
  74. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv0-50.png
  75. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv100-0.png
  76. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv100-100.png
  77. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv100-50.png
  78. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv50-0.png
  79. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv50-100.png
  80. BIN
      Viewer/tests/validation/ReferenceImages/SpecularEnv50-50.png
  81. BIN
      Viewer/tests/validation/ReferenceImages/Transparency.png
  82. 240 12
      Viewer/tests/validation/config.json
  83. 1 1
      Viewer/tests/validation/index.css
  84. 36 16
      Viewer/tests/validation/validation.js
  85. 4 1
      Viewer/tsconfig-gulp.json
  86. 1 1
      Viewer/webpack.gulp.config.js
  87. 12317 0
      dist/preview release/Oimo.js
  88. 21 0
      dist/preview release/Oimo.license
  89. 2 0
      dist/preview release/_headers
  90. 3098 3035
      dist/preview release/babylon.d.ts
  91. 50 50
      dist/preview release/babylon.js
  92. 160 23
      dist/preview release/babylon.max.js
  93. 160 23
      dist/preview release/babylon.no-module.max.js
  94. 50 50
      dist/preview release/babylon.worker.js
  95. 13687 0
      dist/preview release/cannon.js
  96. 22 0
      dist/preview release/cannon.license
  97. 201 0
      dist/preview release/draco.license
  98. 30 0
      dist/preview release/draco_decoder_gltf.js
  99. BIN
      dist/preview release/draco_decoder_gltf.wasm
  100. 0 0
      dist/preview release/draco_wasm_wrapper_gltf.js

+ 1 - 0
CNAME

@@ -0,0 +1 @@
+babylonjs.com

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 21192 - 21104
Playground/babylon.d.txt


+ 3 - 3
Playground/index.html

@@ -25,11 +25,11 @@
         <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
         <meta name="theme-color" content="#ffffff">
 
-        <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+        <script src="js/libs/pep.min.js"></script>
         <!--For canvas/code separator-->
         <script src="js/libs/split.js"></script>
 
-        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+        <script src="js/libs/dat.gui.min.js"></script>
         <!-- jszip -->
         <script src="js/libs/jszip.min.js"></script>
         <script src="js/libs/fileSaver.js"></script>
@@ -484,7 +484,7 @@
             <img src="waitlogo.png" id="waitLogo" />
         </div>
 
-        <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="js/libs/jquery.min.js"></script>
 
         <script src="js/actions.js"></script>
         <script src="js/pbt.js"></script>

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


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5 - 0
Playground/js/libs/jquery.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 206 - 0
Playground/js/libs/pep.min.js


+ 67 - 28
Playground/scripts/webvr.js

@@ -1,35 +1,74 @@
-var createScene = function () {
+var createScene = function() {
+    // Create scene
+	var scene = new BABYLON.Scene(engine);
 
-    // This creates a basic Babylon Scene object (non-mesh)
-    var scene = new BABYLON.Scene(engine);
-    scene.createDefaultVRExperience();
+    // Create simple sphere
+    var sphere = BABYLON.Mesh.CreateIcoSphere("sphere", {radius:0.2, flat:true, subdivisions: 1}, this.scene);
+    sphere.position.y = 3;
+    sphere.material = new BABYLON.StandardMaterial("sphere material",scene)
 
-    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
-    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
+    // Lights and camera
+    var light = new BABYLON.DirectionalLight("light", new BABYLON.Vector3(0, -0.5, 1.0), scene);
+    light.position = new BABYLON.Vector3(0, 5, -2);
+    var camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 4, 3, new BABYLON.Vector3(0, 3, 0), scene);
+    camera.attachControl(canvas, true);
+    scene.activeCamera.beta += 0.8;
 
-    // Default intensity is 1. Let's dim the light a small amount
-    light.intensity = 0.7;
+    // Default Environment
+    var environment = scene.createDefaultEnvironment({ enableGroundShadow: true, groundYBias: 1 });
+    environment.setMainColor(BABYLON.Color3.FromHexString("#74b9ff"))
+    
+    // Shadows
+    var shadowGenerator = new BABYLON.ShadowGenerator(1024, light);
+    shadowGenerator.useBlurExponentialShadowMap = true;
+    shadowGenerator.blurKernel = 32;
+    shadowGenerator.addShadowCaster(sphere, true);
 
-    // Create some spheres at the default eye level (2m)
-    createSphereBox(scene, 2, 2);
-    createSphereBox(scene, 3, 2);
-        
-    // Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene
-    var ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);
+    // Enable VR
+    var vrHelper = scene.createDefaultVRExperience({createDeviceOrientationCamera:false});
+    vrHelper.enableTeleportation({floorMeshes: [environment.ground]});
 
-    return scene;
+    // Runs every frame to rotate the sphere
+    scene.onBeforeRenderObservable.add(()=>{
+        sphere.rotation.y += 0.0001*scene.getEngine().getDeltaTime();
+        sphere.rotation.x += 0.0001*scene.getEngine().getDeltaTime();
+    })
+
+    // GUI
+    var plane = BABYLON.Mesh.CreatePlane("plane", 1);
+    plane.position = new BABYLON.Vector3(0.4, 4, 0.4)
+    var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateForMesh(plane);
+    var panel = new BABYLON.GUI.StackPanel();    
+    advancedTexture.addControl(panel);  
+    var header = new BABYLON.GUI.TextBlock();
+    header.text = "Color GUI";
+    header.height = "100px";
+    header.color = "white";
+    header.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
+    header.fontSize = "120"
+    panel.addControl(header); 
+    var picker = new BABYLON.GUI.ColorPicker();
+    picker.value = sphere.material.diffuseColor;
+    picker.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
+    picker.height = "350px";
+    picker.width = "350px";
+    picker.onValueChangedObservable.add(function(value) {
+        sphere.material.diffuseColor.copyFrom(value);
+    });
+    panel.addControl(picker);
+    
+	return scene;
 };
 
-function createSphereBox(scene, distance, height) {    
-    createSphere(scene,  distance, height,  distance);
-    createSphere(scene,  distance, height, -distance);
-    createSphere(scene, -distance, height,  distance);
-    createSphere(scene, -distance, height, -distance);    
-}
-function createSphere(scene, x, y, z) {
-    // Our built-in 'sphere' shape. Params: name, subdivs, size, scene
-    var sphere = BABYLON.Mesh.CreateSphere("sphere1", 4, 0.4, scene);
-    sphere.position.x = x;
-    sphere.position.y = y;
-    sphere.position.z = z;
-}
+var colors = {
+        seaFoam: BABYLON.Color3.FromHexString("#16a085"),
+        green: BABYLON.Color3.FromHexString("#27ae60"),
+        blue: BABYLON.Color3.FromHexString("#2980b9"),
+        purple: BABYLON.Color3.FromHexString("#8e44ad"),
+        navy: BABYLON.Color3.FromHexString("#2c3e50"),
+        yellow: BABYLON.Color3.FromHexString("#f39c12"),
+        orange: BABYLON.Color3.FromHexString("#d35400"),
+        red: BABYLON.Color3.FromHexString("#c0392b"),
+        white: BABYLON.Color3.FromHexString("#bdc3c7"),
+        gray: BABYLON.Color3.FromHexString("#7f8c8d")
+    }

BIN
Viewer/assets/babylon.woff


+ 13 - 2
Viewer/assets/templates/default/navbar.html

@@ -140,9 +140,8 @@
     }
 
     .help-icon:after {
-        /* TODO: wrong Icon, need font update */
         font-size: 16px;
-        content: "\F70C";
+        content: "\EF4E";
     }
 
     .progress-control {
@@ -151,6 +150,7 @@
         position: relative;
         overflow: hidden;
         cursor: pointer;
+        align-items: center;
     }
 
     .animation-number {
@@ -231,6 +231,12 @@
         display: none;
     }
 
+    /* Disable fullscreen button for small screens */
+
+    .fullscreen {
+        display: none;
+    }
+
     @media screen and (min-width: 540px) {
         .help,
         .types-icon,
@@ -257,6 +263,10 @@
         .speed .menu-options {
             width: 64px;
         }
+
+        .fullscreen {
+            display: block;
+        }
     }
 
     @media screen and (min-width: 1024px) {
@@ -301,6 +311,7 @@
         width: 100%;
         outline: none;
         margin: 0 12px;
+        height: 30px;
         background-color: transparent;
     }
 

+ 5 - 1
Viewer/src/configuration/configuration.ts

@@ -4,7 +4,7 @@ import { EngineOptions, IGlowLayerOptions, DepthOfFieldEffectBlurLevel } from 'b
 export function getConfigurationKey(key: string, configObject: any) {
     let splits = key.split('.');
 
-    if (splits.length === 0 || !configObject) return false;
+    if (splits.length === 0 || !configObject) return;
     else if (splits.length === 1) {
         if (configObject[key] !== undefined) {
             return configObject[key];
@@ -160,6 +160,7 @@ export interface IDefaultRenderingPipelineConfiguration {
     bllomThreshold?: number;
     hdr?: boolean;
     samples?: number;
+    glowLayerEnabled?: boolean;
 }
 
 export interface IModelConfiguration {
@@ -271,6 +272,9 @@ export interface ISceneConfiguration {
     environmentTexture?: string;
     colorGrading?: IColorGradingConfiguration;
     environmentRotationY?: number;
+    /**
+     * Deprecated, please use default rendering pipeline
+     */
     glow?: boolean | IGlowLayerOptions;
     disableHdr?: boolean;
     renderInBackground?: boolean;

+ 48 - 0
Viewer/src/configuration/configurationCompatibility.ts

@@ -0,0 +1,48 @@
+import { ViewerConfiguration, getConfigurationKey } from './'
+/**
+ * This function will make sure the configuration file is taking deprecated fields into account
+ * and is setting them to the correct keys and values.
+ * 
+ * @param configuration The configuration to process. Mutable!
+ */
+export function processConfigurationCompatibility(configuration: ViewerConfiguration) {
+
+
+
+    if (configuration.camera) {
+        // camera contrast -> image processing contrast
+        if (configuration.camera.contrast !== undefined) {
+            setKeyInObject(configuration, "scene.imageProcessingConfiguration.contrast", configuration.camera.contrast);
+        }
+
+        // camera exposure -> image processing exposure
+        if (configuration.camera.exposure !== undefined) {
+            setKeyInObject(configuration, "scene.imageProcessingConfiguration.exposure", configuration.camera.exposure);
+        }
+    }
+
+    if (configuration.scene) {
+        //glow
+        if (configuration.scene.glow) {
+            setKeyInObject(configuration, "lab.defaultRenderingPipelines.glowLayerEnabled", true);
+            let enabledProcessing = getConfigurationKey("scene.imageProcessingConfiguration.isEnabled", configuration);
+            if (enabledProcessing !== false) {
+                setKeyInObject(configuration, "scene.imageProcessingConfiguration.isEnabled", true);
+            }
+        }
+    }
+}
+
+function setKeyInObject(object: any, keys: string, value: any, shouldOverwrite?: boolean) {
+    let keySplit = keys.split(".");
+    if (keySplit.length === 0) return;
+    let lastKey = keySplit.pop();
+    if (!lastKey) return;
+    let curObj = object;
+    keySplit.forEach(key => {
+        curObj[key] = curObj[key] || {};
+        curObj = curObj[key];
+    });
+    if (curObj[lastKey] !== undefined && !shouldOverwrite) return;
+    curObj[lastKey] = value;
+}

+ 1 - 0
Viewer/src/configuration/index.ts

@@ -0,0 +1 @@
+export * from './configuration';

+ 3 - 0
Viewer/src/configuration/loader.ts

@@ -1,6 +1,7 @@
 import { mapperManager } from './mappers';
 import { ViewerConfiguration } from './configuration';
 import { getConfigurationType } from './types';
+import { processConfigurationCompatibility } from './configurationCompatibility';
 
 import * as deepmerge from '../../assets/deepmerge.min.js';
 import { Tools, IFileRequest } from 'babylonjs';
@@ -73,10 +74,12 @@ export class ConfigurationLoader {
                 let mapper = mapperManager.getMapper(mapperType);
                 let parsed = mapper.map(data);
                 let merged = deepmerge(loadedConfig, parsed);
+                processConfigurationCompatibility(merged);
                 if (callback) callback(merged);
                 return merged;
             });
         } else {
+            processConfigurationCompatibility(loadedConfig);
             if (callback) callback(loadedConfig);
             return Promise.resolve(loadedConfig);
         }

+ 1 - 1
Viewer/src/configuration/mappers.ts

@@ -163,7 +163,7 @@ export class MapperManager {
         if (!this._mappers[type]) {
             Tools.Error("No mapper defined for " + type);
         }
-        return this._mappers[type] || this._mappers[MapperManager.DefaultMapper];
+        return this._mappers[type];
     }
 
     /**

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

@@ -43,7 +43,7 @@ export let defaultConfiguration: ViewerConfiguration = {
                 logoText: 'BabylonJS',
                 logoLink: 'https://babylonjs.com',
                 hideHelp: true,
-                disableOnFullscreen: true,
+                disableOnFullscreen: false,
             },
             events: {
                 pointerdown: {
@@ -102,4 +102,4 @@ export let defaultConfiguration: ViewerConfiguration = {
     },
     scene: {
     }
-}
+}

+ 2 - 0
Viewer/src/index.ts

@@ -46,3 +46,5 @@ console.log("Babylon.js viewer (v" + Version + ")");
 
 // public API for initialization
 export { BABYLON, Version, InitTags, DefaultViewer, AbstractViewer, viewerGlobals, telemetryManager, disableInit, viewerManager, mapperManager, disposeAll, ModelLoader, ViewerModel, AnimationPlayMode, AnimationState, ModelState, ILoaderPlugin };
+// export publicliy all configuration interfaces
+export * from './configuration';

+ 3 - 2
Viewer/src/viewer/defaultViewer.ts

@@ -60,7 +60,8 @@ export class DefaultViewer extends AbstractViewer {
             }, "pointerdown", "#help-button");
 
             this.templateManager.eventManager.registerCallback("navBar", (event: EventCallback) => {
-                let element = <HTMLInputElement>event.event.srcElement;
+                const evt = event.event;
+                const element = <HTMLInputElement>(evt.target);
                 if (!this._currentAnimation) return;
                 const gotoFrame = +element.value / 100 * this._currentAnimation.frames;
                 if (isNaN(gotoFrame)) return;
@@ -85,7 +86,7 @@ export class DefaultViewer extends AbstractViewer {
 
         let pointerDown = <PointerEvent>event.event;
         if (pointerDown.button !== 0) return;
-        var element = (<HTMLElement>event.event.srcElement);
+        var element = (<HTMLElement>event.event.target);
 
         if (!element) {
             return;

+ 18 - 26
Viewer/src/viewer/sceneManager.ts

@@ -331,7 +331,7 @@ export class SceneManager {
 
         this._mainColor = Color3.White();
 
-        if (sceneConfiguration.glow) {
+        /*if (sceneConfiguration.glow) {
             let options: Partial<IGlowLayerOptions> = {
                 mainTextureFixedSize: 512
             };
@@ -339,7 +339,7 @@ export class SceneManager {
                 options = sceneConfiguration.glow
             }
             var gl = new BABYLON.GlowLayer("glow", this.scene, options);
-        }
+        }*/
 
         return this.onSceneInitObservable.notifyObserversWithPromise(this.scene);
     }
@@ -603,22 +603,14 @@ export class SceneManager {
 
             this._reflectionColor.copyFrom(this.mainColor);
 
-            if (this._viewer.configuration.camera && this._viewer.configuration.camera.exposure) {
 
-                let environmentTint = getConfigurationKey("lab.environmentMap.tintLevel", this._viewer.configuration) || 0;
+            let environmentTint = getConfigurationKey("lab.environmentMap.tintLevel", this._viewer.configuration) || 0;
 
-                /*this._mainColor.toLinearSpaceToRef(this._mainColor);
-                let exposure = Math.pow(2.0, -(this._viewer.configuration.camera.exposure) * Math.PI);
-                this._mainColor.scaleToRef(1 / exposure, this._mainColor);
-                let tmpColor = Color3.Lerp(this._white, this._mainColor, environmentTint);
-                this._mainColor.copyFrom(tmpColor);*/
-
-                // reflection color
-                this._reflectionColor.toLinearSpaceToRef(this._reflectionColor);
-                this._reflectionColor.scaleToRef(1 / this._viewer.configuration.camera.exposure, this._reflectionColor);
-                let tmpColor3 = Color3.Lerp(this._white, this._reflectionColor, environmentTint);
-                this._reflectionColor.copyFrom(tmpColor3);
-            }
+            // reflection color
+            this._reflectionColor.toLinearSpaceToRef(this._reflectionColor);
+            this._reflectionColor.scaleToRef(1 / this.scene.imageProcessingConfiguration.exposure, this._reflectionColor);
+            let tmpColor3 = Color3.Lerp(this._white, this._reflectionColor, environmentTint);
+            this._reflectionColor.copyFrom(tmpColor3);
 
             //update the environment, if exists
             if (this.environmentHelper) {
@@ -786,10 +778,6 @@ export class SceneManager {
         if (this.scene.imageProcessingConfiguration) {
             this.scene.imageProcessingConfiguration.colorCurvesEnabled = true;
             this.scene.imageProcessingConfiguration.vignetteEnabled = true;
-            if (cameraConfig.contrast !== undefined)
-                this.scene.imageProcessingConfiguration.contrast = cameraConfig.contrast;
-            if (cameraConfig.exposure !== undefined)
-                this.scene.imageProcessingConfiguration.exposure = cameraConfig.exposure;
             this.scene.imageProcessingConfiguration.toneMappingEnabled = !!cameraConfig.toneMappingEnabled;
         }
 
@@ -915,7 +903,7 @@ export class SceneManager {
         if (!this.environmentHelper) {
             this.environmentHelper = this.scene.createDefaultEnvironment(options)!;
         } else {
-            // there might be a new scene! we need to dispose.
+            // unlikely, but there might be a new scene! we need to dispose.
 
             // get the scene used by the envHelper
             let scene: Scene = this.environmentHelper.rootMesh.getScene();
@@ -933,15 +921,17 @@ export class SceneManager {
         }
 
         let groundConfig = (typeof groundConfiguration === 'boolean') ? {} : groundConfiguration;
-        if (this.environmentHelper.groundMaterial && groundConfig && groundConfig.material) {
+        if (this.environmentHelper.groundMaterial && groundConfig) {
             this.environmentHelper.groundMaterial._perceptualColor = this.mainColor;
-            extendClassWithConfig(this.environmentHelper.groundMaterial, groundConfig.material);
+            if (groundConfig.material) {
+                extendClassWithConfig(this.environmentHelper.groundMaterial, groundConfig.material);
+            }
 
             if (this.environmentHelper.groundMirror) {
                 const mirrorClearColor = this.environmentHelper.groundMaterial._perceptualColor.toLinearSpace();
                 // TODO user camera exposure value to set the mirror clear color
-                //let exposure = Math.pow(2.0, -this.configuration.camera.exposure) * Math.PI;
-                //mirrorClearColor.scaleToRef(1 / exposure, mirrorClearColor);
+                let exposure = Math.pow(2.0, -this.scene.imageProcessingConfiguration.exposure) * Math.PI;
+                mirrorClearColor.scaleToRef(1 / exposure, mirrorClearColor);
 
                 this.environmentHelper.groundMirror.clearColor.r = Scalar.Clamp(mirrorClearColor.r);
                 this.environmentHelper.groundMirror.clearColor.g = Scalar.Clamp(mirrorClearColor.g);
@@ -1282,7 +1272,9 @@ export class SceneManager {
 
         this.models.length = 0;
 
-        this.scene.dispose();
+        if (this.scene) {
+            this.scene.dispose();
+        }
     }
 
     private _setCameraBehavior(behaviorConfig: number | {

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

@@ -210,9 +210,7 @@ export abstract class AbstractViewer {
 
         this.onInitDoneObservable.add(() => {
             this._isInit = true;
-            //this.sceneManager.scene.executeWhenReady(() => {
             this.engine.runRenderLoop(this._render);
-            //});
         });
     }
 
@@ -234,14 +232,16 @@ export abstract class AbstractViewer {
      * Is the engine currently set to rende even when the page is in background
      */
     public get renderInBackground() {
-        return this.engine.renderEvenInBackground;
+        return this.engine && this.engine.renderEvenInBackground;
     }
 
     /**
      * Set the viewer's background rendering flag.
      */
     public set renderInBackground(value: boolean) {
-        this.engine.renderEvenInBackground = value;
+        if (this.engine) {
+            this.engine.renderEvenInBackground = value;
+        }
     }
 
     /**
@@ -410,7 +410,7 @@ export abstract class AbstractViewer {
         this.onModelAddedObservable.clear();
         this.onModelRemovedObservable.clear();
 
-        if (this.sceneManager.scene.activeCamera) {
+        if (this.sceneManager.scene && this.sceneManager.scene.activeCamera) {
             this.sceneManager.scene.activeCamera.detachControl(this.canvas);
         }
 
@@ -421,7 +421,9 @@ export abstract class AbstractViewer {
 
         this.modelLoader.dispose();
 
-        this.engine.dispose();
+        if (this.engine) {
+            this.engine.dispose();
+        }
 
         this.templateManager.dispose();
         viewerManager.removeViewer(this);
@@ -449,6 +451,10 @@ export abstract class AbstractViewer {
      * But first - it will load the extendible onTemplateLoaded()!
      */
     private _onTemplateLoaded(): Promise<AbstractViewer> {
+        // check if viewer was disposed right after created
+        if (this._isDisposed) {
+            return Promise.reject("viewer was disposed");
+        }
         return this._onTemplatesLoaded().then(() => {
             let autoLoad = typeof this._configuration.model === 'string' || (this._configuration.model && this._configuration.model.url);
             return this._initEngine().then((engine) => {

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

@@ -98,9 +98,14 @@ export class ViewerManager {
      * dispose the manager and all of its associated viewers
      */
     public dispose() {
+        delete this._onViewerAdded;
+
         for (let id in this._viewers) {
             this._viewers[id].dispose();
         }
+
+        this.onViewerAddedObservable.clear();
+        this.onViewerRemovedObservable.clear();
     }
 }
 

+ 55 - 0
Viewer/tests/unit/src/configuration/loader.ts

@@ -0,0 +1,55 @@
+import { Helper } from "../../../commons/helper";
+import { assert, expect, should } from "../viewerReference";
+import { mapperManager, ViewerConfiguration } from "..";
+import { IMapper } from "../../../../src/configuration/mappers";
+import { ConfigurationLoader } from "../../../../src/configuration/loader";
+
+export let name = "configuration loader";
+
+describe("Configuration loader", () => {
+
+    it("should call callback when configuration is loaded", (done) => {
+        let configurationLoader = new ConfigurationLoader();
+
+        configurationLoader.loadConfiguration({}, (newConfig) => {
+            done();
+        });
+    });
+
+    it("should resolve the promise when configuration is loaded", (done) => {
+        let configurationLoader = new ConfigurationLoader();
+
+        configurationLoader.loadConfiguration({}).then(() => {
+            done();
+        });
+    });
+
+    it("should not change configuration is not needed initConfig", (done) => {
+        let configurationLoader = new ConfigurationLoader();
+
+        let config: ViewerConfiguration = {
+            version: "" + Math.random(),
+            extends: "none"
+        };
+        configurationLoader.loadConfiguration(config, (newConfig) => {
+            assert.deepEqual(config, newConfig);
+            done();
+        });
+    });
+
+    it("should load default configuration is no configuration extension provided", (done) => {
+        let configurationLoader = new ConfigurationLoader();
+
+        let config: ViewerConfiguration = {
+            version: "" + Math.random()
+        };
+        configurationLoader.loadConfiguration(config, (newConfig) => {
+            assert.equal(config.version, newConfig.version);
+            assert.notDeepEqual(config, newConfig);
+            assert.isDefined(newConfig.engine);
+            assert.isDefined(newConfig.scene);
+            assert.isDefined(newConfig.templates);
+            done();
+        });
+    });
+});

+ 97 - 0
Viewer/tests/unit/src/configuration/mappers.ts

@@ -0,0 +1,97 @@
+import { Helper } from "../../../commons/helper";
+import { assert, expect, should } from "../viewerReference";
+import { mapperManager } from "..";
+import { IMapper } from "../../../../src/configuration/mappers";
+
+export let name = "configuration mappers";
+
+describe("Configuration mappers", () => {
+
+    it("should have html, json and dom mappers", (done) => {
+        assert.isDefined(mapperManager);
+        assert.isDefined(mapperManager.getMapper("html"));
+        assert.isDefined(mapperManager.getMapper("json"));
+        assert.isDefined(mapperManager.getMapper("dom"));
+        done();
+    });
+
+    it("should map html elements correctly", (done) => {
+        let htmlMappers = mapperManager.getMapper("html");
+
+        let randomNumber = Math.random();
+        let randomString = "test-" + Math.random();
+        let htmlString = `<test-element model.rotation-offset-angle="${randomNumber}" model.cast-shadow="true" model.id="${randomString}"></test-element>`;
+
+        var d = document.createElement('div');
+        d.innerHTML = htmlString;
+        let htmlElement = d.firstChild;
+
+        let config = htmlMappers.map(htmlElement);
+
+        if (config.model && typeof config.model === 'object') {
+            assert.equal(config.model.rotationOffsetAngle, randomNumber);
+            assert.isTrue(config.model.castShadow);
+            assert.equal(config.model.id, randomString);
+            done();
+        } else {
+            assert.fail();
+        }
+    });
+
+    it("should map dom elements correctly", (done) => {
+        let domMappers = mapperManager.getMapper("dom");
+
+        let randomNumber = Math.random();
+        let randomString = "test-" + Math.random();
+        let htmlString = `<test-element>
+    <model rotation-offset-angle="${randomNumber}" cast-shadow="true" id="${randomString}">
+    </model>
+</test-element>`;
+
+        var d = document.createElement('div');
+        d.innerHTML = htmlString;
+        let htmlElement = d.firstChild;
+
+        let config = domMappers.map(htmlElement);
+
+        if (config.model && typeof config.model === 'object') {
+            assert.equal(config.model.rotationOffsetAngle, randomNumber);
+            assert.isTrue(config.model.castShadow);
+            assert.equal(config.model.id, randomString);
+            done();
+        } else {
+            assert.fail();
+        }
+    });
+
+    it("should register a new mapper and allow to use it", (done) => {
+
+        let randomVersion = "version" + Math.random();
+        let randomName = "test" + Math.random();
+        randomName = randomName.replace(".", "");
+        let newMapper: IMapper = {
+            map: (rawSource) => {
+                return {
+                    version: randomVersion
+                }
+            }
+        }
+
+        console.log("Next error log is expected");
+
+        assert.isUndefined(mapperManager.getMapper(randomName));
+
+        mapperManager.registerMapper(randomName, newMapper);
+
+        let mapperTest = mapperManager.getMapper(randomName);
+        assert.isDefined(mapperTest);
+        assert.equal(mapperTest, newMapper);
+
+        let config = mapperTest.map("");
+
+        assert.equal(config.version, randomVersion);
+        done();
+
+    });
+
+});

+ 84 - 0
Viewer/tests/unit/src/helper.ts

@@ -0,0 +1,84 @@
+import { Helper } from "./../../commons/helper";
+import { assert, expect, should } from "./viewerReference";
+import { mapperManager, ViewerConfiguration } from ".";
+import { camelToKebab, kebabToCamel, isUrl, extendClassWithConfig } from "../../../src/helper";
+
+export let name = "viewer helper tests";
+
+describe("viewer helper", () => {
+
+    it("should convert camelCase to kebab-case and back", (done) => {
+
+        let camelString = "oneTestTwoTestThreeTest";
+
+        let kebab = camelToKebab(camelString);
+
+        assert.equal(kebab, "one-test-two-test-three-test");
+
+        assert.equal(kebabToCamel(kebab), camelString);
+
+        done();
+    });
+
+    it("should find absolute and relative http urls", (done) => {
+
+        let url = "http://test.url/?param=123";
+        let https = "https://https.url.to.check/"
+        let relativeUrl = "/url/to/find";
+        let notUrl = "not a url!";
+        let ftp = "ftp://test.ftp.server";
+
+        assert.isTrue(isUrl(url));
+        assert.isTrue(isUrl(https));
+        assert.isTrue(isUrl(relativeUrl));
+        assert.isFalse(isUrl(notUrl));
+        assert.isFalse(isUrl(ftp));
+
+        done();
+    });
+
+    it("should extend objects correctly", (done) => {
+
+        let finalKey = Math.random();
+
+        let toAugoment: any = {
+            definedKey: Math.random(),
+            color: {
+                r: 0,
+                g: 0
+            },
+            test: function () {
+
+            }
+        }
+
+        let augmentation: any = {
+            definedKey: finalKey,
+            color: {
+                r: finalKey,
+                g: finalKey,
+                b: finalKey
+            },
+            undefinedKey: "shouldNotBeAugmented",
+            test: "should be ignored"
+        }
+
+        assert.notEqual(toAugoment.definedKey, augmentation.definedKey);
+
+        extendClassWithConfig(toAugoment, augmentation);
+
+        //defined keys should be replaced
+        assert.equal(toAugoment.definedKey, finalKey);
+        //undefined keys should not be set
+        assert.isUndefined(toAugoment.undefinedKey);
+        // functions should be ignored
+        assert.isFunction(toAugoment.test);
+        //should iterate to deep objects
+        assert.equal(toAugoment.color.r, finalKey);
+        assert.equal(toAugoment.color.g, finalKey);
+        //b should not be set!
+        assert.isUndefined(toAugoment.color.b);
+
+        done();
+    });
+});

+ 5 - 1
Viewer/tests/unit/src/index.ts

@@ -2,5 +2,9 @@ import { main } from '../../commons/boot';
 if (window && !window['validation']) {
     main();
 }
-export * from './viewer/viewer';
+import './viewer/viewer';
+import './viewer/viewerManager';
+import './configuration/mappers';
+import './configuration/loader';
+import './helper';
 export * from '../../../src'

+ 46 - 31
Viewer/tests/unit/src/viewer/viewer.ts

@@ -175,12 +175,14 @@ describe('Viewer', function () {
         let viewer = Helper.getNewViewerInstance();
         viewer.onInitDoneObservable.add(() => {
             assert.isTrue(viewer.engine.renderEvenInBackground, "Engine is rendering in background");
+            assert.equal(viewer.engine.renderEvenInBackground, viewer.renderInBackground, "engine render in background should be equal to the viewer's");
             viewer.updateConfiguration({
                 scene: {
                     renderInBackground: false
                 }
             });
             assert.isFalse(viewer.engine.renderEvenInBackground, "Engine is not rendering in background");
+            assert.equal(viewer.engine.renderEvenInBackground, viewer.renderInBackground, "engine render in background should be equal to the viewer's");
             viewer.dispose();
             done();
         });
@@ -260,6 +262,50 @@ describe('Viewer', function () {
             viewer.forceRender();
         });
     });
+
+    it('should have the correct base ID', (done) => {
+        let element = document.createElement("div");
+        let randomString = "" + Math.random();
+        element.id = randomString;
+        let viewer = Helper.getNewViewerInstance(element);
+        assert.equal(viewer.baseId, viewer.containerElement.id);
+        assert.equal(randomString, viewer.baseId);
+        viewer.dispose();
+        done();
+    });
+
+    it('should update the configuration object when updateConfiguration is called', (done) => {
+        let randomVersion = "" + Math.random();
+        let viewer = Helper.getNewViewerInstance(undefined, {
+            version: randomVersion
+        });
+        viewer.onInitDoneObservable.add(() => {
+            assert.equal(viewer.configuration.version, randomVersion);
+            let newRandom = "" + Math.random();
+            viewer.updateConfiguration({
+                version: newRandom
+            });
+            assert.equal(viewer.configuration.version, newRandom);
+            viewer.dispose();
+            done();
+        });
+    });
+
+    it('should not init engine if viewer is disposed right after created', (done) => {
+        let viewer = Helper.getNewViewerInstance();
+        viewer.dispose();
+        // wait a bit for the engine to initialize, if failed
+        let timeout = setTimeout(() => {
+            assert.isUndefined(viewer.engine);
+            done();
+        }, 1000);
+
+        viewer.onEngineInitObservable.add(() => {
+            assert.fail();
+            clearTimeout(timeout);
+            done();
+        });
+    });
 });
 
 //}
@@ -399,35 +445,4 @@ QUnit.test('Test getEnvironmentAssetUrl absolute root', function (assert) {
     assert.ok(viewer.getEnvironmentAssetUrl("http://foo.png") === "http://foo.png", "Absolute url should not be undefined with configuration.");
 });
 
-QUnit.test('unlockBabylonFeatures', function () {
-    let viewer = Helper.createViewer();
-
-    QUnit.assert.ok(viewer.Scene.EngineScene.shadowsEnabled, "shadowsEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.particlesEnabled, "particlesEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.collisionsEnabled, "collisionsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.lightsEnabled, "lightsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.texturesEnabled, "texturesEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.lensFlaresEnabled, "lensFlaresEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.proceduralTexturesEnabled, "proceduralTexturesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.renderTargetsEnabled, "renderTargetsEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.spritesEnabled, "spritesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.skeletonsEnabled, "skeletonsEnabled");
-    QUnit.assert.ok(!viewer.Scene.EngineScene.audioEnabled, "audioEnabled");
-
-    viewer.unlockBabylonFeatures();
-
-    QUnit.assert.ok(viewer.Scene.EngineScene.shadowsEnabled, "shadowsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.particlesEnabled, "particlesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.postProcessesEnabled, "postProcessesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.collisionsEnabled, "collisionsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.lightsEnabled, "lightsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.texturesEnabled, "texturesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.lensFlaresEnabled, "lensFlaresEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.proceduralTexturesEnabled, "proceduralTexturesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.renderTargetsEnabled, "renderTargetsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.spritesEnabled, "spritesEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.skeletonsEnabled, "skeletonsEnabled");
-    QUnit.assert.ok(viewer.Scene.EngineScene.audioEnabled, "audioEnabled");
-});
-
 */

+ 86 - 0
Viewer/tests/unit/src/viewer/viewerManager.ts

@@ -0,0 +1,86 @@
+import { Helper } from "../../../commons/helper";
+import { assert, expect, should } from "../viewerReference";
+import { DefaultViewer, AbstractViewer, Version, viewerManager } from "../../../../src";
+
+export let name = "viewer manager tests";
+
+describe('Viewer Manager', function () {
+    it("should be defined when the library is loaded", (done) => {
+        assert.isDefined(viewerManager, "viewerManager is not defined");
+        done();
+    });
+
+    it("should add and remove a viewer when viewer constructed and disposed", (done) => {
+        let element = document.createElement("div");
+        let randomString = "" + Math.random();
+        element.id = randomString;
+
+        assert.isUndefined(viewerManager.getViewerByHTMLElement(element));
+        assert.isUndefined(viewerManager.getViewerById(randomString));
+        let viewer = Helper.getNewViewerInstance(element);
+        assert.isDefined(viewerManager.getViewerByHTMLElement(element));
+        assert.isDefined(viewerManager.getViewerById(randomString));
+        viewer.dispose();
+        assert.isUndefined(viewerManager.getViewerByHTMLElement(element));
+        assert.isUndefined(viewerManager.getViewerById(randomString));
+        done();
+    });
+
+    it("should trigger the promsie when viewer was added", (done) => {
+        let element = document.createElement("div");
+        let randomString = "" + Math.random();
+        element.id = randomString;
+
+        let viewer = Helper.getNewViewerInstance(element);
+        viewerManager.getViewerPromiseById(randomString).then(() => {
+            viewer.dispose();
+            done();
+        }, (error) => {
+            assert.fail();
+        });
+    });
+
+    it("should trigger observers when viewer constructed and disposed", (done) => {
+        let element = document.createElement("div");
+        let randomString = "" + Math.random();
+        element.id = randomString;
+
+        let addedFlag = false;
+
+        viewerManager.onViewerAddedObservable.add((addedViewer) => {
+            assert.equal(addedViewer.baseId, randomString);
+            addedFlag = true;
+        });
+
+        viewerManager.onViewerRemovedObservable.add((viewerId) => {
+            assert.equal(randomString, viewerId);
+            if (addedFlag) {
+                viewerManager.dispose();
+                done();
+            } else {
+                assert.fail();
+            }
+        });
+
+        let viewer = Helper.getNewViewerInstance(element);
+        viewer.dispose();
+    });
+
+    it("should dispose viewer(s) when disposed", (done) => {
+        let element = document.createElement("div");
+        let randomString = "" + Math.random();
+        element.id = randomString;
+
+        let viewer = Helper.getNewViewerInstance(element);
+
+        let dispose = viewer.dispose;
+
+        viewer.dispose = () => {
+            dispose.call(viewer);
+            done();
+        }
+
+        viewerManager.dispose();
+
+    });
+});

BIN
Viewer/tests/validation/ReferenceImages/BrainStem.png


BIN
Viewer/tests/validation/ReferenceImages/BrainStemEnv.png


BIN
Viewer/tests/validation/ReferenceImages/BrainStemTransformation.png


BIN
Viewer/tests/validation/ReferenceImages/CameraContrast0.png


BIN
Viewer/tests/validation/ReferenceImages/CameraContrast1.png


BIN
Viewer/tests/validation/ReferenceImages/CameraExposure0.png


BIN
Viewer/tests/validation/ReferenceImages/CameraExposure1.png


BIN
Viewer/tests/validation/ReferenceImages/Control.png


BIN
Viewer/tests/validation/ReferenceImages/ControlDefault.png


BIN
Viewer/tests/validation/ReferenceImages/Diffuse.png


BIN
Viewer/tests/validation/ReferenceImages/Emissive.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv0-0.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv0-100.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv0-50.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv100-0.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv100-100.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv100-50.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv50-0.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv50-100.png


BIN
Viewer/tests/validation/ReferenceImages/MainColorEnv50-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular0-0.png


BIN
Viewer/tests/validation/ReferenceImages/Specular0-100.png


BIN
Viewer/tests/validation/ReferenceImages/Specular0-25.png


BIN
Viewer/tests/validation/ReferenceImages/Specular0-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular0-75.png


BIN
Viewer/tests/validation/ReferenceImages/Specular100-0.png


BIN
Viewer/tests/validation/ReferenceImages/Specular100-100.png


BIN
Viewer/tests/validation/ReferenceImages/Specular100-25.png


BIN
Viewer/tests/validation/ReferenceImages/Specular100-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular100-75.png


BIN
Viewer/tests/validation/ReferenceImages/Specular25-0.png


BIN
Viewer/tests/validation/ReferenceImages/Specular25-100.png


BIN
Viewer/tests/validation/ReferenceImages/Specular25-25.png


BIN
Viewer/tests/validation/ReferenceImages/Specular25-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular25-75.png


BIN
Viewer/tests/validation/ReferenceImages/Specular50-0.png


BIN
Viewer/tests/validation/ReferenceImages/Specular50-100.png


BIN
Viewer/tests/validation/ReferenceImages/Specular50-25.png


BIN
Viewer/tests/validation/ReferenceImages/Specular50-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular50-75.png


BIN
Viewer/tests/validation/ReferenceImages/Specular75-0.png


BIN
Viewer/tests/validation/ReferenceImages/Specular75-100.png


BIN
Viewer/tests/validation/ReferenceImages/Specular75-25.png


BIN
Viewer/tests/validation/ReferenceImages/Specular75-50.png


BIN
Viewer/tests/validation/ReferenceImages/Specular75-75.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv0-0.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv0-100.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv0-50.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv100-0.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv100-100.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv100-50.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv50-0.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv50-100.png


BIN
Viewer/tests/validation/ReferenceImages/SpecularEnv50-50.png


BIN
Viewer/tests/validation/ReferenceImages/Transparency.png


+ 240 - 12
Viewer/tests/validation/config.json

@@ -2,10 +2,18 @@
     "root": "",
     "tests": [
         {
+            "title": "Control Default",
+            "createMesh": true,
+            "configuration": {
+                "extends": "default"
+            },
+            "referenceImage": "ControlDefault.png"
+        },
+        {
             "title": "Control",
             "createMesh": true,
             "configuration": {
-                "extends": "extended, shadowDirectionalLight"
+                "extends": "extended"
             },
             "referenceImage": "Control.png"
         },
@@ -14,7 +22,7 @@
             "createMesh": true,
             "createMaterial": true,
             "configuration": {
-                "extends": "extended, shadowDirectionalLight",
+                "extends": "extended",
                 "castShadow": true,
                 "model": {
                     "material": {
@@ -35,13 +43,224 @@
             "referenceImage": "Diffuse.png"
         },
         {
-            "title": "Specular {{glos * 20}} - {{spec * 20}}",
+            "title": "Emissive",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 1,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0.8,
+                            "g": 0.8,
+                            "b": 0.8
+                        },
+                        "microSurface": 0
+                    }
+                }
+            },
+            "referenceImage": "Emissive.png"
+        },
+        {
+            "title": "Transparency",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0.5,
+                            "g": 0.5,
+                            "b": 0.5
+                        },
+                        "alpha": 0.5,
+                        "microSurface": 0.5
+                    }
+                }
+            },
+            "referenceImage": "Transparency.png"
+        },
+        {
+            "title": "Camera Contrast 0",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 0
+                        },
+                        "microSurface": 1
+                    }
+                },
+                "camera": {
+                    "contrast": 0
+                }
+            },
+            "referenceImage": "CameraContrast0.png"
+        },
+        {
+            "title": "Camera Contrast 1",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 0
+                        },
+                        "microSurface": 1
+                    }
+                },
+                "camera": {
+                    "contrast": 1
+                }
+            },
+            "referenceImage": "CameraContrast1.png"
+        },
+        {
+            "title": "Camera Exposure 0.001",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 0
+                        },
+                        "microSurface": 1
+                    }
+                },
+                "camera": {
+                    "exposure": 0.001
+                }
+            },
+            "referenceImage": "CameraExposure0.png"
+        },
+        {
+            "title": "Camera Exposure 1",
+            "createMesh": true,
+            "createMaterial": true,
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": 0,
+                            "g": 0,
+                            "b": 0
+                        },
+                        "microSurface": 1
+                    }
+                },
+                "camera": {
+                    "exposure": 1
+                }
+            },
+            "referenceImage": "CameraExposure1.png"
+        },
+        {
+            "title": "Specular With Env {{glos * 50}} - {{spec * 50}}",
             "createMesh": true,
             "createMaterial": true,
             "repeatVariables": "glos,spec",
-            "repeatTimes": "6,6",
+            "repeatTimes": "3,3",
             "configuration": {
-                "extends": "extended, shadowDirectionalLight",
+                "extends": "extended",
+                "castShadow": true,
+                "model": {
+                    "material": {
+                        "albedoColor": {
+                            "r": 1,
+                            "g": 0,
+                            "b": 1
+                        },
+                        "reflectivityColor": {
+                            "r": "{{spec / 2}}",
+                            "g": "{{spec / 2}}",
+                            "b": "{{spec / 2}}"
+                        },
+                        "microSurface": "{{glos / 2}}"
+                    }
+                }
+            },
+            "referenceImage": "SpecularEnv{{glos * 50}}-{{spec * 50}}.png",
+            "enableEnvironment": true
+        },
+        {
+            "title": "Main Color Env {{r * 50}} - {{g * 50}}",
+            "createMesh": true,
+            "createMaterial": true,
+            "repeatVariables": "r,g",
+            "repeatTimes": "3,3",
+            "configuration": {
+                "extends": "extended",
+                "castShadow": true,
+                "scene": {
+                    "mainColor": {
+                        "r": "{{r / 2}}",
+                        "g": "{{g / 2}}",
+                        "b": "1"
+                    }
+                }
+            },
+            "referenceImage": "MainColorEnv{{r * 50}}-{{g * 50}}.png",
+            "enableEnvironment": true
+        },
+        {
+            "title": "Specular {{glos * 25}} - {{spec * 25}}",
+            "createMesh": true,
+            "createMaterial": true,
+            "repeatVariables": "glos,spec",
+            "repeatTimes": "5,5",
+            "configuration": {
+                "extends": "extended",
                 "castShadow": true,
                 "model": {
                     "material": {
@@ -51,28 +270,37 @@
                             "b": 1
                         },
                         "reflectivityColor": {
-                            "r": "{{spec / 5}}",
-                            "g": "{{spec / 5}}",
-                            "b": "{{spec / 5}}"
+                            "r": "{{spec / 4}}",
+                            "g": "{{spec / 4}}",
+                            "b": "{{spec / 4}}"
                         },
-                        "microSurface": "{{glos / 5}}"
+                        "microSurface": "{{glos / 4}}"
                     }
                 }
             },
-            "referenceImage": "Specular{{glos * 20}}-{{spec * 20}}.png"
+            "referenceImage": "Specular{{glos * 25}}-{{spec * 25}}.png"
         },
         {
             "title": "BrainStem",
             "configuration": {
-                "extends": "extended, shadowDirectionalLight"
+                "extends": "extended"
             },
             "model": "/dist/assets/BrainStem/BrainStem.gltf",
             "referenceImage": "BrainStem.png"
         },
         {
+            "title": "BrainStem Environment",
+            "configuration": {
+                "extends": "extended"
+            },
+            "model": "/dist/assets/BrainStem/BrainStem.gltf",
+            "referenceImage": "BrainStemEnv.png",
+            "enableEnvironment": true
+        },
+        {
             "title": "BrainStem transformation",
             "configuration": {
-                "extends": "extended, shadowDirectionalLight",
+                "extends": "extended",
                 "camera": {
                     "disableAutoFocus": true
                 },

+ 1 - 1
Viewer/tests/validation/index.css

@@ -72,7 +72,7 @@ babylon {
     position: absolute !important;
     transform: translateX(-600px);
     width: 600px;
-    height: 400px;
+    height: 400px !important;
 }
 
 .renderImage {

+ 36 - 16
Viewer/tests/validation/validation.js

@@ -90,6 +90,22 @@ function saveRenderImage(data, canvas) {
     return screenshotCanvas.toDataURL();
 }
 
+function downloadDataUrlFromJavascript(filename, dataUrl) {
+
+    // Construct the 'a' element
+    var link = document.createElement("a");
+    link.download = filename;
+    link.target = "_blank";
+
+    // Construct the URI
+    link.href = dataUrl;
+    document.body.appendChild(link);
+    link.click();
+
+    // Cleanup the DOM
+    document.body.removeChild(link);
+}
+
 function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done) {
     seed = 100000;
     var renderData = getRenderData(currentViewer.canvas, currentViewer.engine);
@@ -122,6 +138,7 @@ function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done
 
     var renderB64 = saveRenderImage(renderData, currentViewer.canvas);
     renderImage.src = renderB64;
+    // downloadDataUrlFromJavascript(test.referenceImage, renderB64)
 
     done(testRes, renderB64);
 }
@@ -197,20 +214,25 @@ function runTest(index, done) {
     configuration.camera.behaviors = null;
 
     // make sure we use only local assets
-    configuration.skybox = {
+    /*configuration.skybox = {
         cubeTexture: {
-            url: "/dist/assets/environment/DefaultSkybox_cube_radiance_256.dds"
+            url: "DefaultSkybox_cube_radiance_256.dds"
         }
-    }
+    }*/
 
     //envirnonment directory
     configuration.lab = configuration.lab || {};
-    configuration.lab.environmentAssetsRootURL = "/dist/assets/environment/";
-    configuration.lab.environmentMap = false;
+    configuration.lab.assetsRootURL = "/dist/assets/environment/";
+    if (!test.enableEnvironment) {
+        configuration.lab.environmentMap = false;
+    } else {
+        console.log(configuration.lab.environmentMap)
+    }
 
     //model config
     configuration.model = configuration.model || {};
-    configuration.model.castShadow = !test.createMesh
+    //configuration.model.castShadow = !test.createMesh
+    configuration.model.entryAnimation = false;
 
     // create a new viewer
     currentViewer && currentViewer.dispose();
@@ -222,7 +244,7 @@ function runTest(index, done) {
     currentViewer.onInitDoneObservable.add(() => {
 
         var currentFrame = 0;
-        var waitForFrame = test.waitForFrame || 4;
+        var waitForFrame = test.waitForFrame || 0;
 
         if (test.model) {
             currentViewer.initModel(test.model);
@@ -242,7 +264,6 @@ function runTest(index, done) {
                 }
                 currentFrame++;
             });
-
         })
     });
 }
@@ -253,14 +274,13 @@ function prepareMeshForViewer(viewer, configuration, test) {
     let sphereMesh = BABYLON.Mesh.CreateSphere('sphere-' + test.title, 20, 1.0, viewer.sceneManager.scene);
     if (test.createMaterial) {
         let material = new BABYLON.PBRMaterial("sphereMat", viewer.sceneManager.scene);
-        material.environmentBRDFTexture = null;
-        material.useAlphaFresnel = material.needAlphaBlending();
-        material.backFaceCulling = material.forceDepthWrite;
-        material.twoSidedLighting = true;
-        material.useSpecularOverAlpha = false;
-        material.useRadianceOverAlpha = false;
-        material.usePhysicalLightFalloff = true;
-        material.forceNormalForward = true;
+        /* material.useAlphaFresnel = material.needAlphaBlending();
+         material.backFaceCulling = material.forceDepthWrite;
+         material.twoSidedLighting = true;
+         material.useSpecularOverAlpha = false;
+         material.useRadianceOverAlpha = false;
+         material.usePhysicalLightFalloff = true;
+         material.forceNormalForward = true;*/
         sphereMesh.material = material;
     }
     meshModel.addMesh(sphereMesh, true);

+ 4 - 1
Viewer/tsconfig-gulp.json

@@ -19,7 +19,7 @@
         "types": [
             "node"
         ],
-        "baseUrl": ".",
+        "baseUrl": "./",
         "paths": {
             "babylonjs": [
                 "../dist/preview release/babylon.d.ts"
@@ -33,5 +33,8 @@
         "node_modules",
         "dist",
         "tests"
+    ],
+    "include": [
+        "./src/**/*.ts"
     ]
 }

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

@@ -1,5 +1,5 @@
 module.exports = {
-    //context: __dirname,
+    // context: __dirname,
     entry: [
         __dirname + '/src/index.ts'
     ]

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


+ 21 - 0
dist/preview release/Oimo.license

@@ -0,0 +1,21 @@
+The MIT License
+
+Copyright © 2010-2017 three.js authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 2 - 0
dist/preview release/_headers

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

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


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


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


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


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


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


+ 22 - 0
dist/preview release/cannon.license

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015 cannon.js Authors
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */

+ 201 - 0
dist/preview release/draco.license

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

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


BIN
dist/preview release/draco_decoder_gltf.wasm


+ 0 - 0
dist/preview release/draco_wasm_wrapper_gltf.js


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