Sfoglia il codice sorgente

Merge pull request #6505 from p3d-in/gltf_node_extras

Store glTF nodes' extras in BJS metadata
Gary Hsu 6 anni fa
parent
commit
4983e0274f

BIN
Playground/scenes/Box/Box_extras.bin


+ 242 - 0
Playground/scenes/Box/Box_extras.gltf

@@ -0,0 +1,242 @@
+{
+    "asset" : {
+        "generator" : "Khronos glTF Blender I/O v0.9.28",
+        "version" : "2.0"
+    },
+    "extensionsUsed" : [
+        "KHR_lights_punctual"
+    ],
+    "extensionsRequired" : [
+        "KHR_lights_punctual"
+    ],
+    "extensions" : {
+        "KHR_lights_punctual" : {
+            "lights" : [
+                {
+                    "color" : [
+                        1,
+                        1,
+                        1
+                    ],
+                    "intensity" : 1000,
+                    "type" : "point",
+                    "name" : "Light"
+                }
+            ]
+        }
+    },
+    "scene" : 0,
+    "scenes" : [
+        {
+            "extras" : {
+                "custom" : "sceneProp"
+            },
+            "name" : "Scene",
+            "nodes" : [
+                1,
+                3,
+                4
+            ]
+        }
+    ],
+    "nodes" : [
+        {
+            "extensions" : {
+                "KHR_lights_punctual" : {
+                    "light" : 0
+                }
+            },
+            "name" : "Light_Orientation",
+            "rotation" : [
+                -0.7071067690849304,
+                0,
+                0,
+                0.7071067690849304
+            ]
+        },
+        {
+            "children" : [
+                0
+            ],
+            "name" : "Light",
+            "rotation" : [
+                0.16907575726509094,
+                0.7558803558349609,
+                -0.27217137813568115,
+                0.570947527885437
+            ],
+            "translation" : [
+                4.076245307922363,
+                5.903861999511719,
+                -1.0054539442062378
+            ]
+        },
+        {
+            "camera" : 0,
+            "name" : "Camera_Orientation",
+            "rotation" : [
+                -0.7071067690849304,
+                0,
+                0,
+                0.7071067690849304
+            ]
+        },
+        {
+            "children" : [
+                2
+            ],
+            "name" : "Camera",
+            "rotation" : [
+                0.483536034822464,
+                0.33687159419059753,
+                -0.20870360732078552,
+                0.7804827094078064
+            ],
+            "translation" : [
+                7.358891487121582,
+                4.958309173583984,
+                6.925790786743164
+            ]
+        },
+        {
+            "extras" : {
+                "kind" : "nice cube",
+                "magic" : 42
+            },
+            "mesh" : 0,
+            "name" : "Box001",
+            "rotation" : [
+                1,
+                0,
+                0,
+                -1.3435885648505064e-07
+            ]
+        }
+    ],
+    "cameras" : [
+        {
+            "extras" : {
+                "custom" : "cameraProp"
+            },
+            "name" : "Camera",
+            "perspective" : {
+                "yfov" : 0.39959652046304894,
+                "zfar" : 100,
+                "znear" : 0.10000000149011612
+            },
+            "type" : "perspective"
+        }
+    ],
+    "materials" : [
+        {
+            "doubleSided" : true,
+            "extras" : {
+                "custom" : "materialProp"
+            },
+            "name" : "01___Default",
+            "pbrMetallicRoughness" : {
+                "baseColorTexture" : {
+                    "index" : 0,
+                    "texCoord" : 0
+                },
+                "metallicFactor" : 0,
+                "roughnessFactor" : 0.8945907354354858
+            }
+        }
+    ],
+    "meshes" : [
+        {
+            "extras" : {
+                "custom" : "meshProp"
+            },
+            "name" : "Box001",
+            "primitives" : [
+                {
+                    "attributes" : {
+                        "POSITION" : 0,
+                        "NORMAL" : 1,
+                        "TEXCOORD_0" : 2
+                    },
+                    "indices" : 3,
+                    "material" : 0
+                }
+            ]
+        }
+    ],
+    "textures" : [
+        {
+            "source" : 0
+        }
+    ],
+    "images" : [
+        {
+            "mimeType" : "image/png",
+            "name" : "20140615_192225",
+            "uri" : "20140615_192225.png"
+        }
+    ],
+    "accessors" : [
+        {
+            "bufferView" : 0,
+            "componentType" : 5126,
+            "count" : 24,
+            "max" : [
+                13.23270034790039,
+                0,
+                16.17329978942871
+            ],
+            "min" : [
+                -13.83899974822998,
+                -23.56559944152832,
+                -16.098499298095703
+            ],
+            "type" : "VEC3"
+        },
+        {
+            "bufferView" : 1,
+            "componentType" : 5126,
+            "count" : 24,
+            "type" : "VEC3"
+        },
+        {
+            "bufferView" : 2,
+            "componentType" : 5126,
+            "count" : 24,
+            "type" : "VEC2"
+        },
+        {
+            "bufferView" : 3,
+            "componentType" : 5123,
+            "count" : 36,
+            "type" : "SCALAR"
+        }
+    ],
+    "bufferViews" : [
+        {
+            "buffer" : 0,
+            "byteLength" : 288,
+            "byteOffset" : 0
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 288,
+            "byteOffset" : 288
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 192,
+            "byteOffset" : 576
+        },
+        {
+            "buffer" : 0,
+            "byteLength" : 72,
+            "byteOffset" : 768
+        }
+    ],
+    "buffers" : [
+        {
+            "byteLength" : 840,
+            "uri" : "Box_extras.bin"
+        }
+    ]
+}

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

@@ -58,6 +58,7 @@
 ### Loaders
 - Added support for non-float accessors in animation data for glTF loader. ([bghgary](https://github.com/bghgary))
 - Support loading cube data in .basis loader ([TrevorDev](https://github.com/TrevorDev))
+- Load glTF extras into BJS metadata ([pjoe](https://github.com/pjoe))
 
 ### Materials
 - Added `ShaderMaterial.setColor4Array` ([JonathanTron](https://github.com/JonathanTron/))

+ 101 - 0
loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts

@@ -0,0 +1,101 @@
+import { Nullable } from "babylonjs/types";
+import { TransformNode } from "babylonjs/Meshes/transformNode";
+import { Camera } from "babylonjs/Cameras/camera";
+
+import { IProperty } from "babylonjs-gltf2interface";
+import { INode, ICamera, IMaterial } from "../glTFLoaderInterfaces";
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
+import { GLTFLoader } from "../glTFLoader";
+import { Material } from "babylonjs/Materials/material";
+
+const NAME = "ExtrasAsMetadata";
+
+interface ObjectWithMetadata {
+    metadata: any;
+}
+
+/**
+ * Store glTF extras (if present) in BJS objects' metadata
+ */
+export class ExtrasAsMetadata implements IGLTFLoaderExtension {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoader;
+
+    private _assignExtras(
+        babylonObject: ObjectWithMetadata,
+        gltfProp: IProperty
+    ): void {
+        if (gltfProp.extras && Object.keys(gltfProp.extras).length > 0) {
+            const metadata = (babylonObject.metadata = babylonObject.metadata || {});
+            const gltf = (metadata.gltf = metadata.gltf || {});
+            gltf.extras = gltfProp.extras;
+        }
+    }
+
+    /** @hidden */
+    public constructor(loader: GLTFLoader) {
+        this._loader = loader;
+    }
+
+    /** @hidden */
+    public dispose(): void {
+        delete this._loader;
+    }
+
+    /** @hidden */
+    public loadNodeAsync(
+        context: string,
+        node: INode,
+        assign: (babylonTransformNode: TransformNode) => void
+    ): Nullable<Promise<TransformNode>> {
+        return this._loader.loadNodeAsync(
+            context,
+            node,
+            (babylonTransformNode): void => {
+                this._assignExtras(babylonTransformNode, node);
+                assign(babylonTransformNode);
+            }
+        );
+    }
+
+    /** @hidden */
+    public loadCameraAsync(
+        context: string,
+        camera: ICamera,
+        assign: (babylonCamera: Camera) => void
+    ): Nullable<Promise<Camera>> {
+        return this._loader.loadCameraAsync(
+            context,
+            camera,
+            (babylonCamera): void => {
+                this._assignExtras(babylonCamera, camera);
+                assign(babylonCamera);
+            }
+        );
+    }
+
+    /** @hidden */
+    public createMaterial(
+        context: string,
+        material: IMaterial,
+        babylonDrawMode: number
+    ): Nullable<Material> {
+        const babylonMaterial = this._loader.createMaterial(
+            context,
+            material,
+            babylonDrawMode
+        );
+        this._assignExtras(babylonMaterial, material);
+        return babylonMaterial;
+    }
+}
+
+GLTFLoader.RegisterExtension(
+    NAME,
+    (loader): IGLTFLoaderExtension => new ExtrasAsMetadata(loader)
+);

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

@@ -7,4 +7,5 @@ export * from "./KHR_texture_transform";
 export * from "./MSFT_audio_emitter";
 export * from "./MSFT_lod";
 export * from "./MSFT_minecraftMesh";
-export * from "./MSFT_sRGBFactors";
+export * from "./MSFT_sRGBFactors";
+export * from "./ExtrasAsMetadata";

+ 28 - 0
tests/unit/babylon/src/Loading/babylon.sceneLoader.tests.ts

@@ -513,6 +513,34 @@ describe('Babylon Scene Loader', function() {
             });
         });
 
+        it('Load Box with extras', () => {
+            const scene = new BABYLON.Scene(subject);
+            return BABYLON.SceneLoader.AppendAsync("/Playground/scenes/Box/", "Box_extras.gltf", scene).then((scene) => {
+                expect(scene.meshes.length, "scene.meshes.length").to.equal(2);
+                expect(scene.materials.length, "scene.materials.length").to.equal(1);
+                const mesh = scene.getMeshByName("Box001");
+                expect(mesh, "Box001").to.exist;
+                expect(mesh.metadata, "Box001 metadata").to.exist;
+                expect(mesh.metadata.gltf, "Box001 metadata.gltf").to.exist;
+                expect(mesh.metadata.gltf.extras, "Box001 metadata.gltf.extras").to.exist;
+                expect(mesh.metadata.gltf.extras.kind, "Box001 extras.kind").to.equal("nice cube");
+                expect(mesh.metadata.gltf.extras.magic, "Box001 extras.magic").to.equal(42);
+                const camera = scene.getCameraByName("Camera");
+                expect(camera, "Camera").to.exist;
+                expect(camera.metadata, "Camera metadata").to.exist;
+                expect(mesh.metadata.gltf, "Camera metadata.gltf").to.exist;
+                expect(mesh.metadata.gltf.extras, "Camera metadata.gltf.extras").to.exist;
+                expect(camera.metadata.gltf.extras.custom, "Camera extras.custom").to.equal("cameraProp");
+                const material = scene.getMaterialByName("01___Default")
+                expect(material, "Material").to.exist;
+                expect(material.metadata, "Material metadata").to.exist;
+                expect(mesh.metadata.gltf, "Material metadata.gltf").to.exist;
+                expect(mesh.metadata.gltf.extras, "Material metadata.gltf.extras").to.exist;
+                expect(material.metadata.gltf.extras.custom, "Material extras.custom").to.equal("materialProp");
+
+            });
+        });
+
         // TODO: test animation group callback
         // TODO: test material instancing
         // TODO: test KHR_materials_pbrSpecularGlossiness