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

Simplify reading, modifying, and writing glTF models #105

Open
javagl opened this issue Mar 21, 2024 · 1 comment
Open

Simplify reading, modifying, and writing glTF models #105

javagl opened this issue Mar 21, 2024 · 1 comment

Comments

@javagl
Copy link
Owner

javagl commented Mar 21, 2024

(This is related to #100 reported by @CloseFile, but tries to put some of the possible improvements into another context)

There currently is an infrastructure for reading glTF models. This is pretty simple:

GltfModelReader r = new GltfModelReader();
GltfModel gltfModel = r.read(Paths.get("input.glb"));

There you go.

There also is an infrastructure for writing glTF models. This is also simple:

GltfModelWriter w = new GltfModelWriter();
w.writeBinary(gltfModel, new File("output.glb"));

All lean and clean.
(Except for that difference of Path vs. File... maybe I'll fix that...)


Now, users might expect that they can read the model, modify it, and write back the modified model.

This is currently not possible!

(Well, it is possible but not nearly as simple as it should be)

The GltfModelWriter is stupid: It just takes the model as it is, and writes it. It does not care about any form of "consistency" of the model. For example, when someone removes one MeshPrimitiveModel from a (Default)GltfModel, and writes out the result, then the output will still contain the data of the mesh primitive that has been removed. Removing a mesh primitive does not imply the removal of the associated accessor/bufferView/buffer structures.

The reason for that is ... that this is far trickier than it looks. One could naively say: "When removing a mesh primitive, you can just remove its accessors as well". But this is not even remotely true. The accessors could be shared between mesh primitives, and might still be used by mesh primitives that have not been removed. And even when the accessors can be removed, this will imply structural changes in the associated bufferView/buffer structures that can essentially only be handled by completely re-building these structures, from scratch.

However, there could be some functionality to make this easier.

A very rough idea for a first shot (really just brainstorming now): There could be a function like revalidate(DefaultGltfModel) or GltfModel prune(GltfModel). (The difference roughly being whether this happens "in-place", or whether it creates a new model...).

This could be implemented by taking all elements of the input model, throwing away the bufferView/buffer information, and re-building this information from the remaining data (i.e. from the accessors). Most of the required functionality for that should already exist, in the GltfModelBuilder and (internal) BufferStructureBuilder classes. It would still imply some "boilerplate" code (for "shallow-copying" the other model elements and such). And it could be less efficient than other solutions (but these "other solutions" might require larger refactorings). It could be useful as a first step for simplfying the "read-modify-write" cycle, though.

Further improvements beyond that would be to make this process "smarter". This mainly refers to

  • trying to detect "unused elements" automatically
  • trying to ensure more consistency during the modifications of the model
    • (For example: It is currently possible - with some casting - to remove an AccessorModel that is still used by a MeshPrimitiveModel, and the resulting model will be "invalid"...)

For both goals, there's one thing that would invalidate most "simple, straightforward" approaches, namely extensions. There may be arbitrary extensions that use other model elements, and in order to detect "unused elements" and "consistency", there has to be a (model-level) representation and understanding of these extensions.

@javagl
Copy link
Owner Author

javagl commented Jul 16, 2024

Some of this was addressed via #108 , but this issue goes beyond what has been addressed in that PR, so I'll leave it open for further brainstorming.

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