Merge branch 'decoupled-audio' into 'master'

Add option to use camera as sound listener

Closes #5944

See merge request OpenMW/openmw!3836
BindlessTest
psi29a 11 months ago
commit 744cd50520

@ -79,6 +79,7 @@ Programmers
Eduard Cot (trombonecot) Eduard Cot (trombonecot)
Eli2 Eli2
Emanuel Guével (potatoesmaster) Emanuel Guével (potatoesmaster)
Epoch
Eris Caffee (eris) Eris Caffee (eris)
eroen eroen
escondida escondida

@ -146,6 +146,7 @@
Feature #5173: Support for NiFogProperty Feature #5173: Support for NiFogProperty
Feature #5492: Let rain and snow collide with statics Feature #5492: Let rain and snow collide with statics
Feature #5926: Refraction based on water depth Feature #5926: Refraction based on water depth
Feature #5944: Option to use camera as sound listener
Feature #6149: Dehardcode Lua API_REVISION Feature #6149: Dehardcode Lua API_REVISION
Feature #6152: Playing music via lua scripts Feature #6152: Playing music via lua scripts
Feature #6188: Specular lighting from point light sources Feature #6188: Specular lighting from point light sources

@ -294,6 +294,7 @@ bool Launcher::SettingsPage::loadSettings()
hrtfProfileSelectorComboBox->setCurrentIndex(hrtfProfileIndex); hrtfProfileSelectorComboBox->setCurrentIndex(hrtfProfileIndex);
} }
} }
loadSettingBool(Settings::sound().mCameraListener, *cameraListenerCheckBox);
} }
// Interface Changes // Interface Changes
@ -490,6 +491,9 @@ void Launcher::SettingsPage::saveSettings()
Settings::sound().mHrtf.set(hrtfProfileSelectorComboBox->currentText().toStdString()); Settings::sound().mHrtf.set(hrtfProfileSelectorComboBox->currentText().toStdString());
else else
Settings::sound().mHrtf.set({}); Settings::sound().mHrtf.set({});
const bool cCameraListener = cameraListenerCheckBox->checkState() != Qt::Unchecked;
Settings::sound().mCameraListener.set(cCameraListener);
} }
// Interface Changes // Interface Changes

@ -1320,6 +1320,16 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="0" column="0">
<widget class="QCheckBox" name="cameraListenerCheckBox">
<property name="toolTip">
<string>In third-person view, use the camera as the sound listener instead of the player character.</string>
</property>
<property name="text">
<string>Use the camera as the sound listener</string>
</property>
</widget>
</item>
<item> <item>
<spacer> <spacer>
<property name="orientation"> <property name="orientation">

@ -109,8 +109,7 @@ namespace MWRender
void Camera::updateCamera(osg::Camera* cam) void Camera::updateCamera(osg::Camera* cam)
{ {
osg::Quat orient = osg::Quat(mRoll + mExtraRoll, osg::Vec3d(0, 1, 0)) osg::Quat orient = getOrient();
* osg::Quat(mPitch + mExtraPitch, osg::Vec3d(1, 0, 0)) * osg::Quat(mYaw + mExtraYaw, osg::Vec3d(0, 0, 1));
osg::Vec3d forward = orient * osg::Vec3d(0, 1, 0); osg::Vec3d forward = orient * osg::Vec3d(0, 1, 0);
osg::Vec3d up = orient * osg::Vec3d(0, 0, 1); osg::Vec3d up = orient * osg::Vec3d(0, 0, 1);
@ -209,6 +208,12 @@ namespace MWRender
mPosition = focal + offset; 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) void Camera::setMode(Mode newMode, bool force)
{ {
if (mMode == newMode) if (mMode == newMode)

@ -72,6 +72,8 @@ namespace MWRender
void setExtraYaw(float angle) { mExtraYaw = angle; } void setExtraYaw(float angle) { mExtraYaw = angle; }
void setExtraRoll(float angle) { mExtraRoll = angle; } void setExtraRoll(float angle) { mExtraRoll = angle; }
osg::Quat getOrient() const;
/// @param Force view mode switch, even if currently not allowed by the animation. /// @param Force view mode switch, even if currently not allowed by the animation.
void toggleViewMode(bool force = false); void toggleViewMode(bool force = false);
bool toggleVanityMode(bool enable); bool toggleVanityMode(bool enable);

@ -1738,23 +1738,27 @@ namespace MWWorld
void World::updateSoundListener() void World::updateSoundListener()
{ {
osg::Vec3f cameraPosition = mRendering->getCamera()->getPosition(); const MWRender::Camera* camera = mRendering->getCamera();
const auto& player = getPlayerPtr(); const auto& player = getPlayerPtr();
const ESM::Position& refpos = player.getRefData().getPosition(); const ESM::Position& refpos = player.getRefData().getPosition();
osg::Vec3f listenerPos; osg::Vec3f listenerPos, up, forward;
osg::Quat listenerOrient;
if (isFirstPerson()) if (isFirstPerson() || Settings::sound().mCameraListener)
listenerPos = cameraPosition; listenerPos = camera->getPosition();
else else
listenerPos = refpos.asVec3() + osg::Vec3f(0, 0, 1.85f * mPhysics->getHalfExtents(player).z()); 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)) 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::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); forward = listenerOrient * osg::Vec3f(0, 1, 0);
osg::Vec3f up = listenerOrient * osg::Vec3f(0, 0, 1); 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); MWBase::Environment::get().getSoundManager()->setListenerPosDir(listenerPos, forward, up, underwater);
} }

@ -23,6 +23,7 @@ namespace Settings
SettingValue<int> mBufferCacheMax{ mIndex, "Sound", "buffer cache max", makeMaxSanitizerInt(1) }; SettingValue<int> mBufferCacheMax{ mIndex, "Sound", "buffer cache max", makeMaxSanitizerInt(1) };
SettingValue<HrtfMode> mHrtfEnable{ mIndex, "Sound", "hrtf enable" }; SettingValue<HrtfMode> mHrtfEnable{ mIndex, "Sound", "hrtf enable" };
SettingValue<std::string> mHrtf{ mIndex, "Sound", "hrtf" }; SettingValue<std::string> mHrtf{ mIndex, "Sound", "hrtf" };
SettingValue<bool> mCameraListener{ mIndex, "Sound", "camera listener" };
}; };
} }

@ -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. The default value is empty, which uses the default profile.
This setting can be controlled in the Settings tab of the launcher. 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.

@ -1447,5 +1447,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
<source>Lights minimum interior brightness</source> <source>Lights minimum interior brightness</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>In third-person view, use the camera as the sound listener instead of the player character.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Use the camera as the sound listener</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
</TS> </TS>

@ -1447,5 +1447,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
<source>Lights minimum interior brightness</source> <source>Lights minimum interior brightness</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>In third-person view, use the camera as the sound listener instead of the player character.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Use the camera as the sound listener</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
</TS> </TS>

@ -1462,5 +1462,13 @@ to default Morrowind fonts. Check this box if you still prefer original fonts ov
<source>Lights minimum interior brightness</source> <source>Lights minimum interior brightness</source>
<translation>Минимальный уровень освещения в помещениях</translation> <translation>Минимальный уровень освещения в помещениях</translation>
</message> </message>
<message>
<source>In third-person view, use the camera as the sound listener instead of the player character.</source>
<translation>Использовать в виде от третьего лица положение камеры, а не персонажа игрока для прослушивания звуков.</translation>
</message>
<message>
<source>Use the camera as the sound listener</source>
<translation>Использовать камеру как слушателя</translation>
</message>
</context> </context>
</TS> </TS>

@ -608,6 +608,9 @@ hrtf enable = -1
# Specifies which HRTF to use when HRTF is used. Blank means use the default. # Specifies which HRTF to use when HRTF is used. Blank means use the default.
hrtf = hrtf =
# Specifies whether to use camera as audio listener
camera listener = false
[Video] [Video]
# Resolution of the OpenMW window or screen. # Resolution of the OpenMW window or screen.

Loading…
Cancel
Save