Bladeren bron

first stab at gltf tab

David Catuhe 6 jaren geleden
bovenliggende
commit
f27187a760

+ 24 - 0
inspector/src/Inspector.ts

@@ -7,6 +7,8 @@ import { Scene, Observable, Observer, Nullable, IInspectorOptions } from "babylo
 import { EmbedHostComponent } from "./components/embedHost/embedHostComponent";
 import { PropertyChangedEvent } from "./components/propertyChangedEvent";
 import { GlobalState } from "./components/globalState";
+import { IGLTFLoaderExtension } from "babylonjs-gltf2interface";
+import {GLTFFileLoader} from "babylonjs-loaders"
 
 interface IInternalInspectorOptions extends IInspectorOptions {
     popup: boolean;
@@ -301,6 +303,23 @@ export class Inspector {
         if (!this._GlobalState.onSelectionChangeObservable) {
             this._GlobalState.onSelectionChangeObservable = this.OnSelectionChangeObservable;
         }
+        if (!this._GlobalState.onPluginActivatedObserver) {
+            this._GlobalState.onPluginActivatedObserver = BABYLON.SceneLoader.OnPluginActivatedObservable.add((loader: GLTFFileLoader) => {
+                if (loader.name === "gltf") {
+                    this._GlobalState.prepareGLTFPlugin(loader);
+    
+                    loader.onValidatedObservable.add((results: IGLTFValidationResults) => {
+                        this._GlobalState.validationResults = results;
+    
+                        this._GlobalState.onValidationResultsUpdatedObservable.notifyObservers(results);
+                    });
+
+                    loader.onExtensionLoadedObservable.add((extension: IGLTFLoaderExtension) => {
+
+                    });
+                }
+            });
+        }
 
         // Make sure it is not already opened
         if (this.IsVisible && options.original) {
@@ -456,5 +475,10 @@ export class Inspector {
 
         Inspector._OpenedPane = 0;
         this._Cleanup();
+
+        if (!this._GlobalState.onPluginActivatedObserver) {
+            BABYLON.SceneLoader.OnPluginActivatedObservable.remove(this._GlobalState.onPluginActivatedObserver);
+            this._GlobalState.onPluginActivatedObserver = null;
+        }
     }
 }

+ 1 - 1
inspector/src/components/actionTabs/actionTabsComponent.tsx

@@ -54,7 +54,7 @@ export class ActionTabsComponent extends React.Component<IActionTabsComponentPro
                     onPropertyChangedObservable={this.props.globalState.onPropertyChangedObservable} />
                 <DebugTabComponent title="Debug" icon={faBug} scene={this.props.scene} />
                 <StatisticsTabComponent title="Statistics" icon={faChartBar} scene={this.props.scene} />
-                <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} />
+                <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} globalState={this.props.globalState}/>
             </TabsComponent>
         )
     }

+ 3 - 1
inspector/src/components/actionTabs/paneComponent.tsx

@@ -2,13 +2,15 @@ import * as React from "react";
 import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
 import { Scene, Observable } from "babylonjs";
 import { PropertyChangedEvent } from "../propertyChangedEvent";
+import { GlobalState } from "components/globalState";
 
 export interface IPaneComponentProps {
     title: string,
     icon: IconDefinition, scene: Scene,
     selectedEntity?: any,
     onSelectionChangeObservable?: Observable<any>,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    globalState?: GlobalState
 }
 
 export class PaneComponent extends React.Component<IPaneComponentProps, { tag: any }> {

+ 58 - 0
inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx

@@ -0,0 +1,58 @@
+import * as React from "react";
+import { Scene, TransformNode, PBRMaterial, StandardMaterial, BackgroundMaterial } from "babylonjs";
+import { LineContainerComponent } from "../../lineContainerComponent";
+import { ButtonLineComponent } from "../../lines/buttonLineComponent";
+import { GLTFData } from "babylonjs-serializers";
+import { CheckBoxLineComponent } from "../../lines/checkBoxLineComponent";
+import { GlobalState } from "../../../globalState";
+
+interface IGLTFComponentProps {
+    scene: Scene,
+    globalState: GlobalState
+}
+
+export class GLTFComponent extends React.Component<IGLTFComponentProps> {
+    constructor(props: IGLTFComponentProps) {
+        super(props);
+    }
+
+    shouldExport(transformNode: TransformNode): boolean {
+
+        // No skybox
+        if (transformNode instanceof BABYLON.Mesh) {
+            if (transformNode.material) {
+                const material = transformNode.material as PBRMaterial | StandardMaterial | BackgroundMaterial;
+                const reflectionTexture = material.reflectionTexture;
+                if (reflectionTexture && reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE) {
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    exportGLTF() {
+        const scene = this.props.scene;
+
+        BABYLON.GLTF2Export.GLBAsync(scene, "scene", {
+            shouldExportTransformNode: (transformNode) => this.shouldExport(transformNode)
+        }).then((glb: GLTFData) => {
+            glb.downloadFiles();
+        });
+    }
+
+    render() {
+        const extensionStates = this.props.globalState.glTFLoaderDefaults;
+        return (
+            <div>
+                <LineContainerComponent title="SCENE EXPORT">
+                    <ButtonLineComponent label="Export to GLB" onClick={() => this.exportGLTF()} />
+                </LineContainerComponent>
+                <LineContainerComponent title="GLTF EXTENSIONS">
+                    <CheckBoxLineComponent label="MSFT_lod" isSelected={() => extensionStates["MSFT_lod"]} onSelect={value => extensionStates["MSFT_lod"] = value}/>
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 5 - 32
inspector/src/components/actionTabs/tabs/toolsTabComponent.tsx

@@ -2,8 +2,9 @@ import * as React from "react";
 import { PaneComponent, IPaneComponentProps } from "../paneComponent";
 import { LineContainerComponent } from "../lineContainerComponent";
 import { ButtonLineComponent } from "../lines/buttonLineComponent";
-import { VideoRecorder, TransformNode, PBRMaterial, StandardMaterial, BackgroundMaterial, Nullable } from "babylonjs";
-import { GLTFData } from "babylonjs-serializers";
+import { VideoRecorder, Nullable } from "babylonjs";
+import { GLTFComponent } from "./tools/gltfComponent";
+
 
 export class ToolsTabComponent extends PaneComponent {
     private _videoRecorder: Nullable<VideoRecorder>;
@@ -54,32 +55,6 @@ export class ToolsTabComponent extends PaneComponent {
         this.setState({ tag: "Stop recording" })
     }
 
-    shouldExport(transformNode: TransformNode): boolean {
-
-        // No skybox
-        if (transformNode instanceof BABYLON.Mesh) {
-            if (transformNode.material) {
-                const material = transformNode.material as PBRMaterial | StandardMaterial | BackgroundMaterial;
-                const reflectionTexture = material.reflectionTexture;
-                if (reflectionTexture && reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE) {
-                    return false;
-                }
-            }
-        }
-
-        return true;
-    }
-
-    exportGLTF() {
-        const scene = this.props.scene;
-
-        BABYLON.GLTF2Export.GLBAsync(scene, "scene", {
-            shouldExportTransformNode: (transformNode) => this.shouldExport(transformNode)
-        }).then((glb: GLTFData) => {
-            glb.downloadFiles();
-        });
-    }
-
     render() {
         const scene = this.props.scene;
 
@@ -92,10 +67,8 @@ export class ToolsTabComponent extends PaneComponent {
                 <LineContainerComponent title="CAPTURE">
                     <ButtonLineComponent label="Screenshot" onClick={() => this.captureScreenshot()} />
                     <ButtonLineComponent label={this.state.tag} onClick={() => this.recordVideo()} />
-                </LineContainerComponent>
-                <LineContainerComponent title="GLTF">
-                    <ButtonLineComponent label="Export" onClick={() => this.exportGLTF()} />
-                </LineContainerComponent>
+                </LineContainerComponent>   
+                <GLTFComponent scene={scene} globalState={this.props.globalState!}/> 
             </div>
         );
     }

+ 19 - 1
inspector/src/components/globalState.ts

@@ -1,7 +1,25 @@
-import { Observable } from "babylonjs";
+import { Observable, ISceneLoaderPlugin, ISceneLoaderPluginAsync, Observer, Nullable } from "babylonjs";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
+import {IGLTFLoaderExtension, GLTFFileLoader} from "babylonjs-loaders"
 
 export class GlobalState {
     public onSelectionChangeObservable: Observable<string>;
     public onPropertyChangedObservable: Observable<PropertyChangedEvent>;
+    public onPluginActivatedObserver: Nullable<Observer<ISceneLoaderPlugin | ISceneLoaderPluginAsync>>;
+    
+    public validationResults: IGLTFValidationResults;
+    public onValidationResultsUpdatedObservable = new Observable<IGLTFValidationResults>();
+
+    public onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+    public glTFLoaderDefaults: {[key: string]: boolean} = {};
+
+    public prepareGLTFPlugin(loader: GLTFFileLoader) {
+        loader.onExtensionLoadedObservable.add((extension: IGLTFLoaderExtension) => {
+
+            var extensionState = this.glTFLoaderDefaults[extension.name];
+            if (extensionState !== undefined) {
+                extension.enabled = extensionState;
+            }
+        });
+    }
 }