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);
}
}