Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized support for external- and vendor extensions #12223

Open
javagl opened this issue Sep 28, 2024 · 0 comments
Open

Generalized support for external- and vendor extensions #12223

javagl opened this issue Sep 28, 2024 · 0 comments

Comments

@javagl
Copy link
Contributor

javagl commented Sep 28, 2024

This issue refers to both 3D Tiles extensions and glTF extensions. There may be subtle differences in how they are addressed. But the goal is the same in both cases:

There should be a mechanism for supporting arbitrary, vendor-specific extensions.

Many of the official, ratified glTF extensions are affecting the rendering engine on a low, technical level. They may require a certain infrastructure in CesiumJS (in terms of internal classes and "wiring") to be fully supported and useful. For example: All the glTF PBR extensions will require adjustments on the level of shaders in order to be supported in CesiumJS.

But there may be extensions that are rather put "on top" of glTF, and not affect the rendering engine directly. Instead, they will offer a functionality that is application-specific. In the extreme form, this may refer to vendor extensions that are not even "public".

Clients should still have the option to add support for handling these extensions in CesiumJS, so that they can use them in their application. In the most generic form, this could or should be some form of a "plugin-concept". Pseudocode could be:

// Globally register a loader: When `MY_extension` is found in one of the elements 
// of the glTF, then this will be processed with the `MyExtensionLoader`:
Model.registerExtensionLoader("MY_extension", new MyExensionLoader());

// Load a model that contains the extension:
const model = await Model.fromGltfAsync(...);

// Obtain the parsed/processed result that was generated by 
// the MyExensionLoader:
const myExtension = model.getExtension("MY_extension");

A recent example where this came up was during the implementation of GPM support. Right now, this PR only addresses the NGA_gpm_local extension, which is a glTF extension. Some specific questions that came up in this PR, and how they have been addressed there, preliminarily(!):

  • The classes for that extension are summarized in a Model/Extensions/Gpm subdirectory. This is for an extension that is directly supported by CesiumJS. For external/application-specific support, a mechanism for making these classes available will be necessary
  • One of the classes for that extension is the GltfGpmLoader. This is currently hard-wired into the GltfLoader. But it should be easy to generalize this, to allow a registration like the registerExtensionLoader in the pseudocode above
  • When a model with this extension has been parsed, then it is possible to access the parsed extension object with
    const result = model.getExtension("NGA_gpm_local");

The last point is not sufficient: It only refers to extensions that are contained in the root of the glTF asset. The NGA_gpm_local extension also defines extension objects for mesh primitives. In order to access these objects, it will be necessary to somehow define the object from which the extension should be obtained, resembling the pseudocode of
const result = model.meshes[m].primitives[o].getExtension("NGA_gpm_local");

(Right now, the Model does not offer access to any of its elements - so some thought will have to go into that...)


The GPM specification also defines a NGA_gpm (without local....) extension. This is a 3D Tiles extension. It is located at the root of a tileset JSON. And similar questions will have to be answered there.

  • There will likely be a directory for the related classes - maybe Scene/Extensions/Gpm....?
  • A loader will have to be plugged in at the right place - probably some TilesetJsonLoader...
  • The parsed result has to be offered for the client - maybe tileset.getExtension("NGA_gpm") ...?
  • There will have to be a mechanism to access elements that are not at the root.

The last point may be even more tricky in the case of 3D Tiles. Pseudocode like
const result = tileset.root.children[2].children[4].children[0].content.getExtension("EXAMPLE_extension");
is probably not the way to go here. But maybe something like
tileset.forEachExtensionObject("EXAMPLE_extension", someCallback)
could be sufficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant