Gltf crate related issue

When using A deserializable type generic with serde to import only specific data from a glb/gltf with serde_json, how do you declare member variables within the struct like weights/weight paint data and a skeleton, as well as vertices, indices, uvs and normals? if there's no way for some or all of them, what's the closest most efficient way to do so even if the methods aren't similar?

no, you can't declare fields for generic types. you can only add trait (and lifetime) bounds for generic types in rust.

if your goal is to validate some json data, you can just define your own schema type. if the data deserializes successfully, then you know its valid.

if this is not your actual use case, feel free to provide more details.

Apologies, I meant something like this as a reference of base.

let models: Vec<GltfModel> = serde_json::from_slice(
        &gltf::Glb::from_slice(&std::fs::read(
            args.get(1).expect("Error: First argument unavailable."),
        )?)?
        .json,
    )?;
#[derive(serde::Deserialize)]
struct GltfModel {
    mesh: Mesh,
    animation: Option<Vec<Animation>>,
}

I'm a little confused, you mentioned generic type in OP, but the example didn't show any usage of generics?

also, the gltf json schema is well defined by the spec, you don't need a custom deserializable type, you can create your model type by converting from the predefined type.

I mispoke. I didn't mean generics. and how do I convert from a predefined type to achieve my goal? My goal is also to not parse the full json to avoid an immense performance decrease.

I'm not familiar with gltf, I only know it is a container format for 3d scenes. but looking at the crate docs, it seems the schema for the json data is the Root struct:

the gltf crate already provides high level types for the scenes and functions to load the model (and the associated resources). since you choose the manual approach, I assume you want be in direct control of resource loading, so you must manually decode the binary data after the json. I don't know much about the binary data format, I'm not really into 3d rendering.

Your program will still have to parse most of the JSON[1], but you can certainly avoid building data structures from the parts you don't need. You will need to define your own struct similar to gltf_json::Root, but it can contain only the fields for the glTF objects that you care about, and you can reuse gltf_json’s types for those particular objects.


  1. that is, look for all of the {, }, and " ↩︎

Side question, does setting up a reader for gltf buffers effectively only build the data structures you "read" (i.e. read_tex_coords())? Primary question, would I effectively need to write a feature for gltf if I want to make my own gltf_json::Root or is there a builtin way in one of the gltf crates?

You will have to write your own code to read the right sections of the binary data, but that should not be too complex, at least if you are loading GLB. In particular, you can

  1. Use gltf::Glb to parse a .glb and get the binary part and the JSON part
  2. Pass the JSON part to serde_json to deserialize it into using your own custom root type.
  3. Use the information from the JSON to decide which slice of the binary part you need.

Some of this will end up needing to be code that duplicates code that is already in gltf, but this is not surprising when you want to write a specialized loader that does less work.

Question is it worth the performance increase when it's for a cli that converts glb to my own object format? How much do I lose from importing things other than vertices, indices, uvs, normals, animations, and the skeleton?

That's the sort of question that can only really be answered by benchmarking both options. But I would guess that the benefits are not worth maintaining special code.

Me as well considering anything else most likely won't ever be as heavy in content, except weight paint data which I forgot to include.

You might also be interested in this new release: