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

Extension support is incomplete #661

Open
eoineoineoin opened this issue Jan 16, 2023 · 6 comments
Open

Extension support is incomplete #661

eoineoineoin opened this issue Jan 16, 2023 · 6 comments
Assignees

Comments

@eoineoineoin
Copy link
Member

I might be holding this wrong, but it looks like support for extensions is incomplete and documentation around extensions is lacking.

There is an ExtensionFactory and IExtension interface exposed, and users can register their own callbacks for extensions; however, these seem to have only exposed a Serialize() and Deserialize() method to read/write the extension data - it seems there's no callback to associate the data with a GameObject (i.e. to do anything useful with the extension data.)

The GLTFSceneImporter class has hardcoded a specially-privileged "MSFT_LOD" extension - this is an indication that the extension support is not good enough. There should be sufficient callbacks in the importer to do this without having to modify the importer.

At the very least, there should be a sample which shows how users can register and use custom extensions to add their own MonoBehaviour to GameObjects.

@pfcDorn
Copy link
Contributor

pfcDorn commented Jan 24, 2024

There is a new plugin system in the current version. Please take a look :) (Documentation stills lags a bit behind, but more samples are planned)
When you still missing some explicit usecases what do you want to archive, please post it here

@eoineoineoin
Copy link
Member Author

Thanks for bringing this to my attention. Following the "Extensibility" section in the Readme.md, I was able to get an implementation of my extension easily enough. The extension support is looking really good now.

One thing that I didn't see in the documentation was that in order to read data, a user needs an implementation of a GLTF.Schema.ExtensionFactory and that impl needs to be registered in GLTF.Schema.GLTFProperty._extensionRegistry. I just put that registration in my GLTFImportPlugin.CreateInstance() - not sure if there's a better place to do that?

Another piece which was maybe a little strange was the user's ExtensionFactory.Deserialize() method is called for both the root glTF document, as well as the nodes which have the extension, so inside Deserialize(), I needed a heuristic to determine what to parse. Is there a more robust way to determine the what is being deserialized at that point?

Otherwise, it all looks great and I've been able to get the results I wanted. I reckon it's worthwhile adding a sample which shows the full process of extending the loader with some sort of trivial extension. Happy to help out here.

@marwie
Copy link
Contributor

marwie commented Jan 29, 2024

@eoineoineoin by "to read data" you mean on import to read e.g. extensions on nodes in the GLTF json?

If yes then I don't think you need to register anything to this ExtensionFactory. Here's a snippet from the Needle Engine import plugin to read component data in case it helps:

public override void OnAfterImportNode(Node node, int nodeIndex, GameObject nodeObject)
{
	needleImportContext.Register("/nodes/" + nodeIndex, nodeObject);
	if (node.Extensions != null)
	{
		foreach (var kvp in node.Extensions)
		{
			if (kvp.Value is DefaultExtension defaultExtension)
			{
				var data = defaultExtension.ExtensionData;
				switch (kvp.Key)
				{
					case UnityGltf_NEEDLE_components_Extension.EXTENSION_NAME:
						var ext = data.Children().First() as JObject;
						NeedleComponentsImporter.OnImport(needleImportContext, nodeObject, nodeIndex, ext);
						break;
				}
			}
		}
	}
}

@eoineoineoin
Copy link
Member Author

Interesting; I am reading extensions on nodes in the JSON. I didn't realise that there was a DefaultExtension which enabled access to the data like that. The reason I ended up with that opinion was from my reading of the Readme.md:

If your plugin reads/writes custom extension data, you need to also implement GLTF.Schema.IExtension for serialization and deserialization.

So I followed the breadcrumbs from there and made my own IExtension; then, the class responsible for instantiating my IExtension was the ExtensionFactory, and in order to get that to run, I needed to register it with the extension registry.

@pfcDorn
Copy link
Contributor

pfcDorn commented Feb 9, 2024

Can i close this issue? :)

@hybridherbst
Copy link
Collaborator

I think a follow-up task here is to update the Readme and provide more complete examples for "how to make your own import and export extensions". If you make a follow-up issue for that and reference this issue here, this issue here can be closed.

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

4 participants