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