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