Revision control
Copy as Markdown
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QSignalSpy>
#include <QScopedPointer>
#include <QtQuick3D/private/qquick3dmodel_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlesystem_p.h>
#include <QtQuick3DParticles/private/qquick3dparticleemitter_p.h>
#include <QtQuick3DParticles/private/qquick3dparticlesceneshape_p.h>
class tst_QQuick3DParticleSceneShape : public QObject
{
Q_OBJECT
private slots:
void testInitialization();
void testModelWithGeometry();
};
void tst_QQuick3DParticleSceneShape::testInitialization()
{
QScopedPointer<QQuick3DParticleSceneShape> sceneShape(new QQuick3DParticleSceneShape());
QVERIFY(qFuzzyCompare(sceneShape->sceneCenter(), QVector3D(0,0,0)));
QVERIFY(qFuzzyCompare(sceneShape->sceneExtents(), QVector3D(0,0,0)));
QVERIFY(qFuzzyCompare(sceneShape->shapeResolution(), 10.0f));
QCOMPARE(sceneShape->scene(), nullptr);
QCOMPARE(sceneShape->geometry(), nullptr);
}
void tst_QQuick3DParticleSceneShape::testModelWithGeometry()
{
QScopedPointer<QQuick3DParticleSystem> system(new QQuick3DParticleSystem());
QScopedPointer<QQuick3DParticleEmitter> emitter(new QQuick3DParticleEmitter());
QScopedPointer<QQuick3DNode> root(new QQuick3DNode());
QQuick3DModel *model = new QQuick3DModel(root.get());
QScopedPointer<QQuick3DGeometry> geometry(new QQuick3DGeometry());
emitter->setSystem(system.get());
system->setSeed(31);
geometry->setBounds(QVector3D(-100, 0, -100), QVector3D(-50, 0, 100));
// Purposfully exclude origin
QVector3D vertexData[] = {{-100, 0, 100}, {-100, 0, -100}, {-50, 0, -100}, {-50, 0, -100}};
quint32 indexData[] = {0, 2, 1, 0, 2, 3};
QByteArray indices(reinterpret_cast<const char *>(indexData), sizeof(quint32) * 6u);
QByteArray vertices(reinterpret_cast<const char *>(vertexData), sizeof(QVector3D) * 4u);
geometry->setIndexData(indices);
geometry->setVertexData(vertices);
geometry->addAttribute(QQuick3DGeometry::Attribute::PositionSemantic, 0, QQuick3DGeometry::Attribute::F32Type);
geometry->addAttribute(QQuick3DGeometry::Attribute::IndexSemantic, 0, QQuick3DGeometry::Attribute::U32Type);
geometry->setPrimitiveType(QQuick3DGeometry::PrimitiveType::Triangles);
geometry->setStride(sizeof(QVector3D));
model->setGeometry(geometry.get());
QQuick3DParticleSceneShape *sceneShape = new QQuick3DParticleSceneShape(emitter.get());
emitter->setShape(sceneShape);
sceneShape->setShapeResolution(40.0f);
sceneShape->setSceneExtents(QVector3D(100.0f, 100.0f, 100.0f));
sceneShape->setScene(model);
const QVector3D position = sceneShape->getPosition(0);
const QVector3D normal = sceneShape->getSurfaceNormal(0);
QVERIFY(qFuzzyCompare(normal, QVector3D(0, 1.0f, 0)));
QVERIFY(qFuzzyCompare(position.y(), 0.0f));
QVERIFY(position.x() >= -100.0f && position.x() <= -50.0f);
QVERIFY(position.z() >= -100.0f && position.z() <= 100.0f);
}
QTEST_APPLESS_MAIN(tst_QQuick3DParticleSceneShape)
#include "tst_qquick3dparticlesceneshape.moc"