1/****************************************************************************
2**
3** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <Qt3DRender/private/entity_p.h>
31#include <Qt3DRender/private/triangleboundingvolume_p.h>
32#include <Qt3DRender/private/qraycastingservice_p.h>
33#include <Qt3DRender/private/qray3d_p.h>
34#include <Qt3DRender/qcameralens.h>
35#include <Qt3DRender/qcamera.h>
36#include <Qt3DRender/private/qboundingvolume_p.h>
37
38class tst_TriangleBoundingVolume : public QObject
39{
40 Q_OBJECT
41public:
42 tst_TriangleBoundingVolume() {}
43 ~tst_TriangleBoundingVolume() {}
44
45private Q_SLOTS:
46 void checkInitialState()
47 {
48 // GIVEN
49 Qt3DRender::Render::TriangleBoundingVolume volume = Qt3DRender::Render::TriangleBoundingVolume(Qt3DCore::QNodeId(),
50 Vector3D(),
51 Vector3D(),
52 Vector3D());
53
54 // THEN
55 QCOMPARE(volume.id(), Qt3DCore::QNodeId());
56 QCOMPARE(volume.a(), Vector3D());
57 QCOMPARE(volume.b(), Vector3D());
58 QCOMPARE(volume.c(), Vector3D());
59 QCOMPARE(volume.type(), Qt3DRender::RayCasting::QBoundingVolume::Triangle);
60 }
61
62 void transformed_data()
63 {
64 QTest::addColumn<Vector3D>(name: "a");
65 QTest::addColumn<Vector3D>(name: "b");
66 QTest::addColumn<Vector3D>(name: "c");
67
68 QTest::addColumn<Vector3D>(name: "transformedA");
69 QTest::addColumn<Vector3D>(name: "transformedB");
70 QTest::addColumn<Vector3D>(name: "transformedC");
71
72 QTest::newRow(dataTag: "onFarPlane")
73 << Vector3D(-1.0, 1.0, 0.0)
74 << Vector3D(0.0, -1.0, 0.0)
75 << Vector3D(1.0, 1.0, 0.0)
76 << Vector3D(-1.0, 1.0, -40.0)
77 << Vector3D(0.0, -1.0, -40.0)
78 << Vector3D(1.0, 1.0, -40.0);
79
80 QTest::newRow(dataTag: "onNearPlane")
81 << Vector3D(-1.0, 1.0, 40.0)
82 << Vector3D(0.0, -1.0, 40.0)
83 << Vector3D(1.0, 1.0, 40.0)
84 << Vector3D(-1.0, 1.0, 0.0)
85 << Vector3D(0.0, -1.0, 0.0)
86 << Vector3D(1.0, 1.0, 0.0);
87
88
89 }
90
91 void transformed()
92 {
93 // GIVEN
94 QFETCH(Vector3D, a);
95 QFETCH(Vector3D, b);
96 QFETCH(Vector3D, c);
97 QFETCH(Vector3D, transformedA);
98 QFETCH(Vector3D, transformedB);
99 QFETCH(Vector3D, transformedC);
100 Qt3DRender::Render::TriangleBoundingVolume volume(Qt3DCore::QNodeId(),
101 a,
102 b,
103 c);
104 Qt3DRender::QCamera camera;
105 camera.setProjectionType(Qt3DRender::QCameraLens::PerspectiveProjection);
106 camera.setFieldOfView(45.0f);
107 camera.setAspectRatio(800.0f/600.0f);
108 camera.setNearPlane(0.1f);
109 camera.setFarPlane(1000.0f);
110 camera.setPosition(QVector3D(0.0f, 0.0f, 40.0f));
111 camera.setUpVector(QVector3D(0.0f, 1.0f, 0.0f));
112 camera.setViewCenter(QVector3D(0.0f, 0.0f, 0.0f));
113
114 const Matrix4x4 viewMatrix(camera.viewMatrix());
115
116 // WHEN
117 volume.transform(mat: viewMatrix);
118
119 // THEN
120 QCOMPARE(transformedA, volume.a());
121 QCOMPARE(transformedB, volume.b());
122 QCOMPARE(transformedC, volume.c());
123 }
124
125 void intersects_data()
126 {
127 QTest::addColumn<Qt3DRender::RayCasting::QRay3D>(name: "ray");
128 QTest::addColumn<Vector3D>(name: "a");
129 QTest::addColumn<Vector3D>(name: "b");
130 QTest::addColumn<Vector3D>(name: "c");
131 QTest::addColumn<Vector3D>(name: "uvw");
132 QTest::addColumn<float>(name: "t");
133 QTest::addColumn<bool>(name: "isIntersecting");
134
135 const float farPlaneDistance = 40.0;
136
137 QTest::newRow(dataTag: "halfway_center")
138 << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
139 << Vector3D(3.0, 1.5, 20.0)
140 << Vector3D(0.0, -1.5, 20.0)
141 << Vector3D(-3, 1.5, 20.0)
142 << Vector3D(0.25, 0.5, 0.25)
143 << 0.5f
144 << true;
145 QTest::newRow(dataTag: "miss_halfway_center_too_short")
146 << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance * 0.25f)
147 << Vector3D(3.0, 1.5, 20.0)
148 << Vector3D(0.0, -1.5, 20.0)
149 << Vector3D(-3, 1.5, 20.0)
150 << Vector3D()
151 << 0.0f
152 << false;
153 QTest::newRow(dataTag: "far_center")
154 << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), farPlaneDistance)
155 << Vector3D(3.0, 1.5, 40.0)
156 << Vector3D(0.0, -1.5, 40.0)
157 << Vector3D(-3, 1.5, 40.0)
158 << Vector3D(0.25, 0.5, 0.25)
159 << 1.0f
160 << true;
161 QTest::newRow(dataTag: "near_center")
162 << Qt3DRender::RayCasting::QRay3D(Vector3D(), Vector3D(0.0, 0.0, 1.0), 1.0f)
163 << Vector3D(3.0, 1.5, 0.0)
164 << Vector3D(0.0, -1.5, 0.0)
165 << Vector3D(-3, 1.5, 0.0)
166 << Vector3D(0.25, 0.5, 0.25)
167 << 0.0f
168 << true;
169 QTest::newRow(dataTag: "above_miss_center")
170 << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, 2.0, 0.0), Vector3D(0.0, 2.0, 1.0), 1.0f)
171 << Vector3D(3.0, 1.5, 0.0)
172 << Vector3D(0.0, -1.5, 0.0)
173 << Vector3D(-3, 1.5, 0.0)
174 << Vector3D()
175 << 0.0f
176 << false;
177 QTest::newRow(dataTag: "below_miss_center")
178 << Qt3DRender::RayCasting::QRay3D(Vector3D(0.0, -2.0, 0.0), Vector3D(0.0, -2.0, 1.0), 1.0f)
179 << Vector3D(3.0, 1.5, 0.0)
180 << Vector3D(0.0, -1.5, 0.0)
181 << Vector3D(-3, 1.5, 0.0)
182 << Vector3D()
183 << 0.0f
184 << false;
185 }
186
187 void intersects()
188 {
189 // GIVEN
190 QFETCH(Qt3DRender::RayCasting::QRay3D, ray);
191 QFETCH(Vector3D, a);
192 QFETCH(Vector3D, b);
193 QFETCH(Vector3D, c);
194 QFETCH(Vector3D, uvw);
195 QFETCH(float, t);
196 QFETCH(bool, isIntersecting);
197
198 // WHEN
199 Vector3D tmp_uvw;
200 float tmp_t;
201 const bool shouldBeIntersecting = Qt3DRender::Render::intersectsSegmentTriangle(ray,
202 a, b, c,
203 uvw&: tmp_uvw,
204 t&: tmp_t);
205
206 // THEN
207 QCOMPARE(shouldBeIntersecting, isIntersecting);
208 if (isIntersecting) {
209 QVERIFY(qFuzzyCompare(uvw, tmp_uvw));
210 QVERIFY(qFuzzyCompare(t, tmp_t));
211 }
212 }
213};
214
215QTEST_APPLESS_MAIN(tst_TriangleBoundingVolume)
216
217#include "tst_triangleboundingvolume.moc"
218

source code of qt3d/tests/auto/render/triangleboundingvolume/tst_triangleboundingvolume.cpp