Browse Source

gltf done

David Catuhe 6 years ago
parent
commit
4e8d7f7391

+ 23 - 18
inspector/src/Inspector.ts

@@ -283,6 +283,26 @@ export class Inspector {
         return this._OpenedPane > 0;
     }
 
+    public static EarlyAttachToLoader() {
+        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) => {
+
+                    });
+                }
+            });
+        }
+    }
+
     public static Show(scene: Scene, userOptions: Partial<IInspectorOptions>) {
         const options: IInternalInspectorOptions = {
             original: true,
@@ -303,23 +323,6 @@ 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) {
@@ -481,4 +484,6 @@ export class Inspector {
             this._GlobalState.onPluginActivatedObserver = null;
         }
     }
-}
+}
+
+Inspector.EarlyAttachToLoader();

+ 12 - 0
inspector/src/components/actionTabs/actionTabs.scss

@@ -164,6 +164,13 @@
                     }
                 }
 
+                .messageLine {
+                    text-align: center;
+                    font-size: 12px;
+                    font-style: italic;
+                    opacity: 0.6;
+                }
+
                 .textLine {
                     padding-left: 5px;
                     height: 30px;
@@ -559,6 +566,11 @@
                     }
                 }
 
+                .gltf-extension-property {
+                    margin-left: 30px;
+                    border-left: 1px solid rgb(51, 122, 183);
+                }
+
                 .floatLine {
                     padding-left: 5px;
                     height: 30px;

+ 2 - 2
inspector/src/components/actionTabs/lines/booleanLineComponent.tsx

@@ -1,6 +1,6 @@
 import * as React from "react";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCheck, faTimes } from "@fortawesome/free-solid-svg-icons";
+import { faCheck, faTimesCircle } from "@fortawesome/free-solid-svg-icons";
 
 export interface IBooleanLineComponentProps {
     label: string,
@@ -14,7 +14,7 @@ export class BooleanLineComponent extends React.Component<IBooleanLineComponentP
 
     render() {
 
-        const check = this.props.value ? <FontAwesomeIcon icon={faCheck} /> : <FontAwesomeIcon icon={faTimes} />
+        const check = this.props.value ? <FontAwesomeIcon icon={faCheck} /> : <FontAwesomeIcon icon={faTimesCircle} />
         const className = this.props.value ? "value check" : "value uncheck";
 
         return (

+ 8 - 6
inspector/src/components/actionTabs/lines/checkBoxLineComponent.tsx

@@ -49,12 +49,14 @@ export class CheckBoxLineComponent extends React.Component<ICheckBoxLineComponen
         if (this.props.onSelect) {
             this.props.onSelect(!this.state.isSelected);
         } else {
-            this.props.onPropertyChangedObservable!.notifyObservers({
-                object: this.props.target,
-                property: this.props.propertyName!,
-                value: !this.state.isSelected,
-                initialValue: this.state.isSelected
-            });
+            if (this.props.onPropertyChangedObservable) {
+                this.props.onPropertyChangedObservable.notifyObservers({
+                    object: this.props.target,
+                    property: this.props.propertyName!,
+                    value: !this.state.isSelected,
+                    initialValue: this.state.isSelected
+                });
+            }
 
             this.props.target[this.props.propertyName!] = !this.state.isSelected;
         }

+ 3 - 2
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -7,7 +7,8 @@ interface IFloatLineComponentProps {
     target: any,
     propertyName: string,
     step?: number,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    additionalClass?: string
 }
 
 export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
@@ -73,7 +74,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
 
         const step = this.props.step !== undefined ? this.props.step : 0.1;
         return (
-            <div className="floatLine">
+            <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
                 <div className="label">
                     {this.props.label}
                 </div>

+ 22 - 0
inspector/src/components/actionTabs/lines/messageLineComponent.tsx

@@ -0,0 +1,22 @@
+import * as React from "react";
+
+interface IMessageLineComponentProps {
+    text: string,
+    color?: string,
+}
+
+export class MessageLineComponent extends React.Component<IMessageLineComponentProps> {
+    constructor(props: IMessageLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <div className="messageLine">
+                <div className="value" title={this.props.text} style={{ color: this.props.color ? this.props.color : "" }}>
+                    {this.props.text}
+                </div>
+            </div>
+        );
+    }
+}

+ 110 - 6
inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx

@@ -3,6 +3,11 @@ import { Scene } from "babylonjs";
 import { LineContainerComponent } from "../../lineContainerComponent";
 import { CheckBoxLineComponent } from "../../lines/checkBoxLineComponent";
 import { GlobalState } from "../../../globalState";
+import { FloatLineComponent } from "../../lines/floatLineComponent";
+import { OptionsLineComponent } from "../../lines/optionsLineComponent";
+import { MessageLineComponent } from "../../lines/messageLineComponent";
+import { BooleanLineComponent } from "../../lines/booleanLineComponent";
+import { TextLineComponent } from "../../lines/textLineComponent";
 
 interface IGLTFComponentProps {
     scene: Scene,
@@ -13,19 +18,118 @@ export class GLTFComponent extends React.Component<IGLTFComponentProps> {
     constructor(props: IGLTFComponentProps) {
         super(props);
 
-        const extensionStates = this.props.globalState.glTFLoaderDefaults;
-        extensionStates["MSFT_lod"] = extensionStates["MSFT_lod"] || { isEnabled: true };
+        const extensionStates = this.props.globalState.glTFLoaderExtensionDefaults;
+
+        extensionStates["MSFT_lod"] = extensionStates["MSFT_lod"] || { enabled: true, maxLODsToLoad: Number.MAX_VALUE };
+        extensionStates["MSFT_minecraftMesh"] = extensionStates["MSFT_minecraftMesh"] || { enabled: true };
+        extensionStates["MSFT_sRGBFactors"] = extensionStates["MSFT_sRGBFactors"] || { enabled: true };
+        extensionStates["MSFT_audio_emitter"] = extensionStates["MSFT_audio_emitter"] || { enabled: true };
+        extensionStates["KHR_draco_mesh_compression"] = extensionStates["KHR_draco_mesh_compression"] || { enabled: true };
+        extensionStates["KHR_materials_pbrSpecularGlossiness"] = extensionStates["KHR_materials_pbrSpecularGlossiness"] || { enabled: true };
+        extensionStates["KHR_materials_unlit"] = extensionStates["KHR_materials_unlit"] || { enabled: true };
+        extensionStates["KHR_lights_punctual"] = extensionStates["KHR_lights_punctual"] || { enabled: true };
+        extensionStates["KHR_texture_transform"] = extensionStates["KHR_texture_transform"] || { enabled: true };
+        extensionStates["EXT_lights_image_based"] = extensionStates["EXT_lights_image_based"] || { enabled: true };
+
+        const loaderState = this.props.globalState.glTFLoaderDefaults;
+
+        if (loaderState["animationStartMode"] === undefined) {
+            loaderState["animationStartMode"] = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
+        }
+        loaderState["capturePerformanceCounters"] = loaderState["capturePerformanceCounters"] || false;
+        loaderState["compileMaterials"] = loaderState["compileMaterials"] || false;
+        loaderState["compileShadowGenerators"] = loaderState["compileShadowGenerators"] || false;
+        loaderState["coordinateSystemMode"] = loaderState["coordinateSystemMode"] || BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
+        loaderState["loggingEnabled"] = loaderState["loggingEnabled"] || false;
+        loaderState["transparencyAsCoverage"] = loaderState["transparencyAsCoverage"] || false;
+        loaderState["useClipPlane"] = loaderState["useClipPlane"] || false;
+        loaderState["validate"] = loaderState["validate"] || true;
+    }
+
+    openValidationDetails() {
+        const validationResults = this.props.globalState.validationResults;
+        const win = window.open("", "_blank");
+        if (win) {
+            // TODO: format this better and use generator registry (https://github.com/KhronosGroup/glTF-Generator-Registry)
+            win.document.title = "glTF Validation Results";
+            win.document.body.innerText = JSON.stringify(validationResults, null, 2);
+            win.document.body.style.whiteSpace = "pre";
+            win.document.body.style.fontFamily = `monospace`;
+            win.document.body.style.fontSize = `14px`;
+            win.focus();
+        }
+    }
+
+    prepareText(singularForm: string, count: number) {
+        if (count) {
+            return `${count} ${singularForm}s`;
+        }
+
+        return `No ${singularForm}`;
+    }
+
+    renderValidation() {
+        const validationResults = this.props.globalState.validationResults;
+        const issues = validationResults.issues;
+
+        return (
+            <LineContainerComponent title="GLTF VALIDATION" closed={true}>
+                <BooleanLineComponent label={this.prepareText("error", issues.numErrors)} value={issues.numErrors === 0} />
+                <BooleanLineComponent label={this.prepareText("warning", issues.numWarnings)} value={issues.numWarnings === 0} />
+                <BooleanLineComponent label={this.prepareText("info", issues.numInfos)} value={issues.numInfos === 0} />
+                <BooleanLineComponent label={this.prepareText("hint", issues.numHints)} value={issues.numHints === 0} />
+                <TextLineComponent label="More details" value="Click here" onLink={() => this.openValidationDetails()} />
+            </LineContainerComponent>
+        )
     }
 
     render() {
-        const extensionStates = this.props.globalState.glTFLoaderDefaults;
+        const extensionStates = this.props.globalState.glTFLoaderExtensionDefaults;
+        const loaderState = this.props.globalState.glTFLoaderDefaults;
+
+        var animationStartMode = [
+            { label: "None", value: BABYLON.GLTFLoaderAnimationStartMode.NONE },
+            { label: "First", value: BABYLON.GLTFLoaderAnimationStartMode.FIRST },
+            { label: "ALL", value: BABYLON.GLTFLoaderAnimationStartMode.ALL }
+        ];
+
+        var coordinateSystemMode = [
+            { label: "Auto", value: BABYLON.GLTFLoaderCoordinateSystemMode.AUTO },
+            { label: "Right handed", value: BABYLON.GLTFLoaderCoordinateSystemMode.FORCE_RIGHT_HANDED }
+        ];
+
         return (
             <div>
-                <LineContainerComponent title="GLTF EXTENSIONS">
-                    <CheckBoxLineComponent label="MSFT_lod" isSelected={() => extensionStates["MSFT_lod"].isEnabled} onSelect={value => extensionStates["MSFT_lod"].isEnabled = value} />
+                <LineContainerComponent title="GLTF LOADER" closed={true}>
+                    <OptionsLineComponent label="Animation start mode" options={animationStartMode} target={loaderState} propertyName="animationStartMode" />
+                    <CheckBoxLineComponent label="Capture performance counters" target={loaderState} propertyName="capturePerformanceCounters" />
+                    <CheckBoxLineComponent label="Compile materials" target={loaderState} propertyName="compileMaterials" />
+                    <CheckBoxLineComponent label="Compile shadow generators" target={loaderState} propertyName="compileShadowGenerators" />
+                    <OptionsLineComponent label="Coordinate system" options={coordinateSystemMode} target={loaderState} propertyName="coordinateSystemMode" />
+                    <CheckBoxLineComponent label="Enable logging" target={loaderState} propertyName="loggingEnabled" />
+                    <CheckBoxLineComponent label="Transparency as coverage" target={loaderState} propertyName="transparencyAsCoverage" />
+                    <CheckBoxLineComponent label="Use clip plane" target={loaderState} propertyName="useClipPlane" />
+                    <CheckBoxLineComponent label="Validate" target={loaderState} propertyName="validate" />
+                    <MessageLineComponent text="You need to reload your file to see these changes" />
                 </LineContainerComponent>
-                <LineContainerComponent title="GLTF VALIDATION RESULTS">
+                <LineContainerComponent title="GLTF EXTENSIONS" closed={true}>
+                    <CheckBoxLineComponent label="MSFT_lod" isSelected={() => extensionStates["MSFT_lod"].enabled} onSelect={value => extensionStates["MSFT_lod"].enabled = value} />
+                    <FloatLineComponent label="Maximum LODs" target={extensionStates["MSFT_lod"]} propertyName="maxLODsToLoad" step={1} additionalClass="gltf-extension-property" />
+                    <CheckBoxLineComponent label="MSFT_minecraftMesh" isSelected={() => extensionStates["MSFT_minecraftMesh"].enabled} onSelect={value => extensionStates["MSFT_minecraftMesh"].enabled = value} />
+                    <CheckBoxLineComponent label="MSFT_sRGBFactors" isSelected={() => extensionStates["MSFT_sRGBFactors"].enabled} onSelect={value => extensionStates["MSFT_sRGBFactors"].enabled = value} />
+                    <CheckBoxLineComponent label="MSFT_audio_emitter" isSelected={() => extensionStates["MSFT_audio_emitter"].enabled} onSelect={value => extensionStates["MSFT_audio_emitter"].enabled = value} />
+                    <CheckBoxLineComponent label="KHR_draco_mesh_compression" isSelected={() => extensionStates["KHR_draco_mesh_compression"].enabled} onSelect={value => extensionStates["KHR_draco_mesh_compression"].enabled = value} />
+                    <CheckBoxLineComponent label="KHR_materials_pbrSpecularGlossiness" isSelected={() => extensionStates["KHR_materials_pbrSpecularGlossiness"].enabled} onSelect={value => extensionStates["KHR_materials_pbrSpecularGlossiness"].enabled = value} />
+                    <CheckBoxLineComponent label="KHR_materials_unlit" isSelected={() => extensionStates["KHR_materials_unlit"].enabled} onSelect={value => extensionStates["KHR_materials_unlit"].enabled = value} />
+                    <CheckBoxLineComponent label="KHR_lights_punctual" isSelected={() => extensionStates["KHR_lights_punctual"].enabled} onSelect={value => extensionStates["KHR_lights_punctual"].enabled = value} />
+                    <CheckBoxLineComponent label="KHR_texture_transform" isSelected={() => extensionStates["KHR_texture_transform"].enabled} onSelect={value => extensionStates["KHR_texture_transform"].enabled = value} />
+                    <CheckBoxLineComponent label="EXT_lights_image_based" isSelected={() => extensionStates["EXT_lights_image_based"].enabled} onSelect={value => extensionStates["EXT_lights_image_based"].enabled = value} />
+                    <MessageLineComponent text="You need to reload your file to see these changes" />
                 </LineContainerComponent>
+                {
+                    loaderState["validate"] && this.props.globalState.validationResults &&
+                    this.renderValidation()
+                }
             </div>
         );
     }

+ 10 - 2
inspector/src/components/globalState.ts

@@ -11,12 +11,20 @@ export class GlobalState {
     public onValidationResultsUpdatedObservable = new Observable<IGLTFValidationResults>();
 
     public onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
-    public glTFLoaderDefaults: { [name: string]: { [key: string]: any } } = {};
+    public glTFLoaderExtensionDefaults: { [name: string]: { [key: string]: any } } = {};
+    public glTFLoaderDefaults: { [key: string]: any } = { "validate": true };
 
     public prepareGLTFPlugin(loader: GLTFFileLoader) {
+        var loaderState = this.glTFLoaderDefaults;
+        if (loaderState !== undefined) {
+            for (const key in loaderState) {
+                (loader as any)[key] = loaderState[key];
+            }
+        }
+
         loader.onExtensionLoadedObservable.add((extension: IGLTFLoaderExtension) => {
 
-            var extensionState = this.glTFLoaderDefaults[extension.name];
+            var extensionState = this.glTFLoaderExtensionDefaults[extension.name];
             if (extensionState !== undefined) {
                 for (const key in extensionState) {
                     (extension as any)[key] = extensionState[key];