185 if (!engine || sourceId < 0)
187 auto *ep = QAudioEnginePrivate::get(engine);
188 if (!ep->currentRoom())
190 auto *rp = QAudioRoomPrivate::get(ep->currentRoom());
194 auto listenerPos = ep->listenerPosition();
198 QVector3D roomDim2 = ep->currentRoom()->dimensions() / 2.;
199 QVector3D roomPos = ep->currentRoom()->position();
200 QQuaternion roomRot = ep->currentRoom()->rotation();
201 QVector3D dist = pos - roomPos;
203 dist = roomRot.rotatedVector(dist);
204 if (qAbs(dist.x()) <= roomDim2.x() &&
205 qAbs(dist.y()) <= roomDim2.y() &&
206 qAbs(dist.z()) <= roomDim2.z()) {
208 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 1);
217 auto relativeListenerPos = *listenerPos - roomPos;
218 relativeListenerPos = roomRot.rotatedVector(relativeListenerPos);
220 auto direction = dist.normalized();
226 const float transitionDistance =
size + 0.4;
227 QAudioRoom::Wall walls[3];
228 walls[X] = direction.x() > 0 ? QAudioRoom::RightWall : QAudioRoom::LeftWall;
229 walls[Y] = direction.y() > 0 ? QAudioRoom::FrontWall : QAudioRoom::BackWall;
230 walls[Z] = direction.z() > 0 ? QAudioRoom::Ceiling : QAudioRoom::Floor;
231 float factors[3] = { 0., 0., 0. };
232 bool foundWall =
false;
233 if (direction.x() != 0) {
234 float sign = direction.x() > 0 ? 1.f : -1.f;
235 float dx = sign * roomDim2.x() - relativeListenerPos.x();
236 QVector3D intersection = relativeListenerPos + direction*dx/direction.x();
237 float dy = roomDim2.y() - qAbs(intersection.y());
238 float dz = roomDim2.z() - qAbs(intersection.z());
239 if (dy > 0 && dz > 0) {
242 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
243 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
244 factors[X] = 1.f - factors[Y] - factors[Z];
248 if (!foundWall && direction.y() != 0) {
249 float sign = direction.y() > 0 ? 1.f : -1.f;
250 float dy = sign * roomDim2.y() - relativeListenerPos.y();
251 QVector3D intersection = relativeListenerPos + direction*dy/direction.y();
252 float dx = roomDim2.x() - qAbs(intersection.x());
253 float dz = roomDim2.z() - qAbs(intersection.z());
254 if (dx > 0 && dz > 0) {
257 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
258 factors[Z] = qMax(0.f, 1.f/3.f - dz/transitionDistance);
259 factors[Y] = 1.f - factors[X] - factors[Z];
264 Q_ASSERT(direction.z() != 0);
265 float sign = direction.z() > 0 ? 1.f : -1.f;
266 float dz = sign * roomDim2.z() - relativeListenerPos.z();
267 QVector3D intersection = relativeListenerPos + direction*dz/direction.z();
268 float dx = roomDim2.x() - qAbs(intersection.x());
269 float dy = roomDim2.y() - qAbs(intersection.y());
270 if (dx > 0 && dy > 0) {
273 factors[X] = qMax(0.f, 1.f/3.f - dx/transitionDistance);
274 factors[Y] = qMax(0.f, 1.f/3.f - dy/transitionDistance);
275 factors[Z] = 1.f - factors[X] - factors[Y];
281 for (
int i = 0; i < 3; ++i) {
287 ep->resonanceAudio->api->SetSourceRoomEffectsGain(sourceId, 0);
290 ep->resonanceAudio->api->SetSourceVolume(sourceId, volume*wallDampening);