Преглед на файлове

Add KHR_xmp_json_ld for glTF loader

Gary Hsu преди 4 години
родител
ревизия
a6f98a22f8

+ 6 - 9
dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts

@@ -1162,22 +1162,19 @@ declare module BABYLON.GLTF2 {
     }
 
     /**
-     * Interfaces from the KHR_xmp extension
+     * Interfaces from the KHR_xmp_json_ld extension
      * !!! Experimental Extension Subject to Changes !!!
      */
 
     /** @hidden */
-    interface IKHRXmp_Data {
-        [key: string]: unknown;
-    }
-
-    /** @hidden */
-    interface IKHRXmp_Gltf {
-        packets: IKHRXmp_Data[];
+    interface IKHRXmpJsonLd_Gltf {
+        packets: Array<{
+            [key: string]: unknown;
+        }>;
     }
 
     /** @hidden */
-    interface IKHRXmp_Node {
+    interface IKHRXmpJsonLd_Node {
         packet: number;
     }
 

+ 1 - 0
dist/preview release/what's new.md

@@ -19,6 +19,7 @@
 - Increased KHR_materials_transmission render target texture default size. ([Drigax](https://github.com/drigax))
 - Changed glTF loader to remove empty animation groups if there are no animation channels loaded with the given options. ([bghgary](https://github.com/bghgary))
 - Update glTF validator to `2.0.0-dev.3.3`. ([bghgary](https://github.com/bghgary))
+- Added support for KHR_xmp_json_ld for glTF loader. ([Sebavan](https://github.com/sebavan/), [bghgary](https://github.com/bghgary))
 
 ### Navigation
 

+ 85 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/commonPropertyGridComponent.tsx

@@ -0,0 +1,85 @@
+import * as React from "react";
+
+import { Observable } from "babylonjs/Misc/observable";
+
+import { PropertyChangedEvent } from "../../../propertyChangedEvent";
+import { LineContainerComponent } from "../../lineContainerComponent";
+import { LockObject } from "./lockObject";
+import { GlobalState } from "../../../globalState";
+import { TextLineComponent } from '../../lines/textLineComponent';
+import { IndentedTextLineComponent } from '../../lines/indentedTextLineComponent';
+
+interface ICommonPropertyGridComponentProps {
+    globalState: GlobalState;
+    host: { metadata: any };
+    lockObject: LockObject;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+}
+
+export class CommonPropertyGridComponent extends React.Component<ICommonPropertyGridComponentProps> {
+    constructor(props: ICommonPropertyGridComponentProps) {
+        super(props);
+    }
+
+    renderLevel(jsonObject: any) {
+        let components = [];
+
+        for (var data in jsonObject) {
+            let value = jsonObject[data];
+            let type = Object.prototype.toString.call(value);
+
+            switch (type) {
+                case '[object String]':
+                    components.push(
+                        <TextLineComponent key={data} label={data} ignoreValue={true} />
+                    );
+                    components.push(
+                        <IndentedTextLineComponent key={data + value} value={value} />
+                    );
+                    break;
+                case '[object Array]':
+                    components.push(
+                        <TextLineComponent key={data} label={data} ignoreValue={true} />
+                    );
+                    for (var entry of value) {
+                        components.push(
+                            <IndentedTextLineComponent key={data + entry} value={entry} />
+                        );
+                    }
+                    break;
+                case '[object Object]':
+                    components.push(
+                        <TextLineComponent key={data} label={data} ignoreValue={true} />
+                    );
+                    for (var entryKey in value) {
+                        components.push(
+                            <TextLineComponent key={data + entry} label={entryKey} value={value[entryKey]} additionalClass="reduced-opacity" />
+                        );
+                    }
+                    break;
+            }
+        }
+
+        return components;
+    }
+
+    render() {
+        if (!this.props.host.metadata) {
+            return null;
+        }
+
+        if (!this.props.host.metadata.xmp) {
+            return null;
+        }
+
+        return (
+            <div>
+                <LineContainerComponent globalState={this.props.globalState} title="XMP METADATA">
+                    {
+                        this.renderLevel(this.props.host.metadata.xmp)
+                    }
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 2 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx

@@ -30,6 +30,7 @@ import { ButtonLineComponent } from "../../../../../sharedUiComponents/lines/but
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { AnimationGridComponent } from "../animations/animationPropertyGridComponent";
 import { RenderingManager } from "babylonjs/Rendering/renderingManager";
+import { CommonPropertyGridComponent } from "../commonPropertyGridComponent";
 import { VariantsPropertyGridComponent } from "../variantsPropertyGridComponent";
 import { HexLineComponent } from "../../../lines/hexLineComponent";
 import { SkeletonViewer } from "babylonjs/Debug/skeletonViewer";
@@ -434,6 +435,7 @@ export class MeshPropertyGridComponent extends React.Component<
                         }}
                     />
                 </LineContainerComponent>
+                <CommonPropertyGridComponent host={mesh} lockObject={this.props.lockObject} globalState={this.props.globalState} />
                 <VariantsPropertyGridComponent host={mesh} lockObject={this.props.lockObject} globalState={this.props.globalState} />
                 <LineContainerComponent globalState={this.props.globalState} title="TRANSFORMS">
                     <Vector3LineComponent label="Position" target={mesh} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 2 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/transformNodePropertyGridComponent.tsx

@@ -15,6 +15,7 @@ import { CustomPropertyGridComponent } from '../customPropertyGridComponent';
 import { ButtonLineComponent } from '../../../../../sharedUiComponents/lines/buttonLineComponent';
 import { TextInputLineComponent } from '../../../lines/textInputLineComponent';
 import { AnimationGridComponent } from '../animations/animationPropertyGridComponent';
+import { CommonPropertyGridComponent } from '../commonPropertyGridComponent';
 import { VariantsPropertyGridComponent } from '../variantsPropertyGridComponent';
 import { Mesh } from 'babylonjs/Meshes/mesh';
 
@@ -53,6 +54,7 @@ export class TransformNodePropertyGridComponent extends React.Component<ITransfo
                         this.props.globalState.onSelectionChangedObservable.notifyObservers(null);
                     }} />
                 </LineContainerComponent>
+                <CommonPropertyGridComponent host={transformNode} lockObject={this.props.lockObject} globalState={this.props.globalState} />
                 <VariantsPropertyGridComponent host={transformNode as Mesh} lockObject={this.props.lockObject} globalState={this.props.globalState} />
                 <LineContainerComponent globalState={this.props.globalState} title="TRANSFORMATIONS">
                     <Vector3LineComponent label="Position" target={transformNode} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 10 - 9
inspector/src/components/actionTabs/tabs/tools/gltfComponent.tsx

@@ -123,13 +123,10 @@ export class GLTFComponent extends React.Component<IGLTFComponentProps> {
                     <MessageLineComponent text="You need to reload your file to see these changes" />
                 </LineContainerComponent>
                 <LineContainerComponent globalState={this.props.globalState} 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" additionalClass="gltf-extension-property" isInteger={true} />
-                    <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="EXT_lights_image_based" isSelected={() => extensionStates["EXT_lights_image_based"].enabled} onSelect={(value) => (extensionStates["EXT_lights_image_based"].enabled = value)} />
+                    <CheckBoxLineComponent label="EXT_mesh_gpu_instancing" isSelected={() => extensionStates["EXT_mesh_gpu_instancing"].enabled} onSelect={(value) => (extensionStates["EXT_mesh_gpu_instancing"].enabled = value)} />
+                    <CheckBoxLineComponent label="EXT_texture_webp" isSelected={() => extensionStates["EXT_texture_webp"].enabled} onSelect={(value) => (extensionStates["EXT_texture_webp"].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_mesh_quantization" isSelected={() => extensionStates["KHR_mesh_quantization"].enabled} onSelect={(value) => (extensionStates["KHR_mesh_quantization"].enabled = value)} />
                     <CheckBoxLineComponent label="KHR_materials_pbrSpecularGloss..." isSelected={() => extensionStates["KHR_materials_pbrSpecularGlossiness"].enabled} onSelect={(value) => (extensionStates["KHR_materials_pbrSpecularGlossiness"].enabled = value)} />
                     <CheckBoxLineComponent label="KHR_materials_clearcoat" isSelected={() => extensionStates["KHR_materials_clearcoat"].enabled} onSelect={(value) => (extensionStates["KHR_materials_clearcoat"].enabled = value)} />
                     <CheckBoxLineComponent label="KHR_materials_ior" isSelected={() => extensionStates["KHR_materials_ior"].enabled} onSelect={(value) => (extensionStates["KHR_materials_ior"].enabled = value)} />
@@ -139,12 +136,16 @@ export class GLTFComponent extends React.Component<IGLTFComponentProps> {
                     <CheckBoxLineComponent label="KHR_materials_variants" isSelected={() => extensionStates["KHR_materials_variants"].enabled} onSelect={(value) => (extensionStates["KHR_materials_variants"].enabled = value)} />
                     <CheckBoxLineComponent label="KHR_materials_transmission" isSelected={() => extensionStates["KHR_materials_transmission"].enabled} onSelect={(value) => (extensionStates["KHR_materials_transmission"].enabled = value)} />
                     <CheckBoxLineComponent label="KHR_materials_translucency" isSelected={() => extensionStates["KHR_materials_translucency"].enabled} onSelect={(value) => (extensionStates["KHR_materials_translucency"].enabled = value)} />
+                    <CheckBoxLineComponent label="KHR_mesh_quantization" isSelected={() => extensionStates["KHR_mesh_quantization"].enabled} onSelect={(value) => (extensionStates["KHR_mesh_quantization"].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_basisu" isSelected={() => extensionStates["KHR_texture_basisu"].enabled} onSelect={(value) => (extensionStates["KHR_texture_basisu"].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)} />
-                    <CheckBoxLineComponent label="EXT_mesh_gpu_instancing" isSelected={() => extensionStates["EXT_mesh_gpu_instancing"].enabled} onSelect={(value) => (extensionStates["EXT_mesh_gpu_instancing"].enabled = value)} />
-                    <CheckBoxLineComponent label="EXT_texture_webp" isSelected={() => extensionStates["EXT_texture_webp"].enabled} onSelect={(value) => (extensionStates["EXT_texture_webp"].enabled = value)} />
+                    <CheckBoxLineComponent label="KHR_xmp_json_ld" isSelected={() => extensionStates["KHR_xmp_json_ld"].enabled} onSelect={(value) => (extensionStates["KHR_xmp_json_ld"].enabled = value)} />
+                    <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" additionalClass="gltf-extension-property" isInteger={true} />
+                    <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)} />
                     <MessageLineComponent text="You need to reload your file to see these changes" />
                 </LineContainerComponent>
                 {loaderState["validate"] && this.props.globalState.validationResults && this.renderValidation()}

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

@@ -33,6 +33,7 @@ export class GlobalState {
         MSFT_minecraftMesh: { enabled: true },
         MSFT_sRGBFactors: { enabled: true },
         MSFT_audio_emitter: { enabled: true },
+        KHR_xmp_json_ld: { enabled: true },
         KHR_draco_mesh_compression: { enabled: true },
         KHR_mesh_quantization: { enabled: true },
         KHR_materials_pbrSpecularGlossiness: { enabled: true },

+ 56 - 0
loaders/src/glTF/2.0/Extensions/KHR_xmp_json_ld.ts

@@ -0,0 +1,56 @@
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
+import { GLTFLoader } from "../glTFLoader";
+import { IKHRXmpJsonLd_Gltf, IKHRXmpJsonLd_Node } from 'babylonjs-gltf2interface';
+
+const NAME = "KHR_xmp_json_ld";
+
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1893)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+export class KHR_xmp_json_ld implements IGLTFLoaderExtension {
+    /**
+     * The name of this extension.
+     */
+    public readonly name = NAME;
+
+    /**
+     * Defines whether this extension is enabled.
+     */
+    public enabled: boolean;
+
+    /**
+     * Defines a number that determines the order the extensions are applied.
+     */
+    public order = 100;
+
+    private _loader: GLTFLoader;
+
+    /** @hidden */
+    constructor(loader: GLTFLoader) {
+        this._loader = loader;
+        this.enabled = this._loader.isExtensionUsed(NAME);
+    }
+
+    /** @hidden */
+    public dispose() {
+        (this._loader as any) = null;
+    }
+
+    /**
+     * Called after the loader state changes to LOADING.
+     */
+    public onLoading(): void {
+        const xmp_gltf = (this._loader.gltf.extensions?.KHR_xmp_json_ld as IKHRXmpJsonLd_Gltf);
+        const xmp_node = (this._loader.gltf.asset?.extensions?.KHR_xmp_json_ld as IKHRXmpJsonLd_Node);
+        if (xmp_gltf && xmp_node) {
+            const packet = +xmp_node.packet;
+            if (xmp_gltf.packets && packet < xmp_gltf.packets.length) {
+                this._loader.rootBabylonMesh.metadata = this._loader.rootBabylonMesh.metadata || { };
+                this._loader.rootBabylonMesh.metadata.xmp = xmp_gltf.packets[packet];
+            }
+        }
+    }
+}
+
+GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_xmp_json_ld(loader));

+ 1 - 0
loaders/src/glTF/2.0/Extensions/index.ts

@@ -16,6 +16,7 @@ export * from "./KHR_materials_translucency";
 export * from "./KHR_mesh_quantization";
 export * from "./KHR_texture_basisu";
 export * from "./KHR_texture_transform";
+export * from "./KHR_xmp_json_ld";
 export * from "./MSFT_audio_emitter";
 export * from "./MSFT_lod";
 export * from "./MSFT_minecraftMesh";