Best practices for tileset and glTF structure and embedding metadata

Hey @Marco13
I finally got some time to work on this again.

I just tried it out, and it seems to work for me…

  • Which FireFox version are you using?

Actually I can not reproduce this anymore. Maybe it in fact was due to an older Firefox version.


I think that the example at How to filter 3D tiles by group defined in 3DTILES_metadata Extension or 3dtiles 1.1? - #2 by Marco13 already shows one way. As I said, there are some questions about the exact structure if this is supposed to be done in a “real” application, but … does that example work for you in principle?

Looking at this, I found a way that works for us:

    tilesRef.current.forEach(tile => tile.applyStyle(new Cesium3DTileStyle({
      color: {
        conditions: [
          [tile.metadata.getProperty("level") < 1 && tile.metadata.getProperty("buildingId") === 303, "color('green')"],
        ],
      },
      show: {
        conditions: [
          [tile.metadata.getProperty("buildingId") === 303 && tile.metadata.getProperty("level") <= 0, "true"],
          ["true", "false"]
        ]
      }
    })))

But as you can see, we have to loop over every tile for that to work in runtime. Ok for now, but not the most elegant solution I guess.

Initally and like I mentioned before I thought it would be much simpler, as shown in Cesium Guide: Styling and Filtering 3D Tiles. But it seems to be only working for features as of now and not with the 3D Tiles 1.1 metadata. In the meantime somebody even opened a github issue about this (Styling based on metadata is not applied). So I guess I’m waiting for the results on this issue. If it gets solved then it would also solve our non elegant solution ‘problem’, I guess :wink:


I’m so glad for your help and very happy that we understand how and where to put our metadata and how to use it in CesiumJs, but I have one more question on this thread:

Right now I’m still using this kind of building tileset:

// a building's tileset
root {
    metadata: {
      buildingId
    }
  ...
  children: [
    {
      content: {
        uri: "floor-1.gltf"
      },
      metadata: {
        floorNumber
      }
    },
    ...
    {
      content: {
        uri: "floor-n.gltf"
      },
      metadata: {
        floorNumber
      }
    }
  ]
}

So we have not yet exported every room of a floor as stand-alone glTF as we planned together in this thread here.
However with this structure we can already do most of the things we want to do (show/hide/color certain floors of certain buildings) with 3D Tiles related features.

Two things are still missing: Getting the ID of a room and color a hovered or picked room.
Until recently I was not aware that using a click handler (viewer.screenSpaceEventHandler) we can easily get the selected node of a glTF and access the room ID there (it is stored in a node’s ‘extras’ object).
So now the last missing feature is the coloring of the selected/hovered glTF node.
In an ancient issue on github or thread in this community (unfortunately I can not find it anymore) people manipulated the material of glTF nodes, something like this:

pickedElement.detail.node._node.primitives[0].material = new Material({
  fabric: {
    type: 'Color',
    uniforms: {
      color: new CesiumColor(1.0, 1.0, 0.0, 1.0)
    }
  }
})

But there were also answers suggesting that it does not work since Cesium’s version xy and I couldn’t get it to work either.
So after all these information my question is: Is there any way we can color a hovered/clicked room (which at this point is not a stand-alone glTF but a node in the floor-glTF) with the help of Cesium?

This would be awesome, since it save us a lot of work and we wouldn’t have all the thousands of room-glTFs lying around only to be able to color them!
Let me know if anything is unclear.


One more thing: We are currently also struggling to correctly place our tiles. Since I believe that this does not fit thematically in this thread here, I opened a new one. Any help with that is also much appreciated! (:

Thanks!
Chris