ソースを参照

Merge pull request #3599 from RaananW/viewer-changes-new

Further adjustments for the viewer's flexibility
Raanan Weber 7 年 前
コミット
733073adfe

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

@@ -9,7 +9,8 @@ export interface ViewerConfiguration {
     pageUrl?: string; // will be used for sharing and other fun stuff. This is the page showing the model (not the model's url!)
 
     configuration?: string | {
-        url: string;
+        url?: string;
+        payload?: any;
         mapper?: string; // json (default), html, yaml, xml, etc'. if not provided, file extension will be used.
     };
 
@@ -123,6 +124,9 @@ export interface ViewerConfiguration {
     // engine configuration. optional!
     engine?: {
         antialiasing?: boolean;
+        disableResize?: boolean;
+        engineOptions?: { [key: string]: any };
+        adaptiveQuality?: boolean;
     },
     //templateStructure?: ITemplateStructure,
     templates?: {

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

@@ -23,20 +23,27 @@ export class ConfigurationLoader {
         if (loadedConfig.configuration) {
 
             let mapperType = "json";
-            let url = loadedConfig.configuration;
-
-            // if configuration is an object
-            if (loadedConfig.configuration.url) {
-                url = loadedConfig.configuration.url;
-                mapperType = loadedConfig.configuration.mapper;
-                if (!mapperType) {
-                    // load mapper type from filename / url
-                    mapperType = loadedConfig.configuration.url.split('.').pop();
+            return Promise.resolve().then(() => {
+                if (typeof loadedConfig.configuration === "string" || loadedConfig.configuration.url) {
+                    // a file to load
+                    let url = loadedConfig.configuration;
+
+                    // if configuration is an object
+                    if (loadedConfig.configuration.url) {
+                        url = loadedConfig.configuration.url;
+                        mapperType = loadedConfig.configuration.mapper;
+                        if (!mapperType) {
+                            // load mapper type from filename / url
+                            mapperType = loadedConfig.configuration.url.split('.').pop();
+                        }
+                    }
+                    return this.loadFile(url);
+                } else {
+                    mapperType = loadedConfig.configuration.mapper || mapperType;
+                    return loadedConfig.configuration.payload || {};
                 }
-            }
-
-            let mapper = mapperManager.getMapper(mapperType);
-            return this.loadFile(url).then((data: any) => {
+            }).then((data: any) => {
+                let mapper = mapperManager.getMapper(mapperType);
                 let parsed = mapper.map(data);
                 return deepmerge(loadedConfig, parsed);
             });

+ 11 - 5
Viewer/src/templateManager.ts

@@ -89,8 +89,13 @@ export class TemplateManager {
         }
 
         //build the html tree
-        this.buildHTMLTree(templates).then(htmlTree => {
-            internalInit(htmlTree, 'main');
+        return this.buildHTMLTree(templates).then(htmlTree => {
+            if (this.templates['main']) {
+                internalInit(htmlTree, 'main');
+            } else {
+                this.checkLoadedState();
+            }
+            return;
         });
     }
 
@@ -123,8 +128,9 @@ export class TemplateManager {
                     buildTree(parentObject[element], element);
                 });
             }
-
-            buildTree(templateStructure, "main");
+            if (this.templates['main']) {
+                buildTree(templateStructure, "main");
+            }
             return templateStructure;
         });
     }
@@ -139,7 +145,7 @@ export class TemplateManager {
     }
 
     private checkLoadedState() {
-        let done = Object.keys(this.templates).every((key) => {
+        let done = Object.keys(this.templates).length === 0 || Object.keys(this.templates).every((key) => {
             return this.templates[key].isLoaded && !!this.templates[key].parent;
         });
 

+ 46 - 10
Viewer/src/viewer/viewer.ts

@@ -20,6 +20,8 @@ export abstract class AbstractViewer {
     public onEngineInitObservable: PromiseObservable<Engine>;
     public onModelLoadedObservable: PromiseObservable<AbstractMesh[]>;
 
+    private canvas: HTMLCanvasElement;
+
     constructor(public containerElement: HTMLElement, initialConfiguration: ViewerConfiguration = {}) {
         // if exists, use the container id. otherwise, generate a random string.
         if (containerElement.id) {
@@ -62,6 +64,10 @@ export abstract class AbstractViewer {
             this.templateManager.initTemplate(templateConfiguration);
             // when done, execute onTemplatesLoaded()
             this.templateManager.onAllLoaded.add(() => {
+                let canvas = this.templateManager.getCanvas();
+                if (canvas) {
+                    this.canvas = canvas;
+                }
                 this.onTemplatesLoaded();
             });
         });
@@ -72,6 +78,31 @@ export abstract class AbstractViewer {
         return this.baseId;
     }
 
+    public isCanvasInDOM(): boolean {
+        return !!this.canvas && !!this.canvas.parentElement;
+    }
+
+    protected resize = (): void => {
+        // Only resize if Canvas is in the DOM
+        if (!this.isCanvasInDOM()) {
+            return;
+        }
+
+        if (this.canvas.clientWidth <= 0 || this.canvas.clientHeight <= 0) {
+            return;
+        }
+
+        this.engine.resize();
+    }
+
+    protected render = (): void => {
+        this.scene && this.scene.render();
+    }
+
+    public dispose() {
+        window.removeEventListener('resize', this.resize);
+    }
+
     protected abstract prepareContainerElement();
 
     /**
@@ -84,7 +115,11 @@ export abstract class AbstractViewer {
      */
     protected onTemplatesLoaded(): Promise<AbstractViewer> {
         return this.initEngine().then(() => {
-            return this.loadModel();
+            if (this.configuration.model) {
+                return this.loadModel();
+            } else {
+                return this.scene;
+            }
         }).then(() => {
             return this;
         });
@@ -104,21 +139,22 @@ export abstract class AbstractViewer {
         }
         let config = this.configuration.engine || {};
         // TDO enable further configuration
-        this.engine = new Engine(canvasElement, !!config.antialiasing);
+        this.engine = new Engine(canvasElement, !!config.antialiasing, config.engineOptions);
 
         // Disable manifest checking
         Database.IDBStorageEnabled = false;
 
-        window.addEventListener('resize', () => {
-            this.engine.resize();
-        });
+        if (!config.disableResize) {
+            window.addEventListener('resize', this.resize);
+        }
 
-        this.engine.runRenderLoop(() => {
-            this.scene && this.scene.render();
-        });
 
-        var scale = Math.max(0.5, 1 / (window.devicePixelRatio || 2));
-        this.engine.setHardwareScalingLevel(scale);
+        this.engine.runRenderLoop(this.render);
+
+        if (this.configuration.engine && this.configuration.engine.adaptiveQuality) {
+            var scale = Math.max(0.5, 1 / (window.devicePixelRatio || 2));
+            this.engine.setHardwareScalingLevel(scale);
+        }
 
         return this.onEngineInitObservable.notifyWithPromise(this.engine).then(() => {
             return this.engine;