/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick 3D.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qssgmeshutilities_p.h"

#include <QtCore/QVector>
#include <QtCore/QBuffer>
#include <QtQuick3DUtils/private/qssgdataref_p.h>

QT_BEGIN_NAMESPACE

namespace QSSGMeshUtilities {

struct MeshSubsetV1
{
    // See description of a logical vertex buffer below
    quint32 m_logicalVbufIndex;
    // std::numeric_limits<quint32>::max() means use all available items
    quint32 m_count;
    // Offset is in item size, not bytes.
    quint32 m_offset;
    // Bounds of this subset.  This is filled in by the builder
    // see AddMeshSubset
    QSSGBounds3 m_bounds;
};

struct LogicalVertexBuffer
{
    quint32 m_byteOffset{ 0 };
    quint32 m_byteSize{ 0 };
    LogicalVertexBuffer(quint32 byteOff, quint32 byteSize) : m_byteOffset(byteOff), m_byteSize(byteSize) {}
    LogicalVertexBuffer() = default;
};

struct MeshV1
{
    VertexBuffer m_vertexBuffer;
    IndexBuffer m_indexBuffer;
    OffsetDataRef<LogicalVertexBuffer> m_logicalVertexBuffers; // may be empty
    OffsetDataRef<MeshSubsetV1> m_subsets;
    QSSGRenderDrawMode m_drawMode;
    QSSGRenderWinding m_winding;
    typedef MeshSubsetV1 TSubsetType;
};

template<typename TSerializer>
void serialize(TSerializer &serializer, MeshV1 &mesh)
{
    quint8 *baseAddr = reinterpret_cast<quint8 *>(&mesh);
    serializer.streamify(mesh.m_vertexBuffer.m_entries);
    serializer.align();
    for (quint32 entry = 0, __numItems = (quint32)mesh.m_vertexBuffer.m_entries.size(); entry < __numItems; ++entry) {
        MeshVertexBufferEntry &entryData = const_cast<MeshVertexBufferEntry &>(mesh.m_vertexBuffer.m_entries.index(baseAddr, entry));
        serializer.streamifyCharPointerOffset(entryData.m_nameOffset);
        serializer.align();
    }
    serializer.streamify(mesh.m_vertexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_indexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_logicalVertexBuffers);
    serializer.align();
    serializer.streamify(mesh.m_subsets);
    serializer.align();
}

struct MeshSubsetV2
{
    quint32 m_logicalVbufIndex;
    quint32 m_count;
    quint32 m_offset;
    QSSGBounds3 m_bounds;
    OffsetDataRef<char16_t> m_name;
};

struct MeshV2
{
    static const char16_t *m_defaultName;

    VertexBuffer m_vertexBuffer;
    IndexBuffer m_indexBuffer;
    OffsetDataRef<LogicalVertexBuffer> m_logicalVertexBuffers; // may be empty
    OffsetDataRef<MeshSubsetV2> m_subsets;
    QSSGRenderDrawMode m_drawMode;
    QSSGRenderWinding m_winding;
    typedef MeshSubsetV2 TSubsetType;
};

template<typename TSerializer>
void serialize(TSerializer &serializer, MeshV2 &mesh)
{
    quint8 *baseAddr = reinterpret_cast<quint8 *>(&mesh);
    serializer.streamify(mesh.m_vertexBuffer.m_entries);
    serializer.align();
    for (quint32 entry = 0, __numItems = (quint32)mesh.m_vertexBuffer.m_entries.size(); entry < __numItems; ++entry) {
        MeshVertexBufferEntry &entryData = const_cast<MeshVertexBufferEntry &>(mesh.m_vertexBuffer.m_entries.index(baseAddr, entry));
        serializer.streamifyCharPointerOffset(entryData.m_nameOffset);
        serializer.align();
    }
    serializer.streamify(mesh.m_vertexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_indexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_logicalVertexBuffers);
    serializer.align();
    serializer.streamify(mesh.m_subsets);
    serializer.align();
    for (quint32 entry = 0, __numItems = (quint32)mesh.m_subsets.size(); entry < __numItems; ++entry) {
        MeshSubsetV2 &theSubset = const_cast<MeshSubsetV2 &>(mesh.m_subsets.index(baseAddr, entry));
        serializer.streamify(theSubset.m_name);
        serializer.align();
    }
}

// Localize the knowledge required to read/write a mesh into one function
// written in such a way that you can both read and write by passing
// in one serializer type or another.
// This function needs to be careful to request alignment after every write of a
// buffer that may leave us unaligned.  The easiest way to be correct is to request
// alignment a lot.  The hardest way is to use knowledge of the datatypes and
// only request alignment when necessary.
template<typename TSerializer>
void serialize(TSerializer &serializer, Mesh &mesh)
{
    quint8 *baseAddr = reinterpret_cast<quint8 *>(&mesh);
    serializer.streamify(mesh.m_vertexBuffer.m_entries);
    serializer.align();

    for (quint32 entry = 0, numItems = mesh.m_vertexBuffer.m_entries.size(); entry < numItems; ++entry) {
        MeshVertexBufferEntry &entryData = mesh.m_vertexBuffer.m_entries.index(baseAddr, entry);
        serializer.streamifyCharPointerOffset(entryData.m_nameOffset);
        serializer.align();
    }
    serializer.streamify(mesh.m_vertexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_indexBuffer.m_data);
    serializer.align();
    serializer.streamify(mesh.m_subsets);
    serializer.align();

    for (quint32 entry = 0, numItems = mesh.m_subsets.size(); entry < numItems; ++entry) {
        MeshSubset &theSubset = const_cast<MeshSubset &>(mesh.m_subsets.index(baseAddr, entry));
        serializer.streamify(theSubset.m_name);
        serializer.align();
    }
    serializer.streamify(mesh.m_joints);
    serializer.align();
}

struct TotallingSerializer
{
    quint32 m_numBytes;
    const quint8 *m_baseAddress;
    TotallingSerializer(const quint8 *inBaseAddr) : m_numBytes(0), m_baseAddress(inBaseAddr) {}
    template<typename TDataType>
    void streamify(const OffsetDataRef<TDataType> &data)
    {
        m_numBytes += data.size() * sizeof(TDataType);
    }
    void streamify(const char *data)
    {
        if (data == nullptr)
            data = "";
        quint32 len = (quint32)strlen(data) + 1;
        m_numBytes += 4;
        m_numBytes += len;
    }
    void streamifyCharPointerOffset(quint32 inOffset)
    {
        if (inOffset) {
            const char *dataPtr = (const char *)(inOffset + m_baseAddress);
            streamify(dataPtr);
        } else
            streamify("");
    }
    bool needsAlignment() const { return getAlignmentAmount() > 0; }
    quint32 getAlignmentAmount() const { return 4 - (m_numBytes % 4); }
    void align()
    {
        if (needsAlignment())
            m_numBytes += getAlignmentAmount();
    }
};

struct ByteWritingSerializer
{
    QIODevice &m_stream;
    TotallingSerializer m_byteCounter;
    quint8 *m_baseAddress;
    ByteWritingSerializer(QIODevice &str, quint8 *inBaseAddress)
        : m_stream(str), m_byteCounter(inBaseAddress), m_baseAddress(inBaseAddress)
    {
    }

    template<typename TDataType>
    void streamify(const OffsetDataRef<TDataType> &data)
    {
        m_byteCounter.streamify(data);
        const int written = m_stream.write(reinterpret_cast<const char *>(data.begin(m_baseAddress)), data.size() * sizeof(TDataType));
        (void)written;
    }
    void streamify(const char *data)
    {
        m_byteCounter.streamify(data);
        if (data == nullptr)
            data = "";
        quint32 len = (quint32)strlen(data) + 1;
        int written = m_stream.write(reinterpret_cast<const char *>(&len), sizeof(quint32));
        written = m_stream.write(data, len);
        (void)written;
    }
    void streamifyCharPointerOffset(quint32 inOffset)
    {
        const char *dataPtr = (const char *)(inOffset + m_baseAddress);
        streamify(dataPtr);
    }

    void align()
    {
        if (m_byteCounter.needsAlignment()) {
            quint8 buffer[] = { 0, 0, 0, 0 };
            const int written = m_stream.write(reinterpret_cast<const char *>(buffer), m_byteCounter.getAlignmentAmount());
            (void)written;
            m_byteCounter.align();
        }
    }
};

struct MemoryAssigningSerializer
{
    const quint8 *m_memory;
    const quint8 *m_baseAddress;
    quint32 m_size;
    TotallingSerializer m_byteCounter;
    bool m_failure;
    MemoryAssigningSerializer(const quint8 *data, quint32 size, quint32 startOffset)
        : m_memory(data + startOffset), m_baseAddress(data), m_size(size), m_byteCounter(data), m_failure(false)
    {
        // We expect 4 byte aligned memory to begin with
        Q_ASSERT((((size_t)m_memory) % 4) == 0);
    }

    template<typename TDataType>
    void streamify(const OffsetDataRef<TDataType> &_data)
    {
        OffsetDataRef<TDataType> &data = const_cast<OffsetDataRef<TDataType> &>(_data);
        if (m_failure) {
            data.m_size = 0;
            data.m_offset = 0;
            return;
        }
        quint32 current = m_byteCounter.m_numBytes;
        m_byteCounter.streamify(_data);
        if (m_byteCounter.m_numBytes > m_size) {
            data.m_size = 0;
            data.m_offset = 0;
            m_failure = true;
            return;
        }
        quint32 numBytes = m_byteCounter.m_numBytes - current;
        if (numBytes) {
            data.m_offset = (quint32)(m_memory - m_baseAddress);
            updateMemoryBuffer(numBytes);
        } else {
            data.m_offset = 0;
            data.m_size = 0;
        }
    }
    void streamify(const char *&_data)
    {
        quint32 len;
        m_byteCounter.m_numBytes += 4;
        if (m_byteCounter.m_numBytes > m_size) {
            _data = "";
            m_failure = true;
            return;
        }
        memcpy(&len, m_memory, 4);
        updateMemoryBuffer(4);
        m_byteCounter.m_numBytes += len;
        if (m_byteCounter.m_numBytes > m_size) {
            _data = "";
            m_failure = true;
            return;
        }
        _data = (const char *)m_memory;
        updateMemoryBuffer(len);
    }
    void streamifyCharPointerOffset(quint32 &inOffset)
    {
        const char *dataPtr;
        streamify(dataPtr);
        inOffset = (quint32)(dataPtr - (const char *)m_baseAddress);
    }
    void align()
    {
        if (m_byteCounter.needsAlignment()) {
            quint32 numBytes = m_byteCounter.getAlignmentAmount();
            m_byteCounter.align();
            updateMemoryBuffer(numBytes);
        }
    }
    void updateMemoryBuffer(quint32 numBytes) { m_memory += numBytes; }
};

inline quint32 getMeshDataSize(Mesh &mesh)
{
    TotallingSerializer s(reinterpret_cast<quint8 *>(&mesh));
    serialize(s, mesh);
    return s.m_numBytes;
}

template<typename TDataType>
quint32 nextIndex(const quint8 *inBaseAddress, const OffsetDataRef<quint8> data, quint32 idx)
{
    quint32 numItems = data.size() / sizeof(TDataType);
    if (idx < numItems) {
        const TDataType *dataPtr(reinterpret_cast<const TDataType *>(data.begin(inBaseAddress)));
        return dataPtr[idx];
    } else {
        Q_UNREACHABLE();
        return 0;
    }
}

template<typename TDataType>
quint32 nextIndex(const QByteArray &data, quint32 idx)
{
    quint32 numItems = data.size() / sizeof(TDataType);
    if (idx < numItems) {
        const TDataType *dataPtr(reinterpret_cast<const TDataType *>(data.begin()));
        return dataPtr[idx];
    } else {
        Q_ASSERT(false);
        return 0;
    }
}

inline quint32 nextIndex(const QByteArray &inData, QSSGRenderComponentType inCompType, quint32 idx)
{
    if (inData.size() == 0)
        return idx;
    switch (inCompType) {
    case QSSGRenderComponentType::UnsignedInteger8:
        return nextIndex<quint8>(inData, idx);
    case QSSGRenderComponentType::Integer8:
        return nextIndex<quint8>(inData, idx);
    case QSSGRenderComponentType::UnsignedInteger16:
        return nextIndex<quint16>(inData, idx);
    case QSSGRenderComponentType::Integer16:
        return nextIndex<qint16>(inData, idx);
    case QSSGRenderComponentType::UnsignedInteger32:
        return nextIndex<quint32>(inData, idx);
    case QSSGRenderComponentType::Integer32:
        return nextIndex<qint32>(inData, idx);
    default:
        // Invalid index buffer index type.
        Q_ASSERT(false);
    }

    return 0;
}

template<typename TMeshType>
// Not exposed to the outside world
TMeshType *doInitialize(quint16 /*meshFlags*/, QSSGByteView data)
{
    const quint8 *newMem = data.begin();
    quint32 amountLeft = data.size() - sizeof(TMeshType);
    MemoryAssigningSerializer s(newMem, amountLeft, sizeof(TMeshType));
    TMeshType *retval = (TMeshType *)newMem;
    serialize(s, *retval);
    if (s.m_failure)
        return nullptr;
    return retval;
}

static char16_t g_DefaultName[] = { 0 };

const char16_t *Mesh::m_defaultName = g_DefaultName;

template<typename TMeshType>
struct SubsetNameHandler
{
};

template<>
struct SubsetNameHandler<MeshV1>
{
    void assignName(const quint8 * /*v1BaseAddress*/, const MeshSubsetV1 & /*mesh*/, quint8 * /*baseAddress*/, quint8 *& /*nameBuffer*/, MeshSubset &outDest)
    {
        outDest.m_name = OffsetDataRef<char16_t>();
    }
    quint32 nameLength(const MeshSubsetV1 &) { return 0; }
};

template<>
struct SubsetNameHandler<MeshV2>
{
    void assignName(const quint8 *v2BaseAddress, const MeshSubsetV2 &mesh, quint8 *baseAddress, quint8 *&nameBuffer, MeshSubset &outDest)
    {
        outDest.m_name.m_size = mesh.m_name.m_size;
        outDest.m_name.m_offset = (quint32)(nameBuffer - baseAddress);
        quint32 dtypeSize = mesh.m_name.m_size * 2;
        memcpy(nameBuffer, mesh.m_name.begin(v2BaseAddress), dtypeSize);
        nameBuffer += dtypeSize;
    }
    quint32 nameLength(const MeshSubsetV2 &mesh) { return (mesh.m_name.size() + 1) * 2; }
};

quint32 getAlignedOffset(quint32 offset, quint32 align)
{
    quint32 leftover = offset % align;
    if (leftover)
        return offset + (align - leftover);
    return offset;
}

template<typename TPreviousMeshType>
Mesh *createMeshFromPreviousMesh(TPreviousMeshType *temp)
{
    quint32 newMeshSize = sizeof(Mesh);
    quint8 *tempBaseAddress = reinterpret_cast<quint8 *>(temp);
    quint32 alignment = sizeof(void *);

    quint32 vertBufferSize = getAlignedOffset(temp->m_vertexBuffer.m_data.size(), alignment);
    newMeshSize += vertBufferSize;
    quint32 entryDataSize = temp->m_vertexBuffer.m_entries.size() * sizeof(MeshVertexBufferEntry);
    newMeshSize += entryDataSize;
    quint32 indexBufferSize = getAlignedOffset(temp->m_indexBuffer.m_data.size(), alignment);
    newMeshSize += indexBufferSize;
    quint32 entryNameSize = 0;
    for (quint32 entryIdx = 0, entryEnd = temp->m_vertexBuffer.m_entries.size(); entryIdx < entryEnd; ++entryIdx) {
        const QSSGRenderVertexBufferEntry theEntry = temp->m_vertexBuffer.m_entries.index(tempBaseAddress, entryIdx).toVertexBufferEntry(tempBaseAddress);
        const char *namePtr = theEntry.m_name;
        if (namePtr == nullptr)
            namePtr = "";

        entryNameSize += (quint32)strlen(theEntry.m_name) + 1;
    }
    entryNameSize = getAlignedOffset(entryNameSize, alignment);

    newMeshSize += entryNameSize;
    quint32 subsetBufferSize = temp->m_subsets.size() * sizeof(MeshSubset);
    newMeshSize += subsetBufferSize;
    quint32 nameLength = 0;
    for (quint32 subsetIdx = 0, subsetEnd = temp->m_subsets.size(); subsetIdx < subsetEnd; ++subsetIdx) {
        nameLength += SubsetNameHandler<TPreviousMeshType>().nameLength(temp->m_subsets.index(tempBaseAddress, subsetIdx));
    }
    nameLength = getAlignedOffset(nameLength, alignment);

    newMeshSize += nameLength;

    Mesh *retval = new Mesh();
    quint8 *baseOffset = reinterpret_cast<quint8 *>(retval);
    quint8 *vertBufferData = baseOffset + sizeof(Mesh);
    quint8 *entryBufferData = vertBufferData + vertBufferSize;
    quint8 *entryNameBuffer = entryBufferData + entryDataSize;
    quint8 *indexBufferData = entryNameBuffer + entryNameSize;
    quint8 *subsetBufferData = indexBufferData + indexBufferSize;
    quint8 *nameData = subsetBufferData + subsetBufferSize;

    retval->m_drawMode = temp->m_drawMode;
    retval->m_winding = temp->m_winding;
    retval->m_vertexBuffer = temp->m_vertexBuffer;
    retval->m_vertexBuffer.m_data.m_offset = (quint32)(vertBufferData - baseOffset);
    retval->m_vertexBuffer.m_entries.m_offset = (quint32)(entryBufferData - baseOffset);
    memcpy(vertBufferData, temp->m_vertexBuffer.m_data.begin(tempBaseAddress), temp->m_vertexBuffer.m_data.size());
    memcpy(entryBufferData, temp->m_vertexBuffer.m_entries.begin(tempBaseAddress), entryDataSize);
    for (quint32 idx = 0, __numItems = (quint32)temp->m_vertexBuffer.m_entries.size(); idx < __numItems; ++idx) {
        const MeshVertexBufferEntry &src = temp->m_vertexBuffer.m_entries.index(tempBaseAddress, idx);
        MeshVertexBufferEntry &dest = retval->m_vertexBuffer.m_entries.index(baseOffset, idx);

        const char *targetName = reinterpret_cast<const char *>(src.m_nameOffset + tempBaseAddress);
        if (src.m_nameOffset == 0)
            targetName = "";
        quint32 nameLen = (quint32)strlen(targetName) + 1;
        dest.m_nameOffset = (quint32)(entryNameBuffer - baseOffset);
        memcpy(entryNameBuffer, targetName, nameLen);
        entryNameBuffer += nameLen;
    }

    retval->m_indexBuffer = temp->m_indexBuffer;
    retval->m_indexBuffer.m_data.m_offset = (quint32)(indexBufferData - baseOffset);
    memcpy(indexBufferData, temp->m_indexBuffer.m_data.begin(tempBaseAddress), temp->m_indexBuffer.m_data.size());

    retval->m_subsets.m_size = temp->m_subsets.m_size;
    retval->m_subsets.m_offset = (quint32)(subsetBufferData - baseOffset);

    for (quint32 idx = 0, numItems = (quint32)temp->m_subsets.size(); idx < numItems; ++idx) {
        MeshSubset &dest = const_cast<MeshSubset &>(retval->m_subsets.index(baseOffset, idx));
        const typename TPreviousMeshType::TSubsetType &src = temp->m_subsets.index(tempBaseAddress, idx);
        dest.m_count = src.m_count;
        dest.m_offset = src.m_offset;
        dest.m_bounds = src.m_bounds;
        SubsetNameHandler<TPreviousMeshType>().assignName(tempBaseAddress, src, baseOffset, nameData, dest);
    }
    return retval;
}

QSSGBounds3 Mesh::calculateSubsetBounds(const QSSGRenderVertexBufferEntry &inEntry,
                                          const QByteArray &inVertxData,
                                          quint32 inStride,
                                          const QByteArray &inIndexData,
                                          QSSGRenderComponentType inIndexCompType,
                                          quint32 inSubsetCount,
                                          quint32 inSubsetOffset)
{
    QSSGBounds3 retval = QSSGBounds3();
    const QSSGRenderVertexBufferEntry &entry(inEntry);
    if (entry.m_componentType != QSSGRenderComponentType::Float32 || entry.m_numComponents != 3) {
        Q_ASSERT(false);
        return retval;
    }

    const quint8 *beginPtr = reinterpret_cast<const quint8 *>(inVertxData.constData());
    quint32 numBytes = inVertxData.size();
    quint32 dataStride = inStride;
    quint32 posOffset = entry.m_firstItemOffset;
    // The loop below could be template specialized *if* we wanted to do this.
    // and the perf of the existing loop was determined to be a problem.
    // Else I would rather stay way from the template specialization.
    for (quint32 idx = 0, __numItems = (quint32)inSubsetCount; idx < __numItems; ++idx) {
        quint32 dataIdx = nextIndex(inIndexData, inIndexCompType, idx + inSubsetOffset);
        quint32 finalOffset = (dataIdx * dataStride) + posOffset;
        if (finalOffset + sizeof(Vec3) <= numBytes) {
            const quint8 *dataPtr = beginPtr + finalOffset;
            const auto vec3 = *reinterpret_cast<const Vec3 *>(dataPtr);
            retval.include(QVector3D(vec3.x, vec3.y, vec3.z));
        } else {
            Q_ASSERT(false);
        }
    }

    return retval;
}

void Mesh::save(QIODevice &outStream) const
{
    Mesh &mesh(const_cast<Mesh &>(*this));
    quint8 *baseAddress = reinterpret_cast<quint8 *>(&mesh);
    quint32 meshSize = sizeof(Mesh);
    quint32 meshDataSize = getMeshDataSize(mesh);
    quint32 numBytes = meshSize + meshDataSize;
    MeshDataHeader header(numBytes);
    int written = outStream.write(reinterpret_cast<const char *>(&header), sizeof(MeshDataHeader)); // 12 bytes
    written = outStream.write(reinterpret_cast<const char *>(this), sizeof(Mesh));
    (void)written;
    ByteWritingSerializer writer(outStream, baseAddress);
    serialize(writer, mesh);
}

bool Mesh::save(const char *inFilePath) const
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadWrite)) {
        Q_ASSERT(false);
        return false;
    }

    save(file);
    file.close();
    return true;
}

Mesh *Mesh::load(QIODevice &inStream)
{
    MeshDataHeader header;
    inStream.read(reinterpret_cast<char *>(&header), sizeof(MeshDataHeader));
    Q_ASSERT(header.m_fileId == MeshDataHeader::getFileId());
    if (header.m_fileId != MeshDataHeader::getFileId())
        return nullptr;
    if (header.m_fileVersion < 1 || header.m_fileVersion > MeshDataHeader::getCurrentFileVersion())
        return nullptr;
    if (header.m_sizeInBytes < sizeof(Mesh))
        return nullptr;
    char *meshBufferData = reinterpret_cast<char *>(::malloc(header.m_sizeInBytes));
    qint64 sizeRead = inStream.read(meshBufferData, header.m_sizeInBytes);
    //    QByteArray meshBuffer = inStream.read(header.m_sizeInBytes);
    if (sizeRead == header.m_sizeInBytes) {
        QSSGByteView meshBuffer = toByteView(meshBufferData, header.m_sizeInBytes);
        if (header.m_fileVersion == 1) {
            MeshV1 *temp = doInitialize<MeshV1>(header.m_headerFlags, meshBuffer);
            if (temp == nullptr)
                goto failure;
            return createMeshFromPreviousMesh(temp);

        } else if (header.m_fileVersion == 2) {
            MeshV2 *temp = doInitialize<MeshV2>(header.m_headerFlags, meshBuffer);
            if (temp == nullptr)
                goto failure;
            return createMeshFromPreviousMesh(temp);
        } else {
            Mesh *retval = initialize(header.m_fileVersion, header.m_headerFlags, meshBuffer);
            if (retval == nullptr)
                goto failure;
            return retval;
        }
    }

failure:
    Q_ASSERT(false);
    ::free(meshBufferData);
    return nullptr;
}

Mesh *Mesh::load(const char *inFilePath)
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadOnly)) {
        Q_ASSERT(false);
        return nullptr;
    }

    auto mesh = load(file);
    file.close();
    return mesh;
}

Mesh *Mesh::initialize(quint16 meshVersion, quint16 meshFlags, QSSGByteView data)
{
    if (meshVersion != MeshDataHeader::getCurrentFileVersion())
        return nullptr;
    return doInitialize<Mesh>(meshFlags, data);
}

quint32 Mesh::saveMulti(QIODevice &inStream, quint32 inId) const
{
    quint32 nextId = 1;
    MeshMultiHeader tempHeader;
    MeshMultiHeader *theHeader = nullptr;
    MeshMultiHeader *theWriteHeader = nullptr;

    qint64 newMeshStartPos = 0;
    if (inStream.size() != 0) {
        theHeader = loadMultiHeader(inStream);
        if (theHeader == nullptr) {
            Q_ASSERT(false);
            return 0;
        }
        quint8 *headerBaseAddr = reinterpret_cast<quint8 *>(theHeader);
        for (quint32 idx = 0, end = theHeader->m_entries.size(); idx < end; ++idx) {
            if (inId != 0) {
                Q_ASSERT(inId != theHeader->m_entries.index(headerBaseAddr, idx).m_meshId);
            }
            nextId = qMax(nextId, theHeader->m_entries.index(headerBaseAddr, idx).m_meshId + 1);
        }
        newMeshStartPos = sizeof(MeshMultiHeader) + theHeader->m_entries.size() * sizeof(MeshMultiEntry);
        theWriteHeader = theHeader;
    } else {
        theWriteHeader = &tempHeader;
    }

    // inStream.SetPosition(-newMeshStartPos, SeekPosition::End);
    inStream.seek(inStream.size() - newMeshStartPos); // ### not sure about this one
    qint64 meshOffset = inStream.pos();

    save(inStream);

    if (inId != 0)
        nextId = inId;
    quint8 *theWriteBaseAddr = reinterpret_cast<quint8 *>(theWriteHeader);
    // Now write a new header out.
    int written = inStream.write(reinterpret_cast<char *>(theWriteHeader->m_entries.begin(theWriteBaseAddr)),
                   theWriteHeader->m_entries.size());
    MeshMultiEntry newEntry(static_cast<qint64>(meshOffset), nextId);
    written = inStream.write(reinterpret_cast<char *>(&newEntry), sizeof(MeshMultiEntry));
    theWriteHeader->m_entries.m_size++;
    written = inStream.write(reinterpret_cast<char *>(theWriteHeader), sizeof(MeshMultiHeader));
    (void)written;

    return static_cast<quint32>(nextId);
}

quint32 Mesh::saveMulti(const char *inFilePath) const
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadWrite)) {
        Q_ASSERT(false);
        return (quint32)-1;
    }

    quint32 id = saveMulti(file);
    file.close();
    return id;
}

MultiLoadResult Mesh::loadMulti(QIODevice &inStream, quint32 inId)
{
    MeshMultiHeader *theHeader(loadMultiHeader(inStream));
    if (theHeader == nullptr) {
        return MultiLoadResult();
    }
    quint64 fileOffset = (quint64)-1;
    quint32 theId = inId;
    quint8 *theHeaderBaseAddr = reinterpret_cast<quint8 *>(theHeader);
    bool foundMesh = false;
    for (quint32 idx = 0, end = theHeader->m_entries.size(); idx < end && !foundMesh; ++idx) {
        const MeshMultiEntry &theEntry(theHeader->m_entries.index(theHeaderBaseAddr, idx));
        if (theEntry.m_meshId == inId || (inId == 0 && theEntry.m_meshId > theId)) {
            if (theEntry.m_meshId == inId)
                foundMesh = true;
            theId = qMax(theId, (quint32)theEntry.m_meshId);
            fileOffset = theEntry.m_meshOffset;
        }
    }
    Mesh *retval = nullptr;
    if (fileOffset == (quint64)-1) {
        goto endFunction;
    }

    inStream.seek(static_cast<qint64>(fileOffset));
    retval = load(inStream);
endFunction:
    return MultiLoadResult(retval, theId);
}

MultiLoadResult Mesh::loadMulti(const char *inFilePath, quint32 inId)
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadOnly)) {
        Q_ASSERT(false);
        return MultiLoadResult();
    }

    auto result = loadMulti(file, inId);
    file.close();
    return result;
}

bool Mesh::isMulti(QIODevice &inStream)
{
    MeshMultiHeader theHeader;
    inStream.seek(inStream.size() - ((qint64)(sizeof(MeshMultiHeader))));
    quint32 numBytes = inStream.read(reinterpret_cast<char *>(&theHeader), sizeof(MeshMultiHeader));
    if (numBytes != sizeof(MeshMultiHeader))
        return false;
    return theHeader.m_version == MeshMultiHeader::getMultiStaticVersion();
}

MeshMultiHeader *Mesh::loadMultiHeader(QIODevice &inStream)
{
    MeshMultiHeader theHeader;
    inStream.seek(inStream.size() - ((qint64)sizeof(MeshMultiHeader)));
    quint32 numBytes = inStream.read(reinterpret_cast<char *>(&theHeader), sizeof(MeshMultiHeader));
    if (numBytes != sizeof(MeshMultiHeader) || theHeader.m_fileId != MeshMultiHeader::getMultiStaticFileId()
        || theHeader.m_version > MeshMultiHeader::getMultiStaticVersion()) {
        return nullptr;
    }
    size_t allocSize = sizeof(MeshMultiHeader) + theHeader.m_entries.m_size * sizeof(MeshMultiEntry);
    quint8 *baseAddr = static_cast<quint8 *>(::malloc(allocSize));
    if (baseAddr == nullptr) {
        Q_ASSERT(false);
        return nullptr;
    }
    MeshMultiHeader *retval = new (baseAddr) MeshMultiHeader(theHeader);
    quint8 *entryData = baseAddr + sizeof(MeshMultiHeader);
    retval->m_entries.m_offset = (quint32)(entryData - baseAddr);
    inStream.seek(inStream.size() - ((qint64)allocSize));

    numBytes = inStream.read(reinterpret_cast<char *>(entryData), retval->m_entries.m_size * sizeof(MeshMultiEntry));
    if (numBytes != retval->m_entries.m_size * sizeof(MeshMultiEntry)) {
        Q_ASSERT(false);
        delete retval;
        retval = nullptr;
    }
    return retval;
}

MeshMultiHeader *Mesh::loadMultiHeader(const char *inFilePath)
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadOnly)) {
        Q_ASSERT(false);
        return nullptr;
    }

    auto result = loadMultiHeader(file);
    file.close();
    return result;
}

quint32 GetHighestId(MeshMultiHeader *inHeader)
{
    if (inHeader == nullptr) {
        Q_ASSERT(false);
        return 0;
    }
    quint8 *baseHeaderAddr = reinterpret_cast<quint8 *>(inHeader);
    quint32 highestId = 0;
    for (quint32 idx = 0, end = inHeader->m_entries.size(); idx < end; ++idx)
        highestId = qMax(highestId, inHeader->m_entries.index(baseHeaderAddr, idx).m_meshId);
    return highestId;
}

quint32 Mesh::getHighestMultiVersion(QIODevice &inStream)
{
    return GetHighestId(loadMultiHeader(inStream));
}

quint32 Mesh::getHighestMultiVersion(const char *inFilePath)
{
    QFile file(QString::fromLocal8Bit(inFilePath));
    if (!file.open(QIODevice::ReadOnly)) {
        Q_ASSERT(false);
        return (quint32)-1;
    }

    auto result = getHighestMultiVersion(file);
    file.close();
    return result;
}

namespace {

#if 0
MeshBuilderVBufEntry ToEntry(const QVector<float> &data, const char *name, quint32 numComponents)
{
    return MeshBuilderVBufEntry(name, QByteArray(reinterpret_cast<const char *>(data.data())), QSSGRenderComponentTypes::Float32, numComponents);
}
#endif

struct DynamicVBuf
{
    quint32 m_stride;
    QVector<QSSGRenderVertexBufferEntry> m_vertexBufferEntries;
    QByteArray m_vertexData;

    void clear()
    {
        m_stride = 0;
        m_vertexBufferEntries.clear();
        m_vertexData.clear();
    }
};
struct DynamicIndexBuf
{
    QSSGRenderComponentType m_compType;
    QByteArray m_indexData;
    void clear() { m_indexData.clear(); }
};

struct SubsetDesc
{
    quint32 m_count{ 0 };
    quint32 m_offset{ 0 };

    QSSGBounds3 m_bounds;
    QString m_name;
    SubsetDesc(quint32 c, quint32 off) : m_count(c), m_offset(off) {}
    SubsetDesc() = default;
};

class MeshBuilderImpl : public QSSGMeshBuilder
{
    DynamicVBuf m_vertexBuffer;
    DynamicIndexBuf m_indexBuffer;
    QVector<Joint> m_joints;
    QVector<SubsetDesc> m_meshSubsetDescs;
    QSSGRenderDrawMode m_drawMode;
    QSSGRenderWinding m_winding;
    QByteArray m_newIndexBuffer;
    QVector<quint8> m_meshBuffer;

public:
    MeshBuilderImpl() { reset(); }
    ~MeshBuilderImpl() override { reset(); }
    void release() override { delete this; }
    void reset() override
    {
        m_vertexBuffer.clear();
        m_indexBuffer.clear();
        m_joints.clear();
        m_meshSubsetDescs.clear();
        m_drawMode = QSSGRenderDrawMode::Triangles;
        m_winding = QSSGRenderWinding::CounterClockwise;
        m_meshBuffer.clear();
    }

    void setDrawParameters(QSSGRenderDrawMode drawMode, QSSGRenderWinding winding) override
    {
        m_drawMode = drawMode;
        m_winding = winding;
    }

    // Somewhat burly method to interleave the data as tightly as possible
    // while taking alignment into account.
    bool setVertexBuffer(const QVector<MeshBuilderVBufEntry> &entries) override
    {
        quint32 currentOffset = 0;
        quint32 bufferAlignment = 0;
        quint32 numItems = 0;
        bool retval = true;
        for (quint32 idx = 0, __numItems = (quint32)entries.size(); idx < __numItems; ++idx) {
            const MeshBuilderVBufEntry &entry(entries[idx]);
            // Ignore entries with no data.
            if (entry.m_data.begin() == nullptr || entry.m_data.size() == 0)
                continue;

            quint32 alignment = getSizeOfType(entry.m_componentType);
            bufferAlignment = qMax(bufferAlignment, alignment);
            quint32 byteSize = alignment * entry.m_numComponents;

            if (entry.m_data.size() % alignment != 0) {
                Q_ASSERT(false);
                retval = false;
            }

            quint32 localNumItems = entry.m_data.size() / byteSize;
            if (numItems == 0) {
                numItems = localNumItems;
            } else if (numItems != localNumItems) {
                Q_ASSERT(false);
                retval = false;
                numItems = qMin(numItems, localNumItems);
            }
            // Lots of platforms can't handle non-aligned data.
            // so ensure we are aligned.
            currentOffset = getAlignedOffset(currentOffset, alignment);
            QSSGRenderVertexBufferEntry vbufEntry(entry.m_name, entry.m_componentType, entry.m_numComponents, currentOffset);
            m_vertexBuffer.m_vertexBufferEntries.push_back(vbufEntry);
            currentOffset += byteSize;
        }
        m_vertexBuffer.m_stride = getAlignedOffset(currentOffset, bufferAlignment);

        // Packed interleave the data
        for (quint32 idx = 0; idx < numItems; ++idx) {
            quint32 dataOffset = 0;
            for (qint32 entryIdx = 0; entryIdx < entries.size(); ++entryIdx) {
                const MeshBuilderVBufEntry &entry(entries[entryIdx]);
                // Ignore entries with no data.
                if (entry.m_data.begin() == nullptr || entry.m_data.size() == 0)
                    continue;

                quint32 alignment = (quint32)getSizeOfType(entry.m_componentType);
                quint32 byteSize = alignment * entry.m_numComponents;
                quint32 offset = byteSize * idx;
                quint32 newOffset = getAlignedOffset(dataOffset, alignment);
                QBuffer vertexDataBuffer(&m_vertexBuffer.m_vertexData);
                vertexDataBuffer.open(QIODevice::WriteOnly | QIODevice::Append);
                if (newOffset != dataOffset) {
                    QByteArray filler(newOffset - dataOffset, '\0');
                    vertexDataBuffer.write(filler);
                }
                vertexDataBuffer.write(entry.m_data.begin() + offset, byteSize);
                vertexDataBuffer.close();
                dataOffset = newOffset + byteSize;
            }
            Q_ASSERT(dataOffset == m_vertexBuffer.m_stride);
        }
        return retval;
    }

    void setVertexBuffer(const QVector<QSSGRenderVertexBufferEntry> &entries, quint32 stride, QByteArray data) override
    {
        for (quint32 idx = 0, __numItems = (quint32)entries.size(); idx < __numItems; ++idx) {
            m_vertexBuffer.m_vertexBufferEntries.push_back(entries[idx]);
        }
        QBuffer vertexDataBuffer(&m_vertexBuffer.m_vertexData);
        vertexDataBuffer.open(QIODevice::WriteOnly);
        vertexDataBuffer.write(data);
        vertexDataBuffer.close();
        if (stride == 0) {
            // Calculate the stride of the buffer using the vbuf entries
            for (quint32 idx = 0, __numItems = (quint32)entries.size(); idx < __numItems; ++idx) {
                const QSSGRenderVertexBufferEntry &entry(entries[idx]);
                stride = qMax(stride,
                              (quint32)(entry.m_firstItemOffset
                                        + (entry.m_numComponents * getSizeOfType(entry.m_componentType))));
            }
        }
        m_vertexBuffer.m_stride = stride;
    }

    void setIndexBuffer(const QByteArray &data, QSSGRenderComponentType comp) override
    {
        m_indexBuffer.m_compType = comp;
        QBuffer indexBuffer(&m_indexBuffer.m_indexData);
        indexBuffer.open(QIODevice::WriteOnly);
        indexBuffer.write(data);
        indexBuffer.close();
    }

    void addJoint(qint32 jointID, qint32 parentID, const float *invBindPose, const float *localToGlobalBoneSpace) override
    {
        m_joints.push_back(Joint(jointID, parentID, invBindPose, localToGlobalBoneSpace));
    }

    SubsetDesc createSubset(const char16_t *inName, quint32 count, quint32 offset)
    {
        if (inName == nullptr)
            inName = u"";
        SubsetDesc retval(count, offset);
        retval.m_name = QString::fromUtf16(inName);
        return retval;
    }

    // indexBuffer std::numeric_limits<quint32>::max() means no index buffer.
    // count of std::numeric_limits<quint32>::max() means use all available items.
    // offset means exactly what you would think.  Offset is in item size, not bytes.
    void addMeshSubset(const char16_t *inName, quint32 count, quint32 offset, quint32 boundsPositionEntryIndex) override
    {
        SubsetDesc retval = createSubset(inName, count, offset);
        if (boundsPositionEntryIndex != std::numeric_limits<quint32>::max()) {
            retval.m_bounds = Mesh::calculateSubsetBounds(m_vertexBuffer.m_vertexBufferEntries[boundsPositionEntryIndex],
                                                          m_vertexBuffer.m_vertexData,
                                                          m_vertexBuffer.m_stride,
                                                          m_indexBuffer.m_indexData,
                                                          m_indexBuffer.m_compType,
                                                          count,
                                                          offset);
        }
        m_meshSubsetDescs.push_back(retval);
    }

    void addMeshSubset(const char16_t *inName, quint32 count, quint32 offset, const QSSGBounds3 &inBounds) override
    {
        SubsetDesc retval = createSubset(inName, count, offset);
        retval.m_bounds = inBounds;
        m_meshSubsetDescs.push_back(retval);
    }

    // We connect sub meshes which habe the same material
    void connectSubMeshes() override
    {
        if (m_meshSubsetDescs.size() < 2) {
            // nothing to do
            return;
        }

        quint32 matDuplicates = 0;

        // as a pre-step we check if we have duplicate material at all
        for (quint32 i = 0, subsetEnd = m_meshSubsetDescs.size(); i < subsetEnd && !matDuplicates; ++i) {
            SubsetDesc &currentSubset = m_meshSubsetDescs[i];

            for (quint32 j = 0, subsetEnd = m_meshSubsetDescs.size(); j < subsetEnd; ++j) {
                SubsetDesc &theSubset = m_meshSubsetDescs[j];

                if (i == j)
                    continue;

                if (currentSubset.m_name == theSubset.m_name) {
                    matDuplicates++;
                    break; // found a duplicate bail out
                }
            }
        }

        // did we find some duplicates?
        if (matDuplicates) {
            QVector<SubsetDesc> newMeshSubsetDescs;
            QVector<SubsetDesc>::iterator theIter;
            QString curMatName;
            m_newIndexBuffer.clear();

            for (theIter = m_meshSubsetDescs.begin(); theIter != m_meshSubsetDescs.end(); ++theIter) {
                bool bProcessed = false;

                for (QVector<SubsetDesc>::iterator iter = newMeshSubsetDescs.begin(); iter != newMeshSubsetDescs.end(); ++iter) {
                    if (theIter->m_name == iter->m_name) {
                        bProcessed = true;
                        break;
                    }
                }

                if (bProcessed)
                    continue;

                curMatName = theIter->m_name;

                quint32 theIndexCompSize = (quint32)getSizeOfType(m_indexBuffer.m_compType);
                // get pointer to indices
                char *theIndices = (m_indexBuffer.m_indexData.begin()) + (theIter->m_offset * theIndexCompSize);
                // write new offset
                theIter->m_offset = m_newIndexBuffer.size() / theIndexCompSize;
                // store indices
                QBuffer newIndexBuffer(&m_newIndexBuffer);
                newIndexBuffer.open(QIODevice::WriteOnly);
                newIndexBuffer.write(theIndices, theIter->m_count * theIndexCompSize);

                for (int j = 0, subsetEnd = m_meshSubsetDescs.size(); j < subsetEnd; ++j) {
                    if (theIter == &m_meshSubsetDescs[j])
                        continue;

                    SubsetDesc &theSubset = m_meshSubsetDescs[j];

                    if (curMatName == theSubset.m_name) {
                        // get pointer to indices
                        char *theIndices = (m_indexBuffer.m_indexData.data()) + (theSubset.m_offset * theIndexCompSize);
                        // store indices
                        newIndexBuffer.write(theIndices, theSubset.m_count * theIndexCompSize);
                        // increment indices count
                        theIter->m_count += theSubset.m_count;
                    }
                    newIndexBuffer.close();
                }

                newMeshSubsetDescs.push_back(*theIter);
            }

            m_meshSubsetDescs.clear();
            m_meshSubsetDescs = newMeshSubsetDescs;
            m_indexBuffer.m_indexData.clear();
            QBuffer indexBuffer(&m_indexBuffer.m_indexData);
            indexBuffer.open(QIODevice::WriteOnly);
            indexBuffer.write(m_newIndexBuffer);
            indexBuffer.close();
            // compute new bounding box
            for (theIter = m_meshSubsetDescs.begin(); theIter != m_meshSubsetDescs.end(); ++theIter) {
                theIter->m_bounds = Mesh::calculateSubsetBounds(m_vertexBuffer.m_vertexBufferEntries[0],
                                                                m_vertexBuffer.m_vertexData,
                                                                m_vertexBuffer.m_stride,
                                                                m_indexBuffer.m_indexData,
                                                                m_indexBuffer.m_compType,
                                                                theIter->m_count,
                                                                theIter->m_offset);
            }
        }
    }

    // Here is the NVTriStrip magic.
    void optimizeMesh() override
    {
        if (getSizeOfType(m_indexBuffer.m_compType) != 2) {
            // we currently re-arrange unsigned int indices.
            // this is because NvTriStrip only supports short indices
            Q_ASSERT(getSizeOfType(m_indexBuffer.m_compType) == 4);
            return;
        }
    }

    template<typename TDataType>
    static void assign(quint8 *inBaseAddress, quint8 *inDataAddress, OffsetDataRef<TDataType> &inBuffer, const QByteArray &inDestData)
    {
        inBuffer.m_offset = (quint32)(inDataAddress - inBaseAddress);
        inBuffer.m_size = inDestData.size();
        memcpy(inDataAddress, inDestData.data(), inDestData.size());
    }
    template<typename TDataType>
    static void assign(quint8 *inBaseAddress, quint8 *inDataAddress, OffsetDataRef<TDataType> &inBuffer, const QVector<TDataType> &inDestData)
    {
        inBuffer.m_offset = (quint32)(inDataAddress - inBaseAddress);
        inBuffer.m_size = inDestData.size();
        memcpy(inDataAddress, inDestData.data(), inDestData.size());
    }
    template<typename TDataType>
    static void assign(quint8 *inBaseAddress, quint8 *inDataAddress, OffsetDataRef<TDataType> &inBuffer, quint32 inDestSize)
    {
        inBuffer.m_offset = (quint32)(inDataAddress - inBaseAddress);
        inBuffer.m_size = inDestSize;
    }
    // Return the current mesh.  This is only good for this function call, item may change or be
    // released
    // due to any further function calls.
    Mesh &getMesh() override
    {
        quint32 meshSize = sizeof(Mesh);
        quint32 alignment = sizeof(void *);
        quint32 vertDataSize = getAlignedOffset(m_vertexBuffer.m_vertexData.size(), alignment);
        meshSize += vertDataSize;
        quint32 entrySize = m_vertexBuffer.m_vertexBufferEntries.size() * sizeof(QSSGRenderVertexBufferEntry);
        meshSize += entrySize;
        quint32 entryNameSize = 0;
        for (quint32 idx = 0, end = m_vertexBuffer.m_vertexBufferEntries.size(); idx < end; ++idx) {
            const QSSGRenderVertexBufferEntry &theEntry(m_vertexBuffer.m_vertexBufferEntries[idx]);
            const char *entryName = theEntry.m_name;
            if (entryName == nullptr)
                entryName = "";
            entryNameSize += (quint32)(strlen(theEntry.m_name)) + 1;
        }
        entryNameSize = getAlignedOffset(entryNameSize, alignment);
        meshSize += entryNameSize;
        quint32 indexBufferSize = getAlignedOffset(m_indexBuffer.m_indexData.size(), alignment);
        meshSize += indexBufferSize;
        quint32 subsetSize = m_meshSubsetDescs.size() * sizeof(MeshSubset);
        quint32 nameSize = 0;
        for (quint32 idx = 0, end = m_meshSubsetDescs.size(); idx < end; ++idx) {
            if (!m_meshSubsetDescs[idx].m_name.isEmpty())
                nameSize += m_meshSubsetDescs[idx].m_name.size() + 1;
        }
        nameSize *= sizeof(char16_t);
        nameSize = getAlignedOffset(nameSize, alignment);

        meshSize += subsetSize + nameSize;
        quint32 jointsSize = m_joints.size() * sizeof(Joint);
        meshSize += jointsSize;
        m_meshBuffer.resize(meshSize);
        quint8 *baseAddress = m_meshBuffer.data();
        Mesh *retval = reinterpret_cast<Mesh *>(baseAddress);
        retval->m_drawMode = m_drawMode;
        retval->m_winding = m_winding;
        quint8 *vertBufferData = baseAddress + sizeof(Mesh);
        quint8 *vertEntryData = vertBufferData + vertDataSize;
        quint8 *vertEntryNameData = vertEntryData + entrySize;
        quint8 *indexBufferData = vertEntryNameData + entryNameSize;
        quint8 *subsetBufferData = indexBufferData + indexBufferSize;
        quint8 *nameBufferData = subsetBufferData + subsetSize;
        quint8 *jointBufferData = nameBufferData + nameSize;

        retval->m_vertexBuffer.m_stride = m_vertexBuffer.m_stride;
        assign(baseAddress, vertBufferData, retval->m_vertexBuffer.m_data, m_vertexBuffer.m_vertexData);
        retval->m_vertexBuffer.m_entries.m_size = m_vertexBuffer.m_vertexBufferEntries.size();
        retval->m_vertexBuffer.m_entries.m_offset = (quint32)(vertEntryData - baseAddress);
        for (quint32 idx = 0, end = m_vertexBuffer.m_vertexBufferEntries.size(); idx < end; ++idx) {
            const QSSGRenderVertexBufferEntry &theEntry(m_vertexBuffer.m_vertexBufferEntries[idx]);
            MeshVertexBufferEntry &theDestEntry(retval->m_vertexBuffer.m_entries.index(baseAddress, idx));
            theDestEntry.m_componentType = theEntry.m_componentType;
            theDestEntry.m_firstItemOffset = theEntry.m_firstItemOffset;
            theDestEntry.m_numComponents = theEntry.m_numComponents;
            const char *targetName = theEntry.m_name;
            if (targetName == nullptr)
                targetName = "";

            quint32 entryNameLen = (quint32)(strlen(targetName)) + 1;
            theDestEntry.m_nameOffset = (quint32)(vertEntryNameData - baseAddress);
            memcpy(vertEntryNameData, theEntry.m_name, entryNameLen);
            vertEntryNameData += entryNameLen;
        }

        retval->m_indexBuffer.m_componentType = m_indexBuffer.m_compType;
        assign(baseAddress, indexBufferData, retval->m_indexBuffer.m_data, m_indexBuffer.m_indexData);
        assign(baseAddress, subsetBufferData, retval->m_subsets, m_meshSubsetDescs.size());
        for (quint32 idx = 0, end = m_meshSubsetDescs.size(); idx < end; ++idx) {
            SubsetDesc &theDesc = m_meshSubsetDescs[idx];
            MeshSubset &theSubset = reinterpret_cast<MeshSubset *>(subsetBufferData)[idx];
            theSubset.m_bounds = theDesc.m_bounds;
            theSubset.m_count = theDesc.m_count;
            theSubset.m_offset = theDesc.m_offset;
            if (!theDesc.m_name.isEmpty()) {
                theSubset.m_name.m_size = theDesc.m_name.size() + 1;
                theSubset.m_name.m_offset = (quint32)(nameBufferData - baseAddress);
                std::transform(theDesc.m_name.begin(),
                               theDesc.m_name.end(),
                               reinterpret_cast<char16_t *>(nameBufferData),
                               [](QChar c) { return static_cast<char16_t>(c.unicode()); });
                reinterpret_cast<char16_t *>(nameBufferData)[theDesc.m_name.size()] = 0;
                nameBufferData += (theDesc.m_name.size() + 1) * sizeof(char16_t);
            } else {
                theSubset.m_name.m_size = 0;
                theSubset.m_name.m_offset = 0;
            }
        }
        assign(baseAddress, jointBufferData, retval->m_joints, m_joints);
        return *retval;
    }

    Mesh *buildMesh(const MeshData &meshData, QString &error, const QSSGBounds3 &inBounds) override
    {
        // Do some basic validation of the meshData
        if (meshData.m_vertexBuffer.size() == 0) {
            error = QObject::tr("Vertex buffer empty");
            return nullptr;
        }
        if (meshData.m_attributeCount == 0) {
            error = QObject::tr("No attributes defined");
            return nullptr;
        }

        reset();
        setDrawParameters(static_cast<QSSGRenderDrawMode>(meshData.m_primitiveType),
                          QSSGRenderWinding::CounterClockwise);

        // The expectation is that the vertex buffer included in meshData is already properly
        // formatted and doesn't need further processing.

        // Validate attributes
        QVector<QSSGRenderVertexBufferEntry> vBufEntries;
        QSSGRenderComponentType indexBufferComponentType = QSSGRenderComponentType::Unknown;
        int indexBufferTypeSize = 0;
        for (int i = 0; i < meshData.m_attributeCount; ++i) {
            const MeshData::Attribute &att = meshData.m_attributes[i];
            auto componentType = static_cast<QSSGRenderComponentType>(att.componentType);
            if (att.semantic == MeshData::Attribute::IndexSemantic) {
                indexBufferComponentType = componentType;
                indexBufferTypeSize = att.typeSize();
            } else {
                const char *name = nullptr;
                switch (att.semantic) {
                case MeshData::Attribute::PositionSemantic:
                    name = Mesh::getPositionAttrName();
                    break;
                case MeshData::Attribute::NormalSemantic:
                    name = Mesh::getNormalAttrName();
                    break;
                case MeshData::Attribute::TexCoordSemantic:
                    name = Mesh::getUVAttrName();
                    break;
                case MeshData::Attribute::TangentSemantic:
                    name = Mesh::getTexTanAttrName();
                    break;
                case MeshData::Attribute::BinormalSemantic:
                    name = Mesh::getTexBinormalAttrName();
                    break;
                default:
                    error = QObject::tr("Warning: Invalid attribute semantic: %1")
                            .arg(att.semantic);
                    return nullptr;
                }
                vBufEntries << QSSGRenderVertexBufferEntry(name, componentType,
                                                           unsigned(att.componentCount()),
                                                           unsigned(att.offset));
            }
        }
        setVertexBuffer(vBufEntries, unsigned(meshData.m_stride), meshData.m_vertexBuffer);

        int vertexCount = 0;
        if (indexBufferComponentType != QSSGRenderComponentType::Unknown) {
            setIndexBuffer(meshData.m_indexBuffer, indexBufferComponentType);
            vertexCount = meshData.m_indexBuffer.size() / indexBufferTypeSize;
        } else {
            vertexCount = meshData.m_vertexBuffer.size() / meshData.m_stride;
        }

        addMeshSubset(Mesh::m_defaultName, unsigned(vertexCount), 0, inBounds);

        return &getMesh();
    }
};
}

QSSGMeshBuilder::~QSSGMeshBuilder() = default;

QSSGRef<QSSGMeshBuilder> QSSGMeshBuilder::createMeshBuilder()
{
    return QSSGRef<QSSGMeshBuilder>(new MeshBuilderImpl());
}
}

QT_END_NAMESPACE
