Beispiel #1
0
QGeometry *ObjLoader::geometry() const
{
    QByteArray bufferBytes;
    const int count = m_points.size();
    const quint32 elementSize = 3 + (hasTextureCoordinates() ? 2 : 0)
            + (hasNormals() ? 3 : 0)
            + (hasTangents() ? 4 : 0);
    const quint32 stride = elementSize * sizeof(float);
    bufferBytes.resize(stride * count);
    float* fptr = reinterpret_cast<float*>(bufferBytes.data());

    for (int index = 0; index < count; ++index) {
        *fptr++ = m_points.at(index).x();
        *fptr++ = m_points.at(index).y();
        *fptr++ = m_points.at(index).z();

        if (hasTextureCoordinates()) {
            *fptr++ = m_texCoords.at(index).x();
            *fptr++ = m_texCoords.at(index).y();
        }

        if (hasNormals()) {
            *fptr++ = m_normals.at(index).x();
            *fptr++ = m_normals.at(index).y();
            *fptr++ = m_normals.at(index).z();
        }

        if (hasTangents()) {
            *fptr++ = m_tangents.at(index).x();
            *fptr++ = m_tangents.at(index).y();
            *fptr++ = m_tangents.at(index).z();
            *fptr++ = m_tangents.at(index).w();
        }
    } // of buffer filling loop

    QBuffer *buf(new QBuffer(QBuffer::VertexBuffer));
    buf->setData(bufferBytes);

    QGeometry *geometry = new QGeometry();
    QAttribute *positionAttribute = new QAttribute(buf, QAttribute::defaultPositionAttributeName(), QAttribute::Float, 3, count, 0, stride);
    geometry->addAttribute(positionAttribute);
    quint32 offset = sizeof(float) * 3;

    if (hasTextureCoordinates()) {
        QAttribute *texCoordAttribute = new QAttribute(buf, QAttribute::defaultTextureCoordinateAttributeName(),  QAttribute::Float, 2, count, offset, stride);
        geometry->addAttribute(texCoordAttribute);
        offset += sizeof(float) * 2;
    }

    if (hasNormals()) {
        QAttribute *normalAttribute = new QAttribute(buf, QAttribute::defaultNormalAttributeName(), QAttribute::Float, 3, count, offset, stride);
        geometry->addAttribute(normalAttribute);
        offset += sizeof(float) * 3;
    }

    if (hasTangents()) {
        QAttribute *tangentAttribute = new QAttribute(buf, QAttribute::defaultTangentAttributeName(),QAttribute::Float, 4, count, offset, stride);
        geometry->addAttribute(tangentAttribute);
        offset += sizeof(float) * 4;
    }

    QByteArray indexBytes;
    QAttribute::DataType ty;
    if (m_indices.size() < 65536) {
        // we can use USHORT
        ty = QAttribute::UnsignedShort;
        indexBytes.resize(m_indices.size() * sizeof(quint16));
        quint16* usptr = reinterpret_cast<quint16*>(indexBytes.data());
        for (int i=0; i<m_indices.size(); ++i)
            *usptr++ = static_cast<quint16>(m_indices.at(i));
    } else {
        // use UINT - no conversion needed, but let's ensure int is 32-bit!
        ty = QAttribute::UnsignedInt;
        Q_ASSERT(sizeof(int) == sizeof(quint32));
        indexBytes.resize(m_indices.size() * sizeof(quint32));
        memcpy(indexBytes.data(), reinterpret_cast<const char*>(m_indices.data()), indexBytes.size());
    }

    QBuffer *indexBuffer(new QBuffer(QBuffer::IndexBuffer));
    indexBuffer->setData(indexBytes);
    QAttribute *indexAttribute = new QAttribute(indexBuffer, ty, 1, m_indices.size());
    indexAttribute->setAttributeType(QAttribute::IndexAttribute);
    geometry->addAttribute(indexAttribute);

    return geometry;
}
void GpuInterpolationItem::initData(const MNELIB::MNEBemSurface &tMneBemSurface,
                                   QSharedPointer<SparseMatrix<double> > tInterpolationMatrix)
{
    if(m_bIsDataInit == true)
    {
       qDebug("GpuInterpolationItem::initData data already initialized");
       return;
    }

    m_pMaterial->setWeightMatrix(tInterpolationMatrix);

    //Create draw entity if needed
    if(!m_pMeshDrawEntity)
    {
        m_pMeshDrawEntity = new QEntity(this);

        m_pCustomMesh = new CustomMesh;

        //Interpolated signal attribute
        QAttribute *pInterpolatedSignalAttrib = new QAttribute;
        pInterpolatedSignalAttrib->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
        pInterpolatedSignalAttrib->setDataType(Qt3DRender::QAttribute::Float);
        pInterpolatedSignalAttrib->setVertexSize(4);
        pInterpolatedSignalAttrib->setByteOffset(0);
        pInterpolatedSignalAttrib->setByteStride(4 * sizeof(float));
        pInterpolatedSignalAttrib->setName(QStringLiteral("OutputColor"));
        pInterpolatedSignalAttrib->setBuffer(m_pMaterial->getOutputColorBuffer());

        //add interpolated signal Attribute
        m_pCustomMesh->addAttribute(pInterpolatedSignalAttrib);

        m_pMeshDrawEntity->addComponent(m_pCustomMesh);

        m_pMeshDrawEntity->addComponent(m_pMaterial);
    }

    //Create compute entity if needed
    if(!m_pComputeEntity)
    {
        m_pComputeEntity = new QEntity(this);

        m_pComputeCommand = new QComputeCommand;
        m_pComputeEntity->addComponent(m_pComputeCommand);

        m_pComputeEntity->addComponent(m_pMaterial);
    }

    const uint iWeightMatRows = tMneBemSurface.rr.rows();

    //Set work group size
    const uint iWorkGroupsSize = static_cast<uint>(std::ceil(std::sqrt(iWeightMatRows)));

    m_pComputeCommand->setWorkGroupX(iWorkGroupsSize);
    m_pComputeCommand->setWorkGroupY(iWorkGroupsSize);
    m_pComputeCommand->setWorkGroupZ(1);

    //Set custom mesh data
    //generate mesh base color
    QColor baseColor = QColor(80, 80, 80, 255);
    MatrixX3f matVertColor(tMneBemSurface.rr.rows(),3);

    for(int i = 0; i < matVertColor.rows(); ++i) {
        matVertColor(i,0) = baseColor.redF();
        matVertColor(i,1) = baseColor.greenF();
        matVertColor(i,2) = baseColor.blueF();
    }

    //Set renderable 3D entity mesh and color data
    m_pCustomMesh->setMeshData(tMneBemSurface.rr,
                                tMneBemSurface.nn,
                                tMneBemSurface.tris,
                                matVertColor,
                                Qt3DRender::QGeometryRenderer::Triangles);

    m_bIsDataInit = true;
}