Смещение байта больше, чем длина байта в BufferView - PullRequest
3 голосов
/ 25 марта 2019

Я пытаюсь прочитать данные из файлов scene.bin с помощью Microsoft :: glTF SDK.TinyGLTF не вариант.Когда я пытаюсь прочитать атрибут MeshPrimitive с именем TEXCOORD_0, я получаю ситуацию, когда BufferView byteOffset больше, чем byteLength.Поэтому я не знаю, как правильно читать данные, и моя программа вылетает.

Я пытался читать данные с помощью IStreamReader, который является частью SDK и обязателен при чтении бинарных файлов с использованием этого SDK.Я рассчитываю смещение данных, добавляя accessor.byteOffset + bufferView.byteOffset, который является> byteLength.

struct BuffersAccessors {
    Microsoft::glTF::Accessor accessor;
    Microsoft::glTF::BufferView view;
    Microsoft::glTF::Buffer buffer;

    void operator=(BuffersAccessors accessors);
};

template<typename T> struct BufferInfo {
BuffersAccessors buffersAccessors;
    std::vector<T> bufferData;

    BufferInfo<T>();

    BufferInfo<T>(BuffersAccessors buffersAccessors, std::vector<T> bufferData);

    const void operator=(const BufferInfo<T> &info) {
        buffersAccessors = info.buffersAccessors;
        bufferData = info.bufferData;
    };
};

    template<typename T>
std::vector<T> readBufferData(Microsoft::glTF::Document document, BufferInfo<T> bufferInfo, std::filesystem::path path) {
    std::vector<T> stream;

    if (bufferInfo.buffersAccessors.buffer.uri.length() > 0 || bufferInfo.buffersAccessors.buffer.byteLength > 0) {
        Microsoft::glTF::Buffer buffer = bufferInfo.buffersAccessors.buffer;

        path += bufferInfo.buffersAccessors.buffer.uri;
        path = std::filesystem::absolute(path);
        buffer.uri = path.string();

        std::shared_ptr<StreamReader> streamReader = std::make_shared<StreamReader>(path);
        Microsoft::glTF::GLTFResourceReader reader(streamReader);

        stream = reader.ReadBinaryData<T>(buffer, bufferInfo.buffersAccessors.view);
    }

    return stream;
}

    template<typename T>
BufferInfo<T> getFullBufferData(Microsoft::glTF::Document document, std::string accessorKey, std::filesystem::path path) {
    BufferInfo<T> bufferInfo{};
    BuffersAccessors mainPart = getBufferAccessorFromDocument(document, accessorKey);

    bufferInfo.buffersAccessors = mainPart;
    std::vector<T> bufferData = vkglTF::readBufferData<T>(document, bufferInfo, path);
    const size_t bufferDataOffset = mainPart.accessor.byteOffset + mainPart.view.byteOffset;    //How to properly calculate offset?

    bufferData.erase(bufferData.begin(), bufferData.begin() + bufferDataOffset);

    bufferInfo.bufferData = bufferData;

    return bufferInfo;
}

Я ожидаю данные в таких форматах, как uint8 и uint16, но моя программа падает при попытке сделать bufferData.erase (..).

Редактировать: это происходит и при чтении WEIGHTS_0.

1 Ответ

1 голос
/ 25 марта 2019

Я думаю, что наиболее вероятной ошибкой в ​​вашем коде является смешивание смещений байтов и индексов векторных элементов. Вы пытались разделить bufferDataOffset на sizeof(T)?

Во-вторых, если вы хотите только прочитать данные средства доступа, попробуйте использовать перегрузку ReadBinaryData, которая вместо этого принимает параметр средства доступа. Таким образом, glTF SDK будет обрабатывать все расчеты смещения для вас.

Нет документации, но пример десериализация демонстрирует базовую структуру кода, рекомендованную при использовании glTF SDK.

...