Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquick3dlightmapbaker.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5
8
10
11/*!
12 \class QQuick3DLightmapBaker
13 \inmodule QtQuick3D
14 \internal
15*/
16
17QQuick3DLightmapBaker::QQuick3DLightmapBaker(QQuick3DViewport *view) :
18 QObject(view), m_bakingControl(new BakingControl()), m_view(view)
19{
20
21}
22
23QQuick3DLightmapBaker::~QQuick3DLightmapBaker()
24{
25 if (m_lmWindow) {
26 m_lmWindow->close();
27 delete m_lmWindow;
28 }
29
30 delete m_bakingControl;
31}
32
33/*!
34 Triggers a new frame where lightmap baking will take place.
35 Will call \a callback for feedback and handling.
36
37 \note Lightmap baking is a slow blocking operation running on the
38 render thread. The application will be frozen until completed.
39*/
40void QQuick3DLightmapBaker::bake(Callback callback)
41{
42 Q_ASSERT(m_view);
43 m_bakingRequested = true;
44 m_bakingControl->reset();
45 m_callback = callback;
46 updateView();
47}
48
49/*!
50 \internal
51*/
52void QQuick3DLightmapBaker::bake()
53{
54 Q_ASSERT(m_view);
55 if (m_currentlyBaking)
56 return;
57
58 m_bakingRequested = true;
59 m_bakingControl->reset();
60
61 m_windowCancelRequested = false;
62
63 if (!m_lmWindow) {
64 m_lmWindow = new QQuickView();
65 m_lmWindow->setSource(QUrl::fromLocalFile(QStringLiteral(":/qt-project.org/imports/QtQuick3D/LightmapperOutputWindow.qml")));
66 m_lmWindow->show();
67 m_lmWindow->setProperty("width", 400);
68 m_lmWindow->setProperty("height", 400);
69
70 QObject *rootObject = m_lmWindow->rootObject();
71 QObject *cancelButton = rootObject->findChild<QObject *>(QStringLiteral("cancelButton"));
72 if (cancelButton)
73 QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(onLmCancelButtonClicked()));
74
75 QObject::connect(m_lmWindow, &QQuickWindow::closing, this, &QQuick3DLightmapBaker::onLmWindowClosing);
76 } else {
77 QObject *rootObject = m_lmWindow->rootObject();
78 QMetaObject::invokeMethod(rootObject, "clearText");
79 }
80
81 m_callback = [this] (const QVariantMap &payload, BakingControl *bakingControl) {
82 if (m_windowCancelRequested && !bakingControl->isCancelled())
83 bakingControl->requestCancel();
84
85 const BakingStatus status = static_cast<BakingStatus>(payload[QStringLiteral("status")].toInt());
86
87 QQuickWindow *window = m_view->window();
88 if (status == BakingStatus::Complete) {
89 m_currentlyBaking = false;
90 QQuickWindowPrivate::get(window)->updatesEnabled = true;
91 } else if (status != BakingStatus::None) {
92 if (status == BakingStatus::Cancelled || status == BakingStatus::Failed) {
93 m_currentlyBaking = false;
94 }
95
96 if (m_lmWindow) {
97 QObject *rootObject = m_lmWindow->rootObject();
98
99 QString msg;
100 if (payload.contains(QStringLiteral("message"))) {
101 msg = payload[QStringLiteral("message")].toString();
102 }
103 if (!msg.isEmpty()) {
104 if (status == BakingStatus::Warning)
105 msg.prepend(QStringLiteral("Warning: "));
106 else if (status == BakingStatus::Error)
107 msg.prepend(QStringLiteral("Error: "));
108
109 }
110
111 QMetaObject::invokeMethod(rootObject, "update", Q_ARG(QVariant, payload));
112 }
113 }
114 };
115
116 m_currentlyBaking = true;
117 updateView();
118}
119
120/*!
121 Triggers a new frame where lightmap denoising will take place.
122 Will call \a callback for feedback and handling.
123*/
124void QQuick3DLightmapBaker::denoise(Callback callback)
125{
126 Q_ASSERT(m_view);
127 m_denoisingRequested = true;
128 m_bakingControl->reset();
129 m_callback = callback;
130 updateView();
131}
132
133/*!
134 \internal
135*/
136void QQuick3DLightmapBaker::denoise()
137{
138 Q_ASSERT(m_view);
139 if (m_currentlyBaking)
140 return;
141 m_denoisingRequested = true;
142 m_bakingControl->reset();
143
144 m_windowCancelRequested = false;
145
146 if (!m_lmWindow) {
147 m_lmWindow = new QQuickView();
148 m_lmWindow->setSource(QUrl::fromLocalFile(QStringLiteral(":/qt-project.org/imports/QtQuick3D/LightmapperOutputWindow.qml")));
149 m_lmWindow->show();
150 m_lmWindow->setProperty("width", 400);
151 m_lmWindow->setProperty("height", 400);
152
153 QObject *rootObject = m_lmWindow->rootObject();
154 QObject *cancelButton = rootObject->findChild<QObject *>(QStringLiteral("cancelButton"));
155 if (cancelButton)
156 QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(onLmCancelButtonClicked()));
157
158 QObject::connect(m_lmWindow, &QQuickWindow::closing, this, &QQuick3DLightmapBaker::onLmWindowClosing);
159 } else {
160 QObject *rootObject = m_lmWindow->rootObject();
161 QMetaObject::invokeMethod(rootObject, "clearText");
162 }
163
164 m_callback = [this] (const QVariantMap &payload, BakingControl *bakingControl) {
165 if (m_windowCancelRequested && !bakingControl->isCancelled())
166 bakingControl->requestCancel();
167
168 const BakingStatus status = static_cast<BakingStatus>(payload[QStringLiteral("status")].toInt());
169
170 QQuickWindow *window = m_view->window();
171 if (status == BakingStatus::Complete) {
172 QMetaObject::invokeMethod(window, "releaseResources", Qt::QueuedConnection);
173 updateView();
174 m_currentlyBaking = false;
175 QQuickWindowPrivate::get(window)->updatesEnabled = true;
176 } else if (status != BakingStatus::None) {
177 if (status == BakingStatus::Cancelled || status == BakingStatus::Failed)
178 m_currentlyBaking = false;
179
180 if (m_lmWindow) {
181 QObject *rootObject = m_lmWindow->rootObject();
182
183 QString msg;
184 if (payload.contains(QStringLiteral("message"))) {
185 msg = payload[QStringLiteral("message")].toString();
186 }
187 if (!msg.isEmpty()) {
188 if (status == BakingStatus::Warning)
189 msg.prepend(QStringLiteral("Warning: "));
190 else if (status == BakingStatus::Error)
191 msg.prepend(QStringLiteral("Error: "));
192
193 }
194
195 QMetaObject::invokeMethod(rootObject, "update", Q_ARG(QVariant, payload));
196 }
197 }
198 };
199
200 m_currentlyBaking = true;
201 updateView();
202}
203
204void QQuick3DLightmapBaker::updateView()
205{
206 QMetaObject::invokeMethod(m_view, "update", Qt::QueuedConnection);
207}
208
209void QQuick3DLightmapBaker::onLmCancelButtonClicked()
210{
211 if (m_windowCancelRequested)
212 return;
213
214 m_windowCancelRequested = true;
215}
216
217void QQuick3DLightmapBaker::onLmWindowClosing(QQuickCloseEvent *event)
218{
219 Q_UNUSED(event);
220
221 onLmCancelButtonClicked();
222 m_lmWindow->deleteLater();
223 m_lmWindow = nullptr;
224}
225
226void QQuick3DLightmapBaker::BakingControl::reset() {
227 cancelFlag = false;
228}
229
230void QQuick3DLightmapBaker::BakingControl::requestCancel() {
231 cancelFlag = true;
232}
233
234bool QQuick3DLightmapBaker::BakingControl::isCancelled() const {
235 return cancelFlag;
236}
237
238QT_END_NAMESPACE
Combined button and popup list for selecting options.