Fix picking with primitive restart

Task-number: QTBUG-71919
Change-Id: If7923fab6c43f5d7139d1bbdceb73c17bf489099
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
Mike Krus 2019-12-07 13:03:58 +00:00
parent 3019497559
commit 69789d0184
5 changed files with 42 additions and 8 deletions

View File

@ -74,6 +74,8 @@ struct BufferInfo
, count(0)
, byteStride(0)
, byteOffset(0)
, restartEnabled(false)
, restartIndexValue(-1)
{}
QByteArray data;
@ -82,6 +84,8 @@ struct BufferInfo
uint count;
uint byteStride;
uint byteOffset;
bool restartEnabled;
int restartIndexValue;
};

View File

@ -140,13 +140,18 @@ void traverseSegmentStripIndexed(Index *indices,
uint ndx[2];
Vector3D abc[2];
ndx[0] = indices[0];
startLinePrimitive:ndx[0] = indices[i];
uint idx = ndx[0] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[0][j] = vertices[idx + j];
while (i < indexInfo.count - 1) {
ndx[1] = indices[i + 1];
if (ndx[0] != ndx[1]) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(ndx[1])) {
i += 2;
goto startLinePrimitive;
}
idx = ndx[1] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[1][j] = vertices[idx + j];

View File

@ -153,6 +153,10 @@ void traverseTriangleStripIndexed(index *indices,
uint ndx[3];
Vector3D abc[3];
while (i < indexInfo.count - 2) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 2])) {
i += 3;
continue;
}
bool degenerate = false;
for (uint u = 0; u < 3; ++u) {
ndx[u] = indices[i + u];
@ -216,6 +220,11 @@ void traverseTriangleFanIndexed(index *indices,
ndx[0] = indices[0];
uint i = 1;
while (i < indexInfo.count - 1) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i + 1])) {
ndx[0] = indices[i + 2];
i += 3;
continue;
}
for (uint u = 0; u < 2; ++u) {
ndx[u + 1] = indices[i + u];
uint idx = ndx[u + 1] * verticesStride;
@ -224,7 +233,7 @@ void traverseTriangleFanIndexed(index *indices,
}
}
visitor->visit(ndx[2], abc[2], ndx[1], abc[1], ndx[0], abc[0]);
i += 1;
++i;
}
}

View File

@ -149,6 +149,8 @@ void visitPrimitives(NodeManagers *manager, const GeometryRenderer *renderer, Vi
indexBufferInfo.byteOffset = indexAttribute->byteOffset();
indexBufferInfo.byteStride = indexAttribute->byteStride();
indexBufferInfo.count = indexAttribute->count();
indexBufferInfo.restartEnabled = renderer->primitiveRestartEnabled();
indexBufferInfo.restartIndexValue = renderer->restartIndexValue();
IndexExecutor executor;
executor.m_vertexBufferInfo = vertexBufferInfo;

View File

@ -454,7 +454,7 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 3 * 4);
indexData.resize(sizeof(uint) * 4 * 4);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
@ -468,6 +468,10 @@ private Q_SLOTS:
iDataPtr[9] = 4;
iDataPtr[10] = 3;
iDataPtr[11] = 2;
iDataPtr[12] = static_cast<uint>(-1);
iDataPtr[13] = 0;
iDataPtr[14] = 1;
iDataPtr[15] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -486,7 +490,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*4);
indexAttribute->setCount(4*4);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -494,6 +498,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleStrip);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -516,7 +522,7 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QVERIFY(visitor.triangleCount() == 8);
QCOMPARE(visitor.triangleCount(), 9U);
QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(1, 3,2,1, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(2, 4,3,2, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,1,0)));
@ -525,6 +531,7 @@ private Q_SLOTS:
QVERIFY(visitor.verifyTriangle(5, 4,0,1, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(6, 3,4,0, Vector3D(0,0,1), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(7, 2,3,4, Vector3D(0,1,0), Vector3D(0,0,1), Vector3D(1,0,0)));
QVERIFY(visitor.verifyTriangle(8, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTriangleFan()
@ -643,7 +650,7 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 3 * 2);
indexData.resize(sizeof(uint) * 10);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
@ -651,6 +658,10 @@ private Q_SLOTS:
iDataPtr[3] = 3;
iDataPtr[4] = 4;
iDataPtr[5] = 5;
iDataPtr[6] = static_cast<uint>(-1);
iDataPtr[7] = 0;
iDataPtr[8] = 1;
iDataPtr[9] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -669,7 +680,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(3*2);
indexAttribute->setCount(10);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -677,6 +688,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::TriangleFan);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -699,11 +712,12 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QVERIFY(visitor.triangleCount() == 4);
QCOMPARE(visitor.triangleCount(), 5U);
QVERIFY(visitor.verifyTriangle(0, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(1, 3,2,0, Vector3D(0,0,1), Vector3D(0,1,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(2, 4,3,0, Vector3D(1,0,0), Vector3D(0,0,1), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(3, 5,4,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
QVERIFY(visitor.verifyTriangle(4, 2,1,0, Vector3D(0,1,0), Vector3D(1,0,0), Vector3D(0,0,1)));
}
void testVisitTrianglesAdjacency()