字节偏移大于BufferView中的字节长度

时间:2019-03-25 00:25:40

标签: c++ sdk c++17 gltf

我正在尝试使用Microsoft :: glTF SDK从scene.bin文件中读取数据。 TinyGLTF不是一个选择。当我尝试读取称为TEXCOORD_0的MeshPrimitive属性时,出现BufferView byteOffset大于byteLength的情况。因此,我不知道如何正确读取给定的数据,并且程序崩溃。

我尝试使用IStreamReader读取数据,该数据是SDK的一部分,并且在使用此SDK读取bin文件时必须这样做。我通过添加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 个答案:

答案 0 :(得分:1)

我认为您的代码最可能出现的错误是字节偏移量和矢量元素索引的混合。您是否尝试过将bufferDataOffset除以sizeof(T)

第二,如果您只想读取访问者的数据,则尝试使用ReadBinaryData重载来代替,该重载接受一个Accessor参数。这样,glTF SDK将为您处理所有偏移量计算。

没有文档,但是deserialize示例演示了使用glTF SDK时建议的基本代码结构。