void BufferBuilder::AddAccessors()

in GLTFSDK/Source/BufferBuilder.cpp [134:214]


void BufferBuilder::AddAccessors(const void* data, size_t count, size_t byteStride, const AccessorDesc* pDescs, size_t descCount, std::string* pOutIds)
{
    Buffer& buffer = m_buffers.Back();
    BufferView& bufferView = m_bufferViews.Back();

    if (count == 0 || pDescs == nullptr || descCount == 0)
    {
        throw InvalidGLTFException("invalid parameters specified");
    }

    for (size_t i = 0; i < descCount; ++i)
    {
        if (!pDescs[i].IsValid())
        {
            throw InvalidGLTFException("invalid AccessorDesc specified in pDescs");
        }
    }

    if (bufferView.byteLength != 0U)
    {
        throw InvalidGLTFException("current buffer view already has written data - this interface doesn't support appending to an existing buffer view");
    }

    size_t extent;

    if (byteStride == 0)
    {
        if (descCount > 1)
        {
            throw InvalidGLTFException("glTF 2.0 specification denotes that byte stride must be >= 4 when a buffer view is accessed by more than one accessor");
        }

        extent = count * Accessor::GetComponentTypeSize(pDescs[0].componentType) * Accessor::GetTypeCount(pDescs[0].accessorType);
    }
    else
    {
        extent = count * byteStride;

        // Ensure all accessors fit within the buffer view's extent.
        const size_t lastElement = (count - 1) * (bufferView.byteStride ? bufferView.byteStride.Get() : 0U);

        for (size_t i = 0; i < descCount; ++i)
        {
            const size_t accessorSize = Accessor::GetTypeCount(pDescs[i].accessorType) * Accessor::GetComponentTypeSize(pDescs[i].componentType);
            const size_t accessorEnd = lastElement + pDescs[i].byteOffset + accessorSize;

            if (extent < accessorEnd)
            {
                throw InvalidGLTFException("specified accessor does not fit within the currently defined buffer view");
            }
        }
    }

    // Calculate the max alignment.
    size_t alignment = 1;
    for (size_t i = 0; i < descCount; ++i)
    {
        alignment = std::max(alignment, GetAlignment(pDescs[i]));
    }

    bufferView.byteStride = byteStride;
    bufferView.byteLength = extent;
    bufferView.byteOffset += ::GetPadding(bufferView.byteOffset, alignment);

    buffer.byteLength = bufferView.byteOffset + bufferView.byteLength;

    for (size_t i = 0; i < descCount; ++i)
    {
        AddAccessor(count, pDescs[i]);

        if (pOutIds != nullptr)
        {
            pOutIds[i] = GetCurrentAccessor().id;
        }
    }

    if (m_resourceWriter)
    {
        m_resourceWriter->Write(bufferView, data);
    }
}