summaryrefslogtreecommitdiffstats
path: root/tests/auto/extras
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/extras')
-rw-r--r--tests/auto/extras/common/common.pri6
-rw-r--r--tests/auto/extras/common/geometrytesthelper.h105
-rw-r--r--tests/auto/extras/extras.pro3
-rw-r--r--tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro2
-rw-r--r--tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp72
-rw-r--r--tests/auto/extras/qtorusgeometry/qtorusgeometry.pro12
-rw-r--r--tests/auto/extras/qtorusgeometry/tst_qtorusgeometry.cpp366
7 files changed, 494 insertions, 72 deletions
diff --git a/tests/auto/extras/common/common.pri b/tests/auto/extras/common/common.pri
new file mode 100644
index 000000000..4f73c65b5
--- /dev/null
+++ b/tests/auto/extras/common/common.pri
@@ -0,0 +1,6 @@
+HEADERS += \
+ $$PWD/geometrytesthelper.h
+
+INCLUDEPATH += $$PWD
+
+QT += core-private 3drender
diff --git a/tests/auto/extras/common/geometrytesthelper.h b/tests/auto/extras/common/geometrytesthelper.h
new file mode 100644
index 000000000..48e674cd9
--- /dev/null
+++ b/tests/auto/extras/common/geometrytesthelper.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GEOMETRYTESTHELPER_H
+#define GEOMETRYTESTHELPER_H
+
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qgeometry.h>
+
+inline void generateGeometry(Qt3DRender::QGeometry &geometry)
+{
+ // Get all attributes
+ const QVector<Qt3DRender::QAttribute *> attributes = geometry.attributes();
+
+ // Get all unique data generators from the buffers referenced by the attributes
+ QHash<Qt3DRender::QBufferDataGeneratorPtr, Qt3DRender::QBuffer *> dataGenerators;
+ for (const auto attribute : attributes) {
+ const auto dataGenerator = attribute->buffer()->dataGenerator();
+ if (!dataGenerators.contains(dataGenerator))
+ dataGenerators.insert(dataGenerator, attribute->buffer());
+ }
+
+ // Generate data for each buffer
+ const auto end = dataGenerators.end();
+ for (auto it = dataGenerators.begin(); it != end; ++it) {
+ Qt3DRender::QBufferDataGeneratorPtr dataGenerator = it.key();
+ const QByteArray data = (*dataGenerator)();
+
+ Qt3DRender::QBuffer *buffer = it.value();
+ buffer->setData(data);
+ }
+}
+
+template<typename IndexType>
+IndexType extractIndexData(Qt3DRender::QAttribute *attribute, int index)
+{
+ // Get the raw data
+ const IndexType *typedData = reinterpret_cast<const IndexType *>(attribute->buffer()->data().constData());
+
+ // Offset into the data taking stride and offset into account
+ const IndexType indexValue = *(typedData + index);
+ return indexValue;
+}
+
+template<typename VertexType, typename IndexType>
+VertexType extractVertexData(Qt3DRender::QAttribute *attribute, IndexType index)
+{
+ // Get the raw data
+ const char *rawData = attribute->buffer()->data().constData();
+
+ // Offset into the data taking stride and offset into account
+ const char *vertexData = rawData + (index * attribute->byteStride() + attribute->byteOffset());
+
+ // Construct vertex from the typed data
+ VertexType vertex;
+ const Qt3DRender::QAttribute::VertexBaseType type = attribute->vertexBaseType();
+ switch (type)
+ {
+ case Qt3DRender::QAttribute::Float: {
+ const float *typedVertexData = reinterpret_cast<const float *>(vertexData);
+ const int components = attribute->vertexSize();
+ for (int i = 0; i < components; ++i)
+ vertex[i] = typedVertexData[i];
+ break;
+
+ // TODO: Handle other types as needed
+ }
+
+ default:
+ qWarning() << "Unhandled type";
+ Q_UNREACHABLE();
+ break;
+ }
+
+ return vertex;
+}
+
+#endif // GEOMETRYTESTHELPER_H
diff --git a/tests/auto/extras/extras.pro b/tests/auto/extras/extras.pro
index 3bba4d37b..381924d7b 100644
--- a/tests/auto/extras/extras.pro
+++ b/tests/auto/extras/extras.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
SUBDIRS = \
- qcuboidgeometry
+ qcuboidgeometry \
+ qtorusgeometry
diff --git a/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro b/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro
index 7208f1c7b..1e55fffad 100644
--- a/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro
+++ b/tests/auto/extras/qcuboidgeometry/qcuboidgeometry.pro
@@ -8,3 +8,5 @@ CONFIG += testcase
SOURCES += \
tst_qcuboidgeometry.cpp
+
+include(../common/common.pri)
diff --git a/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp b/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp
index fa1657732..973a1d613 100644
--- a/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp
+++ b/tests/auto/extras/qcuboidgeometry/tst_qcuboidgeometry.cpp
@@ -40,77 +40,7 @@
#include <QtCore/qsharedpointer.h>
#include <QSignalSpy>
-namespace {
-
-void generateGeometry(Qt3DRender::QGeometry &geometry)
-{
- // Get all attributes
- const QVector<Qt3DRender::QAttribute *> attributes = geometry.attributes();
-
- // Get all unique data generators from the buffers referenced by the attributes
- QHash<Qt3DRender::QBufferDataGeneratorPtr, Qt3DRender::QBuffer *> dataGenerators;
- for (const auto attribute : attributes) {
- const auto dataGenerator = attribute->buffer()->dataGenerator();
- if (!dataGenerators.contains(dataGenerator))
- dataGenerators.insert(dataGenerator, attribute->buffer());
- }
-
- // Generate data for each buffer
- const auto end = dataGenerators.end();
- for (auto it = dataGenerators.begin(); it != end; ++it) {
- Qt3DRender::QBufferDataGeneratorPtr dataGenerator = it.key();
- const QByteArray data = (*dataGenerator)();
-
- Qt3DRender::QBuffer *buffer = it.value();
- buffer->setData(data);
- }
-}
-
-template<typename IndexType>
-IndexType extractIndexData(Qt3DRender::QAttribute *attribute, int index)
-{
- // Get the raw data
- const IndexType *typedData = reinterpret_cast<const IndexType *>(attribute->buffer()->data().constData());
-
- // Offset into the data taking stride and offset into account
- const IndexType indexValue = *(typedData + index);
- return indexValue;
-}
-
-template<typename VertexType, typename IndexType>
-VertexType extractVertexData(Qt3DRender::QAttribute *attribute, IndexType index)
-{
- // Get the raw data
- const char *rawData = attribute->buffer()->data().constData();
-
- // Offset into the data taking stride and offset into account
- const char *vertexData = rawData + (index * attribute->byteStride() + attribute->byteOffset());
-
- // Construct vertex from the typed data
- VertexType vertex;
- const Qt3DRender::QAttribute::VertexBaseType type = attribute->vertexBaseType();
- switch (type)
- {
- case Qt3DRender::QAttribute::Float: {
- const float *typedVertexData = reinterpret_cast<const float *>(vertexData);
- const int components = attribute->vertexSize();
- for (int i = 0; i < components; ++i)
- vertex[i] = typedVertexData[i];
- break;
-
- // TODO: Handle other types as needed
- }
-
- default:
- qWarning() << "Unhandled type";
- Q_UNREACHABLE();
- break;
- }
-
- return vertex;
-}
-
-}
+#include "geometrytesthelper.h"
class tst_QCuboidGeometry : public QObject
{
diff --git a/tests/auto/extras/qtorusgeometry/qtorusgeometry.pro b/tests/auto/extras/qtorusgeometry/qtorusgeometry.pro
new file mode 100644
index 000000000..e20e447dc
--- /dev/null
+++ b/tests/auto/extras/qtorusgeometry/qtorusgeometry.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+TARGET = tst_qtorusgeometry
+
+QT += 3dextras testlib
+
+CONFIG += testcase
+
+SOURCES += \
+ tst_qtorusgeometry.cpp
+
+include(../common/common.pri)
diff --git a/tests/auto/extras/qtorusgeometry/tst_qtorusgeometry.cpp b/tests/auto/extras/qtorusgeometry/tst_qtorusgeometry.cpp
new file mode 100644
index 000000000..28fe76ae9
--- /dev/null
+++ b/tests/auto/extras/qtorusgeometry/tst_qtorusgeometry.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QTest>
+#include <QObject>
+#include <Qt3DExtras/qtorusgeometry.h>
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <QtGui/qopenglcontext.h>
+#include <QtGui/qvector2d.h>
+#include <QtGui/qvector3d.h>
+#include <QtGui/qvector4d.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qsharedpointer.h>
+#include <QSignalSpy>
+#include <qmath.h>
+
+#include "geometrytesthelper.h"
+
+class tst_QTorusGeometry : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void defaultConstruction()
+ {
+ // WHEN
+ Qt3DExtras::QTorusGeometry geometry;
+
+ // THEN
+ QCOMPARE(geometry.rings(), 16);
+ QCOMPARE(geometry.slices(), 16);
+ QCOMPARE(geometry.radius(), 1.0f);
+ QCOMPARE(geometry.minorRadius(), 1.0f);
+ QVERIFY(geometry.positionAttribute() != nullptr);
+ QCOMPARE(geometry.positionAttribute()->name(), Qt3DRender::QAttribute::defaultPositionAttributeName());
+ QVERIFY(geometry.normalAttribute() != nullptr);
+ QCOMPARE(geometry.normalAttribute()->name(), Qt3DRender::QAttribute::defaultNormalAttributeName());
+ QVERIFY(geometry.texCoordAttribute() != nullptr);
+ QCOMPARE(geometry.texCoordAttribute()->name(), Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName());
+ // TODO: Expose tangent attribute in Qt 5.8 and see below
+// QVERIFY(geometry.tangentAttribute() != nullptr);
+// QCOMPARE(geometry.tangentAttribute()->name(), Qt3DRender::QAttribute::defaultTangentAttributeName());
+ QVERIFY(geometry.indexAttribute() != nullptr);
+ }
+
+ void properties()
+ {
+ // GIVEN
+ Qt3DExtras::QTorusGeometry geometry;
+
+ {
+ // WHEN
+ QSignalSpy spy(&geometry, SIGNAL(ringsChanged(int)));
+ const int newValue = 20;
+ geometry.setRings(newValue);
+
+ // THEN
+ QCOMPARE(geometry.rings(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ geometry.setRings(newValue);
+
+ // THEN
+ QCOMPARE(geometry.rings(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
+ QSignalSpy spy(&geometry, SIGNAL(slicesChanged(int)));
+ const int newValue = 2.0f;
+ geometry.setSlices(newValue);
+
+ // THEN
+ QCOMPARE(geometry.slices(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ geometry.setSlices(newValue);
+
+ // THEN
+ QCOMPARE(geometry.slices(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
+ QSignalSpy spy(&geometry, SIGNAL(radiusChanged(float)));
+ const float newValue = 2.0f;
+ geometry.setRadius(newValue);
+
+ // THEN
+ QCOMPARE(geometry.radius(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ geometry.setRadius(newValue);
+
+ // THEN
+ QCOMPARE(geometry.radius(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+
+ {
+ // WHEN
+ QSignalSpy spy(&geometry, SIGNAL(minorRadiusChanged(float)));
+ const float newValue = 0.25f;
+ geometry.setMinorRadius(newValue);
+
+ // THEN
+ QCOMPARE(geometry.minorRadius(), newValue);
+ QCOMPARE(spy.count(), 1);
+
+ // WHEN
+ spy.clear();
+ geometry.setMinorRadius(newValue);
+
+ // THEN
+ QCOMPARE(geometry.minorRadius(), newValue);
+ QCOMPARE(spy.count(), 0);
+ }
+ }
+
+ void generatedGeometryShouldBeConsistent_data()
+ {
+ QTest::addColumn<int>("rings");
+ QTest::addColumn<int>("slices");
+ QTest::addColumn<float>("radius");
+ QTest::addColumn<float>("minorRadius");
+ QTest::addColumn<int>("triangleIndex");
+ QTest::addColumn<QVector<quint16>>("indices");
+ QTest::addColumn<QVector<QVector3D>>("positions");
+ QTest::addColumn<QVector<QVector3D>>("normals");
+ QTest::addColumn<QVector<QVector2D>>("texCoords");
+ QTest::addColumn<QVector<QVector4D>>("tangents");
+
+ {
+ // Torus properties
+ const int rings = 8;
+ const int slices = 8;
+ const float radius = 2.0f;
+ const float minorRadius = 0.5f;
+
+ // Angular factors for the vertices:
+ // u iterates around the major radius
+ // v iterates around the minor radius (around each ring)
+ const float du = float(2.0 * M_PI / rings);
+ const float dv = float(2.0 * M_PI / slices);
+ const float u0 = 0.0f;
+ const float u1 = du;
+ const float v0 = 0.0f;
+ const float v1 = dv;
+
+ const float cosu0 = float(qCos(u0));
+ const float sinu0 = float(qSin(u0));
+ const float cosu1 = float(qCos(u1));
+ const float sinu1 = float(qSin(u1));
+
+ const float cosv0 = float(qCos(v0 + M_PI)); // Seam is on inner edge
+ const float sinv0 = float(qSin(v0));
+ const float cosv1 = float(qCos(v1 + M_PI));
+ const float sinv1 = float(qSin(v1));
+
+ // The triangle and indices
+ const int triangleIndex = 0;
+ const auto indices = (QVector<quint16>() << 0 << 1 << 9);
+
+ // Calculate attributes for vertices A, B, and C of the triangle
+ const float rA = radius + minorRadius * cosv0;
+ const float rB = radius + minorRadius * cosv1;
+ const float rC = radius + minorRadius * cosv0;
+
+ const auto posA = QVector3D(rA * cosu0, rA * sinu0, minorRadius * sinv0);
+ const auto posB = QVector3D(rB * cosu0, rB * sinu0, minorRadius * sinv1);
+ const auto posC = QVector3D(rC * cosu1, rC * sinu1, minorRadius * sinv0);
+ const auto positions = (QVector<QVector3D>() << posA << posB << posC);
+
+ const auto nA = QVector3D(cosv0 * cosu0, cosv0 * sinu0, sinv0).normalized();
+ const auto nB = QVector3D(cosv1 * cosu0, cosv1 * sinu0, sinv1).normalized();
+ const auto nC = QVector3D(cosv0 * cosu1, cosv0 * sinu1, sinv0).normalized();
+ const auto normals = (QVector<QVector3D>() << nA << nB << nC);
+
+ const auto tcA = QVector2D(u0, v0) / float(2.0 * M_PI);
+ const auto tcB = QVector2D(u0, v1) / float(2.0 * M_PI);
+ const auto tcC = QVector2D(u1, v0) / float(2.0 * M_PI);
+ const auto texCoords = (QVector<QVector2D>() << tcA << tcB << tcC);
+
+ const auto tA = QVector4D(-sinu0, cosu0, 0.0f, 1.0f);
+ const auto tB = QVector4D(-sinu0, cosu0, 0.0f, 1.0f);
+ const auto tC = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
+ const auto tangents = (QVector<QVector4D>() << tA << tB << tC);
+
+ // Add the row
+ QTest::newRow("8rings_8slices_firstTriangle")
+ << rings << slices << radius << minorRadius
+ << triangleIndex
+ << indices << positions << normals << texCoords << tangents;
+ }
+
+ {
+ // Note: The vertices used in this test case are different than the
+ // ones above. So, we cannot abstract this into a function easily.
+ // Here we use the 2nd triangle in a rectangular face, the test above
+ // uses the first triangle in the rectangular face.
+
+ // Torus properties
+ const int rings = 8;
+ const int slices = 8;
+ const float radius = 2.0f;
+ const float minorRadius = 0.5f;
+
+ // Angular factors for the vertices:
+ // u iterates around the major radius
+ // v iterates around the minor radius (around each ring)
+ const float du = float(2.0 * M_PI / rings);
+ const float dv = float(2.0 * M_PI / slices);
+ const float u0 = 7.0f * du;
+ const float u1 = float(2.0 * M_PI);
+ const float v0 = 7.0f * dv;
+ const float v1 = float(2.0 * M_PI);
+
+ const float cosu0 = float(qCos(u0));
+ const float sinu0 = float(qSin(u0));
+ const float cosu1 = float(qCos(u1));
+ const float sinu1 = float(qSin(u1));
+
+ const float cosv0 = float(qCos(v0 + M_PI)); // Seam is on inner edge
+ const float sinv0 = float(qSin(v0));
+ const float cosv1 = float(qCos(v1 + M_PI));
+ const float sinv1 = float(qSin(v1));
+
+ // The triangle and indices
+ const int triangleIndex = 127;
+ const auto indices = (QVector<quint16>() << 71 << 80 << 79);
+
+ // Calculate attributes for vertices A, B, and C of the triangle
+ const float rA = radius + minorRadius * cosv1;
+ const float rB = radius + minorRadius * cosv1;
+ const float rC = radius + minorRadius * cosv0;
+
+ const auto posA = QVector3D(rA * cosu0, rA * sinu0, minorRadius * sinv1);
+ const auto posB = QVector3D(rB * cosu1, rB * sinu1, minorRadius * sinv1);
+ const auto posC = QVector3D(rC * cosu1, rC * sinu1, minorRadius * sinv0);
+ const auto positions = (QVector<QVector3D>() << posA << posB << posC);
+
+ const auto nA = QVector3D(cosv1 * cosu0, cosv1 * sinu0, sinv1).normalized();
+ const auto nB = QVector3D(cosv1 * cosu1, cosv1 * sinu1, sinv1).normalized();
+ const auto nC = QVector3D(cosv0 * cosu1, cosv0 * sinu1, sinv0).normalized();
+ const auto normals = (QVector<QVector3D>() << nA << nB << nC);
+
+ const auto tcA = QVector2D(u0, v1) / float(2.0 * M_PI);
+ const auto tcB = QVector2D(u1, v1) / float(2.0 * M_PI);
+ const auto tcC = QVector2D(u1, v0) / float(2.0 * M_PI);
+ const auto texCoords = (QVector<QVector2D>() << tcA << tcB << tcC);
+
+ const auto tA = QVector4D(-sinu0, cosu1, 0.0f, 1.0f);
+ const auto tB = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
+ const auto tC = QVector4D(-sinu1, cosu1, 0.0f, 1.0f);
+ const auto tangents = (QVector<QVector4D>() << tA << tB << tC);
+
+ // Add the row
+ QTest::newRow("8rings_8slices_lastTriangle")
+ << rings << slices << radius << minorRadius
+ << triangleIndex
+ << indices << positions << normals << texCoords << tangents;
+ }
+ }
+
+ void generatedGeometryShouldBeConsistent()
+ {
+ // GIVEN
+ Qt3DExtras::QTorusGeometry geometry;
+ const QVector<Qt3DRender::QAttribute *> attributes = geometry.attributes();
+ Qt3DRender::QAttribute *positionAttribute = geometry.positionAttribute();
+ Qt3DRender::QAttribute *normalAttribute = geometry.normalAttribute();
+ Qt3DRender::QAttribute *texCoordAttribute = geometry.texCoordAttribute();
+// Qt3DRender::QAttribute *tangentAttribute = geometry.tangentAttribute();
+ Qt3DRender::QAttribute *indexAttribute = geometry.indexAttribute();
+
+ // WHEN
+ QFETCH(int, rings);
+ QFETCH(int, slices);
+ QFETCH(float, radius);
+ QFETCH(float, minorRadius);
+ geometry.setRings(rings);
+ geometry.setSlices(slices);
+ geometry.setRadius(radius);
+ geometry.setMinorRadius(minorRadius);
+
+ generateGeometry(geometry);
+
+ // THEN
+
+ // Check buffer of each attribute is valid and actually has some data
+ for (const auto &attribute : attributes) {
+ Qt3DRender::QBuffer *buffer = attribute->buffer();
+ QVERIFY(buffer != nullptr);
+ QVERIFY(buffer->data().size() != 0);
+ }
+
+ // Check some data in the buffers
+
+ // Check specific indices and vertex attributes of triangle under test
+ QFETCH(int, triangleIndex);
+ QFETCH(QVector<quint16>, indices);
+ QFETCH(QVector<QVector3D>, positions);
+ QFETCH(QVector<QVector3D>, normals);
+ QFETCH(QVector<QVector2D>, texCoords);
+// QFETCH(QVector<QVector4D>, tangents);
+
+ int i = 0;
+ for (auto index : indices) {
+ const auto testIndex = extractIndexData<quint16>(indexAttribute, 3 * triangleIndex + i);
+ QCOMPARE(testIndex, indices.at(i));
+
+ const auto position = extractVertexData<QVector3D, quint32>(positionAttribute, index);
+ QVERIFY(qFuzzyCompare(position, positions.at(i)));
+
+ const auto normal = extractVertexData<QVector3D, quint32>(normalAttribute, index);
+ QVERIFY(qFuzzyCompare(normal, normals.at(i)));
+
+ const auto texCoord = extractVertexData<QVector2D, quint32>(texCoordAttribute, index);
+ QVERIFY(qFuzzyCompare(texCoord, texCoords.at(i)));
+
+// const auto tangent = extractVertexData<QVector4D, quint32>(tangentAttribute, index);
+// QVERIFY(qFuzzyCompare(tangent, tangents.at(i)));
+
+ ++i;
+ }
+ }
+};
+
+
+QTEST_APPLESS_MAIN(tst_QTorusGeometry)
+
+#include "tst_qtorusgeometry.moc"