Reading a glTF file
See original GitHub issueHi, i have written a glTF exporter for my custom model format using this library and it was really simple to do as the library did most of the work for me, for example writing the joints and weights just took about 25 lines total as all i had to do was create the 2 buffers, create an accessor model for each, add the 2 attributes(JOINTS_0 and WEIGHTS_0) and create a buffer view model which was extremely easy due to the ‘helper’ classes like BufferStructureBuilder
Now i am not sure about importing a glTF file and extracting data from it, are there any helper methods that make it simpler? For example if i wanted to read the weights of a mesh primitive, this is what i do right now:
GltfReaderV2 reader = new GltfReaderV2();
GlTF gltf = reader.read(new ByteArrayInputStream(Files.readAllBytes(filePath)));
Mesh mesh = gltf.getMeshes().get(0); // the gltf file only has 1 mesh
MeshPrimitive primitive = mesh.getPrimitives().get(0); // the mesh only has 1 mesh primitive(for now)
int weightsIndex = primitive.getAttributes().get("WEIGHTS_0");
Accessor weightsAccessor = gltf.getAccessors().get(weightsIndex);
BufferView weightsBufferView = gltf.getBufferViews().get(weightsAccessor.getBufferView());
Buffer gltfBuffer = gltf.getBuffers().get(weightsBufferView.getBuffer());
String base64 = gltfBuffer.getUri().substring(gltfBuffer.getUri().indexOf("base64") + "base64, ".length());
byte[] bytes = Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
int byteOffset = weightsBufferView.getByteOffset();
int byteLength = weightsBufferView.getByteLength();
//TODO create float buffer and start reading weights
This isn’t very tedious to do, but im still curious if there are perhaps simpler ways. Any advice is appreciated.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Yes, sorry, I had quickly created this example while being on the
model-creation
branch. In the released version, the line should beThe packages in the
releases
are only preview releases of the standalonegltf-browser
application. (This hasn’t been updated in a while). The latest “official” release is version 2.0.0 in Maven Central.Some background: When I started creating that library, glTF 1.0 was published, and the update for the next version was in progress. Unfortunately, the changes from glTF 1.0 to glTF 2.0 turned out to be significant. I naively tried to find some sort of “abstraction” for changes, in form of the
...Model
classes. In hindsight, much of this could have been much simpler and cleaner if I had just dropped the glTF 1.0 support. However, here we are. I’m trying to make the best out of this.When you mention the
BufferStructureBuilder
, then I have to emphasize the JavaDoc comment from the current state of this class:But I’m aware of the demand for such a “helper” class: Most of glTF is somewhat trivial to build (for simple gemetry models, at least). But the buffer-bufferView-accessor structures are the most tricky part, even for “simple” models. Therefore, I started extending that functionality, with the goal to be able to “easily” create glTF models. The progress is slow (too many other things to do), but I actually made a bit of progress recently. This is done in the https://github.com/javagl/JglTF/tree/model-creation branch.
The goal of this “refactoring” is to offer more convenient classes for building models (and there will be some changes in the
BufferStructureBuilder
and related classes). An example of what this could look like can be found at https://github.com/javagl/JglTF/blob/model-creation/jgltf-model-builder/src/test/java/de/javagl/jgltf/model/creation/example/GltfModelCreationExample.java#L97 . Feedback and suggestions for improvements are welcome - but I’m aware that until now, only a tiny fraction of glTF is covered with these classes, and there are some things that I’ll have to address before making these changes “official”.Coming back to your actual question:
There are some degrees of freedom, depending on your exact goals. But as I mentioned above, there are two levels of abstraction:
de.javagl.jgltf.impl.v2
package. These are low-level classes, auto-generated from the JSON schema. And that’s what you are using in the code that you showed.de.javagl.jgltf.model
package. These are “convenience classes”, representing the glTF asset in a form that is supposed to be easier to use, when you don’t need to manipulate things on the level of the JSON inputAnd I think that the code that you showed is tedious (at least, more tedious than it should be). There are many assumptions in the code. This refers to the special case like having only 1 mesh primitive, but also to the fact that the
buffer
has adata-uri
and so on. And when the//TODO create float buffer and start reading weights
is to be addressed, things can become tricky and clumsy very quickly: You’ll have to check the component type, number of elements, and think about sparse accessors and such…The model classes, and particularly the
AccessorModel
/AccessorData
classes, should make that a bit easier. Here is an example that loads theSimpleSkin
sample model, and prints theWEIGHTS_0
data:When you change the
modelName
toSimpleSparseAccessor
, and theattributeName
toPOSITION
, then it will print the positions, with the sparse substitution already applied - just as one example where these model classes can make things a bit simpler…