Fix picking with primitive restart for line loops

Previous fix was not closing the loop on every primitive,
just the last one.

Task-number: QTBUG-71919
Change-Id: I22d52258477b0c4777118ee36a0b3868da982885
Reviewed-by: Volker Enderlein <volker.enderlein@ifm-chemnitz.de>
Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
This commit is contained in:
Mike Krus 2019-12-09 15:10:53 +00:00
parent cfaa43c554
commit ecd193d7b5
2 changed files with 52 additions and 32 deletions

View File

@ -135,39 +135,44 @@ void traverseSegmentStripIndexed(Index *indices,
bool loop)
{
uint i = 0;
uint stripStartIndex = 0;
const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2];
Vector3D abc[2];
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];
visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
while (i < indexInfo.count) {
if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i])) {
++i;
continue;
}
stripStartIndex = i;
ndx[0] = indices[stripStartIndex];
uint idx = ndx[0] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[0][j] = vertices[idx + j];
++i;
ndx[0] = ndx[1];
abc[0] = abc[1];
}
if (loop) {
ndx[1] = indices[0];
if (ndx[0] != ndx[1]) {
idx = ndx[1] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[1][j] = vertices[idx + j];
visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
while (i < indexInfo.count && (!indexInfo.restartEnabled || indexInfo.restartIndexValue != static_cast<int>(indices[i]))) {
ndx[1] = indices[i];
if (ndx[0] != ndx[1]) {
idx = ndx[1] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[1][j] = vertices[idx + j];
visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
}
++i;
ndx[0] = ndx[1];
abc[0] = abc[1];
}
if (loop) {
ndx[1] = indices[stripStartIndex];
if (ndx[0] != ndx[1]) {
idx = ndx[1] * verticesStride;
for (uint j = 0; j < maxVerticesDataSize; ++j)
abc[1][j] = vertices[idx + j];
visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
}
}
}
}

View File

@ -426,12 +426,15 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 2 * 4);
indexData.resize(sizeof(uint) * 7);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
iDataPtr[2] = 2;
iDataPtr[3] = 3;
iDataPtr[4] = static_cast<uint>(-1);
iDataPtr[5] = 0;
iDataPtr[6] = 1;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -450,7 +453,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(4);
indexAttribute->setCount(7);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -458,6 +461,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -480,10 +485,11 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QCOMPARE(visitor.segmentCount(), uint(3));
QCOMPARE(visitor.segmentCount(), uint(4));
QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
QVERIFY(visitor.verifySegment(3, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
}
void testVisitLineLoop()
@ -588,12 +594,16 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData;
indexData.resize(sizeof(uint) * 2 * 4);
indexData.resize(sizeof(uint) * 8);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0;
iDataPtr[1] = 1;
iDataPtr[2] = 2;
iDataPtr[3] = 3;
iDataPtr[4] = static_cast<uint>(-1);
iDataPtr[5] = 0;
iDataPtr[6] = 1;
iDataPtr[7] = 2;
indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -612,7 +622,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(4);
indexAttribute->setCount(8);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data());
@ -620,6 +630,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer);
@ -642,11 +654,14 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN
QCOMPARE(visitor.segmentCount(), uint(4));
QCOMPARE(visitor.segmentCount(), uint(7));
QVERIFY(visitor.verifySegment(0, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifySegment(1, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
QVERIFY(visitor.verifySegment(2, 2,3, Vector3D(1,1,0), Vector3D(0,1,0)));
QVERIFY(visitor.verifySegment(3, 3,0, Vector3D(0,1,0), Vector3D(0,0,0)));
QVERIFY(visitor.verifySegment(4, 0,1, Vector3D(0,0,0), Vector3D(1,0,0)));
QVERIFY(visitor.verifySegment(5, 1,2, Vector3D(1,0,0), Vector3D(1,1,0)));
QVERIFY(visitor.verifySegment(6, 2,0, Vector3D(1,1,0), Vector3D(0,0,0)));
}
void testVisitLineAdjacency()