diff --git a/AUTHORS.md b/AUTHORS.md index 8873113da2..4d03fba227 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -79,6 +79,7 @@ Programmers Eduard Cot (trombonecot) Eli2 Emanuel Guével (potatoesmaster) + Epoch Eris Caffee (eris) eroen escondida diff --git a/CHANGELOG.md b/CHANGELOG.md index 93eb959e18..c2a8c8e34d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -146,6 +146,7 @@ Feature #5173: Support for NiFogProperty Feature #5492: Let rain and snow collide with statics Feature #5926: Refraction based on water depth + Feature #5944: Option to use camera as sound listener Feature #6149: Dehardcode Lua API_REVISION Feature #6152: Playing music via lua scripts Feature #6188: Specular lighting from point light sources diff --git a/apps/launcher/settingspage.cpp b/apps/launcher/settingspage.cpp index c274b75f79..0b5f542888 100644 --- a/apps/launcher/settingspage.cpp +++ b/apps/launcher/settingspage.cpp @@ -294,6 +294,7 @@ bool Launcher::SettingsPage::loadSettings() hrtfProfileSelectorComboBox->setCurrentIndex(hrtfProfileIndex); } } + loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox); } // Interface Changes @@ -490,6 +491,9 @@ void Launcher::SettingsPage::saveSettings() Settings::sound().mHrtf.set(hrtfProfileSelectorComboBox->currentText().toStdString()); else Settings::sound().mHrtf.set({}); + + const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked; + Settings::sound().mCameraListener.set(cCameraListener); } // Interface Changes diff --git a/apps/launcher/ui/settingspage.ui b/apps/launcher/ui/settingspage.ui index a59891eb54..ca23ec1bb4 100644 --- a/apps/launcher/ui/settingspage.ui +++ b/apps/launcher/ui/settingspage.ui @@ -1320,6 +1320,16 @@ + + + + In third-person view, use the camera as the sound listener instead of the player character. + + + Use the camera as the sound listener + + + diff --git a/apps/openmw/mwrender/camera.cpp b/apps/openmw/mwrender/camera.cpp index 86d5699d75..1c163a6701 100644 --- a/apps/openmw/mwrender/camera.cpp +++ b/apps/openmw/mwrender/camera.cpp @@ -109,8 +109,7 @@ namespace MWRender void Camera::updateCamera(osg::Camera* cam) { - osg::Quat orient = osg::Quat(mRoll + mExtraRoll, osg::Vec3d(0, 1, 0)) - * osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1)); + osg::Quat orient = getOrient(); osg::Vec3d forward = orient * osg::Vec3d(0, 1, 0); osg::Vec3d up = orient * osg::Vec3d(0, 0, 1); @@ -209,6 +208,12 @@ namespace MWRender mPosition = focal + offset; } + osg::Quat Camera::getOrient() const + { + return osg::Quat(mRoll + mExtraRoll, osg::Vec3d(0, 1, 0)) * osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) + * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1)); + } + void Camera::setMode(Mode newMode, bool force) { if (mMode == newMode) diff --git a/apps/openmw/mwrender/camera.hpp b/apps/openmw/mwrender/camera.hpp index c6500160fd..e09a265293 100644 --- a/apps/openmw/mwrender/camera.hpp +++ b/apps/openmw/mwrender/camera.hpp @@ -72,6 +72,8 @@ namespace MWRender void setExtraYaw(float angle) { mExtraYaw = angle; } void setExtraRoll(float angle) { mExtraRoll = angle; } + osg::Quat getOrient() const; + /// @param Force view mode switch, even if currently not allowed by the animation. void toggleViewMode(bool force = false); bool toggleVanityMode(bool enable); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e28efbf671..cbef6789f1 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1738,23 +1738,27 @@ namespace MWWorld void World::updateSoundListener() { - osg::Vec3f cameraPosition = mRendering->getCamera()->getPosition(); + const MWRender::Camera* camera = mRendering->getCamera(); const auto& player = getPlayerPtr(); const ESM::Position& refpos = player.getRefData().getPosition(); - osg::Vec3f listenerPos; + osg::Vec3f listenerPos, up, forward; + osg::Quat listenerOrient; - if (isFirstPerson()) - listenerPos = cameraPosition; + if (isFirstPerson() || Settings::sound().mCameraListener) + listenerPos = camera->getPosition(); else listenerPos = refpos.asVec3() + osg::Vec3f(0, 0, 1.85f * mPhysics->getHalfExtents(player).z()); - osg::Quat listenerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0, -1, 0)) - * osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1)); + if (isFirstPerson() || Settings::sound().mCameraListener) + listenerOrient = camera->getOrient(); + else + listenerOrient = osg::Quat(refpos.rot[1], osg::Vec3f(0, -1, 0)) + * osg::Quat(refpos.rot[0], osg::Vec3f(-1, 0, 0)) * osg::Quat(refpos.rot[2], osg::Vec3f(0, 0, -1)); - osg::Vec3f forward = listenerOrient * osg::Vec3f(0, 1, 0); - osg::Vec3f up = listenerOrient * osg::Vec3f(0, 0, 1); + forward = listenerOrient * osg::Vec3f(0, 1, 0); + up = listenerOrient * osg::Vec3f(0, 0, 1); - bool underwater = isUnderwater(player.getCell(), cameraPosition); + bool underwater = isUnderwater(player.getCell(), camera->getPosition()); MWBase::Environment::get().getSoundManager()->setListenerPosDir(listenerPos, forward, up, underwater); } diff --git a/components/settings/categories/sound.hpp b/components/settings/categories/sound.hpp index 995bce2a58..8398a38c55 100644 --- a/components/settings/categories/sound.hpp +++ b/components/settings/categories/sound.hpp @@ -23,6 +23,7 @@ namespace Settings SettingValue mBufferCacheMax{ mIndex, "Sound", "buffer cache max", makeMaxSanitizerInt(1) }; SettingValue mHrtfEnable{ mIndex, "Sound", "hrtf enable" }; SettingValue mHrtf{ mIndex, "Sound", "hrtf" }; + SettingValue mCameraListener{ mIndex, "Sound", "camera listener" }; }; } diff --git a/docs/source/reference/modding/settings/sound.rst b/docs/source/reference/modding/settings/sound.rst index 7a5718735c..dbcad65d0d 100644 --- a/docs/source/reference/modding/settings/sound.rst +++ b/docs/source/reference/modding/settings/sound.rst @@ -127,3 +127,16 @@ Allowed values for this field are enumerated in openmw.log file is an HRTF enabl The default value is empty, which uses the default profile. This setting can be controlled in the Settings tab of the launcher. + +camera listener +--------------- + +:Type: boolean +:Range: True/False +:Default: False + +When true, uses the camera position and direction for audio instead of the player position. +This makes audio in third person sound relative to camera instead of the player. +False is vanilla Morrowind behaviour. + +This setting can be controlled in the Settings tab of the launcher. \ No newline at end of file diff --git a/files/lang/launcher_de.ts b/files/lang/launcher_de.ts index 3b911e2288..11dd865c56 100644 --- a/files/lang/launcher_de.ts +++ b/files/lang/launcher_de.ts @@ -1447,5 +1447,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov Lights minimum interior brightness + + In third-person view, use the camera as the sound listener instead of the player character. + + + + Use the camera as the sound listener + + diff --git a/files/lang/launcher_fr.ts b/files/lang/launcher_fr.ts index 757121d1d3..5df4822808 100644 --- a/files/lang/launcher_fr.ts +++ b/files/lang/launcher_fr.ts @@ -1447,5 +1447,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov Lights minimum interior brightness + + In third-person view, use the camera as the sound listener instead of the player character. + + + + Use the camera as the sound listener + + diff --git a/files/lang/launcher_ru.ts b/files/lang/launcher_ru.ts index dad899aff6..1db804e2df 100644 --- a/files/lang/launcher_ru.ts +++ b/files/lang/launcher_ru.ts @@ -1462,5 +1462,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov Lights minimum interior brightness Минимальный уровень освещения в помещениях + + In third-person view, use the camera as the sound listener instead of the player character. + Использовать в виде от третьего лица положение камеры, а не персонажа игрока для прослушивания звуков. + + + Use the camera as the sound listener + Использовать камеру как слушателя + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 4a90a46cc5..1caf03c123 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -608,6 +608,9 @@ hrtf enable = -1 # Specifies which HRTF to use when HRTF is used. Blank means use the default. hrtf = +# Specifies whether to use camera as audio listener +camera listener = false + [Video] # Resolution of the OpenMW window or screen.