blob: b037c461f73dc6ea99612d7fd67571bcb9c89510 [file] [log] [blame]
/****************************************************************************
**
** 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/QtTest>
#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"