Revision control
Copy as Markdown
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QSignalSpy>
#include <QtQuick3D/private/qquick3dgeometry_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
#include <QtQuick3DUtils/private/qssgmesh_p.h>
class tst_QQuick3DGeometry : public QObject
{
Q_OBJECT
// Work-around to get access to updateSpatialNode
class Geometry : public QQuick3DGeometry
{
public:
using QQuick3DGeometry::updateSpatialNode;
};
private slots:
void testGeometry();
void testGeometry2();
void testPartialUpdate();
void testGeometrySubset();
};
void tst_QQuick3DGeometry::testGeometry()
{
QSSGRenderGeometry geom;
QByteArray vertexData;
vertexData.resize(100);
vertexData.fill(0);
geom.setVertexData(vertexData);
QCOMPARE(vertexData.size(), geom.vertexBuffer().size());
QVERIFY(geom.vertexBuffer().compare(vertexData) == 0);
QByteArray indexData;
indexData.resize(100);
indexData.fill(0);
geom.setIndexData(indexData);
QCOMPARE(indexData.size(), geom.indexBuffer().size());
QVERIFY(geom.indexBuffer().compare(indexData) == 0);
const int stride = 20;
geom.setStride(stride);
QCOMPARE(stride, geom.stride());
const QVector3D minimum(-10.f, -10.f, -10.f);
const QVector3D maximum(10.f, 10.f, 10.f);
geom.setBounds(minimum, maximum);
QVERIFY(qFuzzyCompare(minimum, geom.boundsMin()));
QVERIFY(qFuzzyCompare(maximum, geom.boundsMax()));
geom.clear();
QSSGBounds3 emptyBounds;
QCOMPARE(geom.vertexBuffer().size(), 0);
QCOMPARE(geom.indexBuffer().size(), 0);
QVERIFY(qFuzzyCompare(emptyBounds.minimum, geom.boundsMin()));
QVERIFY(qFuzzyCompare(emptyBounds.maximum, geom.boundsMax()));
QCOMPARE(geom.attributeCount(), 0);
const QSSGMesh::Mesh::DrawMode primitiveTypes[] = {
QSSGMesh::Mesh::DrawMode::Points,
QSSGMesh::Mesh::DrawMode::LineStrip,
QSSGMesh::Mesh::DrawMode::LineLoop,
QSSGMesh::Mesh::DrawMode::Lines,
QSSGMesh::Mesh::DrawMode::TriangleStrip,
QSSGMesh::Mesh::DrawMode::TriangleFan,
QSSGMesh::Mesh::DrawMode::Triangles
};
for (const auto primitiveType : primitiveTypes) {
geom.setPrimitiveType(primitiveType);
QCOMPARE(primitiveType, geom.primitiveType());
}
const QSSGMesh::RuntimeMeshData::Attribute::Semantic semantics[] = {
QSSGMesh::RuntimeMeshData::Attribute::IndexSemantic,
QSSGMesh::RuntimeMeshData::Attribute::PositionSemantic,
QSSGMesh::RuntimeMeshData::Attribute::NormalSemantic,
QSSGMesh::RuntimeMeshData::Attribute::TexCoordSemantic,
QSSGMesh::RuntimeMeshData::Attribute::TangentSemantic,
QSSGMesh::RuntimeMeshData::Attribute::BinormalSemantic,
};
const int offsets[] = {
0, 16, 21, 33, 46, 52,
};
const QSSGMesh::Mesh::ComponentType types[] = {
QSSGMesh::Mesh::ComponentType::UnsignedInt8,
QSSGMesh::Mesh::ComponentType::Int8,
QSSGMesh::Mesh::ComponentType::UnsignedInt16,
QSSGMesh::Mesh::ComponentType::Int16,
QSSGMesh::Mesh::ComponentType::UnsignedInt32,
QSSGMesh::Mesh::ComponentType::Int32,
QSSGMesh::Mesh::ComponentType::UnsignedInt64,
QSSGMesh::Mesh::ComponentType::Int64,
QSSGMesh::Mesh::ComponentType::Float16,
QSSGMesh::Mesh::ComponentType::Float32,
QSSGMesh::Mesh::ComponentType::Float64
};
for (int i = 0; i < 6; i++) {
geom.addAttribute(semantics[i], offsets[i], QSSGMesh::Mesh::ComponentType::Float32);
QCOMPARE(semantics[i], geom.attribute(i).semantic);
QCOMPARE(offsets[i], geom.attribute(i).offset);
QCOMPARE(geom.attributeCount(), i+1);
}
QCOMPARE(geom.attributeCount(), 6);
geom.clear();
QCOMPARE(geom.attributeCount(), 0);
for (auto componentType : types) {
geom.addAttribute(QSSGMesh::RuntimeMeshData::Attribute::PositionSemantic, 0, componentType);
QCOMPARE(componentType, geom.attribute(0).componentType);
geom.clear();
}
}
void tst_QQuick3DGeometry::testGeometry2()
{
Geometry geom;
QByteArray vertexData;
vertexData.resize(100);
vertexData.fill(0);
geom.setVertexData(vertexData);
QCOMPARE(vertexData.size(), geom.vertexData().size());
QVERIFY(geom.vertexData().compare(vertexData) == 0);
QByteArray indexData;
indexData.resize(100);
indexData.fill(0);
geom.setIndexData(indexData);
QCOMPARE(indexData.size(), geom.indexData().size());
QVERIFY(geom.indexData().compare(indexData) == 0);
const int stride = 20;
geom.setStride(stride);
QCOMPARE(stride, geom.stride());
const QVector3D minimum(-10.f, -10.f, -10.f);
const QVector3D maximum(10.f, 10.f, 10.f);
geom.setBounds(minimum, maximum);
QVERIFY(qFuzzyCompare(minimum, geom.boundsMin()));
QVERIFY(qFuzzyCompare(maximum, geom.boundsMax()));
geom.clear();
QCOMPARE(geom.vertexData().size(), 0);
QCOMPARE(geom.indexData().size(), 0);
QCOMPARE(geom.attributeCount(), 0);
const QQuick3DGeometry::PrimitiveType primitiveTypes[] = {
QQuick3DGeometry::PrimitiveType::Points,
QQuick3DGeometry::PrimitiveType::LineStrip,
QQuick3DGeometry::PrimitiveType::Lines,
QQuick3DGeometry::PrimitiveType::TriangleStrip,
QQuick3DGeometry::PrimitiveType::TriangleFan,
QQuick3DGeometry::PrimitiveType::Triangles,
};
for (const auto primitiveType : primitiveTypes) {
geom.setPrimitiveType(primitiveType);
QCOMPARE(primitiveType, geom.primitiveType());
}
const QQuick3DGeometry::Attribute::Semantic semantics[] = {
QQuick3DGeometry::Attribute::IndexSemantic,
QQuick3DGeometry::Attribute::PositionSemantic,
QQuick3DGeometry::Attribute::NormalSemantic,
QQuick3DGeometry::Attribute::TexCoordSemantic,
QQuick3DGeometry::Attribute::TangentSemantic,
QQuick3DGeometry::Attribute::BinormalSemantic,
};
const int offsets[] = {
0, 16, 21, 33, 46, 52,
};
const QQuick3DGeometry::Attribute::ComponentType types[] = {
QQuick3DGeometry::Attribute::U16Type,
QQuick3DGeometry::Attribute::U32Type,
QQuick3DGeometry::Attribute::F32Type,
};
for (int i = 0; i < 6; i++) {
geom.addAttribute(semantics[i], offsets[i], QQuick3DGeometry::Attribute::F32Type);
QCOMPARE(semantics[i], geom.attribute(i).semantic);
QCOMPARE(offsets[i], geom.attribute(i).offset);
QCOMPARE(geom.attributeCount(), i+1);
}
QCOMPARE(geom.attributeCount(), 6);
geom.clear();
QCOMPARE(geom.attributeCount(), 0);
for (auto componentType : types) {
geom.addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0, componentType);
QCOMPARE(componentType, geom.attribute(0).componentType);
geom.clear();
}
}
void tst_QQuick3DGeometry::testPartialUpdate()
{
Geometry geom;
QByteArray vertexData(100, 'a');
geom.setVertexData(vertexData);
QCOMPARE(vertexData.size(), geom.vertexData().size());
QCOMPARE(geom.vertexData(), vertexData);
QByteArray indexData(100, 'a');
geom.setIndexData(indexData);
QCOMPARE(indexData.size(), geom.indexData().size());
QCOMPARE(geom.indexData(), indexData);
QByteArray smallData(10, 'b');
geom.setVertexData(30, smallData);
QCOMPARE(geom.vertexData().size(), 100);
QCOMPARE(geom.vertexData().left(30), QByteArray(30, 'a'));
QCOMPARE(geom.vertexData().mid(30, 10), smallData);
QCOMPARE(geom.vertexData().mid(40), QByteArray(60, 'a'));
geom.setIndexData(40, smallData);
QCOMPARE(geom.indexData().size(), 100);
QCOMPARE(geom.indexData().left(40), QByteArray(40, 'a'));
QCOMPARE(geom.indexData().mid(40, 10), smallData);
QCOMPARE(geom.indexData().mid(50), QByteArray(50, 'a'));
geom.setVertexData(100, smallData);
QCOMPARE(geom.vertexData().size(), 100);
geom.setVertexData(101, smallData);
QCOMPARE(geom.vertexData().size(), 100);
geom.setIndexData(100, smallData);
QCOMPARE(geom.indexData().size(), 100);
geom.setIndexData(101, smallData);
QCOMPARE(geom.indexData().size(), 100);
geom.setVertexData(95, smallData);
QCOMPARE(geom.vertexData().size(), 100);
QCOMPARE(geom.vertexData().mid(45, 50), QByteArray(50, 'a'));
QCOMPARE(geom.vertexData().mid(95), smallData.left(5));
geom.setIndexData(95, smallData);
QCOMPARE(geom.indexData().size(), 100);
QCOMPARE(geom.indexData().mid(55, 40), QByteArray(40, 'a'));
QCOMPARE(geom.indexData().mid(95), smallData.left(5));
}
void tst_QQuick3DGeometry::testGeometrySubset()
{
Geometry geom;
QCOMPARE(geom.subsetCount(), 0);
geom.addSubset(0, 50, QVector3D(-10, -10, -10), QVector3D(0, 0, 0), "subset1");
QCOMPARE(geom.subsetCount(), 1);
geom.addSubset(50, 50, QVector3D(0, 0, 0), QVector3D(10, 10, 10), "subset2");
QCOMPARE(geom.subsetCount(), 2);
QCOMPARE(geom.subsetOffset(0), 0);
QCOMPARE(geom.subsetCount(0), 50);
QVERIFY(qFuzzyCompare(geom.subsetBoundsMin(0), QVector3D(-10, -10, -10)));
QVERIFY(qFuzzyCompare(geom.subsetBoundsMax(0), QVector3D(0, 0, 0)));
QCOMPARE(geom.subsetName(0), "subset1");
QCOMPARE(geom.subsetOffset(1), 50);
QCOMPARE(geom.subsetCount(1), 50);
QVERIFY(qFuzzyCompare(geom.subsetBoundsMin(1), QVector3D(0, 0, 0)));
QVERIFY(qFuzzyCompare(geom.subsetBoundsMax(1), QVector3D(10, 10, 10)));
QCOMPARE(geom.subsetName(1), "subset2");
}
QTEST_APPLESS_MAIN(tst_QQuick3DGeometry)
#include "tst_qquick3dgeometry.moc"