1
$\begingroup$

I am using tinyGLTF to parse gltf files and then render them in my program.

I am currently during the third example in this page.

In particular I am trying to extract the 2 animation buffers: enter image description here

My code:

MeshMap LoadGltf(const std::string& path)
{
    Model model;
    TinyGLTF loader;
    std::string err;
    std::string warn;

    bool ret = loader.LoadASCIIFromFile(&model, &err, &warn, path);

    if(!warn.empty()) { cout << warn << endl; }

    if(!err.empty()) { cout << err << endl; }

    if(!ret) { cout << "Failed to parse glTF" << endl; }

    MeshMap mesh_map;
    for(auto& mesh: model.meshes)
    {
        if(mesh.name.empty())
            mesh.name = "unnamed mesh " + to_string(global_mesh_index++);
        // TODO(low): implement this functionality as needed
        assert(mesh.primitives.size() == 1);
        GetPrimitiveData(model, mesh, mesh_map);
    }

    if(model.animations.size())
    {
        cout << "model.animations.size() " << model.animations.size() << endl;
        cout << "model.animations[0].channels.size() " << model.animations[0].channels.size() << endl;
        cout << "model.animations[0].channels[0].sampler " << model.animations[0].channels[0].sampler << endl;
        cout << "model.animations[0].samplers[0].input " << model.animations[0].samplers[0].input << endl;
        cout << "model.animations[0].samplers[0].output " << model.animations[0].samplers[0].output << endl;

        const int input = model.animations[0].samplers[0].input;
        const int output = model.animations[0].samplers[0].output;

        vector<float> time = ExtractDataFromAccessor<float>(model, input);
        for(auto f : time) cout << f << " ";
        cout << endl;
        cout << time.size() << endl;
        cout << model.accessors[input].name << endl;
        vector<float> rot = ExtractDataFromAccessor<float>(model, output);
        for(auto f : rot) cout << f << " ";
        cout << endl;

        cout << model.animations[0].channels[0].target_node << endl;
        cout << model.animations[0].channels[0].target_path << endl;
    }

    return mesh_map;
}
template<typename T>
std::vector<T> ExtractDataFromAccessor(
    Model& model,
    const int accessor_index)
{
    const int buffer_view_index = model.accessors[accessor_index].bufferView;
    const int buffer_index = model.bufferViews[buffer_view_index].buffer;
    const int buffer_length = model.bufferViews[buffer_view_index].byteLength;
    const int buffer_offset = model.bufferViews[buffer_view_index].byteOffset;
    const int buffer_stride = model.bufferViews[buffer_view_index].byteStride;
    const vector<unsigned char> data = model.buffers[buffer_index].data;

    //TODO(low): extend functionality to handle this as needed.
    assert(buffer_stride == 0);

    std::vector<T> holder(buffer_length / sizeof(T));
    memcpy(
        holder.data(),
        data.data() + buffer_offset,
        buffer_length);

    return holder;
}

Output

model.animations.size() 1
model.animations[0].channels.size() 1
model.animations[0].channels[0].sampler 0
model.animations[0].samplers[0].input 2
model.animations[0].samplers[0].output 3
0 0.25 0.5 0.75 1 0 0 0 1 0 0 0.707 0.707 0 0 1 0 0 0 0.707 -0.707 0 0 0 1 
25

0 0.25 0.5 0.75 1 0 0 0 1 0 0 0.707 0.707 0 0 1 0 0 0 0.707 -0.707 0 0 0 1 
0
rotation

I am very confused in that in and out seem to be equal, and that they are the concatenation of the 2 animation buffers, rather than what I expected. Which was in to be the time buffer and out to be the rotation buffer.

Where is the data that lets you separate them?

$\endgroup$

1 Answer 1

1
$\begingroup$

The accessor (model.accessors[accessor_index]) has its own byteOffset and count values that you need to account for here.

The input and output accessors are allowed to share a bufferView, and your output is showing a dump of the same entire bufferView twice. The first five values in that dump are the input accessor with the times (in seconds, since the start of the animation) and the remainder of the bufferView is pointed at by the output accessor. If you account for the additional settings on the accessor itself, it should allow you to pick apart this bufferView correctly.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.