Revision control

++ // Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++
++ #include <QtTest/QTest>
++ #include <Qt3DRender/private/entity_p.h>
++ #include <Qt3DRender/private/triangleboundingvolume_p.h>
++ #include <Qt3DRender/private/qraycastingservice_p.h>
++ #include <Qt3DRender/private/qray3d_p.h>
++ #include <Qt3DRender/qcameralens.h>
++ #include <Qt3DRender/qcamera.h>
++ #include <Qt3DRender/private/qboundingvolume_p.h>
++
++ class tst_TriangleBoundingVolume : public QObject
++ {
++ Q_OBJECT
++ public:
++ tst_TriangleBoundingVolume() {}
++ ~tst_TriangleBoundingVolume() {}
++
++ private Q_SLOTS:
++ void checkInitialState()
++ {
++ // GIVEN
++ Qt3DRender::Render::TriangleBoundingVolume volume = Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(),
++ Vector3D(),
++ Vector3D(),
++ Vector3D());
++
++ // THEN
++ QCOMPARE(volume.id(), Qt3DCore::QNodeId());
++ QCOMPARE(volume.a(), Vector3D());
++ QCOMPARE(volume.b(), Vector3D());
++ QCOMPARE(volume.c(), Vector3D());
++ QCOMPARE(volume.type(), Qt3DRender::RayCasting::QBoundingVolume::Triangle);
++ }
++
++ void transformed_data()
++ {
++ QTest::addColumn<Vector3D>("a");
++ QTest::addColumn<Vector3D>("b");
++ QTest::addColumn<Vector3D>("c");
++
++ QTest::addColumn<Vector3D>("transformedA");
++ QTest::addColumn<Vector3D>("transformedB");
++ QTest::addColumn<Vector3D>("transformedC");
++
++ QTest::newRow("onFarPlane")
++ << Vector3D(-1.0, 1.0, 0.0)
++ << Vector3D(0.0, -1.0, 0.0)
++ << Vector3D(1.0, 1.0, 0.0)
++ << Vector3D(-1.0, 1.0, -40.0)
++ << Vector3D(0.0, -1.0, -40.0)
++ << Vector3D(1.0, 1.0, -40.0);
++
++ QTest::newRow("onNearPlane")
++ << Vector3D(-1.0, 1.0, 40.0)
++ << Vector3D(0.0, -1.0, 40.0)
++ << Vector3D(1.0, 1.0, 40.0)
++ << Vector3D(-1.0, 1.0, 0.0)
++ << Vector3D(0.0, -1.0, 0.0)
++ << Vector3D(1.0, 1.0, 0.0);
++
++
++ }
++
++ void transformed()
++ {
++ // GIVEN
++ QFETCH(Vector3D, a);
++ QFETCH(Vector3D, b);
++ QFETCH(Vector3D, c);
++ QFETCH(Vector3D, transformedA);
++ QFETCH(Vector3D, transformedB);
++ QFETCH(Vector3D, transformedC);
++ Qt3DRender::Render::TriangleBoundingVolume volume(Qt3DCore::QNodeId(),
++ a,
++ b,
++ c);
++ Qt3DRender::QCamera camera;
++ camera.setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection);
++ camera.setFieldOfView(45.0f);
++ camera.setAspectRatio(800.0f/600.0f);
++ camera.setNearPlane(0.1f);
++ camera.setFarPlane(1000.0f);
++ camera.setPosition(QVector3D(0.0f, 0.0f, 40.0f));
++ camera.setUpVector(QVector3D(0.0f, 1.0f, 0.0f));
++ camera.setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));
++
++ const Matrix4x4 viewMatrix(camera.viewMatrix());
++
++ // WHEN
++ volume.transform(viewMatrix);
++
++ // THEN
++ QCOMPARE(transformedA, volume.a());
++ QCOMPARE(transformedB, volume.b());
++ QCOMPARE(transformedC, volume.c());
++ }
++
++ void intersects_data()
++ {
++ QTest::addColumn<Qt3DRender::RayCasting::QRay3D>("ray");
++ QTest::addColumn<Vector3D>("a");
++ QTest::addColumn<Vector3D>("b");
++ QTest::addColumn<Vector3D>("c");
++ QTest::addColumn<Vector3D>("uvw");
++ QTest::addColumn<float>("t");
++ QTest::addColumn<bool>("isIntersecting");
++
++ const float farPlaneDistance = 40.0;
++
++ QTest::newRow("halfway_center")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
++ << Vector3D(3.0, 1.5, 20.0)
++ << Vector3D(0.0, -1.5, 20.0)
++ << Vector3D(-3, 1.5, 20.0)
++ << Vector3D(0.25, 0.5, 0.25)
++ << 0.5f
++ << true;
++ QTest::newRow("miss_halfway_center_too_short")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance * 0.25f)
++ << Vector3D(3.0, 1.5, 20.0)
++ << Vector3D(0.0, -1.5, 20.0)
++ << Vector3D(-3, 1.5, 20.0)
++ << Vector3D()
++ << 0.0f
++ << false;
++ QTest::newRow("far_center")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
++ << Vector3D(3.0, 1.5, 40.0)
++ << Vector3D(0.0, -1.5, 40.0)
++ << Vector3D(-3, 1.5, 40.0)
++ << Vector3D(0.25, 0.5, 0.25)
++ << 1.0f
++ << true;
++ QTest::newRow("near_center")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), 1.0f)
++ << Vector3D(3.0, 1.5, 0.0)
++ << Vector3D(0.0, -1.5, 0.0)
++ << Vector3D(-3, 1.5, 0.0)
++ << Vector3D(0.25, 0.5, 0.25)
++ << 0.0f
++ << true;
++ QTest::newRow("above_miss_center")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, 2.0, 0.0), Vector3D(0.0, 2.0, 1.0), 1.0f)
++ << Vector3D(3.0, 1.5, 0.0)
++ << Vector3D(0.0, -1.5, 0.0)
++ << Vector3D(-3, 1.5, 0.0)
++ << Vector3D()
++ << 0.0f
++ << false;
++ QTest::newRow("below_miss_center")
++ << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, -2.0, 0.0), Vector3D(0.0, -2.0, 1.0), 1.0f)
++ << Vector3D(3.0, 1.5, 0.0)
++ << Vector3D(0.0, -1.5, 0.0)
++ << Vector3D(-3, 1.5, 0.0)
++ << Vector3D()
++ << 0.0f
++ << false;
++ }
++
++ void intersects()
++ {
++ // GIVEN
++ QFETCH(Qt3DRender::RayCasting::QRay3D, ray);
++ QFETCH(Vector3D, a);
++ QFETCH(Vector3D, b);
++ QFETCH(Vector3D, c);
++ QFETCH(Vector3D, uvw);
++ QFETCH(float, t);
++ QFETCH(bool, isIntersecting);
++
++ // WHEN
++ Vector3D tmp_uvw;
++ float tmp_t;
++ const bool shouldBeIntersecting = Qt3DRender::Render::intersectsSegmentTriangle(ray,
++ a, b, c,
++ tmp_uvw,
++ tmp_t);
++
++ // THEN
++ QCOMPARE(shouldBeIntersecting, isIntersecting);
++ if (isIntersecting) {
++ QVERIFY(qFuzzyCompare(uvw, tmp_uvw));
++ QVERIFY(qFuzzyCompare(t, tmp_t));
++ }
++ }
++ };
++
++ QTEST_APPLESS_MAIN(tst_TriangleBoundingVolume)
++
++ #include "tst_triangleboundingvolume.moc"