1// Copyright (C) 2018 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 "raycaster_p.h"
5#include "qpickevent.h"
6#include <Qt3DRender/private/abstractrenderer_p.h>
7#include <Qt3DRender/qabstractraycaster.h>
8#include <Qt3DRender/qlayer.h>
9#include <Qt3DRender/private/qabstractraycaster_p.h>
10#include <Qt3DRender/private/raycastingjob_p.h>
11#include <Qt3DRender/private/qrenderaspect_p.h>
12
13QT_BEGIN_NAMESPACE
14
15using namespace Qt3DCore;
16
17namespace Qt3DRender {
18
19namespace Render {
20
21RayCaster::RayCaster()
22 : BackendNode(QBackendNode::ReadWrite)
23{
24}
25
26RayCaster::~RayCaster()
27{
28 notifyJob();
29}
30
31QAbstractRayCasterPrivate::RayCasterType RayCaster::type() const
32{
33 return m_type;
34}
35
36QAbstractRayCaster::RunMode RayCaster::runMode() const
37{
38 return m_runMode;
39}
40
41QVector3D RayCaster::origin() const
42{
43 return m_origin;
44}
45
46QVector3D RayCaster::direction() const
47{
48 return m_direction;
49}
50
51float RayCaster::length() const
52{
53 return m_length;
54}
55
56QPoint RayCaster::position() const
57{
58 return m_position;
59}
60
61Qt3DCore::QNodeIdVector RayCaster::layerIds() const
62{
63 return m_layerIds;
64}
65
66QAbstractRayCaster::FilterMode RayCaster::filterMode() const
67{
68 return m_filterMode;
69}
70
71void RayCaster::cleanup()
72{
73 BackendNode::setEnabled(false);
74 m_type = QAbstractRayCasterPrivate::WorldSpaceRayCaster;
75 m_runMode = QAbstractRayCaster::SingleShot;
76 m_direction = QVector3D(0.f, 0.f, 1.f);
77 m_origin = {};
78 m_length = 0.f;
79 m_position = {};
80 m_filterMode = QAbstractRayCaster::AcceptAllMatchingLayers;
81 m_layerIds.clear();
82 notifyJob();
83}
84
85void RayCaster::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
86{
87 const QAbstractRayCaster *node = qobject_cast<const QAbstractRayCaster *>(object: frontEnd);
88 if (!node)
89 return;
90
91 BackendNode::syncFromFrontEnd(frontEnd, firstTime);
92
93 if (node->runMode() != m_runMode) {
94 m_runMode = node->runMode();
95 notifyJob();
96 markDirty(changes: AbstractRenderer::AllDirty);
97 }
98
99 if (node->filterMode() != m_filterMode) {
100 m_filterMode = node->filterMode();
101 notifyJob();
102 markDirty(changes: AbstractRenderer::AllDirty);
103 }
104
105 const Qt3DCore::QNodeIdVector layerIds = Qt3DCore::qIdsForNodes(nodes: node->layers());
106 if (layerIds != m_layerIds) {
107 m_layerIds = layerIds;
108 markDirty(changes: AbstractRenderer::LayersDirty);
109 notifyJob();
110 }
111
112 const QAbstractRayCasterPrivate *d = static_cast<const QAbstractRayCasterPrivate *>(QNodePrivate::get(q: node));
113 if (d->m_direction != m_direction) {
114 m_direction = d->m_direction;
115 notifyJob();
116 markDirty(changes: AbstractRenderer::AllDirty);
117 }
118
119 if (!qFuzzyCompare(p1: d->m_length, p2: m_length)) {
120 m_length = d->m_length;
121 notifyJob();
122 markDirty(changes: AbstractRenderer::AllDirty);
123 }
124
125 if (d->m_origin != m_origin) {
126 m_origin = d->m_origin;
127 notifyJob();
128 markDirty(changes: AbstractRenderer::AllDirty);
129 }
130
131 if (d->m_position != m_position) {
132 m_position = d->m_position;
133 notifyJob();
134 markDirty(changes: AbstractRenderer::AllDirty);
135 }
136
137 if (d->m_rayCasterType != m_type) {
138 m_type = d->m_rayCasterType;
139 notifyJob();
140 markDirty(changes: AbstractRenderer::AllDirty);
141 }
142}
143
144void RayCaster::notifyJob()
145{
146 if (m_renderer && m_renderer->aspect())
147 QRenderAspectPrivate::get(q: m_renderer->aspect())->m_rayCastingJob->markCastersDirty();
148}
149
150} // Render
151
152} // Qt3DRender
153
154QT_END_NAMESPACE
155

source code of qt3d/src/render/picking/raycaster.cpp