1// Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qlevelofdetail.h"
5#include "qlevelofdetail_p.h"
6#include "qcamera.h"
7
8QT_BEGIN_NAMESPACE
9
10namespace Qt3DRender {
11
12QLevelOfDetailPrivate::QLevelOfDetailPrivate()
13 : QComponentPrivate()
14 , m_camera(nullptr)
15 , m_currentIndex(0)
16 , m_thresholdType(QLevelOfDetail::DistanceToCameraThreshold)
17 , m_volumeOverride()
18{
19}
20
21void QLevelOfDetailPrivate::setCurrentIndex(int currentIndex)
22{
23 Q_Q(QLevelOfDetail);
24 if (m_currentIndex != currentIndex) {
25 m_currentIndex = currentIndex;
26 emit q->currentIndexChanged(currentIndex: m_currentIndex);
27 }
28}
29
30/*!
31 \class Qt3DRender::QLevelOfDetail
32 \inmodule Qt3DRender
33 \since 5.9
34 \brief The QLevelOfDetail class provides a way of controlling the complexity
35 of rendered entities based on their size on the screen.
36
37 QLevelOfDetail can be used to control the representation of an entity
38 based on distance from the observer or size on the screen.
39
40 In order to improve rendering performance, objects that are very small
41 can be rendered using far fewer details, in geometry or texture.
42
43 The component is controlled by specifying thresholds of values which are interpreted
44 as either distances from the camera or screen size.
45
46 As the point of view changes, the currentIndex property will change to
47 reflect matching value in the range array.
48
49 The currentIndex property can then be used, for example, to enable or
50 disable entities, change material, etc.
51
52 The LevelOfDetail component is not shareable between multiple \l [QML]{Entity}{entities}.
53
54 \code
55 #include <Qt3DCore/QEntity>
56 #include <Qt3DRender/QGeometryRenderer>
57 #include <Qt3DRender/QLevelOfDetail>
58
59 // Scene
60 Qt3DCore::QEntity *rootEntity = new Qt3DCore::Qt3DCore::QEntity;
61
62 Qt3DCore::QEntity *renderableEntity = new Qt3DCore::QEntity(rootEntity);
63 Qt3DRender::QGeometryRenderer *geometryRenderer = new Qt3DCore::QGeometryRenderer(renderableEntity);
64 renderableEntity->addComponent(geometryRenderer);
65 Qt3DRender::QLevelOfDetail* lod = new Qt3Render::QLevelOfDetail(renderableEntity);
66 QList<qreal> thresholds = {20, 35, 50, 65};
67 lod->setThresholds(thresholds);
68 lod->setCamera(mainCamera);
69 renderableEntity->addComponent(lod);
70
71 // connect to QLevelOfDetail::currentIndexChanged to toggle rendering
72 ...
73 \endcode
74*/
75
76/*!
77 \qmltype LevelOfDetail
78 \instantiates Qt3DRender::QLevelOfDetail
79 \inherits Component3D
80 \inqmlmodule Qt3D.Render
81 \since 5.9
82 \brief LevelOfDetail provides a way of controlling the complexity of
83 rendered entities based on their size on the screen.
84
85 LevelOfDetail can be used to control the representation of an entity
86 based on distance from the observer or size on the screen.
87
88 In order to improve rendering performance, objects that are very small
89 can be rendered using far fewer details, in geometry or texture.
90
91 The component is controlled by specifying thresholds of values which are interpreted
92 as either distances from the camera or screen size.
93
94 As the point of view changes, the currentIndex property will change to
95 reflect matching value in the range array.
96
97 The currentIndex property can then be used, for example, to enable or
98 disable entities, change source in an EntityLoader, or material.
99
100 The LevelOfDetail component is not shareable between multiple Entity's.
101
102 \code
103 import Qt3D.Core 2.0
104 import Qt3D.Render 2.0
105
106 Entity {
107 id: root
108
109 // Scene
110 Camera { id: mainCamera }
111
112 LevelOfDetail {
113 id: lod
114 camera: mainCamera
115 thresholds: [20, 35, 50, 65]
116 thresholdType: LevelOfDetail.DistanceToCameraThreshold
117 }
118
119 GeometryRenderer {
120 id: mesh
121 view: CylinderMesh {
122 property var sliceValues: [20, 10, 6, 4]
123 slices: sliceValues[lod.currentIndex]
124 }
125 }
126
127 Entity {
128 id: renderableEntity
129 components: [ mesh, lod ]
130 }
131 }
132 \endcode
133*/
134
135
136/*!
137 * \enum Qt3DRender::QLevelOfDetail::ThresholdType
138 *
139 * Specifies how the values in the thresholds are interpreted
140 *
141 * \value DistanceToCameraThreshold Distance from the entity to the selected camera
142 * \value ProjectedScreenPixelSizeThreshold Size of the entity when projected on the
143 * screen as seen from the selected camera, expressed in number of
144 * pixels on the side of the bounding square in screen space.
145 */
146
147/*!
148 * \qmlproperty enumeration LevelOfDetail::ThresholdType
149 *
150 * Specifies how the values in the thresholds are interpreted
151 *
152 * \list
153 * \li DistanceToCameraThreshold Distance from the entity to the selected camera
154 * \li ProjectedScreenPixelSizeThreshold Size of the entity when projected on the
155 * screen as seen from the selected camera, expressed in number of
156 * pixels on the side of the bounding square in screen space.
157 * \endlist
158 * \sa Qt3DRender::QLevelOfDetail::ThresholdType
159 */
160
161/*!
162 * \qmlproperty Camera LevelOfDetail::camera
163 *
164 * Holds the id of the camera that is used to compute the actual distance or the screen size.
165 */
166
167/*!
168 * \property QLevelOfDetail::camera
169 *
170 * Holds the id of the camera that is used to compute the actual distance or the screen size.
171 */
172
173/*!
174 * \qmlproperty int LevelOfDetail::currentIndex
175 *
176 * The index in the range array which matches the current distance to the camera or screen size.
177 */
178
179/*!
180 * \property QLevelOfDetail::currentIndex
181 *
182 * The index in the range array which matches the current distance to the camera or screen size.
183 */
184
185/*!
186 * \qmlproperty int LevelOfDetail::thresholdType
187 *
188 * Specifies how range values are interpreted.
189 */
190
191/*!
192 * \property QLevelOfDetail::thresholdType
193 *
194 * Specifies how range values are interpreted.
195 * \sa Qt3DRender::QLevelOfDetail::ThresholdType
196 */
197
198/*!
199 * \qmlproperty QList<qreal> LevelOfDetail::thresholds
200 *
201 * Array of range values as float point numbers. The value for the most detailed representation
202 * should be specified first.
203 *
204 * If LevelOfDetail::thresholdType is set to LevelOfDetail.DistanceToCameraThreshold, values should
205 * be specified in ascending order, in camera space coordinates
206 *
207 * If LevelOfDetail::thresholdType is set to LevelOfDetail.ProjectedScreenPixelSizeThreshold, values
208 * should be specified in descending order, in screen space pixels.
209 */
210
211/*!
212 * \property QLevelOfDetail::thresholds
213 *
214 * Array of range values as float point numbers. The value for the most detailed representation
215 * should be specified first.
216 *
217 * If Qt3DRender::QLevelOfDetail::thresholdType is set to
218 * Qt3DRender::QLevelOfDetail::DistanceToCameraThreshold, values should be specified in
219 * ascending order, in camera space coordinates
220 *
221 * If Qt3DRender::QLevelOfDetail::thresholdType is set to
222 * Qt3DRender::QLevelOfDetail::ProjectedScreenPixelSizeThreshold, values should
223 * be specified in descending order, in screen space pixels.
224 *
225 * \sa Qt3DRender::QLevelOfDetail::ThresholdType
226 */
227
228/*!
229 * \qmlproperty int LevelOfDetail::volumeOverride
230 *
231 * Specifies what is used to evaluate the distance or screen size.
232 *
233 * The default is a sphere of radius 1 and centered at the local origin of the entity.
234 * This proxy volume is used to compute the distance to the camera or the size
235 * of the screen projection.
236 *
237 * If this value to null, the bounding volume of the entity is used. Care must be
238 * taken that this bounding volume never becomes invalid.
239 *
240 * \sa Qt3DRender::QLevelOfDetailBoundingSphere
241 */
242
243/*!
244 * \property QLevelOfDetail::volumeOverride
245 *
246 * The default is a sphere of radius 1 and centered at the local origin of the entity.
247 * This proxy volume is used to compute the distance to the camera or the size
248 * of the screen projection.
249 *
250 * If this value to nullptr, the bounding volume of the entity is used. Care must be
251 * taken that this bounding volume never becomes invalid.
252 *
253 * \sa Qt3DRender::QLevelOfDetailBoundingSphere
254 */
255
256
257/*! \fn Qt3DRender::QLevelOfDetail::QLevelOfDetail(Qt3DCore::QNode *parent)
258 Constructs a new QLevelOfDetail with the specified \a parent.
259 */
260QLevelOfDetail::QLevelOfDetail(QNode *parent)
261 : QComponent(*new QLevelOfDetailPrivate, parent)
262{
263}
264
265/*! \internal */
266QLevelOfDetail::~QLevelOfDetail()
267{
268}
269
270/*! \internal */
271QLevelOfDetail::QLevelOfDetail(QLevelOfDetailPrivate &dd, QNode *parent)
272 : QComponent(dd, parent)
273{
274}
275
276QCamera *QLevelOfDetail::camera() const
277{
278 Q_D(const QLevelOfDetail);
279 return d->m_camera;
280}
281
282/*!
283 * Sets the \a camera relative to which distance and size are computed.
284 */
285void QLevelOfDetail::setCamera(QCamera *camera)
286{
287 Q_D(QLevelOfDetail);
288 if (d->m_camera != camera) {
289 d->m_camera = camera;
290 emit cameraChanged(camera: d->m_camera);
291 }
292}
293
294int QLevelOfDetail::currentIndex() const
295{
296 Q_D(const QLevelOfDetail);
297 return d->m_currentIndex;
298}
299
300/*!
301 * Sets the \a currentIndex.
302 *
303 * \note This should not normally be set by the user.
304 *
305 * However, if the component is disabled, then changing the
306 * current index is a simple way of switching between multiple
307 * representations.
308 */
309void QLevelOfDetail::setCurrentIndex(int currentIndex)
310{
311 Q_D(QLevelOfDetail);
312 d->setCurrentIndex(currentIndex);
313}
314
315QLevelOfDetail::ThresholdType QLevelOfDetail::thresholdType() const
316{
317 Q_D(const QLevelOfDetail);
318 return d->m_thresholdType;
319}
320
321/*!
322 * Sets the way thresholds values are interpreted
323 * with parameter \a thresholdType
324 * \sa Qt3DRender::QLevelOfDetail::ThresholdType
325 */
326void QLevelOfDetail::setThresholdType(QLevelOfDetail::ThresholdType thresholdType)
327{
328 Q_D(QLevelOfDetail);
329 if (d->m_thresholdType != thresholdType) {
330 d->m_thresholdType = thresholdType;
331 emit thresholdTypeChanged(thresholdType: d->m_thresholdType);
332 }
333}
334
335QList<qreal> QLevelOfDetail::thresholds() const
336{
337 Q_D(const QLevelOfDetail);
338 return d->m_thresholds;
339}
340
341QLevelOfDetailBoundingSphere QLevelOfDetail::createBoundingSphere(const QVector3D &center, float radius)
342{
343 return QLevelOfDetailBoundingSphere(center, radius);
344}
345
346/*!
347 * Sets the range values in \a thresholds.
348 * \sa Qt3DRender::QLevelOfDetail::thresholdType
349 */
350void QLevelOfDetail::setThresholds(const QList<qreal> &thresholds)
351{
352 Q_D(QLevelOfDetail);
353 if (d->m_thresholds != thresholds) {
354 d->m_thresholds = thresholds;
355 emit thresholdsChanged(thresholds: d->m_thresholds);
356 }
357}
358
359QLevelOfDetailBoundingSphere QLevelOfDetail::volumeOverride() const
360{
361 Q_D(const QLevelOfDetail);
362 return d->m_volumeOverride;
363}
364
365void QLevelOfDetail::setVolumeOverride(const QLevelOfDetailBoundingSphere &volumeOverride)
366{
367 Q_D(QLevelOfDetail);
368 if (d->m_volumeOverride != volumeOverride) {
369 d->m_volumeOverride = volumeOverride;
370 emit volumeOverrideChanged(volumeOverride);
371 }
372}
373
374} // namespace Qt3DRender
375
376QT_END_NAMESPACE
377
378#include "moc_qlevelofdetail.cpp"
379

source code of qt3d/src/render/frontend/qlevelofdetail.cpp