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) bool loop)
{ {
uint i = 0; uint i = 0;
uint stripStartIndex = 0;
const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex); const uint verticesStride = vertexInfo.byteStride / sizeof(Vertex);
const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U); const uint maxVerticesDataSize = qMin(vertexInfo.dataSize, 3U);
uint ndx[2]; uint ndx[2];
Vector3D abc[2]; Vector3D abc[2];
while (i < indexInfo.count) {
startLinePrimitive:ndx[0] = indices[i]; if (indexInfo.restartEnabled && indexInfo.restartIndexValue == static_cast<int>(indices[i])) {
uint idx = ndx[0] * verticesStride; ++i;
for (uint j = 0; j < maxVerticesDataSize; ++j) continue;
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]);
} }
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; ++i;
ndx[0] = ndx[1]; while (i < indexInfo.count && (!indexInfo.restartEnabled || indexInfo.restartIndexValue != static_cast<int>(indices[i]))) {
abc[0] = abc[1]; ndx[1] = indices[i];
} if (ndx[0] != ndx[1]) {
if (loop) { idx = ndx[1] * verticesStride;
ndx[1] = indices[0]; for (uint j = 0; j < maxVerticesDataSize; ++j)
if (ndx[0] != ndx[1]) { abc[1][j] = vertices[idx + j];
idx = ndx[1] * verticesStride; visitor->visit(ndx[0], abc[0], ndx[1], abc[1]);
for (uint j = 0; j < maxVerticesDataSize; ++j) }
abc[1][j] = vertices[idx + j]; ++i;
visitor->visit(ndx[0], abc[0], ndx[1], abc[1]); 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); simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData; QByteArray indexData;
indexData.resize(sizeof(uint) * 2 * 4); indexData.resize(sizeof(uint) * 7);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0; iDataPtr[0] = 0;
iDataPtr[1] = 1; iDataPtr[1] = 1;
iDataPtr[2] = 2; iDataPtr[2] = 2;
iDataPtr[3] = 3; iDataPtr[3] = 3;
iDataPtr[4] = static_cast<uint>(-1);
iDataPtr[5] = 0;
iDataPtr[6] = 1;
indexDataBuffer->setData(indexData); indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -450,7 +453,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(4); indexAttribute->setCount(7);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data()); geometry->addAttribute(positionAttribute.data());
@ -458,6 +461,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry); geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineStrip);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer); backendAttribute->setRenderer(&renderer);
@ -480,10 +485,11 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId()); visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN // 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(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(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(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() void testVisitLineLoop()
@ -588,12 +594,16 @@ private Q_SLOTS:
simulateInitializationSync(dataBuffer.data(), backendBuffer); simulateInitializationSync(dataBuffer.data(), backendBuffer);
QByteArray indexData; QByteArray indexData;
indexData.resize(sizeof(uint) * 2 * 4); indexData.resize(sizeof(uint) * 8);
uint *iDataPtr = reinterpret_cast<uint *>(indexData.data()); uint *iDataPtr = reinterpret_cast<uint *>(indexData.data());
iDataPtr[0] = 0; iDataPtr[0] = 0;
iDataPtr[1] = 1; iDataPtr[1] = 1;
iDataPtr[2] = 2; iDataPtr[2] = 2;
iDataPtr[3] = 3; iDataPtr[3] = 3;
iDataPtr[4] = static_cast<uint>(-1);
iDataPtr[5] = 0;
iDataPtr[6] = 1;
iDataPtr[7] = 2;
indexDataBuffer->setData(indexData); indexDataBuffer->setData(indexData);
Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id()); Buffer *backendIndexBuffer = nodeManagers->bufferManager()->getOrCreateResource(indexDataBuffer->id());
@ -612,7 +622,7 @@ private Q_SLOTS:
indexAttribute->setBuffer(indexDataBuffer.data()); indexAttribute->setBuffer(indexDataBuffer.data());
indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt); indexAttribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);
indexAttribute->setCount(4); indexAttribute->setCount(8);
indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute); indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
geometry->addAttribute(positionAttribute.data()); geometry->addAttribute(positionAttribute.data());
@ -620,6 +630,8 @@ private Q_SLOTS:
geometryRenderer->setGeometry(geometry); geometryRenderer->setGeometry(geometry);
geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop); geometryRenderer->setPrimitiveType(Qt3DRender::QGeometryRenderer::LineLoop);
geometryRenderer->setPrimitiveRestartEnabled(true);
geometryRenderer->setRestartIndexValue(-1);
Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id()); Attribute *backendAttribute = nodeManagers->attributeManager()->getOrCreateResource(positionAttribute->id());
backendAttribute->setRenderer(&renderer); backendAttribute->setRenderer(&renderer);
@ -642,11 +654,14 @@ private Q_SLOTS:
visitor.apply(backendRenderer, Qt3DCore::QNodeId()); visitor.apply(backendRenderer, Qt3DCore::QNodeId());
// THEN // 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(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(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(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(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() void testVisitLineAdjacency()